From a2c4c1708501e1eb223e34375c506c14d8fb4631 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sun, 15 May 2016 23:41:48 -0300 Subject: [PATCH] Experimental Right Mouse Button menu for SceneTree Will eventually replace the buttons of that dock, so please test it! --- scene/gui/tree.cpp | 45 ++++++++++++++++++++++++--- scene/gui/tree.h | 4 +++ tools/editor/scene_tree_dock.cpp | 49 ++++++++++++++++++++++++++++-- tools/editor/scene_tree_dock.h | 5 +++ tools/editor/scene_tree_editor.cpp | 9 ++++++ tools/editor/scene_tree_editor.h | 3 ++ 6 files changed, 108 insertions(+), 7 deletions(-) diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 6f5f7d82a6d..9c707854088 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -1563,7 +1563,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ col_width-=w+cache.button_margin; } - if (p_button==BUTTON_LEFT) { + if (p_button==BUTTON_LEFT || (p_button==BUTTON_RIGHT && allow_rmb_select)) { /* process selection */ if (p_doubleclick && (!c.editable || c.mode==TreeItem::CELL_MODE_CUSTOM || c.mode==TreeItem::CELL_MODE_ICON /*|| c.mode==TreeItem::CELL_MODE_CHECK*/)) { //it' s confusing for check @@ -1574,10 +1574,13 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ if (select_mode==SELECT_MULTI && p_mod.command && c.selectable) { - if (!c.selected) { + if (!c.selected || p_button==BUTTON_RIGHT) { p_item->select(col); emit_signal("multi_selected",p_item,col,true); + if (p_button==BUTTON_RIGHT) { + emit_signal("item_rmb_selected",get_local_mouse_pos()); + } //p_item->selected_signal.call(col); @@ -1597,15 +1600,25 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ bool inrange=false; select_single_item( p_item, root, col,selected_item,&inrange ); + if (p_button==BUTTON_RIGHT) { + emit_signal("item_rmb_selected",get_local_mouse_pos()); + } } else { int icount = _count_selected_items(root); - if (select_mode==SELECT_MULTI && icount>1) { + if (select_mode==SELECT_MULTI && icount>1 && p_button!=BUTTON_RIGHT) { single_select_defer=p_item; single_select_defer_column=col; } else { - select_single_item( p_item, root, col ); + + if (p_button!=BUTTON_RIGHT || !c.selected) { + select_single_item( p_item, root, col ); + } + + if (p_button==BUTTON_RIGHT) { + emit_signal("item_rmb_selected",get_local_mouse_pos()); + } } } @@ -2348,12 +2361,13 @@ void Tree::_input_event(InputEvent p_event) { } switch(b.button_index) { + case BUTTON_RIGHT: case BUTTON_LEFT: { Ref bg = cache.bg; Point2 pos = Point2(b.x,b.y) - bg->get_offset(); cache.click_type=Cache::CLICK_NONE; - if (show_column_titles) { + if (show_column_titles && b.button_index==BUTTON_LEFT) { pos.y-=_get_title_button_height(); if (pos.y<0) { @@ -2390,6 +2404,9 @@ void Tree::_input_event(InputEvent p_event) { } + if (b.button_index==BUTTON_RIGHT) + break; + if (drag_touching) { set_fixed_process(false); drag_touching_deaccel=false; @@ -3465,6 +3482,17 @@ bool Tree::get_single_select_cell_editing_only_when_already_selected() const { return force_select_on_already_selected; } + +void Tree::set_allow_rmb_select(bool p_allow) { + + allow_rmb_select=p_allow; +} + +bool Tree::get_allow_rmb_select() const{ + + return allow_rmb_select; +} + void Tree::_bind_methods() { ObjectTypeDB::bind_method(_MD("_range_click_timeout"),&Tree::_range_click_timeout); @@ -3515,10 +3543,15 @@ void Tree::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_drop_mode_flags","flags"),&Tree::set_drop_mode_flags); ObjectTypeDB::bind_method(_MD("get_drop_mode_flags"),&Tree::get_drop_mode_flags); + ObjectTypeDB::bind_method(_MD("set_allow_rmb_select","allow"),&Tree::set_allow_rmb_select); + ObjectTypeDB::bind_method(_MD("get_allow_rmb_select"),&Tree::get_allow_rmb_select); + + ObjectTypeDB::bind_method(_MD("set_single_select_cell_editing_only_when_already_selected","enable"),&Tree::set_single_select_cell_editing_only_when_already_selected); ObjectTypeDB::bind_method(_MD("get_single_select_cell_editing_only_when_already_selected"),&Tree::get_single_select_cell_editing_only_when_already_selected); ADD_SIGNAL( MethodInfo("item_selected")); + ADD_SIGNAL( MethodInfo("item_rmb_selected",PropertyInfo(Variant::VECTOR2,"pos"))); ADD_SIGNAL( MethodInfo("cell_selected")); ADD_SIGNAL( MethodInfo("multi_selected",PropertyInfo(Variant::OBJECT,"item"),PropertyInfo(Variant::INT,"column"),PropertyInfo(Variant::BOOL,"selected")) ); ADD_SIGNAL( MethodInfo("item_edited")); @@ -3623,6 +3656,8 @@ Tree::Tree() { drop_mode_section=0; single_select_defer=NULL; force_select_on_already_selected=false; + + allow_rmb_select=false; } diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 4d0167ebb8d..1dad26dffe3 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -438,6 +438,7 @@ friend class TreeItem; bool drag_touching; bool drag_touching_deaccel; bool click_handled; + bool allow_rmb_select; bool force_select_on_already_selected; @@ -519,6 +520,9 @@ public: void set_single_select_cell_editing_only_when_already_selected(bool p_enable); bool get_single_select_cell_editing_only_when_already_selected() const; + void set_allow_rmb_select(bool p_allow); + bool get_allow_rmb_select() const; + void set_value_evaluator(ValueEvaluator *p_evaluator); Tree(); diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp index ce7a0b29112..88bed4c23fa 100644 --- a/tools/editor/scene_tree_dock.cpp +++ b/tools/editor/scene_tree_dock.cpp @@ -1681,9 +1681,50 @@ void SceneTreeDock::_nodes_dragged(Array p_nodes,NodePath p_to,int p_type) { } +void SceneTreeDock::_tree_rmb(const Vector2& p_menu_pos) { + + List selection = editor_selection->get_selected_node_list(); + + if (selection.size()==0) + return; + menu->clear(); + + + if (selection.size()==1) { + menu->add_item("Add Child Node",TOOL_NEW,KEY_MASK_CMD|KEY_A); + menu->add_item("Instance Child",TOOL_INSTANCE); + menu->add_separator(); + menu->add_item("Change Type",TOOL_REPLACE); + menu->add_separator(); + menu->add_item("Edit Groups",TOOL_GROUP); + menu->add_item("Edit Connections",TOOL_CONNECT); + menu->add_separator(); + menu->add_item("Add Script",TOOL_SCRIPT); + menu->add_separator(); + } + + menu->add_item("Move Up",TOOL_MOVE_UP,KEY_MASK_CMD|KEY_UP); + menu->add_item("Move Down",TOOL_MOVE_DOWN,KEY_MASK_CMD|KEY_DOWN); + menu->add_item("Duplicate",TOOL_DUPLICATE,KEY_MASK_CMD|KEY_D); + menu->add_item("Reparent",TOOL_REPARENT); + + if (selection.size()==1) { + menu->add_separator(); + menu->add_item("Save Branch as Scene",TOOL_NEW_SCENE_FROM); + } + menu->add_separator(); + + menu->add_item("Delete Node(s)",TOOL_ERASE,KEY_DELETE); + + menu->set_size(Size2(1,1)); + menu->set_pos(p_menu_pos); + menu->popup(); + +} + void SceneTreeDock::_bind_methods() { - ObjectTypeDB::bind_method(_MD("_tool_selected"),&SceneTreeDock::_tool_selected); + ObjectTypeDB::bind_method(_MD("_tool_selected"),&SceneTreeDock::_tool_selected,DEFVAL(false)); ObjectTypeDB::bind_method(_MD("_create"),&SceneTreeDock::_create); //ObjectTypeDB::bind_method(_MD("_script_created"),&SceneTreeDock::_script_created); ObjectTypeDB::bind_method(_MD("_node_reparent"),&SceneTreeDock::_node_reparent); @@ -1701,6 +1742,7 @@ void SceneTreeDock::_bind_methods() { ObjectTypeDB::bind_method(_MD("_new_scene_from"),&SceneTreeDock::_new_scene_from); ObjectTypeDB::bind_method(_MD("_nodes_dragged"),&SceneTreeDock::_nodes_dragged); ObjectTypeDB::bind_method(_MD("_files_dropped"),&SceneTreeDock::_files_dropped); + ObjectTypeDB::bind_method(_MD("_tree_rmb"),&SceneTreeDock::_tree_rmb); ObjectTypeDB::bind_method(_MD("instance"),&SceneTreeDock::instance); @@ -1765,6 +1807,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelec scene_tree = memnew( SceneTreeEditor(false,true,true )); vbc->add_child(scene_tree); scene_tree->set_v_size_flags(SIZE_EXPAND|SIZE_FILL); + scene_tree->connect("rmb_pressed",this,"_tree_rmb"); scene_tree->connect("node_selected", this,"_node_selected",varray(),CONNECT_DEFERRED); scene_tree->connect("node_renamed", this,"_node_renamed",varray(),CONNECT_DEFERRED); @@ -1869,7 +1912,9 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelec new_scene_from_dialog->connect("file_selected",this,"_new_scene_from"); - + menu = memnew( PopupMenu ); + add_child(menu); + menu->connect("item_pressed",this,"_tool_selected"); first_enter=true; diff --git a/tools/editor/scene_tree_dock.h b/tools/editor/scene_tree_dock.h index 5dc1e3e12e7..9b84c4d44d8 100644 --- a/tools/editor/scene_tree_dock.h +++ b/tools/editor/scene_tree_dock.h @@ -35,6 +35,7 @@ #include "scene/gui/button.h" #include "scene/gui/tool_button.h" #include "scene/gui/box_container.h" +#include "scene/gui/popup_menu.h" #include "scene_tree_editor.h" #include "create_dialog.h" #include "editor_data.h" @@ -93,6 +94,8 @@ class SceneTreeDock : public VBoxContainer { EditorSubScene *import_subscene_dialog; EditorFileDialog *new_scene_from_dialog; + PopupMenu * menu; + bool first_enter; void _create(); @@ -135,6 +138,8 @@ class SceneTreeDock : public VBoxContainer { void _nodes_dragged(Array p_nodes,NodePath p_to,int p_type); void _files_dropped(Vector p_files,NodePath p_to,int p_type); + void _tree_rmb(const Vector2& p_menu_pos); + protected: void _notification(int p_what); diff --git a/tools/editor/scene_tree_editor.cpp b/tools/editor/scene_tree_editor.cpp index fd79460aa89..8760d21c1c1 100644 --- a/tools/editor/scene_tree_editor.cpp +++ b/tools/editor/scene_tree_editor.cpp @@ -908,6 +908,10 @@ void SceneTreeEditor::drop_data_fw(const Point2& p_point,const Variant& p_data,C } +void SceneTreeEditor::_rmb_select(const Vector2& p_pos) { + + emit_signal("rmb_pressed",tree->get_global_transform().xform(p_pos)); +} void SceneTreeEditor::_bind_methods() { @@ -923,6 +927,7 @@ void SceneTreeEditor::_bind_methods() { ObjectTypeDB::bind_method("_cell_button_pressed",&SceneTreeEditor::_cell_button_pressed); ObjectTypeDB::bind_method("_cell_collapsed",&SceneTreeEditor::_cell_collapsed); ObjectTypeDB::bind_method("_subscene_option",&SceneTreeEditor::_subscene_option); + ObjectTypeDB::bind_method("_rmb_select",&SceneTreeEditor::_rmb_select); ObjectTypeDB::bind_method("_node_script_changed",&SceneTreeEditor::_node_script_changed); ObjectTypeDB::bind_method("_node_visibility_changed",&SceneTreeEditor::_node_visibility_changed); @@ -937,6 +942,7 @@ void SceneTreeEditor::_bind_methods() { ADD_SIGNAL( MethodInfo("node_changed") ); ADD_SIGNAL( MethodInfo("nodes_rearranged",PropertyInfo(Variant::ARRAY,"paths"),PropertyInfo(Variant::NODE_PATH,"to_path"),PropertyInfo(Variant::INT,"type") ) ); ADD_SIGNAL( MethodInfo("files_dropped",PropertyInfo(Variant::STRING_ARRAY,"files"),PropertyInfo(Variant::NODE_PATH,"to_path"),PropertyInfo(Variant::INT,"type") ) ); + ADD_SIGNAL( MethodInfo("rmb_pressed",PropertyInfo(Variant::VECTOR2,"pos")) ) ; ADD_SIGNAL( MethodInfo("open") ); ADD_SIGNAL( MethodInfo("open_script") ); @@ -976,6 +982,9 @@ SceneTreeEditor::SceneTreeEditor(bool p_label,bool p_can_rename, bool p_can_open add_child( tree ); tree->set_drag_forwarding(this); + if (p_can_rename) + tree->set_allow_rmb_select(true); + tree->connect("item_rmb_selected",this,"_rmb_select"); tree->connect("cell_selected", this,"_selected_changed"); tree->connect("item_edited", this,"_renamed",varray(),CONNECT_DEFERRED); diff --git a/tools/editor/scene_tree_editor.h b/tools/editor/scene_tree_editor.h index 283db280ed9..5529d36a469 100644 --- a/tools/editor/scene_tree_editor.h +++ b/tools/editor/scene_tree_editor.h @@ -112,6 +112,7 @@ class SceneTreeEditor : public Control { void _subscene_option(int p_idx); + void _selection_changed(); Node *get_scene_node(); @@ -119,6 +120,8 @@ class SceneTreeEditor : public Control { bool can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const; void drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from); + void _rmb_select(const Vector2& p_pos); + public: