diff options
author | Juan Linietsky <reduzio@gmail.com> | 2016-10-30 09:00:45 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2016-10-30 09:00:45 -0300 |
commit | ab4126f51061277e87b41c48b40e7b54942d4eca (patch) | |
tree | c58168b60323c4d43b58743b099e562a89e60a56 /scene/gui | |
parent | 8b15b26eedad4fdd33d50f5f9aa0fcc1875d503f (diff) | |
parent | 914015f3b63dd956e72ea937d46ea4b2db005ada (diff) |
Merge branch 'master' of https://github.com/godotengine/godot
Diffstat (limited to 'scene/gui')
-rw-r--r-- | scene/gui/SCsub | 2 | ||||
-rw-r--r-- | scene/gui/base_button.cpp | 10 | ||||
-rw-r--r-- | scene/gui/button_array.cpp | 60 | ||||
-rw-r--r-- | scene/gui/button_array.h | 8 | ||||
-rw-r--r-- | scene/gui/button_group.cpp | 4 | ||||
-rw-r--r-- | scene/gui/container.cpp | 12 | ||||
-rw-r--r-- | scene/gui/control.cpp | 10 | ||||
-rw-r--r-- | scene/gui/dialogs.cpp | 35 | ||||
-rw-r--r-- | scene/gui/file_dialog.cpp | 34 | ||||
-rw-r--r-- | scene/gui/graph_edit.cpp | 22 | ||||
-rw-r--r-- | scene/gui/graph_node.cpp | 5 | ||||
-rw-r--r-- | scene/gui/item_list.cpp | 35 | ||||
-rw-r--r-- | scene/gui/line_edit.cpp | 21 | ||||
-rw-r--r-- | scene/gui/link_button.cpp | 7 | ||||
-rw-r--r-- | scene/gui/link_button.h | 3 | ||||
-rw-r--r-- | scene/gui/popup_menu.cpp | 38 | ||||
-rw-r--r-- | scene/gui/popup_menu.h | 2 | ||||
-rw-r--r-- | scene/gui/text_edit.cpp | 79 | ||||
-rw-r--r-- | scene/gui/text_edit.h | 17 | ||||
-rw-r--r-- | scene/gui/tree.cpp | 44 | ||||
-rw-r--r-- | scene/gui/tree.h | 3 | ||||
-rw-r--r-- | scene/gui/video_player.cpp | 3 |
22 files changed, 337 insertions, 117 deletions
diff --git a/scene/gui/SCsub b/scene/gui/SCsub index bbe59b3054..9fa89edbf7 100644 --- a/scene/gui/SCsub +++ b/scene/gui/SCsub @@ -1,3 +1,5 @@ +#!/usr/bin/env python + Import('env') env.add_source_files(env.scene_sources,"*.cpp") diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index 6479dd2d02..64d68738b2 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -243,12 +243,22 @@ void BaseButton::_notification(int p_what) { update(); } } + + if (p_what==NOTIFICATION_FOCUS_ENTER) { + + status.hovering=true; + update(); + } if (p_what==NOTIFICATION_FOCUS_EXIT) { if (status.pressing_button && status.press_attempt) { status.press_attempt=false; status.pressing_button=0; + status.hovering=false; + update(); + } else if (status.hovering) { + status.hovering=false; update(); } } diff --git a/scene/gui/button_array.cpp b/scene/gui/button_array.cpp index be48296110..df1872380d 100644 --- a/scene/gui/button_array.cpp +++ b/scene/gui/button_array.cpp @@ -60,6 +60,8 @@ bool ButtonArray::_set(const StringName& p_name, const Variant& p_value) { String f = n.get_slicec('/',2); if (f=="text") buttons[idx].text=p_value; + else if (f=="tooltip") + buttons[idx].tooltip=p_value; else if (f=="icon") buttons[idx].icon=p_value; else @@ -95,6 +97,8 @@ bool ButtonArray::_get(const StringName& p_name,Variant &r_ret) const { String f = n.get_slicec('/',2); if (f=="text") r_ret=buttons[idx].text; + else if (f=="tooltip") + r_ret=buttons[idx].tooltip; else if (f=="icon") r_ret=buttons[idx].icon; else @@ -115,6 +119,7 @@ void ButtonArray::_get_property_list( List<PropertyInfo> *p_list) const { for(int i=0;i<buttons.size();i++) { String base="button/"+itos(i)+"/"; p_list->push_back( PropertyInfo( Variant::STRING, base+"text")); + p_list->push_back( PropertyInfo( Variant::STRING, base+"tooltip")); p_list->push_back( PropertyInfo( Variant::OBJECT, base+"icon",PROPERTY_HINT_RESOURCE_TYPE,"Texture")); } if (buttons.size()>0) { @@ -168,8 +173,12 @@ Size2 ButtonArray::get_minimum_size() const { void ButtonArray::_notification(int p_what) { switch(p_what) { + case NOTIFICATION_MOUSE_EXIT:{ + hover=-1; + update(); + }break; case NOTIFICATION_READY:{ - MethodInfo mi; + MethodInfo mi; mi.name="mouse_sub_enter"; add_user_signal(mi); @@ -245,8 +254,12 @@ void ButtonArray::_notification(int p_what) { 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()) @@ -256,6 +269,8 @@ void ButtonArray::_notification(int p_what) { draw_style_box(style_hover,r); else draw_style_box(style_normal,r); + sbsize=style_selected->get_minimum_size(); + sbofs=style_normal->get_offset(); f=font_normal; c=color_normal; } @@ -265,7 +280,7 @@ void ButtonArray::_notification(int p_what) { ssize.x+=buttons[i].icon->get_width(); } - Point2 text_ofs=((r.size-ssize)/2.0+Point2(0,f->get_ascent())).floor(); + 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))); @@ -349,6 +364,18 @@ void ButtonArray::_input_event(const InputEvent& p_event) { } +String ButtonArray::get_tooltip(const Point2& p_pos) const { + + int ofs = orientation==HORIZONTAL ? p_pos.x: p_pos.y; + for(int i=0;i<buttons.size();i++) { + + if (ofs>=buttons[i]._pos_cache && ofs<buttons[i]._pos_cache+buttons[i]._size_cache) + return buttons[i].tooltip; + + } + return Control::get_tooltip(p_pos); +} + void ButtonArray::set_align(Align p_align) { align=p_align; @@ -362,10 +389,11 @@ ButtonArray::Align ButtonArray::get_align() const { } -void ButtonArray::add_button(const String& p_text) { +void ButtonArray::add_button(const String& p_text,const String& p_tooltip) { Button button; button.text=p_text; + button.tooltip=p_tooltip; buttons.push_back(button); update(); @@ -375,11 +403,12 @@ void ButtonArray::add_button(const String& p_text) { minimum_size_changed(); } -void ButtonArray::add_icon_button(const Ref<Texture>& p_icon,const String& p_text) { +void ButtonArray::add_icon_button(const Ref<Texture>& p_icon,const String& p_text,const String& p_tooltip) { Button button; button.text=p_text; button.icon=p_icon; + button.tooltip=p_tooltip; buttons.push_back(button); if (selected==-1) selected=0; @@ -397,6 +426,13 @@ void ButtonArray::set_button_text(int p_button, const String& p_text) { } +void ButtonArray::set_button_tooltip(int p_button, const String& p_text) { + + ERR_FAIL_INDEX(p_button,buttons.size()); + buttons[p_button].tooltip=p_text; + +} + void ButtonArray::set_button_icon(int p_button, const Ref<Texture>& p_icon) { ERR_FAIL_INDEX(p_button,buttons.size()); @@ -411,6 +447,12 @@ String ButtonArray::get_button_text(int p_button) const { return buttons[p_button].text; } +String ButtonArray::get_button_tooltip(int p_button) const { + + ERR_FAIL_INDEX_V(p_button,buttons.size(),""); + return buttons[p_button].tooltip; +} + Ref<Texture> ButtonArray::get_button_icon(int p_button) const { ERR_FAIL_INDEX_V(p_button,buttons.size(),Ref<Texture>()); @@ -465,18 +507,22 @@ int ButtonArray::get_button_count() const { void ButtonArray::get_translatable_strings(List<String> *p_strings) const { - for(int i=0;i<buttons.size();i++) + for(int i=0;i<buttons.size();i++) { p_strings->push_back(buttons[i].text); + p_strings->push_back(buttons[i].tooltip); + } } void ButtonArray::_bind_methods() { - ObjectTypeDB::bind_method(_MD("add_button","text"),&ButtonArray::add_button); - ObjectTypeDB::bind_method(_MD("add_icon_button","icon:Texture","text"),&ButtonArray::add_icon_button,DEFVAL("")); + ObjectTypeDB::bind_method(_MD("add_button","text","tooltip"),&ButtonArray::add_button,DEFVAL("")); + ObjectTypeDB::bind_method(_MD("add_icon_button","icon:Texture","text","tooltip"),&ButtonArray::add_icon_button,DEFVAL(""),DEFVAL("")); ObjectTypeDB::bind_method(_MD("set_button_text","button_idx","text"),&ButtonArray::set_button_text); + ObjectTypeDB::bind_method(_MD("set_button_tooltip","button_idx","text"),&ButtonArray::set_button_tooltip); ObjectTypeDB::bind_method(_MD("set_button_icon","button_idx","icon:Texture"),&ButtonArray::set_button_icon); ObjectTypeDB::bind_method(_MD("get_button_text","button_idx"),&ButtonArray::get_button_text); + ObjectTypeDB::bind_method(_MD("get_button_tooltip","button_idx"),&ButtonArray::get_button_tooltip); ObjectTypeDB::bind_method(_MD("get_button_icon:Texture","button_idx"),&ButtonArray::get_button_icon); ObjectTypeDB::bind_method(_MD("get_button_count"),&ButtonArray::get_button_count); ObjectTypeDB::bind_method(_MD("get_selected"),&ButtonArray::get_selected); diff --git a/scene/gui/button_array.h b/scene/gui/button_array.h index c4b9b0c9e3..62997a8e36 100644 --- a/scene/gui/button_array.h +++ b/scene/gui/button_array.h @@ -50,6 +50,7 @@ private: struct Button { String text; + String tooltip; Ref<Texture> icon; mutable int _ms_cache; mutable int _pos_cache; @@ -78,14 +79,16 @@ public: void set_align(Align p_align); Align get_align() const; - void add_button(const String& p_button); - void add_icon_button(const Ref<Texture>& p_icon,const String& p_button=""); + void add_button(const String& p_button,const String& p_tooltip=""); + void add_icon_button(const Ref<Texture>& p_icon,const String& p_button="",const String& p_tooltip=""); void set_button_text(int p_button, const String& p_text); + void set_button_tooltip(int p_button, const String& p_text); void set_button_icon(int p_button, const Ref<Texture>& p_icon); String get_button_text(int p_button) const; + String get_button_tooltip(int p_button) const; Ref<Texture> get_button_icon(int p_button) const; int get_selected() const; @@ -100,6 +103,7 @@ public: virtual Size2 get_minimum_size() const; virtual void get_translatable_strings(List<String> *p_strings) const; + virtual String get_tooltip(const Point2& p_pos) const; ButtonArray(Orientation p_orientation=HORIZONTAL); diff --git a/scene/gui/button_group.cpp b/scene/gui/button_group.cpp index 04ba5fc06d..5d9f290f78 100644 --- a/scene/gui/button_group.cpp +++ b/scene/gui/button_group.cpp @@ -60,6 +60,9 @@ void ButtonGroup::_pressed(Object *p_button) { BaseButton *bb=E->get(); bb->set_pressed( b==bb ); + if (b==bb){ + emit_signal("button_selected", b); + } } } @@ -153,6 +156,7 @@ void ButtonGroup::_bind_methods() { ObjectTypeDB::bind_method(_MD("_pressed"),&ButtonGroup::_pressed); ObjectTypeDB::bind_method(_MD("set_pressed_button","button:BaseButton"),&ButtonGroup::_pressed); + ADD_SIGNAL( MethodInfo("button_selected",PropertyInfo(Variant::OBJECT,"button",PROPERTY_HINT_RESOURCE_TYPE,"BaseButton"))); } ButtonGroup::ButtonGroup() : BoxContainer(true) diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp index feaf516f42..83a4f34282 100644 --- a/scene/gui/container.cpp +++ b/scene/gui/container.cpp @@ -151,6 +151,18 @@ void Container::_notification(int p_what) { queue_sort(); } } break; + case NOTIFICATION_SORT_CHILDREN: { + + Size2 s = get_size(); + + for (int i=0; i<get_child_count();i++) { + Control *c = get_child(i)->cast_to<Control>(); + if (!c || !c->is_visible() || c->is_set_as_toplevel()) + continue; + + fit_child_in_rect(c,Rect2(0, 0, s.width, s.height)); + } + } } } diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index a5bee32a69..97f0db97c2 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -1725,11 +1725,11 @@ Control *Control::find_next_valid_focus() const { if (next_child==this) // no next control-> return (get_focus_mode()==FOCUS_ALL)?next_child:NULL; - - if (next_child->get_focus_mode()==FOCUS_ALL) - return next_child; - - from = next_child; + if (next_child) { + if (next_child->get_focus_mode()==FOCUS_ALL) + return next_child; + from = next_child; + } else break; } return NULL; diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index 15ff334c92..b8c5f227c6 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -232,6 +232,8 @@ String AcceptDialog::get_text() const { void AcceptDialog::set_text(String p_text) { label->set_text(p_text); + minimum_size_changed(); + _update_child_rect(); } void AcceptDialog::set_hide_on_ok(bool p_hide) { @@ -253,38 +255,51 @@ void AcceptDialog::register_text_enter(Node *p_line_edit) { void AcceptDialog::_update_child_rect() { - int margin = get_constant("margin","Dialogs"); - Size2 size = get_size(); + const int margin = get_constant("margin","Dialogs"); + const Size2 size = get_size(); Size2 hminsize = hbc->get_combined_minimum_size(); - Vector2 cpos(margin,margin); - Vector2 csize(size.x-margin*2,size.y-margin*3-hminsize.y); + const Size2 max_csize( + size.width - margin * 2, + size.height - margin * 3 - hminsize.height); + hminsize.width = max_csize.width; + + Point2 cpos(margin, margin); + Size2 csize = label->get_combined_minimum_size(); + if(label->get_text().empty()) + csize.y = 0; + csize.x = MIN(csize.width, max_csize.width); + csize.y = MIN(csize.height, max_csize.height); label->set_pos(cpos); label->set_size(csize); - if (child) { + if(child) { + const float child_y_offset = csize.height + (csize.height > 0 ? margin : 0); + cpos.y += child_y_offset; + csize = max_csize; + csize.height -= child_y_offset; child->set_pos(cpos); child->set_size(csize); } - cpos.y+=csize.y+margin; - csize.y=hminsize.y; + cpos.y += csize.height + margin; hbc->set_pos(cpos); - hbc->set_size(csize); - + hbc->set_size(hminsize); } Size2 AcceptDialog::get_minimum_size() const { int margin = get_constant("margin","Dialogs"); Size2 minsize = label->get_combined_minimum_size(); + if(label->get_text().empty()) + minsize.y = 0; if (child) { Size2 cminsize = child->get_combined_minimum_size(); minsize.x=MAX(cminsize.x,minsize.x); - minsize.y=MAX(cminsize.y,minsize.y); + minsize.y += cminsize.y + (minsize.y > 0 ? margin : 0); } Size2 hminsize = hbc->get_combined_minimum_size(); diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 6b43425edc..f942f15ed0 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -186,15 +186,17 @@ void FileDialog::_action_pressed() { hide(); }else if (mode==MODE_OPEN_ANY || mode==MODE_OPEN_DIR) { - String path=dir_access->get_current_dir(); - /*if (tree->get_selected()) { - Dictionary d = tree->get_selected()->get_metadata(0); + + path=path.replace("\\","/"); + + if (TreeItem* item = tree->get_selected()) { + Dictionary d = item->get_metadata(0); if (d["dir"]) { - path=path+"/"+String(d["name"]); + path=path.plus_file(d["name"]); } - }*/ - path=path.replace("\\","/"); + } + emit_signal("dir_selected",path); hide(); } @@ -348,18 +350,18 @@ void FileDialog::update_file_list() { files.sort_custom<NoCaseComparator>(); while(!dirs.empty()) { + String& dir_name = dirs.front()->get(); + TreeItem *ti=tree->create_item(root); + ti->set_text(0,dir_name+"/"); + ti->set_icon(0,folder); - if (dirs.front()->get()!=".") { - TreeItem *ti=tree->create_item(root); - ti->set_text(0,dirs.front()->get()+"/"); - ti->set_icon(0,folder); - Dictionary d; - d["name"]=dirs.front()->get(); - d["dir"]=true; - ti->set_metadata(0,d); - } - dirs.pop_front(); + Dictionary d; + d["name"]=dir_name; + d["dir"]=true; + + ti->set_metadata(0,d); + dirs.pop_front(); } dirs.clear(); diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 0de6add8cb..6366b5ee23 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -151,7 +151,7 @@ void GraphEdit::_update_scroll_offset() { } } - connections_layer->set_pos(-Point2(h_scroll->get_val(),v_scroll->get_val())*zoom); + connections_layer->set_pos(-Point2(h_scroll->get_val(),v_scroll->get_val())); set_block_minimum_size_adjust(false); awaiting_scroll_offset_update=false; @@ -254,6 +254,7 @@ void GraphEdit::add_child_notify(Node *p_child) { gn->set_scale(Vector2(zoom,zoom)); gn->connect("offset_changed",this,"_graph_node_moved",varray(gn)); gn->connect("raise_request",this,"_graph_node_raised",varray(gn)); + gn->connect("item_rect_changed",connections_layer,"update"); _graph_node_moved(gn); gn->set_stop_mouse(false); } @@ -650,8 +651,8 @@ void GraphEdit::_draw_cos_line(CanvasItem* p_where,const Vector2& p_from, const cp_offset=MAX(MIN(cp_len-diff,cp_neg_len),-diff*0.5); } - Vector2 c1 = Vector2(cp_offset,0); - Vector2 c2 = Vector2(-cp_offset,0); + Vector2 c1 = Vector2(cp_offset*zoom,0); + Vector2 c2 = Vector2(-cp_offset*zoom,0); int lines=0; _bake_segment2d(p_where,0,1,p_from,c1,p_to,c2,0,3,9,8,p_color,p_to_color,lines); @@ -726,9 +727,9 @@ void GraphEdit::_connections_layer_draw() { continue; } - Vector2 frompos=gfrom->get_connection_output_pos(E->get().from_port)+gfrom->get_offset(); + Vector2 frompos=gfrom->get_connection_output_pos(E->get().from_port)+gfrom->get_offset()*zoom; Color color = gfrom->get_connection_output_color(E->get().from_port); - Vector2 topos=gto->get_connection_input_pos(E->get().to_port)+gto->get_offset(); + Vector2 topos=gto->get_connection_input_pos(E->get().to_port)+gto->get_offset()*zoom; Color tocolor = gto->get_connection_input_color(E->get().to_port); _draw_cos_line(connections_layer,frompos,topos,color,tocolor); @@ -912,18 +913,20 @@ void GraphEdit::_input_event(const InputEvent& p_ev) { if (b.button_index==BUTTON_LEFT && b.pressed) { GraphNode *gn = NULL; + GraphNode *gn_selected = NULL; for(int i=get_child_count()-1;i>=0;i--) { - gn=get_child(i)->cast_to<GraphNode>(); + gn_selected=get_child(i)->cast_to<GraphNode>(); - if (gn) { + if (gn_selected) { - if (gn->is_resizing()) + if (gn_selected->is_resizing()) continue; - Rect2 r = gn->get_rect(); + Rect2 r = gn_selected->get_rect(); r.size*=zoom; if (r.has_point(get_local_mouse_pos())) + gn = gn_selected; break; } } @@ -1050,6 +1053,7 @@ void GraphEdit::set_zoom(float p_zoom) { top_layer->update(); _update_scroll(); + connections_layer->update(); if (is_visible()) { diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index da298a795a..eec973ebef 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -745,6 +745,9 @@ void GraphNode::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_resizeable","resizeable"),&GraphNode::set_resizeable); ObjectTypeDB::bind_method(_MD("is_resizeable"),&GraphNode::is_resizeable); + ObjectTypeDB::bind_method(_MD("set_selected","selected"),&GraphNode::set_selected); + ObjectTypeDB::bind_method(_MD("is_selected"),&GraphNode::is_selected); + ObjectTypeDB::bind_method(_MD("get_connection_output_count"),&GraphNode::get_connection_output_count); ObjectTypeDB::bind_method(_MD("get_connection_input_count"),&GraphNode::get_connection_input_count); @@ -766,6 +769,7 @@ void GraphNode::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::STRING,"title"),_SCS("set_title"),_SCS("get_title")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"show_close"),_SCS("set_show_close_button"),_SCS("is_close_button_visible")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"resizeable"),_SCS("set_resizeable"),_SCS("is_resizeable")); ADD_SIGNAL(MethodInfo("offset_changed")); ADD_SIGNAL(MethodInfo("dragged",PropertyInfo(Variant::VECTOR2,"from"),PropertyInfo(Variant::VECTOR2,"to"))); @@ -788,4 +792,5 @@ GraphNode::GraphNode() { comment=false; resizeable=false; resizing=false; + selected=false; } diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 89cd509fbd..f69ad8fa7e 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -959,7 +959,23 @@ void ItemList::_notification(int p_what) { 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_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; Vector2 base_ofs = bg->get_offset(); base_ofs.y-=int(scroll_bar->get_val()); @@ -1147,25 +1163,6 @@ void ItemList::_notification(int p_what) { 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; - } } diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 90a8af9238..f7d74b2b49 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -639,6 +639,7 @@ void LineEdit::_notification(int p_what) { if(text.empty()) font_color.a *= placeholder_alpha; + int caret_height = font->get_height() > y_area ? y_area : font->get_height(); while(true) { //end of string, break! @@ -657,14 +658,14 @@ void LineEdit::_notification(int p_what) { bool selected=selection.enabled && char_ofs>=selection.begin && char_ofs<selection.end; if (selected) - VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs), Size2(char_width, y_area)), selection_color); + VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs), Size2(char_width, caret_height)), selection_color); font->draw_char(ci, Point2(x_ofs, y_ofs + font_ascent), cchar, next, selected ? font_color_selected : font_color); if (char_ofs==cursor_pos && draw_caret) { VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2( - Point2( x_ofs , y_ofs ), Size2( 1, y_area ) ), cursor_color ); + Point2( x_ofs , y_ofs ), Size2( 1, caret_height ) ), cursor_color ); } x_ofs+=char_width; @@ -673,7 +674,7 @@ void LineEdit::_notification(int p_what) { if (char_ofs==cursor_pos && draw_caret) {//may be at the end VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2( - Point2( x_ofs , y_ofs ), Size2( 1, y_area ) ), cursor_color ); + Point2( x_ofs , y_ofs ), Size2( 1, caret_height ) ), cursor_color ); } } break; case NOTIFICATION_FOCUS_ENTER: { @@ -1191,24 +1192,28 @@ void LineEdit::menu_option(int p_option) { switch(p_option) { case MENU_CUT: { - cut_text(); + if (editable) { + cut_text(); + } } break; case MENU_COPY: { copy_text(); } break; case MENU_PASTE: { - - paste_text(); + if (editable) { + paste_text(); + } } break; case MENU_CLEAR: { - clear(); + if (editable) { + clear(); + } } break; case MENU_SELECT_ALL: { select_all(); } break; case MENU_UNDO: { - undo(); } break; diff --git a/scene/gui/link_button.cpp b/scene/gui/link_button.cpp index 62829fd5a4..e6f85c5935 100644 --- a/scene/gui/link_button.cpp +++ b/scene/gui/link_button.cpp @@ -87,13 +87,13 @@ void LinkButton::_notification(int p_what) { else color=get_color("font_color"); - do_underline=true; + do_underline=underline_mode!=UNDERLINE_MODE_NEVER; } break; case DRAW_HOVER: { color=get_color("font_color_hover"); - do_underline=true; + do_underline=underline_mode!=UNDERLINE_MODE_NEVER; } break; case DRAW_DISABLED: { @@ -139,9 +139,10 @@ void LinkButton::_bind_methods() { BIND_CONSTANT( UNDERLINE_MODE_ALWAYS ); BIND_CONSTANT( UNDERLINE_MODE_ON_HOVER ); + BIND_CONSTANT( UNDERLINE_MODE_NEVER ); ADD_PROPERTYNZ(PropertyInfo(Variant::STRING,"text"), _SCS("set_text"), _SCS("get_text")); - ADD_PROPERTYNZ(PropertyInfo(Variant::INT,"underline",PROPERTY_HINT_ENUM,"Always,On Hover"), _SCS("set_underline_mode"), _SCS("get_underline_mode")); + ADD_PROPERTYNZ(PropertyInfo(Variant::INT,"underline",PROPERTY_HINT_ENUM,"Always,On Hover,Never"), _SCS("set_underline_mode"), _SCS("get_underline_mode")); } diff --git a/scene/gui/link_button.h b/scene/gui/link_button.h index 9978f66cc0..a44fc2ec1b 100644 --- a/scene/gui/link_button.h +++ b/scene/gui/link_button.h @@ -40,7 +40,8 @@ public: enum UnderlineMode { UNDERLINE_MODE_ALWAYS, - UNDERLINE_MODE_ON_HOVER + UNDERLINE_MODE_ON_HOVER, + UNDERLINE_MODE_NEVER }; private: String text; diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 422e1f5877..7936ee39cb 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -705,6 +705,13 @@ void PopupMenu::set_item_submenu(int p_idx, const String& p_submenu) { update(); } +void PopupMenu::toggle_item_checked(int p_idx) { + + ERR_FAIL_INDEX(p_idx,items.size()); + items[p_idx].checked = !items[p_idx].checked; + update(); +} + String PopupMenu::get_item_text(int p_idx) const { ERR_FAIL_INDEX_V(p_idx,items.size(),""); @@ -1074,33 +1081,40 @@ void PopupMenu::_bind_methods() { ObjectTypeDB::bind_method(_MD("add_icon_check_shortcut","texture","shortcut:ShortCut","id"),&PopupMenu::add_icon_check_shortcut,DEFVAL(-1)); ObjectTypeDB::bind_method(_MD("add_check_shortcut","shortcut:ShortCut","id"),&PopupMenu::add_check_shortcut,DEFVAL(-1)); - ObjectTypeDB::bind_method(_MD("set_item_text","idx","text"),&PopupMenu::set_item_text); ObjectTypeDB::bind_method(_MD("set_item_icon","idx","icon"),&PopupMenu::set_item_icon); + ObjectTypeDB::bind_method(_MD("set_item_checked","idx","checked"),&PopupMenu::set_item_checked); + ObjectTypeDB::bind_method(_MD("set_item_ID","idx","id"),&PopupMenu::set_item_ID); ObjectTypeDB::bind_method(_MD("set_item_accelerator","idx","accel"),&PopupMenu::set_item_accelerator); ObjectTypeDB::bind_method(_MD("set_item_metadata","idx","metadata"),&PopupMenu::set_item_metadata); - ObjectTypeDB::bind_method(_MD("set_item_checked","idx","checked"),&PopupMenu::set_item_checked); ObjectTypeDB::bind_method(_MD("set_item_disabled","idx","disabled"),&PopupMenu::set_item_disabled); - ObjectTypeDB::bind_method(_MD("set_item_shortcut","idx","shortcut:ShortCut"),&PopupMenu::set_item_shortcut); ObjectTypeDB::bind_method(_MD("set_item_submenu","idx","submenu"),&PopupMenu::set_item_submenu); ObjectTypeDB::bind_method(_MD("set_item_as_separator","idx","enable"),&PopupMenu::set_item_as_separator); ObjectTypeDB::bind_method(_MD("set_item_as_checkable","idx","enable"),&PopupMenu::set_item_as_checkable); - ObjectTypeDB::bind_method(_MD("set_item_ID","idx","id"),&PopupMenu::set_item_ID); + ObjectTypeDB::bind_method(_MD("set_item_tooltip","idx","tooltip"),&PopupMenu::set_item_tooltip); + ObjectTypeDB::bind_method(_MD("set_item_shortcut","idx","shortcut:ShortCut"),&PopupMenu::set_item_shortcut); + + ObjectTypeDB::bind_method(_MD("toggle_item_checked","idx"), &PopupMenu::toggle_item_checked); + ObjectTypeDB::bind_method(_MD("get_item_text","idx"),&PopupMenu::get_item_text); ObjectTypeDB::bind_method(_MD("get_item_icon","idx"),&PopupMenu::get_item_icon); - ObjectTypeDB::bind_method(_MD("get_item_metadata","idx"),&PopupMenu::get_item_metadata); + ObjectTypeDB::bind_method(_MD("is_item_checked","idx"),&PopupMenu::is_item_checked); + ObjectTypeDB::bind_method(_MD("get_item_ID","idx"),&PopupMenu::get_item_ID); + ObjectTypeDB::bind_method(_MD("get_item_index","id"),&PopupMenu::get_item_index); ObjectTypeDB::bind_method(_MD("get_item_accelerator","idx"),&PopupMenu::get_item_accelerator); - ObjectTypeDB::bind_method(_MD("get_item_shortcut:ShortCut","idx"),&PopupMenu::get_item_shortcut); + ObjectTypeDB::bind_method(_MD("get_item_metadata","idx"),&PopupMenu::get_item_metadata); + ObjectTypeDB::bind_method(_MD("is_item_disabled","idx"),&PopupMenu::is_item_disabled); ObjectTypeDB::bind_method(_MD("get_item_submenu","idx"),&PopupMenu::get_item_submenu); ObjectTypeDB::bind_method(_MD("is_item_separator","idx"),&PopupMenu::is_item_separator); ObjectTypeDB::bind_method(_MD("is_item_checkable","idx"),&PopupMenu::is_item_checkable); - ObjectTypeDB::bind_method(_MD("is_item_checked","idx"),&PopupMenu::is_item_checked); - ObjectTypeDB::bind_method(_MD("is_item_disabled","idx"),&PopupMenu::is_item_disabled); - ObjectTypeDB::bind_method(_MD("get_item_ID","idx"),&PopupMenu::get_item_ID); - ObjectTypeDB::bind_method(_MD("get_item_index","id"),&PopupMenu::get_item_index); + ObjectTypeDB::bind_method(_MD("get_item_tooltip","idx"),&PopupMenu::get_item_tooltip); + ObjectTypeDB::bind_method(_MD("get_item_shortcut:ShortCut","idx"),&PopupMenu::get_item_shortcut); + ObjectTypeDB::bind_method(_MD("get_item_count"),&PopupMenu::get_item_count); - ObjectTypeDB::bind_method(_MD("add_separator"),&PopupMenu::add_separator); + ObjectTypeDB::bind_method(_MD("remove_item","idx"),&PopupMenu::remove_item); + + ObjectTypeDB::bind_method(_MD("add_separator"),&PopupMenu::add_separator); ObjectTypeDB::bind_method(_MD("clear"),&PopupMenu::clear); ObjectTypeDB::bind_method(_MD("_set_items"),&PopupMenu::_set_items); @@ -1138,5 +1152,3 @@ PopupMenu::PopupMenu() { PopupMenu::~PopupMenu() { } - - diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index 50ba3a2569..a62c37f14d 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -118,6 +118,8 @@ public: void set_item_shortcut(int p_idx, const Ref<ShortCut>& p_shortcut); void set_item_h_offset(int p_idx, int p_offset); + void toggle_item_checked(int p_idx); + String get_item_text(int p_idx) const; Ref<Texture> get_item_icon(int p_idx) const; bool is_item_checked(int p_idx) const; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 9db0a66395..f1a2823e8f 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -482,6 +482,14 @@ void TextEdit::_notification(int p_what) { Color color = cache.font_color; int in_region=-1; + if (line_length_guideline) { + int x=xmargin_beg+cache.font->get_char_size('0').width*line_length_guideline_col-cursor.x_ofs; + if (x>xmargin_beg && x<xmargin_end) { + Color guideline_color(color.r,color.g,color.b,color.a*0.25f); + VisualServer::get_singleton()->canvas_item_add_line(ci,Point2(x,0),Point2(x,cache.size.height),guideline_color); + } + } + if (syntax_coloring) { if (custom_bg_color.a>0.01) { @@ -685,6 +693,8 @@ void TextEdit::_notification(int p_what) { // get the highlighted words String highlighted_text = get_selection_text(); + String line_num_padding = line_numbers_zero_padded ? "0" : " "; + for (int i=0;i<visible_rows;i++) { int line=i+cursor.line_ofs; @@ -750,7 +760,7 @@ void TextEdit::_notification(int p_what) { if (cache.line_number_w) { String fc = String::num(line+1); while (fc.length() < line_number_char_count) { - fc="0"+fc; + fc=line_num_padding+fc; } cache.font->draw(ci,Point2(cache.style_normal->get_margin(MARGIN_LEFT)+cache.breakpoint_gutter_width,ofs_y+cache.font->get_ascent()),fc,cache.line_number_color); @@ -1245,15 +1255,19 @@ void TextEdit::_notification(int p_what) { } if (OS::get_singleton()->has_virtual_keyboard()) OS::get_singleton()->show_virtual_keyboard(get_text(),get_global_rect()); + if (raised_from_completion) { + VisualServer::get_singleton()->canvas_item_set_z(get_canvas_item(), 1); + } } break; case NOTIFICATION_FOCUS_EXIT: { if (OS::get_singleton()->has_virtual_keyboard()) OS::get_singleton()->hide_virtual_keyboard(); - + if (raised_from_completion) { + VisualServer::get_singleton()->canvas_item_set_z(get_canvas_item(), 0); + } } break; - } } @@ -1651,7 +1665,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { update(); } - if (mb.button_index==BUTTON_RIGHT) { + if (mb.button_index==BUTTON_RIGHT && context_menu_enabled) { menu->set_pos(get_global_transform().xform(get_local_mouse_pos())); menu->set_size(Vector2(1,1)); @@ -2542,7 +2556,9 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { } break; case KEY_X: { - + if (readonly) { + break; + } if (!k.mod.command || k.mod.shift || k.mod.alt) { scancode_handled=false; break; @@ -2574,7 +2590,9 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { undo(); } break; case KEY_V: { - + if (readonly) { + break; + } if (!k.mod.command || k.mod.shift || k.mod.alt) { scancode_handled=false; break; @@ -4193,12 +4211,17 @@ void TextEdit::_confirm_completion() { void TextEdit::_cancel_code_hint() { + + VisualServer::get_singleton()->canvas_item_set_z(get_canvas_item(), 0); + raised_from_completion = false; completion_hint=""; update(); } void TextEdit::_cancel_completion() { + VisualServer::get_singleton()->canvas_item_set_z(get_canvas_item(), 0); + raised_from_completion = false; if (!completion_active) return; @@ -4378,6 +4401,8 @@ void TextEdit::query_code_comple() { void TextEdit::set_code_hint(const String& p_hint) { + VisualServer::get_singleton()->canvas_item_set_z(get_canvas_item(), 1); + raised_from_completion = true; completion_hint=p_hint; completion_hint_offset=-0xFFFF; update(); @@ -4385,7 +4410,8 @@ void TextEdit::set_code_hint(const String& p_hint) { void TextEdit::code_complete(const Vector<String> &p_strings) { - + VisualServer::get_singleton()->canvas_item_set_z(get_canvas_item(), 1); + raised_from_completion = true; completion_strings=p_strings; completion_active=true; completion_current=""; @@ -4496,10 +4522,26 @@ void TextEdit::set_show_line_numbers(bool p_show) { update(); } +void TextEdit::set_line_numbers_zero_padded(bool p_zero_padded) { + + line_numbers_zero_padded=p_zero_padded; + update(); +} + bool TextEdit::is_show_line_numbers_enabled() const { return line_numbers; } +void TextEdit::set_show_line_length_guideline(bool p_show) { + line_length_guideline=p_show; + update(); +} + +void TextEdit::set_line_length_guideline_column(int p_column) { + line_length_guideline_col=p_column; + update(); +} + void TextEdit::set_draw_breakpoint_gutter(bool p_draw) { draw_breakpoint_gutter = p_draw; update(); @@ -4527,18 +4569,22 @@ void TextEdit::menu_option(int p_option) { switch( p_option ) { case MENU_CUT: { - - cut(); + if (!readonly) { + cut(); + } } break; case MENU_COPY: { copy(); } break; case MENU_PASTE: { - - paste(); + if (!readonly) { + paste(); + } } break; case MENU_CLEAR: { - clear(); + if (!readonly) { + clear(); + } } break; case MENU_SELECT_ALL: { select_all(); @@ -4561,6 +4607,9 @@ bool TextEdit::is_selecting_identifiers_on_hover_enabled() const { return select_identifiers_enabled; } +void TextEdit::set_context_menu_enabled(bool p_enable) { + context_menu_enabled = p_enable; +} PopupMenu *TextEdit::get_menu() const { return menu; @@ -4770,6 +4819,9 @@ TextEdit::TextEdit() { completion_line_ofs=0; tooltip_obj=NULL; line_numbers=false; + line_numbers_zero_padded=false; + line_length_guideline=false; + line_length_guideline_col=80; draw_breakpoint_gutter=false; next_operation_is_complex=false; scroll_past_end_of_file_enabled=false; @@ -4781,6 +4833,9 @@ TextEdit::TextEdit() { window_has_focus=true; select_identifiers_enabled=false; + raised_from_completion = false; + + context_menu_enabled=true; menu = memnew( PopupMenu ); add_child(menu); menu->add_item(TTR("Cut"),MENU_CUT,KEY_MASK_CMD|KEY_X); diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index cb49618f18..7820fefdd2 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -232,6 +232,9 @@ class TextEdit : public Control { bool text_changed_dirty; bool undo_enabled; bool line_numbers; + bool line_numbers_zero_padded; + bool line_length_guideline; + int line_length_guideline_col; bool draw_breakpoint_gutter; int breakpoint_gutter_width; @@ -244,6 +247,8 @@ class TextEdit : public Control { bool insert_mode; bool select_identifiers_enabled; + bool raised_from_completion; + String hilighted_word; uint64_t last_dblclk; @@ -269,6 +274,8 @@ class TextEdit : public Control { int search_result_line; int search_result_col; + bool context_menu_enabled; + int get_visible_rows() const; int get_char_count(); @@ -319,8 +326,6 @@ class TextEdit : public Control { void _confirm_completion(); void _update_completion_candidates(); - void _get_mouse_pos(const Point2i& p_mouse, int &r_row, int &r_col) const; - protected: virtual String get_tooltip(const Point2& p_pos) const; @@ -360,6 +365,8 @@ public: virtual CursorShape get_cursor_shape(const Point2& p_pos=Point2i()) const; + void _get_mouse_pos(const Point2i& p_mouse, int &r_row, int &r_col) const; + //void delete_char(); //void delete_line(); @@ -483,6 +490,11 @@ public: void set_show_line_numbers(bool p_show); bool is_show_line_numbers_enabled() const; + void set_line_numbers_zero_padded(bool p_zero_padded); + + void set_show_line_length_guideline(bool p_show); + void set_line_length_guideline_column(int p_column); + void set_draw_breakpoint_gutter(bool p_draw); bool is_drawing_breakpoint_gutter() const; @@ -499,6 +511,7 @@ public: void set_select_identifiers_on_hover(bool p_enable); bool is_selecting_identifiers_on_hover_enabled() const; + void set_context_menu_enabled(bool p_enable); PopupMenu *get_menu() const; String get_text_for_completion(); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 20794b2faa..ca9c666c01 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -32,6 +32,7 @@ #include "os/keyboard.h" #include "globals.h" #include "os/input.h" +#include "scene/main/viewport.h" @@ -829,6 +830,8 @@ void Tree::update_cache() { cache.guide_width=get_constant("guide_width"); cache.draw_relationship_lines=get_constant("draw_relationship_lines"); cache.relationship_line_color=get_color("relationship_line_color"); + cache.scroll_border=get_constant("scroll_border"); + cache.scroll_speed=get_constant("scroll_speed"); cache.title_button = get_stylebox("title_button_normal"); cache.title_button_pressed = get_stylebox("title_button_pressed"); @@ -1701,16 +1704,11 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ } break; case TreeItem::CELL_MODE_CHECK: { - Ref<Texture> checked = cache.checked; bring_up_editor=false; //checkboxes are not edited with editor - if (x>=0 && x<= checked->get_width()+cache.hseparation ) { - - - p_item->set_checked(col,!c.checked); - item_edited(col,p_item); - click_handled=true; - //p_item->edited_signal.call(col); - } + p_item->set_checked(col, !c.checked); + item_edited(col, p_item); + click_handled = true; + //p_item->edited_signal.call(col); } break; case TreeItem::CELL_MODE_RANGE: @@ -2681,11 +2679,17 @@ void Tree::_notification(int p_what) { if (p_what==NOTIFICATION_DRAG_END) { drop_mode_flags=0; + scrolling = false; + set_fixed_process(false); update(); } if (p_what==NOTIFICATION_DRAG_BEGIN) { single_select_defer=NULL; + if (cache.scroll_speed > 0 && get_rect().has_point(get_viewport()->get_mouse_pos() - get_global_pos())) { + scrolling = true; + set_fixed_process(true); + } } if (p_what==NOTIFICATION_FIXED_PROCESS) { @@ -2731,6 +2735,28 @@ void Tree::_notification(int p_what) { } } + + if (scrolling) { + Point2 point = get_viewport()->get_mouse_pos() - get_global_pos(); + if (point.x < cache.scroll_border) { + point.x -= cache.scroll_border; + } else if (point.x > get_size().width - cache.scroll_border) { + point.x -= get_size().width - cache.scroll_border; + } else { + point.x = 0; + } + if (point.y < cache.scroll_border) { + point.y -= cache.scroll_border; + } else if (point.y > get_size().height - cache.scroll_border) { + point.y -= get_size().height - cache.scroll_border; + } else { + point.y = 0; + } + point *= cache.scroll_speed * get_fixed_process_delta_time(); + point += get_scroll(); + h_scroll->set_val(point.x); + v_scroll->set_val(point.y); + } } if (p_what==NOTIFICATION_DRAW) { diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 2124dce749..6c2f1dae40 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -390,6 +390,8 @@ friend class TreeItem; int button_margin; Point2 offset; int draw_relationship_lines; + int scroll_border; + int scroll_speed; enum ClickType { CLICK_NONE, @@ -448,6 +450,7 @@ friend class TreeItem; bool drag_touching_deaccel; bool click_handled; bool allow_rmb_select; + bool scrolling; bool force_select_on_already_selected; diff --git a/scene/gui/video_player.cpp b/scene/gui/video_player.cpp index 1be847929d..335672126c 100644 --- a/scene/gui/video_player.cpp +++ b/scene/gui/video_player.cpp @@ -248,7 +248,7 @@ void VideoPlayer::stop() { playback->stop(); AudioServer::get_singleton()->stream_set_active(stream_rid,false); - resampler.clear(); + resampler.flush(); set_process(false); last_audio_time=0; }; @@ -426,5 +426,6 @@ VideoPlayer::~VideoPlayer() { if (stream_rid.is_valid()) AudioServer::get_singleton()->free(stream_rid); + resampler.clear(); //Not necessary here, but make in consistent with other "stream_player" classes }; |