From a724f34ef30bdf362b9059634e4ef21e21101ddd Mon Sep 17 00:00:00 2001 From: Gilles Roudiere Date: Mon, 12 Mar 2018 23:32:25 +0100 Subject: [PATCH] Displays node icon on hover --- editor/icons/icon_editor_position.svg | 69 +++++++++++++++ .../icons/icon_editor_position_unselected.svg | 66 ++++++++++++++ editor/plugins/canvas_item_editor_plugin.cpp | 87 +++++++++++++++++-- editor/plugins/canvas_item_editor_plugin.h | 3 + 4 files changed, 217 insertions(+), 8 deletions(-) create mode 100644 editor/icons/icon_editor_position.svg create mode 100644 editor/icons/icon_editor_position_unselected.svg diff --git a/editor/icons/icon_editor_position.svg b/editor/icons/icon_editor_position.svg new file mode 100644 index 00000000000..7cbce07fab9 --- /dev/null +++ b/editor/icons/icon_editor_position.svg @@ -0,0 +1,69 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/editor/icons/icon_editor_position_unselected.svg b/editor/icons/icon_editor_position_unselected.svg new file mode 100644 index 00000000000..8f32c89f161 --- /dev/null +++ b/editor/icons/icon_editor_position_unselected.svg @@ -0,0 +1,66 @@ + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 480eb62427b..e49ce061001 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -466,13 +466,14 @@ void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_no const real_t grab_distance = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8); CanvasItem *canvas_item = Object::cast_to(p_node); - if (p_node->get_owner() != editor->get_edited_scene() || !p_node->has_meta("_edit_lock_")) { + Node *scene = editor->get_edited_scene(); + if (!(p_node != scene && p_node->get_owner() != scene && (!scene->is_editable_instance(p_node) || p_node->has_meta("_edit_lock_")))) { for (int i = p_node->get_child_count() - 1; i >= 0; i--) { if (canvas_item && !canvas_item->is_set_as_toplevel()) { - _find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, 0, p_parent_xform * canvas_item->get_transform(), p_canvas_xform); + _find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, limit, p_parent_xform * canvas_item->get_transform(), p_canvas_xform); } else { CanvasLayer *cl = Object::cast_to(p_node); - _find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, 0, Transform2D(), cl ? cl->get_transform() : p_canvas_xform); + _find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, limit, Transform2D(), cl ? cl->get_transform() : p_canvas_xform); } if (limit != 0 && r_items.size() >= limit) return; @@ -1850,6 +1851,42 @@ bool CanvasItemEditor::_gui_input_select(const Ref &p_event) { return false; } +bool CanvasItemEditor::_gui_input_hover(const Ref &p_event) { + + Ref m = p_event; + if (m.is_valid()) { + if (drag_type == DRAG_NONE && tool == TOOL_SELECT) { + Point2 click = transform.affine_inverse().xform(m->get_position()); + Node *scene = editor->get_edited_scene(); + + //Checks if the hovered items changed, update the viewport if so + Vector<_SelectResult> hovering_results_tmp; + _find_canvas_items_at_pos(click, scene, hovering_results_tmp); + hovering_results_tmp.sort(); + bool changed = false; + if (hovering_results.size() == hovering_results_tmp.size()) { + for (int i = 0; i < hovering_results.size(); i++) { + if (hovering_results[i].item != hovering_results_tmp[i].item) { + changed = true; + break; + } + } + } else { + changed = true; + } + + if (changed) { + hovering_results = hovering_results_tmp; + viewport->update(); + } + + return true; + } + } + + return false; +} + void CanvasItemEditor::_gui_input_viewport(const Ref &p_event) { bool accepted = false; if ((accepted = _gui_input_rulers_and_guides(p_event))) { @@ -1877,6 +1914,9 @@ void CanvasItemEditor::_gui_input_viewport(const Ref &p_event) { if (accepted) accept_event(); + // Handles the mouse hovering + _gui_input_hover(p_event); + // Change the cursor CursorShape c = CURSOR_ARROW; switch (drag_type) { @@ -2578,7 +2618,7 @@ void CanvasItemEditor::_draw_invisible_nodes_positions(Node *p_node, const Trans ERR_FAIL_COND(!p_node); Node *scene = editor->get_edited_scene(); - if (p_node != scene && p_node->get_owner() != scene && !scene->is_editable_instance(p_node->get_owner())) + if (p_node != scene && p_node->get_owner() != scene && !scene->is_editable_instance(p_node)) return; CanvasItem *canvas_item = Object::cast_to(p_node); if (canvas_item && !canvas_item->is_visible()) @@ -2602,21 +2642,51 @@ void CanvasItemEditor::_draw_invisible_nodes_positions(Node *p_node, const Trans if (canvas_item && !canvas_item->_edit_use_rect() && !editor_selection->is_selected(canvas_item)) { Transform2D xform = transform * canvas_xform * parent_xform; - Ref position_icon = get_icon("EditorPivot", "EditorIcons"); + // Draw the node's position + Ref position_icon = get_icon("EditorPositionUnselected", "EditorIcons"); Transform2D transform = Transform2D(xform.get_rotation(), xform.get_origin()); viewport->draw_set_transform_matrix(transform); viewport->draw_texture(position_icon, -position_icon->get_size() / 2, Color(1.0, 1.0, 1.0, 0.5)); viewport->draw_set_transform_matrix(Transform2D()); + } +} +void CanvasItemEditor::_draw_hover() { + List previous_rects; + + for (int i = 0; i < hovering_results.size(); i++) { + // Draw the node's name and icon + CanvasItem *canvas_item = hovering_results[i].item; + + if (canvas_item->_edit_use_rect()) + continue; + + Transform2D xform = transform * canvas_item->get_global_transform_with_canvas(); + + // Get the resources Ref node_icon; if (has_icon(canvas_item->get_class(), "EditorIcons")) node_icon = get_icon(canvas_item->get_class(), "EditorIcons"); else node_icon = get_icon("Object", "EditorIcons"); - viewport->draw_texture(node_icon, xform.get_origin() + position_icon->get_size() / 3, Color(1.0, 1.0, 1.0, 0.5)); - Ref font = get_font("font", "Label"); - viewport->draw_string(font, xform.get_origin() + position_icon->get_size() / 3 + node_icon->get_size() + Point2(4, -3), canvas_item->get_name(), Color(1.0, 1.0, 1.0, 0.5)); + String node_name = canvas_item->get_name(); + Size2 node_name_size = font->get_string_size(node_name); + Size2 item_size = Size2(node_icon->get_size().x + 4 + node_name_size.x, MAX(node_icon->get_size().y, node_name_size.y - 3)); + + Point2 pos = xform.get_origin() - Point2(0, item_size.y) + (Point2(node_icon->get_size().x, -node_icon->get_size().y) / 4); + // Rectify the position to avoid overlaping items + for (List::Element *E = previous_rects.front(); E; E = E->next()) { + if (E->get().intersects(Rect2(pos, item_size))) { + pos.y = E->get().get_position().y - item_size.y; + } + } + + previous_rects.push_back(Rect2(pos, item_size)); + + // Draw the node icon and name + viewport->draw_texture(node_icon, pos, Color(1.0, 1.0, 1.0, 0.5)); + viewport->draw_string(font, pos + Point2(node_icon->get_size().x + 4, item_size.y - 3), node_name, Color(1.0, 1.0, 1.0, 0.5)); } } @@ -2747,6 +2817,7 @@ void CanvasItemEditor::_draw_viewport() { if (show_guides) _draw_guides(); _draw_focus(); + _draw_hover(); } void CanvasItemEditor::_notification(int p_what) { diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index 27261ae1c36..5ca8a376108 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -258,6 +258,7 @@ class CanvasItemEditor : public VBoxContainer { }; Vector<_SelectResult> selection_results; + Vector<_SelectResult> hovering_results; struct BoneList { @@ -389,6 +390,7 @@ class CanvasItemEditor : public VBoxContainer { void _draw_bones(); void _draw_invisible_nodes_positions(Node *p_node, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D()); void _draw_locks_and_groups(Node *p_node, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D()); + void _draw_hover(); void _draw_viewport(); @@ -401,6 +403,7 @@ class CanvasItemEditor : public VBoxContainer { bool _gui_input_select(const Ref &p_event); bool _gui_input_zoom_or_pan(const Ref &p_event); bool _gui_input_rulers_and_guides(const Ref &p_event); + bool _gui_input_hover(const Ref &p_event); void _gui_input_viewport(const Ref &p_event);