瀏覽代碼

Double click on scene tree element to focus currently selected node
In 3D it will focus in the first viewport
Enable double click for trees

Daniel J. Ramirez 9 年之前
父節點
當前提交
70c9979cce

+ 35 - 3
scene/gui/tree.cpp

@@ -2328,9 +2328,22 @@ void Tree::_input_event(InputEvent p_event) {
 							range_drag_enabled=false;
 							Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
 							warp_mouse(range_drag_capture_pos);
-						} else
-							edit_selected();
+						} else {
+
+							if (delayed_text_editor) {
+								uint64_t diff = OS::get_singleton()->get_ticks_msec() - first_selection_time;
+								if (diff >= 400 && diff <= 800)
+									edit_selected();
+								// fast double click
+								else if (diff < 400) {
+									emit_signal("item_double_clicked");
+								}
 
+								first_selection_time = OS::get_singleton()->get_ticks_msec();
+							} else {
+								edit_selected();
+							}
+						}
 						pressing_for_editor=false;
 
 					}
@@ -2848,7 +2861,6 @@ void Tree::item_changed(int p_column,TreeItem *p_item) {
 
 void Tree::item_selected(int p_column,TreeItem *p_item) {
 
-
 	if (select_mode==SELECT_MULTI) {
 
 		if (!p_item->cells[p_column].selectable)
@@ -2856,8 +2868,11 @@ void Tree::item_selected(int p_column,TreeItem *p_item) {
 
 		p_item->cells[p_column].selected=true;
 		//emit_signal("multi_selected",p_item,p_column,true); - NO this is for TreeItem::select
+		if (delayed_text_editor)
+			first_selection_time = OS::get_singleton()->get_ticks_msec();
 
 	} else {
+
 		select_single_item(p_item,root,p_column);
 	}
 	update();
@@ -3503,6 +3518,16 @@ bool Tree::get_allow_rmb_select() const{
 	return allow_rmb_select;
 }
 
+
+void Tree::set_delayed_text_editor(bool enabled) {
+	delayed_text_editor = enabled;
+}
+
+bool Tree::is_delayed_text_editor_enabled() const {
+	return delayed_text_editor;
+}
+
+
 void Tree::_bind_methods() {
 
 	ObjectTypeDB::bind_method(_MD("_range_click_timeout"),&Tree::_range_click_timeout);
@@ -3556,6 +3581,9 @@ void Tree::_bind_methods() {
 	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_delayed_text_editor","enable"),&Tree::set_delayed_text_editor);
+	ObjectTypeDB::bind_method(_MD("is_delayed_text_editor_enabled"),&Tree::is_delayed_text_editor_enabled);
+
 
 	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);
@@ -3566,6 +3594,7 @@ void Tree::_bind_methods() {
 	ADD_SIGNAL( MethodInfo("item_rmb_selected",PropertyInfo(Variant::VECTOR2,"pos")));
 	ADD_SIGNAL( MethodInfo("empty_tree_rmb_selected",PropertyInfo(Variant::VECTOR2,"pos")));
 	ADD_SIGNAL( MethodInfo("item_edited"));
+	ADD_SIGNAL( MethodInfo("item_double_clicked"));
 	ADD_SIGNAL( MethodInfo("item_collapsed",PropertyInfo(Variant::OBJECT,"item")));
 	//ADD_SIGNAL( MethodInfo("item_doubleclicked" ) );
 	ADD_SIGNAL( MethodInfo("button_pressed",PropertyInfo(Variant::OBJECT,"item"),PropertyInfo(Variant::INT,"column"),PropertyInfo(Variant::INT,"id")));
@@ -3669,6 +3698,9 @@ Tree::Tree() {
 	force_select_on_already_selected=false;
 
 	allow_rmb_select=false;
+
+	first_selection_time = 0;
+	delayed_text_editor = false;
 }
 
 

+ 6 - 0
scene/gui/tree.h

@@ -433,6 +433,9 @@ friend class TreeItem;
 	float last_drag_time;
 	float time_since_motion;*/
 
+	bool delayed_text_editor;
+	uint64_t first_selection_time;
+
 	float drag_speed;
 	float drag_from;
 	float drag_accum;
@@ -527,6 +530,9 @@ public:
 
 	void set_value_evaluator(ValueEvaluator *p_evaluator);
 
+	void set_delayed_text_editor(bool enabled);
+	bool is_delayed_text_editor_enabled() const;
+
 	Tree();
 	~Tree();
 

+ 63 - 51
tools/editor/plugins/canvas_item_editor_plugin.cpp

@@ -2979,57 +2979,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
 		case VIEW_CENTER_TO_SELECTION:
 		case VIEW_FRAME_TO_SELECTION: {
 
-			Vector2 center(0.f, 0.f);
-			Rect2 rect;
-			int count = 0;
-
-			Map<Node*,Object*> &selection = editor_selection->get_selection();
-			for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) {
-				CanvasItem *canvas_item = E->key()->cast_to<CanvasItem>();
-				if (!canvas_item) continue;
-				if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root())
-					continue;
-
-
-				// counting invisible items, for now
-				//if (!canvas_item->is_visible()) continue;
-				++count;
-
-				Rect2 item_rect = canvas_item->get_item_rect();
-
-				Vector2 pos = canvas_item->get_global_transform().get_origin();
-				Vector2 scale = canvas_item->get_global_transform().get_scale();
-				real_t angle = canvas_item->get_global_transform().get_rotation();
-
-				Matrix32 t(angle, Vector2(0.f,0.f));
-				item_rect = t.xform(item_rect);
-				Rect2 canvas_item_rect(pos + scale*item_rect.pos, scale*item_rect.size);
-				if (count == 1) {
-					rect = canvas_item_rect;
-				} else {
-					rect = rect.merge(canvas_item_rect);
-				}
-			};
-			if (count==0) break;
-
-			if (p_op == VIEW_CENTER_TO_SELECTION) {
-
-				center = rect.pos + rect.size/2;
-				Vector2 offset = viewport->get_size()/2 - editor->get_scene_root()->get_global_canvas_transform().xform(center);
-				h_scroll->set_val(h_scroll->get_val() - offset.x/zoom);
-				v_scroll->set_val(v_scroll->get_val() - offset.y/zoom);
-
-			} else { // VIEW_FRAME_TO_SELECTION
-
-				if (rect.size.x > CMP_EPSILON && rect.size.y > CMP_EPSILON) {
-					float scale_x = viewport->get_size().x/rect.size.x;
-					float scale_y = viewport->get_size().y/rect.size.y;
-					zoom = scale_x < scale_y? scale_x:scale_y;
-					zoom *= 0.90;
-					_update_scroll(0);
-					call_deferred("_popup_callback", VIEW_CENTER_TO_SELECTION);
-				}
-			}
+			_focus_selection(p_op);
 
 		} break;
 		case SKELETON_MAKE_BONES: {
@@ -3142,6 +3092,62 @@ template< class P, class C > void CanvasItemEditor::space_selected_items() {
 }
 #endif
 
+
+void CanvasItemEditor::_focus_selection(int p_op) {
+	Vector2 center(0.f, 0.f);
+	Rect2 rect;
+	int count = 0;
+
+	Map<Node*,Object*> &selection = editor_selection->get_selection();
+	for(Map<Node*,Object*>::Element *E=selection.front();E;E=E->next()) {
+		CanvasItem *canvas_item = E->key()->cast_to<CanvasItem>();
+		if (!canvas_item) continue;
+		if (canvas_item->get_viewport()!=EditorNode::get_singleton()->get_scene_root())
+			continue;
+
+
+		// counting invisible items, for now
+		//if (!canvas_item->is_visible()) continue;
+		++count;
+
+		Rect2 item_rect = canvas_item->get_item_rect();
+
+		Vector2 pos = canvas_item->get_global_transform().get_origin();
+		Vector2 scale = canvas_item->get_global_transform().get_scale();
+		real_t angle = canvas_item->get_global_transform().get_rotation();
+
+		Matrix32 t(angle, Vector2(0.f,0.f));
+		item_rect = t.xform(item_rect);
+		Rect2 canvas_item_rect(pos + scale*item_rect.pos, scale*item_rect.size);
+		if (count == 1) {
+			rect = canvas_item_rect;
+		} else {
+			rect = rect.merge(canvas_item_rect);
+		}
+	};
+	if (count==0) return;
+
+	if (p_op == VIEW_CENTER_TO_SELECTION) {
+
+		center = rect.pos + rect.size/2;
+		Vector2 offset = viewport->get_size()/2 - editor->get_scene_root()->get_global_canvas_transform().xform(center);
+		h_scroll->set_val(h_scroll->get_val() - offset.x/zoom);
+		v_scroll->set_val(v_scroll->get_val() - offset.y/zoom);
+
+	} else { // VIEW_FRAME_TO_SELECTION
+
+		if (rect.size.x > CMP_EPSILON && rect.size.y > CMP_EPSILON) {
+			float scale_x = viewport->get_size().x/rect.size.x;
+			float scale_y = viewport->get_size().y/rect.size.y;
+			zoom = scale_x < scale_y? scale_x:scale_y;
+			zoom *= 0.90;
+			_update_scroll(0);
+			call_deferred("_popup_callback", VIEW_CENTER_TO_SELECTION);
+		}
+	}
+}
+
+
 void CanvasItemEditor::_bind_methods() {
 
 	ObjectTypeDB::bind_method("_node_removed",&CanvasItemEditor::_node_removed);
@@ -3247,6 +3253,12 @@ VSplitContainer *CanvasItemEditor::get_bottom_split() {
 	return bottom_split;
 }
 
+
+void CanvasItemEditor::focus_selection() {
+	_focus_selection(VIEW_CENTER_TO_SELECTION);
+}
+
+
 CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
 
 	tool = TOOL_SELECT;

+ 5 - 1
tools/editor/plugins/canvas_item_editor_plugin.h

@@ -352,6 +352,8 @@ class CanvasItemEditor : public VBoxContainer {
 	void _viewport_input_event(const InputEvent& p_event);
 	void _viewport_draw();
 
+	void _focus_selection(int p_op);
+
 	void _set_anchor(Control::AnchorType p_left,Control::AnchorType p_top,Control::AnchorType p_right,Control::AnchorType p_bottom);
 
 	HSplitContainer *palette_split;
@@ -414,10 +416,12 @@ public:
 
 	Control *get_viewport_control() { return viewport; }
 
-
 	bool get_remove_list(List<Node*> *p_list);
 	void set_undo_redo(UndoRedo *p_undo_redo) {undo_redo=p_undo_redo; }
 	void edit(CanvasItem *p_canvas_item);
+
+	void focus_selection();
+
 	CanvasItemEditor(EditorNode *p_editor);
 };
 

+ 33 - 26
tools/editor/plugins/spatial_editor_plugin.cpp

@@ -1980,33 +1980,8 @@ void SpatialEditorViewport::_menu_option(int p_option) {
 		} break;
 		case VIEW_CENTER_TO_SELECTION: {
 
-			if (!get_selected_count())
-				break;
-
-			Vector3 center;
-			int count=0;
-
-			List<Node*> &selection = editor_selection->get_selected_node_list();
-
-			for(List<Node*>::Element *E=selection.front();E;E=E->next()) {
-
-				Spatial *sp = E->get()->cast_to<Spatial>();
-				if (!sp)
-					continue;
+			focus_selection();
 
-				SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp);
-				if (!se)
-					continue;
-
-				center+=sp->get_global_transform().origin;
-				count++;
-			}
-
-			if( count != 0 ) {
-				center/=float(count);
-			}
-
-			cursor.pos=center;
 		} break;
 		case VIEW_ALIGN_SELECTION_WITH_VIEW: {
 
@@ -2323,6 +2298,38 @@ void SpatialEditorViewport::reset() {
 	_update_name();
 }
 
+
+void SpatialEditorViewport::focus_selection() {
+	if (!get_selected_count())
+		return;
+
+	Vector3 center;
+	int count=0;
+
+	List<Node*> &selection = editor_selection->get_selected_node_list();
+
+	for(List<Node*>::Element *E=selection.front();E;E=E->next()) {
+
+		Spatial *sp = E->get()->cast_to<Spatial>();
+		if (!sp)
+			continue;
+
+		SpatialEditorSelectedItem *se=editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp);
+		if (!se)
+			continue;
+
+		center+=sp->get_global_transform().origin;
+		count++;
+	}
+
+	if( count != 0 ) {
+		center/=float(count);
+	}
+
+	cursor.pos=center;
+}
+
+
 SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, EditorNode *p_editor, int p_index) {
 
 	_edit.mode=TRANSFORM_NONE;

+ 3 - 0
tools/editor/plugins/spatial_editor_plugin.h

@@ -253,6 +253,9 @@ public:
 	void set_state(const Dictionary& p_state);
 	Dictionary get_state() const;
 	void reset();
+
+	void focus_selection();
+
 	Viewport *get_viewport_node() { return viewport; }
 
 

+ 20 - 0
tools/editor/scene_tree_dock.cpp

@@ -33,6 +33,7 @@
 #include "scene/resources/packed_scene.h"
 #include "editor_settings.h"
 #include "tools/editor/plugins/canvas_item_editor_plugin.h"
+#include "tools/editor/plugins/spatial_editor_plugin.h"
 #include "script_editor_debugger.h"
 #include "tools/editor/plugins/script_editor_plugin.h"
 #include "core/io/resource_saver.h"
@@ -1825,6 +1826,21 @@ void SceneTreeDock::set_filter(const String& p_filter){
 	scene_tree->set_filter(p_filter);
 }
 
+
+void SceneTreeDock::_focus_node() {
+
+	Node *node = scene_tree->get_selected();
+	ERR_FAIL_COND(!node);
+
+	if (node->is_type("CanvasItem")) {
+		CanvasItemEditorPlugin *editor = editor_data->get_editor("2D")->cast_to<CanvasItemEditorPlugin>();
+		editor->get_canvas_item_editor()->focus_selection();
+	} else {
+		SpatialEditorPlugin *editor = editor_data->get_editor("3D")->cast_to<SpatialEditorPlugin>();
+		editor->get_spatial_editor()->get_editor_viewport(0)->focus_selection();
+	}
+}
+
 void SceneTreeDock::_bind_methods() {
 
 	ObjectTypeDB::bind_method(_MD("_tool_selected"),&SceneTreeDock::_tool_selected,DEFVAL(false));
@@ -1849,6 +1865,7 @@ void SceneTreeDock::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("_files_dropped"),&SceneTreeDock::_files_dropped);
 	ObjectTypeDB::bind_method(_MD("_tree_rmb"),&SceneTreeDock::_tree_rmb);
 	ObjectTypeDB::bind_method(_MD("_filter_changed"),&SceneTreeDock::_filter_changed);
+	ObjectTypeDB::bind_method(_MD("_focus_node"),&SceneTreeDock::_focus_node);
 
 
 	ObjectTypeDB::bind_method(_MD("instance"),&SceneTreeDock::instance);
@@ -1930,6 +1947,9 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelec
 	scene_tree->connect("files_dropped",this,"_files_dropped");
 	scene_tree->connect("nodes_dragged",this,"_nodes_drag_begin");
 
+	scene_tree->get_scene_tree()->connect("item_double_clicked", this, "_focus_node");
+	scene_tree->get_scene_tree()->set_delayed_text_editor(true);
+
 	scene_tree->set_undo_redo(&editor_data->get_undo_redo());
 	scene_tree->set_editor_selection(editor_selection);
 

+ 2 - 0
tools/editor/scene_tree_dock.h

@@ -163,6 +163,8 @@ public:
 	String get_filter();
 	void set_filter(const String& p_filter);
 
+	void _focus_node();
+
 	void import_subscene();
 	void set_edited_scene(Node* p_scene);
 	void instance(const String& p_path);