diff options
-rw-r--r-- | editor/icons/icon_snap.svg | 101 | ||||
-rw-r--r-- | editor/icons/icon_snap_grid.svg | 92 | ||||
-rw-r--r-- | editor/plugins/canvas_item_editor_plugin.cpp | 253 | ||||
-rw-r--r-- | editor/plugins/canvas_item_editor_plugin.h | 25 | ||||
-rw-r--r-- | editor/plugins/polygon_2d_editor_plugin.cpp | 2 | ||||
-rw-r--r-- | scene/gui/graph_edit.cpp | 2 | ||||
-rw-r--r-- | scene/resources/default_theme/default_theme.cpp | 2 | ||||
-rw-r--r-- | scene/resources/default_theme/icon_snap_grid.png (renamed from scene/resources/default_theme/icon_snap.png) | bin | 269 -> 325 bytes | |||
-rw-r--r-- | scene/resources/default_theme/theme_data.h | 4 |
9 files changed, 383 insertions, 98 deletions
diff --git a/editor/icons/icon_snap.svg b/editor/icons/icon_snap.svg index b1f36cfe43..0195f7cfc6 100644 --- a/editor/icons/icon_snap.svg +++ b/editor/icons/icon_snap.svg @@ -1,10 +1,93 @@ -<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path d="m3 1036.4v3h-3v2h3v4h-3v2h3v3h2v-3-2-4h4 2 3v-2h-3v-3h-2v3h-4v-3h-2z" fill="#f3f3f3"/> -<path d="m11 1043.4a4 4 0 0 0 -4 4h2a2 2 0 0 1 2 -2 2 2 0 0 1 2 2h2a4 4 0 0 0 -4 -4z" fill="#ff8484"/> -<rect x="7" y="1047.4" width="2" height="2" fill="#ff8484"/> -<rect x="13" y="1047.4" width="2" height="2" fill="#ff8484"/> -<rect x="7" y="1049.4" width="2" height="2" fill="#fff"/> -<rect x="13" y="1049.4" width="2" height="2" fill="#fff"/> -</g> +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="16" + height="16" + version="1.1" + viewBox="0 0 16 16" + id="svg848" + sodipodi:docname="icon_snap.svg" + inkscape:version="0.92.2 5c3e80d, 2017-08-06"> + <metadata + id="metadata854"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs852" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="2558" + inkscape:window-height="1422" + id="namedview850" + showgrid="true" + inkscape:pagecheckerboard="true" + inkscape:zoom="26.317631" + inkscape:cx="-14.078109" + inkscape:cy="-1.3201296" + inkscape:window-x="1366" + inkscape:window-y="16" + inkscape:window-maximized="1" + inkscape:current-layer="svg848"> + <inkscape:grid + type="xygrid" + id="grid862" /> + </sodipodi:namedview> + <path + style="fill:#ff8484;stroke-width:1.48039925" + inkscape:connector-curvature="0" + id="path836" + d="m 3.9501321,14.20668 a 5.9215969,5.9215969 0 0 0 8.0890509,-2.167455 l -2.5641252,-1.4804 A 2.9607985,2.9607985 0 0 1 5.4305313,11.642553 2.9607985,2.9607985 0 0 1 4.3468039,7.5980268 L 1.7826772,6.1176278 A 5.9215969,5.9215969 0 0 0 3.9501321,14.20668 Z" /> + <rect + style="fill:#ff8484;stroke-width:1.48039925" + id="rect838" + height="2.9607985" + width="2.9607985" + y="-4.4066463" + x="-16.44585" + transform="rotate(-150)" /> + <rect + style="fill:#ff8484;stroke-width:1.48039925" + id="rect840" + height="2.9607985" + width="2.9607985" + y="-4.4066463" + x="-7.5634551" + transform="rotate(-150)" /> + <rect + style="fill:#ffffff;stroke-width:1.48039925" + id="rect842" + height="2.9607985" + width="2.9607985" + y="-1.4458472" + x="-16.44585" + transform="rotate(-150)" /> + <rect + style="fill:#ffffff;stroke-width:1.48039925" + id="rect844" + height="2.9607985" + width="2.9607985" + y="-1.4458472" + x="-7.5634551" + transform="rotate(-150)" /> </svg> diff --git a/editor/icons/icon_snap_grid.svg b/editor/icons/icon_snap_grid.svg new file mode 100644 index 0000000000..b479496327 --- /dev/null +++ b/editor/icons/icon_snap_grid.svg @@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="16" + height="16" + version="1.1" + viewBox="0 0 16 16" + id="svg913" + sodipodi:docname="icon_snap_grid.svg" + inkscape:version="0.92.2 5c3e80d, 2017-08-06"> + <metadata + id="metadata919"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs917" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="2558" + inkscape:window-height="1422" + id="namedview915" + showgrid="false" + inkscape:pagecheckerboard="true" + inkscape:zoom="52.635261" + inkscape:cx="6.4374987" + inkscape:cy="5.7074131" + inkscape:window-x="1366" + inkscape:window-y="16" + inkscape:window-maximized="1" + inkscape:current-layer="svg913" /> + <g + transform="translate(0 -1036.4)" + id="g911"> + <path + d="m3 1036.4v3h-3v2h3v4h-3v2h3v3h2v-3-2-4h4 2 3v-2h-3v-3h-2v3h-4v-3h-2z" + fill="#f3f3f3" + id="path899" /> + <path + d="m11 1043.4a4 4 0 0 0 -4 4h2a2 2 0 0 1 2 -2 2 2 0 0 1 2 2h2a4 4 0 0 0 -4 -4z" + fill="#ff8484" + id="path901" /> + <rect + x="7" + y="1047.4" + width="2" + height="2" + fill="#ff8484" + id="rect903" /> + <rect + x="13" + y="1047.4" + width="2" + height="2" + fill="#ff8484" + id="rect905" /> + <rect + x="7" + y="1049.4" + width="2" + height="2" + fill="#fff" + id="rect907" /> + <rect + x="13" + y="1049.4" + width="2" + height="2" + fill="#fff" + id="rect909" /> + </g> +</svg> diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index e125b5c70e..bf1769e672 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -264,7 +264,7 @@ void CanvasItemEditor::_snap_other_nodes(Point2 p_value, Point2 &r_current_snap, } } -Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const CanvasItem *p_canvas_item) { +Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const CanvasItem *p_canvas_item, unsigned int p_forced_modes) { Point2 dist[2]; bool snapped[2] = { false, false }; @@ -277,7 +277,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const Point2 end; rotation = p_canvas_item->get_global_transform_with_canvas().get_rotation(); - if (p_modes & SNAP_NODE_PARENT) { + if ((snap_active && snap_node_parent && (p_modes & SNAP_NODE_PARENT)) || (p_forced_modes & SNAP_NODE_PARENT)) { // Parent sides and center bool can_snap = false; if (const Control *c = Object::cast_to<Control>(p_canvas_item)) { @@ -298,7 +298,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const } // Self anchors (for sides) - if (p_modes & SNAP_NODE_ANCHORS) { + if ((snap_active && snap_node_anchors && (p_modes & SNAP_NODE_ANCHORS)) || (p_forced_modes & SNAP_NODE_ANCHORS)) { if (const Control *c = Object::cast_to<Control>(p_canvas_item)) { begin = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(c->get_anchor(MARGIN_LEFT), c->get_anchor(MARGIN_TOP)))); end = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(c->get_anchor(MARGIN_RIGHT), c->get_anchor(MARGIN_BOTTOM)))); @@ -308,7 +308,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const } // Self sides (for anchors) - if (p_modes & SNAP_NODE_SIDES) { + if ((snap_active && snap_node_sides && (p_modes & SNAP_NODE_SIDES)) || (p_forced_modes & SNAP_NODE_SIDES)) { begin = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->get_item_rect().get_position()); end = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->get_item_rect().get_position() + p_canvas_item->get_item_rect().get_size()); _snap_if_closer(p_target, begin, output, snapped, rotation); @@ -316,12 +316,12 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const } // Other nodes sides - if (p_modes & SNAP_OTHER_NODES) { + if ((snap_active && snap_other_nodes && (p_modes & SNAP_OTHER_NODES)) || (p_forced_modes & SNAP_OTHER_NODES)) { _snap_other_nodes(p_target, output, snapped, get_tree()->get_edited_scene_root(), p_canvas_item); } } - if ((p_modes & SNAP_GRID) && snap_grid && rotation == 0.0) { + if (((snap_active && snap_grid && (p_modes & SNAP_GRID)) || (p_forced_modes & SNAP_GRID)) && rotation == 0.0) { // Grid Point2 offset = grid_offset; if (snap_relative) { @@ -336,9 +336,11 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const grid_output.x = Math::stepify(p_target.x - offset.x, grid_step.x * Math::pow(2.0, grid_step_multiplier)) + offset.x; grid_output.y = Math::stepify(p_target.y - offset.y, grid_step.y * Math::pow(2.0, grid_step_multiplier)) + offset.y; _snap_if_closer(p_target, grid_output, output, snapped, 0.0, -1.0); - } else if ((p_modes & SNAP_PIXEL) && snap_pixel && rotation == 0.0) { + } + + if (((snap_pixel && (p_modes & SNAP_PIXEL)) || (p_forced_modes & SNAP_PIXEL)) && rotation == 0.0) { // Pixel - output = p_target.snapped(Size2(1, 1)); + output = output.snapped(Size2(1, 1)); } return output; @@ -375,12 +377,12 @@ void CanvasItemEditor::_unhandled_key_input(const Ref<InputEvent> &p_ev) { _edit_set_pivot(mouse_pos); } } - } else if ((snap_grid || snap_show_grid) && multiply_grid_step_shortcut.is_valid() && multiply_grid_step_shortcut->is_shortcut(p_ev)) { + } else if ((snap_grid || show_grid) && multiply_grid_step_shortcut.is_valid() && multiply_grid_step_shortcut->is_shortcut(p_ev)) { // Multiply the grid size grid_step_multiplier = MIN(grid_step_multiplier + 1, 12); viewport_base->update(); viewport->update(); - } else if ((snap_grid || snap_show_grid) && divide_grid_step_shortcut.is_valid() && divide_grid_step_shortcut->is_shortcut(p_ev)) { + } else if ((snap_grid || show_grid) && divide_grid_step_shortcut.is_valid() && divide_grid_step_shortcut->is_shortcut(p_ev)) { // Divide the grid size Point2 new_grid_step = grid_step * Math::pow(2.0, grid_step_multiplier - 1); if (new_grid_step.x >= 1.0 && new_grid_step.y >= 1.0) @@ -421,8 +423,13 @@ Dictionary CanvasItemEditor::get_state() const { state["grid_step"] = grid_step; state["snap_rotation_offset"] = snap_rotation_offset; state["snap_rotation_step"] = snap_rotation_step; + state["snap_active"] = snap_active; + state["snap_node_parent"] = snap_node_parent; + state["snap_node_anchors"] = snap_node_anchors; + state["snap_node_sides"] = snap_node_sides; + state["snap_other_nodes"] = snap_other_nodes; state["snap_grid"] = snap_grid; - state["snap_show_grid"] = snap_show_grid; + state["show_grid"] = show_grid; state["show_rulers"] = show_rulers; state["show_helpers"] = show_helpers; state["snap_rotation"] = snap_rotation; @@ -461,16 +468,45 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) { snap_rotation_offset = state["snap_rotation_offset"]; } + if (state.has("snap_active")) { + snap_active = state["snap_active"]; + snap_button->set_pressed(snap_active); + } + + if (state.has("snap_node_parent")) { + snap_node_parent = state["snap_node_parent"]; + int idx = smartsnap_config_popup->get_item_index(SNAP_USE_NODE_PARENT); + smartsnap_config_popup->set_item_checked(idx, snap_node_parent); + } + + if (state.has("snap_node_anchors")) { + snap_node_anchors = state["snap_node_anchors"]; + int idx = smartsnap_config_popup->get_item_index(SNAP_USE_NODE_ANCHORS); + smartsnap_config_popup->set_item_checked(idx, snap_node_anchors); + } + + if (state.has("snap_node_sides")) { + snap_node_sides = state["snap_node_sides"]; + int idx = smartsnap_config_popup->get_item_index(SNAP_USE_NODE_SIDES); + smartsnap_config_popup->set_item_checked(idx, snap_node_sides); + } + + if (state.has("snap_other_nodes")) { + snap_other_nodes = state["snap_other_nodes"]; + int idx = smartsnap_config_popup->get_item_index(SNAP_USE_OTHER_NODES); + smartsnap_config_popup->set_item_checked(idx, snap_other_nodes); + } + if (state.has("snap_grid")) { snap_grid = state["snap_grid"]; - int idx = edit_menu->get_popup()->get_item_index(SNAP_USE); - edit_menu->get_popup()->set_item_checked(idx, snap_grid); + int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_GRID); + snap_config_menu->get_popup()->set_item_checked(idx, snap_grid); } - if (state.has("snap_show_grid")) { - snap_show_grid = state["snap_show_grid"]; - int idx = edit_menu->get_popup()->get_item_index(SNAP_SHOW_GRID); - edit_menu->get_popup()->set_item_checked(idx, snap_show_grid); + if (state.has("show_grid")) { + show_grid = state["show_grid"]; + int idx = view_menu->get_popup()->get_item_index(SHOW_GRID); + view_menu->get_popup()->set_item_checked(idx, show_grid); } if (state.has("show_rulers")) { @@ -487,26 +523,26 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) { if (state.has("snap_rotation")) { snap_rotation = state["snap_rotation"]; - int idx = edit_menu->get_popup()->get_item_index(SNAP_USE_ROTATION); - edit_menu->get_popup()->set_item_checked(idx, snap_rotation); + int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_ROTATION); + snap_config_menu->get_popup()->set_item_checked(idx, snap_rotation); } if (state.has("snap_relative")) { snap_relative = state["snap_relative"]; - int idx = edit_menu->get_popup()->get_item_index(SNAP_RELATIVE); - edit_menu->get_popup()->set_item_checked(idx, snap_relative); + int idx = snap_config_menu->get_popup()->get_item_index(SNAP_RELATIVE); + snap_config_menu->get_popup()->set_item_checked(idx, snap_relative); } if (state.has("snap_pixel")) { snap_pixel = state["snap_pixel"]; - int idx = edit_menu->get_popup()->get_item_index(SNAP_USE_PIXEL); - edit_menu->get_popup()->set_item_checked(idx, snap_pixel); + int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_PIXEL); + snap_config_menu->get_popup()->set_item_checked(idx, snap_pixel); } if (state.has("skeleton_show_bones")) { skeleton_show_bones = state["skeleton_show_bones"]; - int idx = skeleton_menu->get_item_index(SKELETON_SHOW_BONES); - skeleton_menu->set_item_checked(idx, skeleton_show_bones); + int idx = skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES); + skeleton_menu->get_popup()->set_item_checked(idx, skeleton_show_bones); } viewport->update(); @@ -1719,7 +1755,7 @@ void CanvasItemEditor::_viewport_base_gui_input(const Ref<InputEvent> &p_event) Vector2 anchor = c_trans_rev.xform(dto - drag_from + drag_point_from); anchor = _position_to_anchor(control, anchor); - Vector2 anchor_snapped = c_trans_rev.xform(snap_point(dto - drag_from + drag_point_from, SNAP_NODE_PARENT | SNAP_OTHER_NODES | SNAP_NODE_SIDES, _get_single_item())); + Vector2 anchor_snapped = c_trans_rev.xform(snap_point(dto - drag_from + drag_point_from, SNAP_GRID | SNAP_OTHER_NODES, _get_single_item(), SNAP_NODE_PARENT | SNAP_NODE_SIDES)); anchor_snapped = _position_to_anchor(control, anchor_snapped).snapped(Vector2(0.00001, 0.00001)); bool use_y = Math::abs(drag_vector.y) > Math::abs(drag_vector.x); @@ -2050,7 +2086,7 @@ void CanvasItemEditor::_draw_rulers() { // The rule transform Transform2D ruler_transform; - if (snap_show_grid || snap_grid) { + if (show_grid || snap_grid) { ruler_transform = Transform2D(); if (snap_relative && get_item_count() > 0) { ruler_transform.translate(_find_topleftmost_point()); @@ -2131,7 +2167,7 @@ void CanvasItemEditor::_draw_focus() { } void CanvasItemEditor::_draw_grid() { - if (snap_show_grid) { + if (show_grid) { //Draw the grid Size2 s = viewport->get_size(); int last_cell = 0; @@ -2758,6 +2794,9 @@ void CanvasItemEditor::_notification(int p_what) { list_select_button->set_icon(get_icon("ListSelect", "EditorIcons")); move_button->set_icon(get_icon("ToolMove", "EditorIcons")); rotate_button->set_icon(get_icon("ToolRotate", "EditorIcons")); + snap_button->set_icon(get_icon("Snap", "EditorIcons")); + 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")); pivot_button->set_icon(get_icon("EditPivot", "EditorIcons")); select_handle = get_icon("EditorHandle", "EditorIcons"); @@ -2806,6 +2845,9 @@ void CanvasItemEditor::_notification(int p_what) { list_select_button->set_icon(get_icon("ListSelect", "EditorIcons")); move_button->set_icon(get_icon("ToolMove", "EditorIcons")); rotate_button->set_icon(get_icon("ToolRotate", "EditorIcons")); + snap_button->set_icon(get_icon("Snap", "EditorIcons")); + 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")); pivot_button->set_icon(get_icon("EditPivot", "EditorIcons")); select_handle = get_icon("EditorHandle", "EditorIcons"); @@ -3042,41 +3084,65 @@ void CanvasItemEditor::_zoom_plus() { viewport_base->update(); } +void CanvasItemEditor::_toggle_snap(bool p_status) { + snap_active = p_status; + viewport->update(); + viewport_base->update(); +} + void CanvasItemEditor::_popup_callback(int p_op) { last_option = MenuOption(p_op); switch (p_op) { - case SNAP_USE: { - snap_grid = !snap_grid; - int idx = edit_menu->get_popup()->get_item_index(SNAP_USE); - edit_menu->get_popup()->set_item_checked(idx, snap_grid); + case SHOW_GRID: { + show_grid = !show_grid; + int idx = view_menu->get_popup()->get_item_index(SHOW_GRID); + view_menu->get_popup()->set_item_checked(idx, show_grid); viewport->update(); viewport_base->update(); } break; - case SNAP_SHOW_GRID: { - snap_show_grid = !snap_show_grid; - int idx = edit_menu->get_popup()->get_item_index(SNAP_SHOW_GRID); - edit_menu->get_popup()->set_item_checked(idx, snap_show_grid); - viewport->update(); - viewport_base->update(); + case SNAP_USE_NODE_PARENT: { + snap_node_parent = !snap_node_parent; + int idx = smartsnap_config_popup->get_item_index(SNAP_USE_NODE_PARENT); + smartsnap_config_popup->set_item_checked(idx, snap_node_parent); + } break; + case SNAP_USE_NODE_ANCHORS: { + snap_node_anchors = !snap_node_anchors; + int idx = smartsnap_config_popup->get_item_index(SNAP_USE_NODE_ANCHORS); + smartsnap_config_popup->set_item_checked(idx, snap_node_anchors); + } break; + case SNAP_USE_NODE_SIDES: { + snap_node_sides = !snap_node_sides; + int idx = smartsnap_config_popup->get_item_index(SNAP_USE_NODE_SIDES); + smartsnap_config_popup->set_item_checked(idx, snap_node_sides); + } break; + case SNAP_USE_OTHER_NODES: { + snap_other_nodes = !snap_other_nodes; + int idx = smartsnap_config_popup->get_item_index(SNAP_USE_OTHER_NODES); + smartsnap_config_popup->set_item_checked(idx, snap_other_nodes); + } break; + case SNAP_USE_GRID: { + snap_grid = !snap_grid; + int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_GRID); + snap_config_menu->get_popup()->set_item_checked(idx, snap_grid); } break; case SNAP_USE_ROTATION: { snap_rotation = !snap_rotation; - int idx = edit_menu->get_popup()->get_item_index(SNAP_USE_ROTATION); - edit_menu->get_popup()->set_item_checked(idx, snap_rotation); + int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_ROTATION); + snap_config_menu->get_popup()->set_item_checked(idx, snap_rotation); } break; case SNAP_RELATIVE: { snap_relative = !snap_relative; - int idx = edit_menu->get_popup()->get_item_index(SNAP_RELATIVE); - edit_menu->get_popup()->set_item_checked(idx, snap_relative); + int idx = snap_config_menu->get_popup()->get_item_index(SNAP_RELATIVE); + snap_config_menu->get_popup()->set_item_checked(idx, snap_relative); viewport->update(); viewport_base->update(); } break; case SNAP_USE_PIXEL: { snap_pixel = !snap_pixel; - int idx = edit_menu->get_popup()->get_item_index(SNAP_USE_PIXEL); - edit_menu->get_popup()->set_item_checked(idx, snap_pixel); + int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_PIXEL); + snap_config_menu->get_popup()->set_item_checked(idx, snap_pixel); } break; case SNAP_CONFIGURE: { ((SnapDialog *)snap_dialog)->set_fields(grid_offset, grid_step, snap_rotation_offset, snap_rotation_step); @@ -3084,8 +3150,8 @@ void CanvasItemEditor::_popup_callback(int p_op) { } break; case SKELETON_SHOW_BONES: { skeleton_show_bones = !skeleton_show_bones; - int idx = skeleton_menu->get_item_index(SKELETON_SHOW_BONES); - skeleton_menu->set_item_checked(idx, skeleton_show_bones); + int idx = skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES); + skeleton_menu->get_popup()->set_item_checked(idx, skeleton_show_bones); viewport->update(); } break; case SHOW_HELPERS: { @@ -3448,7 +3514,7 @@ void CanvasItemEditor::_popup_callback(int p_op) { n2d->set_meta("_edit_bone_", true); if (!skeleton_show_bones) - skeleton_menu->activate_item(skeleton_menu->get_item_index(SKELETON_SHOW_BONES)); + skeleton_menu->get_popup()->activate_item(skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES)); } viewport->update(); @@ -3467,7 +3533,7 @@ void CanvasItemEditor::_popup_callback(int p_op) { n2d->set_meta("_edit_bone_", Variant()); if (!skeleton_show_bones) - skeleton_menu->activate_item(skeleton_menu->get_item_index(SKELETON_SHOW_BONES)); + skeleton_menu->get_popup()->activate_item(skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES)); } viewport->update(); @@ -3487,7 +3553,7 @@ void CanvasItemEditor::_popup_callback(int p_op) { canvas_item->set_meta("_edit_ik_", true); if (!skeleton_show_bones) - skeleton_menu->activate_item(skeleton_menu->get_item_index(SKELETON_SHOW_BONES)); + skeleton_menu->get_popup()->activate_item(skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES)); } viewport->update(); @@ -3507,7 +3573,7 @@ void CanvasItemEditor::_popup_callback(int p_op) { n2d->set_meta("_edit_ik_", Variant()); if (!skeleton_show_bones) - skeleton_menu->activate_item(skeleton_menu->get_item_index(SKELETON_SHOW_BONES)); + skeleton_menu->get_popup()->activate_item(skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES)); } viewport->update(); @@ -3573,6 +3639,7 @@ void CanvasItemEditor::_bind_methods() { ClassDB::bind_method("_zoom_minus", &CanvasItemEditor::_zoom_minus); ClassDB::bind_method("_zoom_reset", &CanvasItemEditor::_zoom_reset); ClassDB::bind_method("_zoom_plus", &CanvasItemEditor::_zoom_plus); + ClassDB::bind_method("_toggle_snap", &CanvasItemEditor::_toggle_snap); ClassDB::bind_method("_update_scroll", &CanvasItemEditor::_update_scroll); ClassDB::bind_method("_popup_callback", &CanvasItemEditor::_popup_callback); ClassDB::bind_method("_get_editor_data", &CanvasItemEditor::_get_editor_data); @@ -3735,6 +3802,41 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { hb->add_child(memnew(VSeparator)); + snap_button = memnew(ToolButton); + hb->add_child(snap_button); + snap_button->set_toggle_mode(true); + snap_button->connect("toggled", this, "_toggle_snap"); + snap_button->set_tooltip(TTR("Toggles snapping")); + snap_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/use_snap", TTR("Use Snap"), KEY_S)); + + snap_config_menu = memnew(MenuButton); + hb->add_child(snap_config_menu); + snap_config_menu->get_popup()->connect("id_pressed", this, "_popup_callback"); + snap_config_menu->set_h_size_flags(SIZE_SHRINK_END); + snap_config_menu->set_tooltip(TTR("Snapping options")); + + PopupMenu *p = snap_config_menu->get_popup(); + p->connect("id_pressed", this, "_popup_callback"); + p->set_hide_on_checkable_item_selection(false); + p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_grid", TTR("Snap to grid")), SNAP_USE_GRID); + p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_rotation_snap", TTR("Use Rotation Snap")), SNAP_USE_ROTATION); + p->add_shortcut(ED_SHORTCUT("canvas_item_editor/configure_snap", TTR("Configure Snap...")), SNAP_CONFIGURE); + p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_relative", TTR("Snap Relative")), SNAP_RELATIVE); + p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_pixel_snap", TTR("Use Pixel Snap")), SNAP_USE_PIXEL); + p->add_submenu_item(TTR("Smart snapping"), "SmartSnapping"); + + smartsnap_config_popup = memnew(PopupMenu); + p->add_child(smartsnap_config_popup); + smartsnap_config_popup->set_name("SmartSnapping"); + smartsnap_config_popup->connect("id_pressed", this, "_popup_callback"); + smartsnap_config_popup->set_hide_on_checkable_item_selection(false); + smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_node_parent", TTR("Snap to parent")), SNAP_USE_NODE_PARENT); + smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_node_anchors", TTR("Snap to node anchor")), SNAP_USE_NODE_ANCHORS); + smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_node_sides", TTR("Snap to node sides")), SNAP_USE_NODE_SIDES); + smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_other_nodes", TTR("Snap to other nodes")), SNAP_USE_OTHER_NODES); + + hb->add_child(memnew(VSeparator)); + lock_button = memnew(ToolButton); hb->add_child(lock_button); @@ -3758,35 +3860,23 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { hb->add_child(memnew(VSeparator)); - edit_menu = memnew(MenuButton); - edit_menu->set_text(TTR("Edit")); - hb->add_child(edit_menu); - edit_menu->get_popup()->connect("id_pressed", this, "_popup_callback"); + skeleton_menu = memnew(MenuButton); + hb->add_child(skeleton_menu); - PopupMenu *p; - p = edit_menu->get_popup(); + p = skeleton_menu->get_popup(); p->set_hide_on_checkable_item_selection(false); - p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_snap", TTR("Use Snap"), KEY_S), SNAP_USE); - p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_grid", TTR("Show Grid"), KEY_G), SNAP_SHOW_GRID); - p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_rotation_snap", TTR("Use Rotation Snap")), SNAP_USE_ROTATION); - p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_relative", TTR("Snap Relative")), SNAP_RELATIVE); - p->add_shortcut(ED_SHORTCUT("canvas_item_editor/configure_snap", TTR("Configure Snap..")), SNAP_CONFIGURE); + p->connect("id_pressed", this, "_popup_callback"); + p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_make_bones", TTR("Make Bones"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B), SKELETON_MAKE_BONES); + p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_clear_bones", TTR("Clear Bones")), SKELETON_CLEAR_BONES); p->add_separator(); - p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_pixel_snap", TTR("Use Pixel Snap")), SNAP_USE_PIXEL); + p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_show_bones", TTR("Show Bones")), SKELETON_SHOW_BONES); p->add_separator(); - p->add_submenu_item(TTR("Skeleton.."), "skeleton"); - skeleton_menu = memnew(PopupMenu); - p->add_child(skeleton_menu); - skeleton_menu->set_name("skeleton"); - skeleton_menu->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_make_bones", TTR("Make Bones"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B), SKELETON_MAKE_BONES); - skeleton_menu->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_clear_bones", TTR("Clear Bones")), SKELETON_CLEAR_BONES); - skeleton_menu->add_separator(); - skeleton_menu->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_show_bones", TTR("Show Bones")), SKELETON_SHOW_BONES); - skeleton_menu->add_separator(); - skeleton_menu->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_set_ik_chain", TTR("Make IK Chain")), SKELETON_SET_IK_CHAIN); - skeleton_menu->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_clear_ik_chain", TTR("Clear IK Chain")), SKELETON_CLEAR_IK_CHAIN); - skeleton_menu->set_hide_on_checkable_item_selection(false); - skeleton_menu->connect("id_pressed", this, "_popup_callback"); + p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_set_ik_chain", TTR("Make IK Chain")), SKELETON_SET_IK_CHAIN); + p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_clear_ik_chain", TTR("Clear IK Chain")), SKELETON_CLEAR_IK_CHAIN); + p->set_hide_on_checkable_item_selection(false); + p->connect("id_pressed", this, "_popup_callback"); + + hb->add_child(memnew(VSeparator)); view_menu = memnew(MenuButton); view_menu->set_text(TTR("View")); @@ -3794,7 +3884,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { view_menu->get_popup()->connect("id_pressed", this, "_popup_callback"); p = view_menu->get_popup(); - + 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_separator(); @@ -3885,6 +3975,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { key_rot = true; key_scale = false; + show_grid = false; show_helpers = false; show_rulers = false; zoom = 1; @@ -3893,12 +3984,16 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { grid_step_multiplier = 0; snap_rotation_offset = 0; snap_rotation_step = 15 / (180 / Math_PI); - snap_grid = false; - snap_show_grid = false; + snap_active = false; + snap_node_parent = true; + snap_node_anchors = true; + snap_node_sides = true; + snap_other_nodes = true; + snap_grid = true; snap_rotation = false; snap_pixel = false; skeleton_show_bones = true; - skeleton_menu->set_item_checked(skeleton_menu->get_item_index(SKELETON_SHOW_BONES), true); + skeleton_menu->get_popup()->set_item_checked(skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES), true); box_selecting = false; //zoom=0.5; singleton = this; diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index fe843fdf63..af834507e0 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -81,11 +81,16 @@ class CanvasItemEditor : public VBoxContainer { enum MenuOption { SNAP_USE, - SNAP_SHOW_GRID, + SNAP_USE_NODE_PARENT, + SNAP_USE_NODE_ANCHORS, + SNAP_USE_NODE_SIDES, + SNAP_USE_OTHER_NODES, + SNAP_USE_GRID, SNAP_USE_ROTATION, SNAP_RELATIVE, SNAP_CONFIGURE, SNAP_USE_PIXEL, + SHOW_GRID, SHOW_HELPERS, SHOW_RULERS, LOCK_SELECTED, @@ -174,6 +179,7 @@ class CanvasItemEditor : public VBoxContainer { ToolButton *zoom_plus; Transform2D transform; + bool show_grid; bool show_rulers; bool show_helpers; float zoom; @@ -184,8 +190,12 @@ class CanvasItemEditor : public VBoxContainer { float snap_rotation_step; float snap_rotation_offset; + bool snap_active; + bool snap_node_parent; + bool snap_node_anchors; + bool snap_node_sides; + bool snap_other_nodes; bool snap_grid; - bool snap_show_grid; bool snap_rotation; bool snap_relative; bool snap_pixel; @@ -251,6 +261,10 @@ class CanvasItemEditor : public VBoxContainer { ToolButton *move_button; ToolButton *rotate_button; + ToolButton *snap_button; + MenuButton *snap_config_menu; + PopupMenu *smartsnap_config_popup; + ToolButton *pivot_button; ToolButton *pan_button; @@ -260,8 +274,7 @@ class CanvasItemEditor : public VBoxContainer { ToolButton *group_button; ToolButton *ungroup_button; - MenuButton *edit_menu; - PopupMenu *skeleton_menu; + MenuButton *skeleton_menu; MenuButton *view_menu; HBoxContainer *animation_hb; MenuButton *animation_menu; @@ -378,6 +391,8 @@ class CanvasItemEditor : public VBoxContainer { void _zoom_reset(); void _zoom_plus(); + void _toggle_snap(bool p_status); + HSplitContainer *palette_split; VSplitContainer *bottom_split; @@ -432,7 +447,7 @@ public: SNAP_DEFAULT = 0x03, }; - Point2 snap_point(Point2 p_target, unsigned int p_modes = SNAP_DEFAULT, const CanvasItem *p_canvas_item = NULL); + Point2 snap_point(Point2 p_target, unsigned int p_modes = SNAP_DEFAULT, const CanvasItem *p_canvas_item = NULL, unsigned int p_forced_modes = 0); float snap_angle(float p_target, float p_start = 0) const; Transform2D get_canvas_transform() const { return transform; } diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index 3917c700f0..8c4e1b8f27 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -52,7 +52,7 @@ void Polygon2DEditor::_notification(int p_what) { uv_button[UV_MODE_SCALE]->set_icon(get_icon("ToolScale", "EditorIcons")); b_snap_grid->set_icon(get_icon("Grid", "EditorIcons")); - b_snap_enable->set_icon(get_icon("Snap", "EditorIcons")); + b_snap_enable->set_icon(get_icon("SnapGrid", "EditorIcons")); uv_icon_zoom->set_texture(get_icon("Zoom", "EditorIcons")); get_tree()->connect("node_removed", this, "_node_removed"); diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 5b00aab2ef..4477e9ecf9 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -283,7 +283,7 @@ void GraphEdit::_notification(int p_what) { zoom_minus->set_icon(get_icon("minus")); zoom_reset->set_icon(get_icon("reset")); zoom_plus->set_icon(get_icon("more")); - snap_button->set_icon(get_icon("snap")); + snap_button->set_icon(get_icon("SnapGrid")); //zoom_icon->set_texture( get_icon("Zoom", "EditorIcons")); } if (p_what == NOTIFICATION_DRAW) { diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 1272e5a946..2fbd5ebdd3 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -879,7 +879,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_icon("minus", "GraphEdit", make_icon(icon_zoom_less_png)); theme->set_icon("reset", "GraphEdit", make_icon(icon_zoom_reset_png)); theme->set_icon("more", "GraphEdit", make_icon(icon_zoom_more_png)); - theme->set_icon("snap", "GraphEdit", make_icon(icon_snap_png)); + theme->set_icon("SnapGrid", "GraphEdit", make_icon(icon_snap_grid_png)); theme->set_stylebox("bg", "GraphEdit", make_stylebox(tree_bg_png, 4, 4, 4, 5)); theme->set_color("grid_minor", "GraphEdit", Color(1, 1, 1, 0.05)); theme->set_color("grid_major", "GraphEdit", Color(1, 1, 1, 0.2)); diff --git a/scene/resources/default_theme/icon_snap.png b/scene/resources/default_theme/icon_snap_grid.png Binary files differindex 93194d34e7..44db9bdfdc 100644 --- a/scene/resources/default_theme/icon_snap.png +++ b/scene/resources/default_theme/icon_snap_grid.png diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h index bed4bdb760..6643b4ccc1 100644 --- a/scene/resources/default_theme/theme_data.h +++ b/scene/resources/default_theme/theme_data.h @@ -182,8 +182,8 @@ static const unsigned char icon_reload_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x1, 0x59, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xcd, 0x92, 0x31, 0x4b, 0x3, 0x31, 0x18, 0x86, 0x9f, 0x5c, 0xe, 0xec, 0x20, 0x76, 0x70, 0x39, 0xd0, 0xe3, 0xba, 0x74, 0x51, 0x41, 0xdd, 0xfc, 0x7, 0xba, 0xb8, 0x8, 0x52, 0xec, 0x2e, 0x4e, 0x3a, 0x88, 0x3f, 0xa3, 0xa3, 0x53, 0x7, 0x47, 0x67, 0x41, 0x17, 0xdd, 0x9c, 0x5c, 0x3b, 0xd8, 0x82, 0x64, 0x68, 0xca, 0xd5, 0x55, 0x11, 0x3c, 0x1a, 0x87, 0x24, 0x2e, 0xd7, 0x72, 0x9e, 0x9e, 0xab, 0xbe, 0xd3, 0xc7, 0x1b, 0x9e, 0x37, 0xf9, 0xbe, 0x7c, 0xf0, 0xd7, 0x12, 0x3f, 0x99, 0x4a, 0xa9, 0xb9, 0x30, 0xc, 0x8f, 0x84, 0x10, 0x7, 0xc0, 0x5a, 0x6e, 0x3f, 0x3a, 0xe7, 0x2e, 0xad, 0xb5, 0xdd, 0x66, 0xb3, 0xf9, 0x51, 0x19, 0x90, 0xa6, 0xe9, 0x92, 0xb5, 0xf6, 0x6, 0x58, 0xaf, 0xb8, 0xb4, 0x27, 0xa5, 0xdc, 0x8d, 0xe3, 0xf8, 0x19, 0x20, 0x28, 0xdf, 0x5c, 0x80, 0x53, 0x60, 0xdf, 0x18, 0x53, 0x37, 0xc6, 0xd4, 0xbd, 0xf7, 0x7b, 0xc0, 0x13, 0xb0, 0x61, 0xad, 0xbd, 0x56, 0x4a, 0xcd, 0x1, 0x84, 0xc5, 0x80, 0x30, 0xc, 0x8f, 0xa6, 0xb0, 0x94, 0x72, 0x33, 0x8e, 0xe3, 0x97, 0xc2, 0xf1, 0xd5, 0x68, 0x34, 0xba, 0xf7, 0xde, 0xf7, 0x80, 0xd, 0x29, 0xe5, 0x21, 0x70, 0xfe, 0xe5, 0x5, 0x42, 0x88, 0x76, 0x5e, 0x9e, 0x96, 0x60, 0x0, 0x92, 0x24, 0x79, 0x75, 0xce, 0x9d, 0x1, 0x4, 0x41, 0xd0, 0xfe, 0xd6, 0x2, 0xb0, 0x2, 0x60, 0x8c, 0xb9, 0xab, 0xe8, 0x1f, 0x6b, 0xed, 0x6d, 0x5e, 0xae, 0xce, 0x2, 0xb4, 0xd6, 0x17, 0x5a, 0x6b, 0x7, 0xcc, 0x3, 0xd4, 0x6a, 0xb5, 0x37, 0xad, 0xf5, 0xc5, 0x4f, 0x1, 0x41, 0x10, 0x7c, 0x19, 0x7c, 0x90, 0x3, 0xc7, 0xc0, 0xa0, 0xe0, 0xf, 0x72, 0xef, 0x9b, 0x84, 0x10, 0xdb, 0x79, 0xd9, 0x9f, 0x5, 0x44, 0x51, 0x94, 0x9, 0x21, 0x5a, 0x40, 0x6, 0x64, 0x42, 0x88, 0x56, 0x14, 0x45, 0x59, 0x19, 0x1e, 0x8f, 0xc7, 0x8b, 0x52, 0xca, 0xe, 0x80, 0x73, 0xee, 0x12, 0xa, 0xbf, 0x90, 0x24, 0x49, 0x7f, 0x38, 0x1c, 0x1e, 0x3, 0x34, 0x1a, 0x8d, 0x7e, 0x11, 0x54, 0x4a, 0x2d, 0x48, 0x29, 0x77, 0xac, 0xb5, 0x1d, 0xef, 0xfd, 0x32, 0xd0, 0x9b, 0x4c, 0x26, 0x5d, 0xa8, 0xd8, 0xc4, 0xb2, 0xf2, 0xf9, 0x4c, 0x55, 0xbd, 0x48, 0xbf, 0xe8, 0x1d, 0x78, 0x70, 0xce, 0x9d, 0x64, 0x59, 0xb6, 0x35, 0x85, 0xff, 0x87, 0x3e, 0x1, 0x53, 0x7, 0x87, 0x11, 0xd3, 0x3a, 0x9b, 0x9e, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; -static const unsigned char icon_snap_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xc2, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xad, 0x90, 0xbd, 0xa, 0xc2, 0x30, 0x14, 0x85, 0xbf, 0x5b, 0x5c, 0x23, 0xe8, 0x6c, 0x9f, 0xc1, 0xb7, 0xd0, 0x47, 0xd1, 0x47, 0x70, 0x48, 0xa1, 0x43, 0x57, 0xe9, 0xd3, 0x88, 0x93, 0xef, 0xe0, 0xea, 0x5c, 0x9d, 0x1d, 0xb2, 0x96, 0xc6, 0xa1, 0x9, 0xd4, 0xd8, 0xd8, 0x4a, 0xfd, 0x20, 0x10, 0xee, 0xcf, 0xe1, 0xdc, 0x3, 0x1d, 0x8c, 0x31, 0xd6, 0x18, 0x63, 0x9, 0x88, 0xd5, 0x1, 0x92, 0xbe, 0xe2, 0x2f, 0x4c, 0x16, 0x90, 0x98, 0xb5, 0x21, 0x94, 0x52, 0xf2, 0x17, 0x7, 0x6f, 0x7c, 0xb, 0x2b, 0xc6, 0x64, 0x7, 0xb3, 0xa1, 0x1, 0x5b, 0x14, 0x29, 0x50, 0x2, 0x1b, 0x0, 0x44, 0x2e, 0x34, 0xcd, 0x41, 0xb2, 0xec, 0x6, 0x20, 0xdd, 0x61, 0x6f, 0xdf, 0x7, 0xe4, 0x96, 0xaf, 0xc0, 0x32, 0xd0, 0x7d, 0x2, 0x6b, 0xd1, 0xba, 0x4a, 0xfc, 0xdd, 0x91, 0xdb, 0x4b, 0xb7, 0x7c, 0x2, 0x56, 0xd4, 0x75, 0xa, 0x9c, 0x81, 0x5, 0x70, 0x84, 0xe1, 0xc, 0x5a, 0xdb, 0x75, 0xbd, 0x17, 0xad, 0x1f, 0x92, 0xe7, 0x77, 0x60, 0xe7, 0x7a, 0x5b, 0x80, 0x44, 0x29, 0x25, 0xfe, 0xf5, 0x8, 0x28, 0x0, 0xb7, 0xd8, 0x46, 0xa0, 0x75, 0xe5, 0xbe, 0xf3, 0x31, 0xe, 0x7e, 0x23, 0xcc, 0xc2, 0x3a, 0xc2, 0xb9, 0x58, 0xfd, 0x83, 0xc9, 0x2, 0x63, 0x78, 0x1, 0x4a, 0x50, 0x70, 0x86, 0xcc, 0x86, 0x2, 0x4, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +static const unsigned char icon_snap_grid_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x4, 0x73, 0x42, 0x49, 0x54, 0x8, 0x8, 0x8, 0x8, 0x7c, 0x8, 0x64, 0x88, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xe, 0xc4, 0x0, 0x0, 0xe, 0xc4, 0x1, 0x95, 0x2b, 0xe, 0x1b, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x0, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, 0xee, 0x3c, 0x1a, 0x0, 0x0, 0x0, 0xc2, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xad, 0x90, 0xbd, 0xa, 0xc2, 0x30, 0x14, 0x85, 0xbf, 0x5b, 0x5c, 0x23, 0xe8, 0x6c, 0x9f, 0xc1, 0xb7, 0xd0, 0x47, 0xd1, 0x47, 0x70, 0x48, 0xa1, 0x43, 0x57, 0xe9, 0xd3, 0x88, 0x93, 0xef, 0xe0, 0xea, 0x5c, 0x9d, 0x1d, 0xb2, 0x96, 0xc6, 0xa1, 0x9, 0xd4, 0xd8, 0xd8, 0x4a, 0xfd, 0x20, 0x10, 0xee, 0xcf, 0xe1, 0xdc, 0x3, 0x1d, 0x8c, 0x31, 0xd6, 0x18, 0x63, 0x9, 0x88, 0xd5, 0x1, 0x92, 0xbe, 0xe2, 0x2f, 0x4c, 0x16, 0x90, 0x98, 0xb5, 0x21, 0x94, 0x52, 0xf2, 0x17, 0x7, 0x6f, 0x7c, 0xb, 0x2b, 0xc6, 0x64, 0x7, 0xb3, 0xa1, 0x1, 0x5b, 0x14, 0x29, 0x50, 0x2, 0x1b, 0x0, 0x44, 0x2e, 0x34, 0xcd, 0x41, 0xb2, 0xec, 0x6, 0x20, 0xdd, 0x61, 0x6f, 0xdf, 0x7, 0xe4, 0x96, 0xaf, 0xc0, 0x32, 0xd0, 0x7d, 0x2, 0x6b, 0xd1, 0xba, 0x4a, 0xfc, 0xdd, 0x91, 0xdb, 0x4b, 0xb7, 0x7c, 0x2, 0x56, 0xd4, 0x75, 0xa, 0x9c, 0x81, 0x5, 0x70, 0x84, 0xe1, 0xc, 0x5a, 0xdb, 0x75, 0xbd, 0x17, 0xad, 0x1f, 0x92, 0xe7, 0x77, 0x60, 0xe7, 0x7a, 0x5b, 0x80, 0x44, 0x29, 0x25, 0xfe, 0xf5, 0x8, 0x28, 0x0, 0xb7, 0xd8, 0x46, 0xa0, 0x75, 0xe5, 0xbe, 0xf3, 0x31, 0xe, 0x7e, 0x23, 0xcc, 0xc2, 0x3a, 0xc2, 0xb9, 0x58, 0xfd, 0x83, 0xc9, 0x2, 0x63, 0x78, 0x1, 0x4a, 0x50, 0x70, 0x86, 0xcc, 0x86, 0x2, 0x4, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; static const unsigned char icon_stop_png[] = { |