From 05e5faa876d5c474e8fa879512c7125d655959d0 Mon Sep 17 00:00:00 2001 From: Tomasz Chabora Date: Fri, 30 Aug 2019 22:49:47 +0200 Subject: [PATCH] Add 2D ruler tool --- editor/plugins/canvas_item_editor_plugin.cpp | 134 ++++++++++++++++++- editor/plugins/canvas_item_editor_plugin.h | 8 ++ 2 files changed, 139 insertions(+), 3 deletions(-) diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 2daee70474f..4dda512ceb7 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -2246,6 +2246,40 @@ bool CanvasItemEditor::_gui_input_select(const Ref &p_event) { return false; } +bool CanvasItemEditor::_gui_input_ruler_tool(const Ref &p_event) { + + if (tool != TOOL_RULER) + return false; + + Ref b = p_event; + Ref m = p_event; + + Point2 previous_origin = ruler_tool_origin; + if (!ruler_tool_active) + ruler_tool_origin = snap_point(viewport->get_local_mouse_position() / zoom + view_offset) * zoom; + + if (b.is_valid() && b->get_button_index() == BUTTON_LEFT) { + if (b->is_pressed()) { + ruler_tool_active = true; + } else { + ruler_tool_active = false; + } + + viewport->update(); + return true; + } + + bool is_snap_active = snap_active ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL); + + if (m.is_valid() && (ruler_tool_active || (is_snap_active && previous_origin != ruler_tool_origin))) { + + viewport->update(); + return true; + } + + return false; +} + bool CanvasItemEditor::_gui_input_hover(const Ref &p_event) { Ref m = p_event; @@ -2323,6 +2357,8 @@ void CanvasItemEditor::_gui_input_viewport(const Ref &p_event) { //printf("Anchors\n"); } else if ((accepted = _gui_input_select(p_event))) { //printf("Selection\n"); + } else if ((accepted = _gui_input_ruler_tool(p_event))) { + //printf("Measure\n"); } else { //printf("Not accepted\n"); } @@ -2350,6 +2386,9 @@ void CanvasItemEditor::_gui_input_viewport(const Ref &p_event) { case TOOL_PAN: c = CURSOR_DRAG; break; + case TOOL_RULER: + c = CURSOR_CROSS; + break; default: break; } @@ -2626,6 +2665,83 @@ void CanvasItemEditor::_draw_grid() { } } +void CanvasItemEditor::_draw_ruler_tool() { + + if (tool != TOOL_RULER) + return; + + bool is_snap_active = snap_active ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL); + + if (ruler_tool_active) { + Color ruler_primary_color = get_color("accent_color", "Editor"); + Color ruler_secondary_color = ruler_primary_color; + ruler_secondary_color.a = 0.5; + + Point2 begin = ruler_tool_origin - view_offset * zoom; + Point2 end = snap_point(viewport->get_local_mouse_position() / zoom + view_offset) * zoom - view_offset * zoom; + Point2 corner = Point2(begin.x, end.y); + Vector2 length_vector = (begin - end).abs() / zoom; + + bool draw_secondary_lines = (begin.y != corner.y && end.x != corner.x); + + viewport->draw_line(begin, end, ruler_primary_color, Math::round(EDSCALE * 3), true); + if (draw_secondary_lines) { + viewport->draw_line(begin, corner, ruler_secondary_color, Math::round(EDSCALE)); + viewport->draw_line(corner, end, ruler_secondary_color, Math::round(EDSCALE)); + } + + Ref font = get_font("bold", "EditorFonts"); + Color font_color = get_color("font_color", "Editor"); + Color font_secondary_color = font_color; + font_secondary_color.a = 0.5; + float text_height = font->get_height(); + const float text_width = 76; + + Point2 text_pos = (begin + end) / 2 - Vector2(text_width / 2, text_height / 2); + text_pos.x = CLAMP(text_pos.x, text_width / 2, viewport->get_rect().size.x - text_width * 1.5); + text_pos.y = CLAMP(text_pos.y, text_height * 1.5, viewport->get_rect().size.y - text_height * 1.5); + viewport->draw_string(font, text_pos, vformat("%.2f px", length_vector.length()), font_color); + + if (draw_secondary_lines) { + + Point2 text_pos2 = text_pos; + text_pos2.x = begin.x < text_pos.x ? MIN(text_pos.x - text_width, begin.x - text_width / 2) : MAX(text_pos.x + text_width, begin.x - text_width / 2); + viewport->draw_string(font, text_pos2, vformat("%.2f px", length_vector.y), font_secondary_color); + + text_pos2 = text_pos; + text_pos2.y = end.y < text_pos.y ? MIN(text_pos.y - text_height * 2, end.y - text_height / 2) : MAX(text_pos.y + text_height * 2, end.y - text_height / 2); + viewport->draw_string(font, text_pos2, vformat("%.2f px", length_vector.x), font_secondary_color); + } + + if (is_snap_active) { + + text_pos = (begin + end) / 2 + Vector2(-text_width / 2, text_height / 2); + text_pos.x = CLAMP(text_pos.x, text_width / 2, viewport->get_rect().size.x - text_width * 1.5); + text_pos.y = CLAMP(text_pos.y, text_height * 2.5, viewport->get_rect().size.y - text_height / 2); + + if (draw_secondary_lines) { + viewport->draw_string(font, text_pos, vformat("%.2f units", (length_vector / grid_step).length()), font_color); + + Point2 text_pos2 = text_pos; + text_pos2.x = begin.x < text_pos.x ? MIN(text_pos.x - text_width, begin.x - text_width / 2) : MAX(text_pos.x + text_width, begin.x - text_width / 2); + viewport->draw_string(font, text_pos2, vformat("%d units", (int)(length_vector.y / grid_step.y)), font_secondary_color); + + text_pos2 = text_pos; + text_pos2.y = end.y < text_pos.y ? MIN(text_pos.y - text_height * 2, end.y + text_height / 2) : MAX(text_pos.y + text_height * 2, end.y + text_height / 2); + viewport->draw_string(font, text_pos2, vformat("%d units", (int)(length_vector.x / grid_step.x)), font_secondary_color); + } else { + viewport->draw_string(font, text_pos, vformat("%d units", roundf((length_vector / grid_step).length())), font_color); + } + } + } else { + + if (is_snap_active) { + Ref position_icon = get_icon("EditorPosition", "EditorIcons"); + viewport->draw_texture(get_icon("EditorPosition", "EditorIcons"), ruler_tool_origin - view_offset * zoom - position_icon->get_size() / 2); + } + } +} + void CanvasItemEditor::_draw_control_anchors(Control *control) { Transform2D xform = transform * control->get_global_transform_with_canvas(); RID ci = viewport->get_canvas_item(); @@ -3358,6 +3474,7 @@ void CanvasItemEditor::_draw_viewport() { info_overlay->set_margin(MARGIN_LEFT, (show_rulers ? RULER_WIDTH : 0) + 10); _draw_grid(); + _draw_ruler_tool(); _draw_selection(); _draw_axis(); if (editor->get_edited_scene()) { @@ -3546,6 +3663,7 @@ void CanvasItemEditor::_notification(int p_what) { snap_config_menu->set_icon(get_icon("GuiMiniTabMenu", "EditorIcons")); skeleton_menu->set_icon(get_icon("Bone", "EditorIcons")); pan_button->set_icon(get_icon("ToolPan", "EditorIcons")); + ruler_button->set_icon(get_icon("LineEdit", "EditorIcons")); //Needs a new icon. pivot_button->set_icon(get_icon("EditPivot", "EditorIcons")); select_handle = get_icon("EditorHandle", "EditorIcons"); anchor_handle = get_icon("EditorControlAnchor", "EditorIcons"); @@ -3940,13 +4058,13 @@ void CanvasItemEditor::_button_toggle_snap(bool p_status) { void CanvasItemEditor::_button_tool_select(int p_index) { - ToolButton *tb[TOOL_MAX] = { select_button, list_select_button, move_button, scale_button, rotate_button, pivot_button, pan_button }; + ToolButton *tb[TOOL_MAX] = { select_button, list_select_button, move_button, scale_button, rotate_button, pivot_button, pan_button, ruler_button }; for (int i = 0; i < TOOL_MAX; i++) { tb[i]->set_pressed(i == p_index); } - viewport->update(); tool = (Tool)p_index; + viewport->update(); } void CanvasItemEditor::_insert_animation_keys(bool p_location, bool p_rotation, bool p_scale, bool p_on_existing) { @@ -4926,6 +5044,9 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { panning = false; pan_pressed = false; + ruler_tool_active = false; + ruler_tool_origin = Point2(); + bone_last_frame = 0; bone_list_dirty = false; @@ -5079,6 +5200,13 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { pan_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_PAN)); pan_button->set_tooltip(TTR("Pan Mode")); + ruler_button = memnew(ToolButton); + hb->add_child(ruler_button); + ruler_button->set_toggle_mode(true); + ruler_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_RULER)); + ruler_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/ruler_mode", TTR("Ruler Mode"), KEY_R)); + ruler_button->set_tooltip(TTR("Ruler Mode")); + hb->add_child(memnew(VSeparator)); snap_button = memnew(ToolButton); @@ -5171,7 +5299,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { p->set_hide_on_checkable_item_selection(false); p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_grid", TTR("Show Grid"), KEY_G), SHOW_GRID); p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_helpers", TTR("Show Helpers"), KEY_H), SHOW_HELPERS); - p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_rulers", TTR("Show Rulers"), KEY_R), SHOW_RULERS); + p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_rulers", TTR("Show Rulers"), KEY_MASK_CMD | KEY_R), SHOW_RULERS); p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_guides", TTR("Show Guides"), KEY_Y), SHOW_GUIDES); p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_origin", TTR("Show Origin")), SHOW_ORIGIN); p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_viewport", TTR("Show Viewport")), SHOW_VIEWPORT); diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index ac7d6122928..4e030c63dad 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -80,6 +80,7 @@ public: TOOL_ROTATE, TOOL_EDIT_PIVOT, TOOL_PAN, + TOOL_RULER, TOOL_MAX }; @@ -276,6 +277,9 @@ private: bool panning; bool pan_pressed; + bool ruler_tool_active; + Point2 ruler_tool_origin; + MenuOption last_option; struct _SelectResult { @@ -341,6 +345,8 @@ private: ToolButton *pivot_button; ToolButton *pan_button; + ToolButton *ruler_button; + ToolButton *snap_button; MenuButton *snap_config_menu; PopupMenu *smartsnap_config_popup; @@ -457,6 +463,7 @@ private: void _draw_guides(); void _draw_focus(); void _draw_grid(); + void _draw_ruler_tool(); void _draw_control_anchors(Control *control); void _draw_control_helpers(Control *control); void _draw_selection(); @@ -476,6 +483,7 @@ private: bool _gui_input_resize(const Ref &p_event); bool _gui_input_rotate(const Ref &p_event); bool _gui_input_select(const Ref &p_event); + bool _gui_input_ruler_tool(const Ref &p_event); bool _gui_input_zoom_or_pan(const Ref &p_event, bool p_already_accepted); bool _gui_input_rulers_and_guides(const Ref &p_event); bool _gui_input_hover(const Ref &p_event);