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
This commit is contained in:
Daniel J. Ramirez 2016-07-28 14:37:52 -05:00
parent 3cc08ab1f1
commit 70c9979cce
8 changed files with 167 additions and 81 deletions

View file

@ -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;
}

View file

@ -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();

View file

@ -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;

View file

@ -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);
};

View file

@ -1980,33 +1980,8 @@ void SpatialEditorViewport::_menu_option(int p_option) {
} break;
case VIEW_CENTER_TO_SELECTION: {
if (!get_selected_count())
break;
focus_selection();
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;
} 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;

View file

@ -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; }

View file

@ -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);

View file

@ -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);