void ProgressBar::_notification(int p_what) { if (p_what==NOTIFICATION_DRAW) { Ref<StyleBox> bg = get_stylebox("bg"); Ref<StyleBox> fg = get_stylebox("fg"); Ref<Font> font = get_font("font"); Color font_color=get_color("font_color"); Color font_color_shadow=get_color("font_color_shadow"); draw_style_box(bg,Rect2(Point2(),get_size())); float r = get_unit_value(); int mp = fg->get_minimum_size().width; int p = r*get_size().width-mp; if (p>0) { draw_style_box(fg,Rect2(Point2(),Size2(p+fg->get_minimum_size().width,get_size().height))); } int fh=font->get_height(); String txt=itos(int(get_unit_value()*100))+"%"; font->draw_halign(get_canvas_item(),Point2(0,font->get_ascent()+(get_size().height-font->get_height())/2),HALIGN_CENTER,get_size().width,txt,font_color); } }
void ReferenceFrame::_notification(int p_what) { if (p_what==NOTIFICATION_DRAW) { if (!is_inside_scene()) return; if (get_scene()->is_editor_hint()) draw_style_box(get_stylebox("border"),Rect2(Point2(),get_size())) ; } }
void GraphNode::_notification(int p_what) { if (p_what==NOTIFICATION_DRAW) { Ref<StyleBox> sb=get_stylebox("frame"); Ref<Texture> port =get_icon("port"); Ref<Texture> close =get_icon("close"); int close_offset = get_constant("close_offset"); Ref<Font> title_font = get_font("title_font"); int title_offset = get_constant("title_offset"); Color title_color = get_color("title_color"); Point2i icofs = -port->get_size()*0.5; int edgeofs=get_constant("port_offset"); icofs.y+=sb->get_margin(MARGIN_TOP); draw_style_box(sb,Rect2(Point2(),get_size())); int w = get_size().width-sb->get_minimum_size().x; if (show_close) w-=close->get_width(); draw_string(title_font,Point2(sb->get_margin(MARGIN_LEFT),-title_font->get_height()+title_font->get_ascent()+title_offset),title,title_color,w); if (show_close) { Vector2 cpos = Point2(w+sb->get_margin(MARGIN_LEFT),-close->get_height()+close_offset); draw_texture(close,cpos); close_rect.pos=cpos; close_rect.size=close->get_size(); } else { close_rect=Rect2(); } for (Map<int,Slot>::Element *E=slot_info.front();E;E=E->next()) { if (E->key() < 0 || E->key()>=cache_y.size()) continue; if (!slot_info.has(E->key())) continue; const Slot &s=slot_info[E->key()]; //left if (s.enable_left) port->draw(get_canvas_item(),icofs+Point2(edgeofs,cache_y[E->key()]),s.color_left); if (s.enable_right) port->draw(get_canvas_item(),icofs+Point2(get_size().x-edgeofs,cache_y[E->key()]),s.color_right); } } if (p_what==NOTIFICATION_SORT_CHILDREN) { _resort(); } }
void RichTextLabel::_notification(int p_what) { switch (p_what) { case NOTIFICATION_RESIZED: { main->first_invalid_line=0; //invalidate ALL update(); } break; case NOTIFICATION_ENTER_TREE: { set_bbcode(bbcode); main->first_invalid_line=0; //invalidate ALL update(); } break; case NOTIFICATION_THEME_CHANGED: { if (is_inside_tree() && use_bbcode) { parse_bbcode(bbcode); //first_invalid_line=0; //invalidate ALL //update(); } } break; case NOTIFICATION_DRAW: { _validate_line_caches(main); _update_scroll(); RID ci=get_canvas_item(); Size2 size = get_size(); VisualServer::get_singleton()->canvas_item_set_clip(ci,true); if (has_focus()) { VisualServer::get_singleton()->canvas_item_add_clip_ignore(ci,true); draw_style_box(get_stylebox("focus"),Rect2(Point2(),size)); VisualServer::get_singleton()->canvas_item_add_clip_ignore(ci,false); } int ofs = vscroll->get_val(); //todo, change to binary search int from_line = 0; int total_chars = 0; while (from_line<main->lines.size()) { if (main->lines[from_line].height_accum_cache>=ofs) break; from_line++; total_chars+=main->lines[from_line].char_count; } if (from_line>=main->lines.size()) break; //nothing to draw int y = (main->lines[from_line].height_accum_cache - main->lines[from_line].height_cache) - ofs; Ref<Font> base_font=get_font("normal_font"); Color base_color=get_color("default_color"); while (y<size.height && from_line<main->lines.size()) { _process_line(main,Point2(),y,size.width-scroll_w,from_line,PROCESS_DRAW,base_font,base_color,Point2i(),NULL,NULL,NULL,total_chars); total_chars+=main->lines[from_line].char_count; from_line++; } } } }
void ButtonArray::_notification(int p_what) { switch(p_what) { case NOTIFICATION_MOUSE_EXIT: { hover=-1; update(); } break; case NOTIFICATION_READY: { MethodInfo mi; mi.name="mouse_sub_enter"; add_user_signal(mi); } break; case NOTIFICATION_DRAW: { Size2 size=get_size(); Size2 minsize=get_combined_minimum_size(); Ref<StyleBox> style_normal = get_stylebox("normal"); Ref<StyleBox> style_selected = get_stylebox("selected"); Ref<StyleBox> style_focus = get_stylebox("focus"); Ref<StyleBox> style_hover = get_stylebox("hover"); Ref<Font> font_normal = get_font("font"); Ref<Font> font_selected = get_font("font_selected"); int icon_sep = get_constant("icon_separator"); int button_sep = get_constant("button_separator"); Color color_normal = get_color("font_color"); Color color_selected = get_color("font_color_selected"); int sep=button_sep; int ofs=0; int expand=0; switch(align) { case ALIGN_BEGIN: { ofs=0; } break; case ALIGN_CENTER: { ofs=Math::floor((size[orientation] - minsize[orientation])/2); } break; case ALIGN_END: { ofs=Math::floor((size[orientation] - minsize[orientation])); } break; case ALIGN_FILL: { if (buttons.size()>1) sep+=Math::floor((size[orientation]- minsize[orientation])/(buttons.size()-1.0)); ofs=0; } break; case ALIGN_EXPAND_FILL: { ofs=0; expand=size[orientation] - minsize[orientation]; } break; } int op_size = orientation==VERTICAL ? size.width : size.height; for(int i=0; i<buttons.size(); i++) { int ms = buttons[i]._ms_cache; int s=ms; if (expand>0) { s+=expand/buttons.size(); } if(min_button_size != -1 && s < min_button_size) { s = min_button_size; } Rect2 r; r.pos[orientation]=ofs; r.pos[!orientation]=0; r.size[orientation]=s; r.size[!orientation]=op_size; Ref<Font> f; Color c; Point2 sbsize; Point2 sbofs; if (i==selected) { draw_style_box(style_selected,r); sbsize=style_selected->get_minimum_size(); sbofs=style_selected->get_offset(); f=font_selected; c=color_selected; if (has_focus()) draw_style_box(style_focus,r); } else { if (hover==i) draw_style_box(style_hover,r); else if (!flat) draw_style_box(style_normal,r); sbsize=style_normal->get_minimum_size(); sbofs=style_normal->get_offset(); f=font_normal; c=color_normal; } Size2 ssize = f->get_string_size(buttons[i].text); if (buttons[i].icon.is_valid()) { ssize.x+=buttons[i].icon->get_width(); } Point2 text_ofs=((r.size-ssize-sbsize)/2.0+Point2(0,f->get_ascent())).floor()+sbofs; if (buttons[i].icon.is_valid()) { draw_texture(buttons[i].icon,r.pos+Point2(text_ofs.x,Math::floor((r.size.height-buttons[i].icon->get_height())/2.0))); text_ofs.x+=buttons[i].icon->get_width()+icon_sep; } draw_string(f,text_ofs+r.pos,buttons[i].text,c); buttons[i]._pos_cache=ofs; buttons[i]._size_cache=s; ofs+=s; ofs+=sep; } } break; } }
void GraphEdit::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { port_grab_distance_horizontal = get_constant("port_grab_distance_horizontal"); port_grab_distance_vertical = get_constant("port_grab_distance_vertical"); } if (p_what == NOTIFICATION_READY) { Size2 hmin = h_scroll->get_combined_minimum_size(); Size2 vmin = v_scroll->get_combined_minimum_size(); v_scroll->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_END, -vmin.width); v_scroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, 0); v_scroll->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 0); v_scroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, 0); h_scroll->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_BEGIN, 0); h_scroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, 0); h_scroll->set_anchor_and_margin(MARGIN_TOP, ANCHOR_END, -hmin.height); h_scroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, 0); zoom_minus->set_icon(get_icon("minus")); zoom_reset->set_icon(get_icon("reset")); zoom_plus->set_icon(get_icon("more")); snap_button->set_icon(get_icon("snap")); } if (p_what == NOTIFICATION_DRAW) { draw_style_box(get_stylebox("bg"), Rect2(Point2(), get_size())); if (is_using_snap()) { //draw grid int snap = get_snap(); Vector2 offset = get_scroll_ofs() / zoom; Size2 size = get_size() / zoom; Point2i from = (offset / float(snap)).floor(); Point2i len = (size / float(snap)).floor() + Vector2(1, 1); Color grid_minor = get_color("grid_minor"); Color grid_major = get_color("grid_major"); for (int i = from.x; i < from.x + len.x; i++) { Color color; if (ABS(i) % 10 == 0) color = grid_major; else color = grid_minor; float base_ofs = i * snap * zoom - offset.x * zoom; draw_line(Vector2(base_ofs, 0), Vector2(base_ofs, get_size().height), color); } for (int i = from.y; i < from.y + len.y; i++) { Color color; if (ABS(i) % 10 == 0) color = grid_major; else color = grid_minor; float base_ofs = i * snap * zoom - offset.y * zoom; draw_line(Vector2(0, base_ofs), Vector2(get_size().width, base_ofs), color); } } } if (p_what == NOTIFICATION_RESIZED) { _update_scroll(); top_layer->update(); } }
void EditorAudioBus::_notification(int p_what) { if (p_what == NOTIFICATION_READY) { for (int i = 0; i < CHANNELS_MAX; i++) { channel[i].vu_l->set_under_texture(get_icon("BusVuEmpty", "EditorIcons")); channel[i].vu_l->set_progress_texture(get_icon("BusVuFull", "EditorIcons")); channel[i].vu_r->set_under_texture(get_icon("BusVuEmpty", "EditorIcons")); channel[i].vu_r->set_progress_texture(get_icon("BusVuFull", "EditorIcons")); channel[i].prev_active = true; } scale->set_texture(get_icon("BusVuDb", "EditorIcons")); disabled_vu = get_icon("BusVuFrozen", "EditorIcons"); Color solo_color = Color::html(EditorSettings::get_singleton()->is_dark_theme() ? "#ffe337" : "#ffeb70"); Color mute_color = Color::html(EditorSettings::get_singleton()->is_dark_theme() ? "#ff2929" : "#ff7070"); Color bypass_color = Color::html(EditorSettings::get_singleton()->is_dark_theme() ? "#22ccff" : "#70deff"); solo->set_icon(get_icon("AudioBusSolo", "EditorIcons")); solo->add_color_override("icon_color_pressed", solo_color); mute->set_icon(get_icon("AudioBusMute", "EditorIcons")); mute->add_color_override("icon_color_pressed", mute_color); bypass->set_icon(get_icon("AudioBusBypass", "EditorIcons")); bypass->add_color_override("icon_color_pressed", bypass_color); bus_options->set_icon(get_icon("GuiMiniTabMenu", "EditorIcons")); update_bus(); set_process(true); } if (p_what == NOTIFICATION_DRAW) { if (has_focus()) { draw_style_box(get_stylebox("focus", "Button"), Rect2(Vector2(), get_size())); } else if (is_master) { draw_style_box(get_stylebox("disabled", "Button"), Rect2(Vector2(), get_size())); } } if (p_what == NOTIFICATION_PROCESS) { if (cc != AudioServer::get_singleton()->get_bus_channels(get_index())) { cc = AudioServer::get_singleton()->get_bus_channels(get_index()); _update_visible_channels(); } for (int i = 0; i < cc; i++) { float real_peak[2] = { -100, -100 }; bool activity_found = false; if (AudioServer::get_singleton()->is_bus_channel_active(get_index(), i)) { activity_found = true; real_peak[0] = MAX(real_peak[0], AudioServer::get_singleton()->get_bus_peak_volume_left_db(get_index(), i)); real_peak[1] = MAX(real_peak[1], AudioServer::get_singleton()->get_bus_peak_volume_right_db(get_index(), i)); } if (real_peak[0] > channel[i].peak_l) { channel[i].peak_l = real_peak[0]; } else { channel[i].peak_l -= get_process_delta_time() * 60.0; } if (real_peak[1] > channel[i].peak_r) { channel[i].peak_r = real_peak[1]; } else { channel[i].peak_r -= get_process_delta_time() * 60.0; } channel[i].vu_l->set_value(channel[i].peak_l); channel[i].vu_r->set_value(channel[i].peak_r); if (activity_found != channel[i].prev_active) { if (activity_found) { channel[i].vu_l->set_over_texture(Ref<Texture>()); channel[i].vu_r->set_over_texture(Ref<Texture>()); } else { channel[i].vu_l->set_over_texture(disabled_vu); channel[i].vu_r->set_over_texture(disabled_vu); } channel[i].prev_active = activity_found; } } } if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { for (int i = 0; i < CHANNELS_MAX; i++) { channel[i].peak_l = -100; channel[i].peak_r = -100; channel[i].prev_active = true; } set_process(is_visible_in_tree()); } if (p_what == NOTIFICATION_THEME_CHANGED) { for (int i = 0; i < CHANNELS_MAX; i++) { channel[i].vu_l->set_under_texture(get_icon("BusVuEmpty", "EditorIcons")); channel[i].vu_l->set_progress_texture(get_icon("BusVuFull", "EditorIcons")); channel[i].vu_r->set_under_texture(get_icon("BusVuEmpty", "EditorIcons")); channel[i].vu_r->set_progress_texture(get_icon("BusVuFull", "EditorIcons")); channel[i].prev_active = true; } scale->set_texture(get_icon("BusVuDb", "EditorIcons")); disabled_vu = get_icon("BusVuFrozen", "EditorIcons"); solo->set_icon(get_icon("AudioBusSolo", "EditorIcons")); mute->set_icon(get_icon("AudioBusMute", "EditorIcons")); bypass->set_icon(get_icon("AudioBusBypass", "EditorIcons")); bus_options->set_icon(get_icon("GuiMiniTabMenu", "EditorIcons")); } }
void EditorSpinSlider::_notification(int p_what) { if (p_what == MainLoop::NOTIFICATION_WM_FOCUS_OUT || p_what == MainLoop::NOTIFICATION_WM_FOCUS_OUT) { if (grabbing_spinner) { Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE); grabbing_spinner = false; grabbing_spinner_attempt = false; } } if (p_what == NOTIFICATION_DRAW) { updown_offset = -1; Ref<StyleBox> sb = get_stylebox("normal", "LineEdit"); draw_style_box(sb, Rect2(Vector2(), get_size())); Ref<Font> font = get_font("font", "LineEdit"); int avail_width = get_size().width - sb->get_minimum_size().width - sb->get_minimum_size().width; avail_width -= font->get_string_size(label).width; Ref<Texture> updown = get_icon("updown", "SpinBox"); if (get_step() == 1) { avail_width -= updown->get_width(); } if (has_focus()) { Ref<StyleBox> focus = get_stylebox("focus", "LineEdit"); draw_style_box(focus, Rect2(Vector2(), get_size())); } String numstr = get_text_value(); int vofs = (get_size().height - font->get_height()) / 2 + font->get_ascent(); Color fc = get_color("font_color", "LineEdit"); int label_ofs = sb->get_offset().x + avail_width; draw_string(font, Vector2(label_ofs, vofs), label, fc * Color(1, 1, 1, 0.5)); draw_string(font, Vector2(sb->get_offset().x, vofs), numstr, fc, avail_width); if (get_step() == 1) { Ref<Texture> updown = get_icon("updown", "SpinBox"); int updown_vofs = (get_size().height - updown->get_height()) / 2; updown_offset = get_size().width - sb->get_margin(MARGIN_RIGHT) - updown->get_width(); Color c(1, 1, 1); if (hover_updown) { c *= Color(1.2, 1.2, 1.2); } draw_texture(updown, Vector2(updown_offset, updown_vofs), c); if (grabber->is_visible()) { grabber->hide(); } } else if (!hide_slider) { int grabber_w = 4 * EDSCALE; int width = get_size().width - sb->get_minimum_size().width - grabber_w; int ofs = sb->get_offset().x; int svofs = (get_size().height + vofs) / 2 - 1; Color c = fc; c.a = 0.2; draw_rect(Rect2(ofs, svofs + 1, width, 2 * EDSCALE), c); int gofs = get_as_ratio() * width; c.a = 0.9; Rect2 grabber_rect = Rect2(ofs + gofs, svofs + 1, grabber_w, 2 * EDSCALE); draw_rect(grabber_rect, c); bool display_grabber = (mouse_over_spin || mouse_over_grabber) && !grabbing_spinner; if (grabber->is_visible() != display_grabber) { if (display_grabber) { grabber->show(); } else { grabber->hide(); } } if (display_grabber) { Ref<Texture> grabber_tex; if (mouse_over_grabber) { grabber_tex = get_icon("grabber_highlight", "HSlider"); } else { grabber_tex = get_icon("grabber", "HSlider"); } if (grabber->get_texture() != grabber_tex) { grabber->set_texture(grabber_tex); } grabber->set_size(Size2(0, 0)); grabber->set_position(get_global_position() + grabber_rect.position + grabber_rect.size * 0.5 - grabber->get_size() * 0.5); grabber_range = width; } } } if (p_what == NOTIFICATION_MOUSE_ENTER) { mouse_over_spin = true; update(); } if (p_what == NOTIFICATION_MOUSE_EXIT) { mouse_over_spin = false; update(); } }
void GraphNode::_notification(int p_what) { if (p_what==NOTIFICATION_DRAW) { Ref<StyleBox> sb; if (comment) { sb = get_stylebox( selected? "commentfocus" : "comment"); } else { sb = get_stylebox( selected ? "selectedframe" : "frame"); } sb=sb->duplicate(); sb->call("set_modulate",modulate); Ref<Texture> port =get_icon("port"); Ref<Texture> close =get_icon("close"); Ref<Texture> resizer =get_icon("resizer"); int close_offset = get_constant("close_offset"); Ref<Font> title_font = get_font("title_font"); int title_offset = get_constant("title_offset"); Color title_color = get_color("title_color"); Point2i icofs = -port->get_size()*0.5; int edgeofs=get_constant("port_offset"); icofs.y+=sb->get_margin(MARGIN_TOP); draw_style_box(sb,Rect2(Point2(),get_size())); switch(overlay) { case OVERLAY_DISABLED: { } break; case OVERLAY_BREAKPOINT: { draw_style_box(get_stylebox("breakpoint"),Rect2(Point2(),get_size())); } break; case OVERLAY_POSITION: { draw_style_box(get_stylebox("position"),Rect2(Point2(),get_size())); } break; } int w = get_size().width-sb->get_minimum_size().x; if (show_close) w-=close->get_width(); draw_string(title_font,Point2(sb->get_margin(MARGIN_LEFT),-title_font->get_height()+title_font->get_ascent()+title_offset),title,title_color,w); if (show_close) { Vector2 cpos = Point2(w+sb->get_margin(MARGIN_LEFT),-close->get_height()+close_offset); draw_texture(close,cpos); close_rect.pos=cpos; close_rect.size=close->get_size(); } else { close_rect=Rect2(); } for (Map<int,Slot>::Element *E=slot_info.front();E;E=E->next()) { if (E->key() < 0 || E->key()>=cache_y.size()) continue; if (!slot_info.has(E->key())) continue; const Slot &s=slot_info[E->key()]; //left if (s.enable_left) { Ref<Texture> p = port; if (s.custom_slot_left.is_valid()) { p=s.custom_slot_left; } p->draw(get_canvas_item(),icofs+Point2(edgeofs,cache_y[E->key()]),s.color_left); } if (s.enable_right) { Ref<Texture> p = port; if (s.custom_slot_right.is_valid()) { p=s.custom_slot_right; } p->draw(get_canvas_item(),icofs+Point2(get_size().x-edgeofs,cache_y[E->key()]),s.color_right); } } if (resizeable) { draw_texture(resizer,get_size()-resizer->get_size()); } } if (p_what==NOTIFICATION_SORT_CHILDREN) { _resort(); } }
void ItemList::_notification(int p_what) { if (p_what==NOTIFICATION_RESIZED) { shape_changed=true; update(); } if (p_what==NOTIFICATION_DRAW) { VS::get_singleton()->canvas_item_set_clip(get_canvas_item(),true); Ref<StyleBox> bg = get_stylebox("bg"); int mw = scroll_bar->get_minimum_size().x; scroll_bar->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_END,mw+bg->get_margin(MARGIN_RIGHT)); scroll_bar->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,bg->get_margin(MARGIN_RIGHT)); scroll_bar->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,bg->get_margin(MARGIN_TOP)); scroll_bar->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END,bg->get_margin(MARGIN_BOTTOM)); Size2 size = get_size(); float page = size.height-bg->get_minimum_size().height; int width = size.width - mw - bg->get_minimum_size().width; scroll_bar->set_page(page); draw_style_box(bg,Rect2(Point2(),size)); int hseparation = get_constant("hseparation"); int vseparation = get_constant("vseparation"); int icon_margin = get_constant("icon_margin"); int line_separation = get_constant("line_separation"); Ref<StyleBox> sbsel = has_focus()?get_stylebox("selected_focus"):get_stylebox("selected"); Ref<StyleBox> cursor = has_focus()?get_stylebox("cursor"):get_stylebox("cursor_unfocused"); Ref<Font> font = get_font("font"); Color guide_color = get_color("guide_color"); Color font_color = get_color("font_color"); Color font_color_selected = get_color("font_color_selected"); int font_height = font->get_height(); Vector<int> line_size_cache; Vector<int> line_limit_cache; if (max_text_lines) { line_size_cache.resize(max_text_lines); line_limit_cache.resize(max_text_lines); } if (has_focus()) { VisualServer::get_singleton()->canvas_item_add_clip_ignore(get_canvas_item(),true); draw_style_box(get_stylebox("bg_focus"),Rect2(Point2(),size)); VisualServer::get_singleton()->canvas_item_add_clip_ignore(get_canvas_item(),false); } if (shape_changed) { //1- compute item minimum sizes for(int i=0;i<items.size();i++) { Size2 minsize; if (items[i].icon.is_valid()) { minsize=items[i].get_icon_size(); if (min_icon_size.x!=0) minsize.x = MAX(minsize.x,min_icon_size.x); if (min_icon_size.y!=0) minsize.y = MAX(minsize.y,min_icon_size.y); if (items[i].text!="") { if (icon_mode==ICON_MODE_TOP) { minsize.y+=icon_margin; } else { minsize.x+=icon_margin; } } } if (items[i].text!="") { Size2 s = font->get_string_size(items[i].text); //s.width=MIN(s.width,fixed_column_width); if (icon_mode==ICON_MODE_TOP) { minsize.x=MAX(minsize.x,s.width); if (max_text_lines>0) { minsize.y+=(font_height+line_separation)*max_text_lines; } else { minsize.y+=s.height; } } else { minsize.y=MAX(minsize.y,s.height); minsize.x+=s.width; } } items[i].rect_cache.size=minsize; if (fixed_column_width>0) items[i].rect_cache.size.x=fixed_column_width; } int fit_size = size.x - bg->get_minimum_size().width - mw; //2-attempt best fit current_columns = 0x7FFFFFFF; if (max_columns>0) current_columns=max_columns; while(true) { //repeat util all fits //print_line("try with "+itos(current_columns)); bool all_fit=true; Vector2 ofs; int col=0; int max_h=0; separators.clear();; for(int i=0;i<items.size();i++) { if (current_columns>1 && items[i].rect_cache.size.width+ofs.x > fit_size) { //went past current_columns=MAX(col,1); all_fit=false; break; } items[i].rect_cache.pos=ofs; max_h=MAX(max_h,items[i].rect_cache.size.y); ofs.x+=items[i].rect_cache.size.x; //print_line("item "+itos(i)+" ofs "+rtos(items[i].rect_cache.size.x)); if (col>0) ofs.x+=hseparation; col++; if (col==current_columns) { if (i<items.size()-1) separators.push_back(ofs.y+max_h+vseparation/2); ofs.x=0; ofs.y+=max_h+vseparation; col=0; max_h=0; } } if (all_fit) { float max = MAX(page,ofs.y+max_h); scroll_bar->set_max(max); //print_line("max: "+rtos(max)+" page "+rtos(page)); if (max<=page) { scroll_bar->set_val(0); scroll_bar->hide(); } else { scroll_bar->show(); } break; } } shape_changed=false; } Vector2 base_ofs = bg->get_offset(); base_ofs.y-=int(scroll_bar->get_val()); Rect2 clip(Point2(),size-bg->get_minimum_size()+Vector2(0,scroll_bar->get_val())); for(int i=0;i<items.size();i++) { Rect2 rcache = items[i].rect_cache; if (!clip.intersects(rcache)) continue; if (current_columns==1) { rcache.size.width = width-rcache.pos.x; } Rect2 r=rcache; r.pos+=base_ofs; // Use stylebox to dimension potential bg color, even if not selected r.pos.x-=sbsel->get_margin(MARGIN_LEFT); r.size.x+=sbsel->get_margin(MARGIN_LEFT)+sbsel->get_margin(MARGIN_RIGHT); r.pos.y-=sbsel->get_margin(MARGIN_TOP); r.size.y+=sbsel->get_margin(MARGIN_TOP)+sbsel->get_margin(MARGIN_BOTTOM); if (items[i].selected) { draw_style_box(sbsel,r); } if (items[i].custom_bg.a>0.001) { r.pos.x+=2; r.size.x-=4; r.pos.y+=2; r.size.y-=4; draw_rect(r,items[i].custom_bg); } Vector2 text_ofs; if (items[i].icon.is_valid()) { Size2 icon_size = items[i].get_icon_size(); Vector2 icon_ofs; if (min_icon_size!=Vector2()) { icon_ofs = (min_icon_size - icon_size)/2; } Point2 pos = items[i].rect_cache.pos + icon_ofs + base_ofs; if (icon_mode==ICON_MODE_TOP) { pos.x += Math::floor((items[i].rect_cache.size.width - icon_size.width)/2); text_ofs.y = MAX(icon_size.height, min_icon_size.y) + icon_margin; } else { pos.y += Math::floor((items[i].rect_cache.size.height - icon_size.height)/2); text_ofs.x = MAX(icon_size.width, min_icon_size.x) + icon_margin; } if (items[i].icon_region.has_no_area()) draw_texture(items[i].icon, pos); else draw_texture_rect_region(items[i].icon, Rect2(pos, icon_size), items[i].icon_region); } if (items[i].tag_icon.is_valid()) { draw_texture(items[i].tag_icon,items[i].rect_cache.pos+base_ofs); } if (items[i].text!="") { int max_len=-1; Vector2 size = font->get_string_size(items[i].text); if (fixed_column_width) max_len=fixed_column_width; else max_len=size.x; if (icon_mode==ICON_MODE_TOP && max_text_lines>0) { int ss = items[i].text.length(); float ofs=0; int line=0; for(int j=0;j<=ss;j++) { int cs = j<ss?font->get_char_size(items[i].text[j],items[i].text[j+1]).x:0; if (ofs+cs>max_len || j==ss) { line_limit_cache[line]=j; line_size_cache[line]=ofs; line++; ofs=0; if (line>=max_text_lines) break; } else { ofs+=cs; } } line=0; ofs=0; text_ofs.y+=font->get_ascent(); text_ofs=text_ofs.floor(); text_ofs+=base_ofs; text_ofs+=items[i].rect_cache.pos; for(int j=0;j<ss;j++) { if (j==line_limit_cache[line]) { line++; ofs=0; if (line>=max_text_lines) break; } ofs+=font->draw_char(get_canvas_item(),text_ofs+Vector2(ofs+(max_len-line_size_cache[line])/2,line*(font_height+line_separation)).floor(),items[i].text[j],items[i].text[j+1],items[i].selected?font_color_selected:font_color); } //special multiline mode } else { if (fixed_column_width>0) size.x=MIN(size.x,fixed_column_width); if (icon_mode==ICON_MODE_TOP) { text_ofs.x+=(items[i].rect_cache.size.width-size.x)/2; } else { text_ofs.y+=(items[i].rect_cache.size.height-size.y)/2; } text_ofs.y+=font->get_ascent(); text_ofs=text_ofs.floor(); text_ofs+=base_ofs; text_ofs+=items[i].rect_cache.pos; draw_string(font,text_ofs,items[i].text,items[i].selected?font_color_selected:font_color,max_len+1); } } if (select_mode==SELECT_MULTI && i==current) { Rect2 r=rcache; r.pos+=base_ofs; draw_style_box(cursor,r); } } for(int i=0;i<separators.size();i++) { draw_line(Vector2(bg->get_margin(MARGIN_LEFT),base_ofs.y+separators[i]),Vector2(size.width-bg->get_margin(MARGIN_LEFT),base_ofs.y+separators[i]),guide_color); } if (ensure_selected_visible && current>=0 && current <=items.size()) { Rect2 r = items[current].rect_cache; int from = scroll_bar->get_val(); int to = from + scroll_bar->get_page(); if (r.pos.y < from) { scroll_bar->set_val(r.pos.y); } else if (r.pos.y+r.size.y > to) { scroll_bar->set_val(r.pos.y+r.size.y - (to-from)); } } ensure_selected_visible=false; } }
void EditorPath::_notification(int p_what) { switch(p_what) { case NOTIFICATION_MOUSE_ENTER: { mouse_over=true; update(); } break; case NOTIFICATION_MOUSE_EXIT: { mouse_over=false; update(); } break; case NOTIFICATION_DRAW: { RID ci=get_canvas_item(); Ref<Font> label_font = get_font("font","Label"); Size2i size = get_size(); Ref<Texture> sn = get_icon("SmallNext","EditorIcons"); Ref<StyleBox> sb = get_stylebox("pressed","Button"); int ofs=sb->get_margin(MARGIN_LEFT); if (mouse_over) { draw_style_box(sb,Rect2(Point2(),get_size())); } for(int i=0;i<history->get_path_size();i++) { Object *obj = ObjectDB::get_instance(history->get_path_object(i)); if (!obj) continue; String type = obj->get_class(); Ref<Texture> icon; if (has_icon(obj->get_class(),"EditorIcons")) icon=get_icon(obj->get_class(),"EditorIcons"); else icon=get_icon("Object","EditorIcons"); icon->draw(ci,Point2i(ofs,(size.height-icon->get_height())/2)); ofs+=icon->get_width(); if (i==history->get_path_size()-1) { //add name ofs+=4; int left = size.width - ofs; if (left<0) continue; String name; if (obj->cast_to<Resource>()) { Resource *r = obj->cast_to<Resource>(); if (r->get_path().is_resource_file()) name=r->get_path().get_file(); else name=r->get_name(); if (name=="") name=r->get_class(); } else if (obj->cast_to<Node>()) { name=obj->cast_to<Node>()->get_name(); } else if (obj->cast_to<Resource>() && obj->cast_to<Resource>()->get_name()!="") { name=obj->cast_to<Resource>()->get_name(); } else { name=obj->get_class(); } set_tooltip(obj->get_class()); label_font->draw(ci,Point2i(ofs,(size.height-label_font->get_height())/2+label_font->get_ascent()),name,Color(1,1,1),left); } else { //add arrow //sn->draw(ci,Point2i(ofs,(size.height-sn->get_height())/2)); //ofs+=sn->get_width(); ofs+=5; //just looks better! somehow } } } break; } }
void CurveEditor::_draw() { if (_curve_ref.is_null()) return; Curve &curve = **_curve_ref; update_view_transform(); // Background Vector2 view_size = get_rect().size; draw_style_box(get_stylebox("bg", "Tree"), Rect2(Point2(), view_size)); // Grid draw_set_transform_matrix(_world_to_view); Vector2 min_edge = get_world_pos(Vector2(0, view_size.y)); Vector2 max_edge = get_world_pos(Vector2(view_size.x, 0)); const Color grid_color0 = get_color("grid_major_color", "Editor"); const Color grid_color1 = get_color("grid_minor_color", "Editor"); draw_line(Vector2(min_edge.x, curve.get_min_value()), Vector2(max_edge.x, curve.get_min_value()), grid_color0); draw_line(Vector2(max_edge.x, curve.get_max_value()), Vector2(min_edge.x, curve.get_max_value()), grid_color0); draw_line(Vector2(0, min_edge.y), Vector2(0, max_edge.y), grid_color0); draw_line(Vector2(1, max_edge.y), Vector2(1, min_edge.y), grid_color0); float curve_height = (curve.get_max_value() - curve.get_min_value()); const Vector2 grid_step(0.25, 0.5 * curve_height); for (real_t x = 0; x < 1.0; x += grid_step.x) { draw_line(Vector2(x, min_edge.y), Vector2(x, max_edge.y), grid_color1); } for (real_t y = curve.get_min_value(); y < curve.get_max_value(); y += grid_step.y) { draw_line(Vector2(min_edge.x, y), Vector2(max_edge.x, y), grid_color1); } // Markings draw_set_transform_matrix(Transform2D()); Ref<Font> font = get_font("font", "Label"); float font_height = font->get_height(); Color text_color = get_color("font_color", "Editor"); { // X axis float y = curve.get_min_value(); Vector2 off(0, font_height - 1); draw_string(font, get_view_pos(Vector2(0, y)) + off, "0.0", text_color); draw_string(font, get_view_pos(Vector2(0.25, y)) + off, "0.25", text_color); draw_string(font, get_view_pos(Vector2(0.5, y)) + off, "0.5", text_color); draw_string(font, get_view_pos(Vector2(0.75, y)) + off, "0.75", text_color); draw_string(font, get_view_pos(Vector2(1, y)) + off, "1.0", text_color); } { // Y axis float m0 = curve.get_min_value(); float m1 = 0.5 * (curve.get_min_value() + curve.get_max_value()); float m2 = curve.get_max_value(); Vector2 off(1, -1); draw_string(font, get_view_pos(Vector2(0, m0)) + off, String::num(m0, 2), text_color); draw_string(font, get_view_pos(Vector2(0, m1)) + off, String::num(m1, 2), text_color); draw_string(font, get_view_pos(Vector2(0, m2)) + off, String::num(m2, 3), text_color); } // Draw tangents for current point if (_selected_point >= 0) { const Color tangent_color = get_color("accent_color", "Editor"); int i = _selected_point; Vector2 pos = curve.get_point_position(i); if (i != 0) { Vector2 control_pos = get_tangent_view_pos(i, TANGENT_LEFT); draw_line(get_view_pos(pos), control_pos, tangent_color); draw_rect(Rect2(control_pos, Vector2(1, 1)).grow(2), tangent_color); } if (i != curve.get_point_count() - 1) { Vector2 control_pos = get_tangent_view_pos(i, TANGENT_RIGHT); draw_line(get_view_pos(pos), control_pos, tangent_color); draw_rect(Rect2(control_pos, Vector2(1, 1)).grow(2), tangent_color); } } // Draw lines draw_set_transform_matrix(_world_to_view); const Color line_color = get_color("highlight_color", "Editor"); const Color edge_line_color = get_color("font_color", "Editor"); CanvasItemPlotCurve plot_func(*this, line_color, edge_line_color); plot_curve_accurate(curve, 4.f / view_size.x, plot_func); // Draw points draw_set_transform_matrix(Transform2D()); const Color point_color = get_color("font_color", "Editor"); const Color selected_point_color = get_color("accent_color", "Editor"); for (int i = 0; i < curve.get_point_count(); ++i) { Vector2 pos = curve.get_point_position(i); draw_rect(Rect2(get_view_pos(pos), Vector2(1, 1)).grow(3), i == _selected_point ? selected_point_color : point_color); // TODO Circles are prettier. Needs a fix! Or a texture //draw_circle(pos, 2, point_color); } // Hover if (_hover_point != -1) { const Color hover_color = line_color; Vector2 pos = curve.get_point_position(_hover_point); stroke_rect(Rect2(get_view_pos(pos), Vector2(1, 1)).grow(_hover_radius), hover_color); } // Help text if (_selected_point > 0 && _selected_point + 1 < curve.get_point_count()) { text_color.a *= 0.4; draw_string(font, Vector2(50, font_height), TTR("Hold Shift to edit tangents individually"), text_color); } }
void ItemList::_notification(int p_what) { if (p_what == NOTIFICATION_RESIZED) { shape_changed = true; update(); } if (p_what == NOTIFICATION_DRAW) { Ref<StyleBox> bg = get_stylebox("bg"); int mw = scroll_bar->get_minimum_size().x; scroll_bar->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_END, -mw); scroll_bar->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, 0); scroll_bar->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, bg->get_margin(MARGIN_TOP)); scroll_bar->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, -bg->get_margin(MARGIN_BOTTOM)); Size2 size = get_size(); int width = size.width - bg->get_minimum_size().width; if (scroll_bar->is_visible()) { width -= mw + bg->get_margin(MARGIN_RIGHT); } draw_style_box(bg, Rect2(Point2(), size)); int hseparation = get_constant("hseparation"); int vseparation = get_constant("vseparation"); int icon_margin = get_constant("icon_margin"); int line_separation = get_constant("line_separation"); Ref<StyleBox> sbsel = has_focus() ? get_stylebox("selected_focus") : get_stylebox("selected"); Ref<StyleBox> cursor = has_focus() ? get_stylebox("cursor") : get_stylebox("cursor_unfocused"); Ref<Font> font = get_font("font"); Color guide_color = get_color("guide_color"); Color font_color = get_color("font_color"); Color font_color_selected = get_color("font_color_selected"); int font_height = font->get_height(); Vector<int> line_size_cache; Vector<int> line_limit_cache; if (max_text_lines) { line_size_cache.resize(max_text_lines); line_limit_cache.resize(max_text_lines); } if (has_focus()) { draw_style_box(get_stylebox("bg_focus"), Rect2(Point2(), size)); } if (shape_changed) { float max_column_width = 0; //1- compute item minimum sizes for (int i = 0; i < items.size(); i++) { Size2 minsize; if (items[i].icon.is_valid()) { if (fixed_icon_size.x > 0 && fixed_icon_size.y > 0) { minsize = fixed_icon_size * icon_scale; } else { minsize = items[i].get_icon_size() * icon_scale; } if (items[i].text != "") { if (icon_mode == ICON_MODE_TOP) { minsize.y += icon_margin; } else { minsize.x += icon_margin; } } } if (items[i].text != "") { Size2 s = font->get_string_size(items[i].text); //s.width=MIN(s.width,fixed_column_width); if (icon_mode == ICON_MODE_TOP) { minsize.x = MAX(minsize.x, s.width); if (max_text_lines > 0) { minsize.y += (font_height + line_separation) * max_text_lines; } else { minsize.y += s.height; } } else { minsize.y = MAX(minsize.y, s.height); minsize.x += s.width; } } if (fixed_column_width > 0) minsize.x = fixed_column_width; max_column_width = MAX(max_column_width, minsize.x); // elements need to adapt to the selected size minsize.y += vseparation; minsize.x += hseparation; items[i].rect_cache.size = minsize; items[i].min_rect_cache.size = minsize; } int fit_size = size.x - bg->get_minimum_size().width - mw; //2-attempt best fit current_columns = 0x7FFFFFFF; if (max_columns > 0) current_columns = max_columns; while (true) { //repeat util all fits bool all_fit = true; Vector2 ofs; int col = 0; int max_h = 0; separators.clear(); for (int i = 0; i < items.size(); i++) { if (current_columns > 1 && items[i].rect_cache.size.width + ofs.x > fit_size) { //went past current_columns = MAX(col, 1); all_fit = false; break; } if (same_column_width) items[i].rect_cache.size.x = max_column_width; items[i].rect_cache.position = ofs; max_h = MAX(max_h, items[i].rect_cache.size.y); ofs.x += items[i].rect_cache.size.x + hseparation; col++; if (col == current_columns) { if (i < items.size() - 1) separators.push_back(ofs.y + max_h + vseparation / 2); for (int j = i; j >= 0 && col > 0; j--, col--) { items[j].rect_cache.size.y = max_h; } ofs.x = 0; ofs.y += max_h + vseparation; col = 0; max_h = 0; } } for (int j = items.size() - 1; j >= 0 && col > 0; j--, col--) { items[j].rect_cache.size.y = max_h; } if (all_fit) { float page = size.height - bg->get_minimum_size().height; float max = MAX(page, ofs.y + max_h); if (auto_height) auto_height_value = ofs.y + max_h + bg->get_minimum_size().height; scroll_bar->set_max(max); scroll_bar->set_page(page); if (max <= page) { scroll_bar->set_value(0); scroll_bar->hide(); } else { scroll_bar->show(); } break; } } shape_changed = false; } //ensure_selected_visible needs to be checked before we draw the list. if (ensure_selected_visible && current >= 0 && current <= items.size()) { Rect2 r = items[current].rect_cache; int from = scroll_bar->get_value(); int to = from + scroll_bar->get_page(); if (r.position.y < from) { scroll_bar->set_value(r.position.y); } else if (r.position.y + r.size.y > to) { scroll_bar->set_value(r.position.y + r.size.y - (to - from)); } } ensure_selected_visible = false; Vector2 base_ofs = bg->get_offset(); base_ofs.y -= int(scroll_bar->get_value()); Rect2 clip(Point2(), size - bg->get_minimum_size() + Vector2(0, scroll_bar->get_value())); for (int i = 0; i < items.size(); i++) { Rect2 rcache = items[i].rect_cache; if (!clip.intersects(rcache)) continue; if (current_columns == 1) { rcache.size.width = width - rcache.position.x; } if (items[i].selected) { Rect2 r = rcache; r.position += base_ofs; r.position.y -= vseparation / 2; r.size.y += vseparation; r.position.x -= hseparation / 2; r.size.x += hseparation; draw_style_box(sbsel, r); } if (items[i].custom_bg.a > 0.001) { Rect2 r = rcache; r.position += base_ofs; // Size rect to make the align the temperature colors r.position.y -= vseparation / 2; r.size.y += vseparation; r.position.x -= hseparation / 2; r.size.x += hseparation; draw_rect(r, items[i].custom_bg); } Vector2 text_ofs; if (items[i].icon.is_valid()) { Size2 icon_size; //= _adjust_to_max_size(items[i].get_icon_size(),fixed_icon_size) * icon_scale; if (fixed_icon_size.x > 0 && fixed_icon_size.y > 0) { icon_size = fixed_icon_size * icon_scale; } else { icon_size = items[i].get_icon_size() * icon_scale; } Vector2 icon_ofs; Point2 pos = items[i].rect_cache.position + icon_ofs + base_ofs; if (icon_mode == ICON_MODE_TOP) { pos.x += Math::floor((items[i].rect_cache.size.width - icon_size.width) / 2); pos.y += MIN( Math::floor((items[i].rect_cache.size.height - icon_size.height) / 2), items[i].rect_cache.size.height - items[i].min_rect_cache.size.height); text_ofs.y = icon_size.height + icon_margin; text_ofs.y += items[i].rect_cache.size.height - items[i].min_rect_cache.size.height; } else { pos.y += Math::floor((items[i].rect_cache.size.height - icon_size.height) / 2); text_ofs.x = icon_size.width + icon_margin; } Rect2 draw_rect = Rect2(pos, icon_size); if (fixed_icon_size.x > 0 && fixed_icon_size.y > 0) { Rect2 adj = _adjust_to_max_size(items[i].get_icon_size() * icon_scale, icon_size); draw_rect.position += adj.position; draw_rect.size = adj.size; } Color modulate = Color(1, 1, 1, 1); if (items[i].disabled) modulate.a *= 0.5; if (items[i].icon_region.has_no_area()) draw_texture_rect(items[i].icon, draw_rect, false, modulate); else draw_texture_rect_region(items[i].icon, draw_rect, items[i].icon_region, modulate); } if (items[i].tag_icon.is_valid()) { draw_texture(items[i].tag_icon, items[i].rect_cache.position + base_ofs); } if (items[i].text != "") { int max_len = -1; Vector2 size = font->get_string_size(items[i].text); if (fixed_column_width) max_len = fixed_column_width; else if (same_column_width) max_len = items[i].rect_cache.size.x; else max_len = size.x; Color modulate = items[i].selected ? font_color_selected : (items[i].custom_fg != Color() ? items[i].custom_fg : font_color); if (items[i].disabled) modulate.a *= 0.5; if (icon_mode == ICON_MODE_TOP && max_text_lines > 0) { int ss = items[i].text.length(); float ofs = 0; int line = 0; for (int j = 0; j <= ss; j++) { int cs = j < ss ? font->get_char_size(items[i].text[j], items[i].text[j + 1]).x : 0; if (ofs + cs > max_len || j == ss) { line_limit_cache[line] = j; line_size_cache[line] = ofs; line++; ofs = 0; if (line >= max_text_lines) break; } else { ofs += cs; } } line = 0; ofs = 0; text_ofs.y += font->get_ascent(); text_ofs = text_ofs.floor(); text_ofs += base_ofs; text_ofs += items[i].rect_cache.position; for (int j = 0; j < ss; j++) { if (j == line_limit_cache[line]) { line++; ofs = 0; if (line >= max_text_lines) break; } ofs += font->draw_char(get_canvas_item(), text_ofs + Vector2(ofs + (max_len - line_size_cache[line]) / 2, line * (font_height + line_separation)).floor(), items[i].text[j], items[i].text[j + 1], modulate); } //special multiline mode } else { if (fixed_column_width > 0) size.x = MIN(size.x, fixed_column_width); if (icon_mode == ICON_MODE_TOP) { text_ofs.x += (items[i].rect_cache.size.width - size.x) / 2; } else { text_ofs.y += (items[i].rect_cache.size.height - size.y) / 2; } text_ofs.y += font->get_ascent(); text_ofs = text_ofs.floor(); text_ofs += base_ofs; text_ofs += items[i].rect_cache.position; draw_string(font, text_ofs, items[i].text, modulate, max_len + 1); } } if (select_mode == SELECT_MULTI && i == current) { Rect2 r = rcache; r.position += base_ofs; r.position.y -= vseparation / 2; r.size.y += vseparation; r.position.x -= hseparation / 2; r.size.x += hseparation; draw_style_box(cursor, r); } } for (int i = 0; i < separators.size(); i++) { draw_line(Vector2(bg->get_margin(MARGIN_LEFT), base_ofs.y + separators[i]), Vector2(size.width - bg->get_margin(MARGIN_RIGHT), base_ofs.y + separators[i]), guide_color); } } }