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:
parent
3cc08ab1f1
commit
70c9979cce
8 changed files with 167 additions and 81 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue