diff --git a/assets/graphics/blue_themes/tools/polygonselect.png b/assets/graphics/blue_themes/tools/polygonselect.png new file mode 100644 index 000000000..34d1b3618 Binary files /dev/null and b/assets/graphics/blue_themes/tools/polygonselect.png differ diff --git a/assets/graphics/blue_themes/tools/polygonselect.png.import b/assets/graphics/blue_themes/tools/polygonselect.png.import new file mode 100644 index 000000000..e8a3fff44 --- /dev/null +++ b/assets/graphics/blue_themes/tools/polygonselect.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/polygonselect.png-448fe1e0b611f853c789ce4def03e3d8.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/graphics/blue_themes/tools/polygonselect.png" +dest_files=[ "res://.import/polygonselect.png-448fe1e0b611f853c789ce4def03e3d8.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/assets/graphics/cursor_icons/polygonselect_cursor.png b/assets/graphics/cursor_icons/polygonselect_cursor.png new file mode 100644 index 000000000..2dd92d75a Binary files /dev/null and b/assets/graphics/cursor_icons/polygonselect_cursor.png differ diff --git a/assets/graphics/cursor_icons/polygonselect_cursor.png.import b/assets/graphics/cursor_icons/polygonselect_cursor.png.import new file mode 100644 index 000000000..41c8a73fe --- /dev/null +++ b/assets/graphics/cursor_icons/polygonselect_cursor.png.import @@ -0,0 +1,13 @@ +[remap] + +importer="image" +type="Image" +path="res://.import/polygonselect_cursor.png-75834308db46d270a4fc7c38d5d978ac.image" + +[deps] + +source_file="res://assets/graphics/cursor_icons/polygonselect_cursor.png" +dest_files=[ "res://.import/polygonselect_cursor.png-75834308db46d270a4fc7c38d5d978ac.image" ] + +[params] + diff --git a/assets/graphics/dark_themes/tools/polygonselect.png b/assets/graphics/dark_themes/tools/polygonselect.png new file mode 100644 index 000000000..34d1b3618 Binary files /dev/null and b/assets/graphics/dark_themes/tools/polygonselect.png differ diff --git a/assets/graphics/dark_themes/tools/polygonselect.png.import b/assets/graphics/dark_themes/tools/polygonselect.png.import new file mode 100644 index 000000000..31ba44beb --- /dev/null +++ b/assets/graphics/dark_themes/tools/polygonselect.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/polygonselect.png-0c3075019f6acbc7e1ab495dbfbd82b3.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/graphics/dark_themes/tools/polygonselect.png" +dest_files=[ "res://.import/polygonselect.png-0c3075019f6acbc7e1ab495dbfbd82b3.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/assets/graphics/light_themes/tools/polygonselect.png b/assets/graphics/light_themes/tools/polygonselect.png new file mode 100644 index 000000000..f054ceac8 Binary files /dev/null and b/assets/graphics/light_themes/tools/polygonselect.png differ diff --git a/assets/graphics/light_themes/tools/polygonselect.png.import b/assets/graphics/light_themes/tools/polygonselect.png.import new file mode 100644 index 000000000..564be1e6b --- /dev/null +++ b/assets/graphics/light_themes/tools/polygonselect.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/polygonselect.png-53b426a7a45b4c3dd874336a05d66eda.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/graphics/light_themes/tools/polygonselect.png" +dest_files=[ "res://.import/polygonselect.png-53b426a7a45b4c3dd874336a05d66eda.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/project.godot b/project.godot index 478be171a..35781a47d 100644 --- a/project.godot +++ b/project.godot @@ -586,6 +586,16 @@ right_lasso_tool={ "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":true,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":70,"unicode":0,"echo":false,"script":null) ] } +left_polygon_select_tool={ +"deadzone": 0.5, +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":75,"unicode":0,"echo":false,"script":null) + ] +} +right_polygon_select_tool={ +"deadzone": 0.5, +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":true,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":75,"unicode":0,"echo":false,"script":null) + ] +} [locale] diff --git a/src/Autoload/Global.gd b/src/Autoload/Global.gd index a2453ff68..2d8d73d56 100644 --- a/src/Autoload/Global.gd +++ b/src/Autoload/Global.gd @@ -484,6 +484,13 @@ func update_hint_tooltips() -> void: %s for right mouse button""") % [InputMap.get_action_list("left_ellipse_select_tool")[0].as_text(), InputMap.get_action_list("right_ellipse_select_tool")[0].as_text()] + var polygon_select : BaseButton = tool_buttons.find_node("PolygonSelect") + polygon_select.hint_tooltip = tr("""Polygonal Selection + +%s for left mouse button +%s for right mouse button""") % [InputMap.get_action_list("left_polygon_select_tool")[0].as_text(), InputMap.get_action_list("right_polygon_select_tool")[0].as_text()] + + var color_select : BaseButton = tool_buttons.find_node("ColorSelect") color_select.hint_tooltip = tr("""Select By Color diff --git a/src/Autoload/Tools.gd b/src/Autoload/Tools.gd index f43a151a2..618f9bbd5 100644 --- a/src/Autoload/Tools.gd +++ b/src/Autoload/Tools.gd @@ -41,6 +41,7 @@ signal color_changed(color, button) var _tools = { "RectSelect" : "res://src/Tools/SelectionTools/RectSelect.tscn", "EllipseSelect" : "res://src/Tools/SelectionTools/EllipseSelect.tscn", + "PolygonSelect" : "res://src/Tools/SelectionTools/PolygonSelect.tscn", "ColorSelect" : "res://src/Tools/SelectionTools/ColorSelect.tscn", "MagicWand" : "res://src/Tools/SelectionTools/MagicWand.tscn", "Lasso" : "res://src/Tools/SelectionTools/Lasso.tscn", diff --git a/src/Tools/SelectionTools/PolygonSelect.gd b/src/Tools/SelectionTools/PolygonSelect.gd new file mode 100644 index 000000000..9a3c30df9 --- /dev/null +++ b/src/Tools/SelectionTools/PolygonSelect.gd @@ -0,0 +1,214 @@ +extends SelectionTool + + +var _last_position := Vector2.INF +var _draw_points := [] +var ready_to_apply := false + + +func _input(event : InputEvent) -> void: + ._input(event) + if _move: + return + if event is InputEventMouseMotion: + _last_position = Global.canvas.current_pixel.floor() + elif event is InputEventMouseButton: + if event.doubleclick and event.button_index == tool_slot.button and _draw_points: + $DoubleClickTimer.start() + append_gap(_draw_points[-1], _draw_points[0], _draw_points) + ready_to_apply = true + apply_selection(Vector2.ZERO) # Argument doesn't matter + + +func draw_start(position : Vector2) -> void: + if !$DoubleClickTimer.is_stopped(): + return + .draw_start(position) + if !_move and !_draw_points: + _ongoing_selection = true + _draw_points.append(position) + _last_position = position + + +func draw_move(position : Vector2) -> void: + if selection_node.arrow_key_move: + return + .draw_move(position) + + +func draw_end(position : Vector2) -> void: + if selection_node.arrow_key_move: + return + if !_move and _draw_points: + append_gap(_draw_points[-1], position, _draw_points) + if position == _draw_points[0] and _draw_points.size() > 1: + ready_to_apply = true + + .draw_end(position) + + +func draw_preview() -> void: + if _ongoing_selection and !_move: + var canvas : Node2D = Global.canvas.previews + var _position := canvas.position + var _scale := canvas.scale + if Global.mirror_view: + _position.x = _position.x + Global.current_project.size.x + _scale.x = -1 + + var preview_draw_points := _draw_points.duplicate() + append_gap(_draw_points[-1], _last_position, preview_draw_points) + + canvas.draw_set_transform(_position, canvas.rotation, _scale) + var indicator := _fill_bitmap_with_points(preview_draw_points, Global.current_project.size) + + for line in _create_polylines(indicator): + canvas.draw_polyline(PoolVector2Array(line), Color.black) + + var circle_radius := Global.camera.zoom * 10 + circle_radius.x = clamp(circle_radius.x, 2, circle_radius.x) + circle_radius.y = clamp(circle_radius.y, 2, circle_radius.y) + + if _last_position == _draw_points[0] and _draw_points.size() > 1: + draw_empty_circle(canvas, _draw_points[0] + Vector2.ONE * 0.5, circle_radius, Color.black) + + # Handle mirroring + if tool_slot.horizontal_mirror: + for line in _create_polylines(_fill_bitmap_with_points(mirror_array(preview_draw_points, true, false), Global.current_project.size)): + canvas.draw_polyline(PoolVector2Array(line), Color.black) + if tool_slot.vertical_mirror: + for line in _create_polylines(_fill_bitmap_with_points(mirror_array(preview_draw_points, true, true), Global.current_project.size)): + canvas.draw_polyline(PoolVector2Array(line), Color.black) + if tool_slot.vertical_mirror: + for line in _create_polylines(_fill_bitmap_with_points(mirror_array(preview_draw_points, false, true), Global.current_project.size)): + canvas.draw_polyline(PoolVector2Array(line), Color.black) + + canvas.draw_set_transform(canvas.position, canvas.rotation, canvas.scale) + + +func apply_selection(_position) -> void: + if !ready_to_apply: + return + var project : Project = Global.current_project + var cleared := false + if !_add and !_subtract and !_intersect: + cleared = true + Global.canvas.selection.clear_selection() + if _draw_points.size() > 3: + var selection_bitmap_copy : BitMap = project.selection_bitmap.duplicate() + var bitmap_size : Vector2 = selection_bitmap_copy.get_size() + if _intersect: + selection_bitmap_copy.set_bit_rect(Rect2(Vector2.ZERO, bitmap_size), false) + lasso_selection(selection_bitmap_copy, _draw_points) + + # Handle mirroring + if tool_slot.horizontal_mirror: + lasso_selection(selection_bitmap_copy, mirror_array(_draw_points, true, false)) + if tool_slot.vertical_mirror: + lasso_selection(selection_bitmap_copy, mirror_array(_draw_points, true, true)) + if tool_slot.vertical_mirror: + lasso_selection(selection_bitmap_copy, mirror_array(_draw_points, false, true)) + + project.selection_bitmap = selection_bitmap_copy + Global.canvas.selection.big_bounding_rectangle = project.get_selection_rectangle(project.selection_bitmap) + else: + if !cleared: + Global.canvas.selection.clear_selection() + + Global.canvas.selection.commit_undo("Rectangle Select", undo_data) + _ongoing_selection = false + _draw_points.clear() + ready_to_apply = false + Global.canvas.previews.update() + + +func lasso_selection(bitmap : BitMap, points : PoolVector2Array) -> void: + var project : Project = Global.current_project + var size := bitmap.get_size() + for point in points: + if point.x < 0 or point.y < 0 or point.x >= size.x or point.y >= size.y: + continue + if _intersect: + if project.selection_bitmap.get_bit(point): + bitmap.set_bit(point, true) + else: + bitmap.set_bit(point, !_subtract) + + var image = _get_draw_image() + var v := Vector2() + var image_size = image.get_size() + for x in image_size.x: + v.x = x + for y in image_size.y: + v.y = y + if Geometry.is_point_in_polygon(v, points): + if _intersect: + if project.selection_bitmap.get_bit(v): + bitmap.set_bit(v, true) + else: + bitmap.set_bit(v, !_subtract) + + +# Bresenham's Algorithm +# Thanks to https://godotengine.org/qa/35276/tile-based-line-drawing-algorithm-efficiency +func append_gap(start : Vector2, end : Vector2, array : Array) -> void: + var dx := int(abs(end.x - start.x)) + var dy := int(-abs(end.y - start.y)) + var err := dx + dy + var e2 := err << 1 + var sx = 1 if start.x < end.x else -1 + var sy = 1 if start.y < end.y else -1 + var x = start.x + var y = start.y + while !(x == end.x && y == end.y): + e2 = err << 1 + if e2 >= dy: + err += dy + x += sx + if e2 <= dx: + err += dx + y += sy + array.append(Vector2(x, y)) + + +func _fill_bitmap_with_points(points: Array, size: Vector2) -> BitMap: + var bitmap := BitMap.new() + bitmap.create(size) + + for point in points: + if point.x < 0 or point.y < 0 or point.x >= size.x or point.y >= size.y: + continue + bitmap.set_bit(point, 1) + + return bitmap + + +func mirror_array(array : Array, h : bool, v : bool) -> Array: + var new_array := [] + var project := Global.current_project + for point in array: + if h and v: + new_array.append(Vector2(project.x_symmetry_point - point.x, project.y_symmetry_point - point.y)) + elif h: + new_array.append(Vector2(project.x_symmetry_point - point.x, point.y)) + elif v: + new_array.append(Vector2(point.x, project.y_symmetry_point - point.y)) + + return new_array + + +# Thanks to https://www.reddit.com/r/godot/comments/3ktq39/drawing_empty_circles_and_curves/cv0f4eo/?utm_source=reddit&utm_medium=web2x&context=3 +func draw_empty_circle(canvas : CanvasItem, circle_center : Vector2, circle_radius : Vector2, color : Color) -> void: + var draw_counter := 1 + var line_origin := Vector2() + var line_end := Vector2() + line_origin = circle_radius + circle_center + + while draw_counter <= 360: + line_end = circle_radius.rotated(deg2rad(draw_counter)) + circle_center + canvas.draw_line(line_origin, line_end, color) + draw_counter += 1 + line_origin = line_end + + line_end = circle_radius.rotated(deg2rad(360)) + circle_center + canvas.draw_line(line_origin, line_end, color) diff --git a/src/Tools/SelectionTools/PolygonSelect.tscn b/src/Tools/SelectionTools/PolygonSelect.tscn new file mode 100644 index 000000000..737d9e8e6 --- /dev/null +++ b/src/Tools/SelectionTools/PolygonSelect.tscn @@ -0,0 +1,11 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://src/Tools/SelectionTools/SelectionTool.tscn" type="PackedScene" id=1] +[ext_resource path="res://src/Tools/SelectionTools/PolygonSelect.gd" type="Script" id=2] + +[node name="ToolOptions" instance=ExtResource( 1 )] +script = ExtResource( 2 ) + +[node name="DoubleClickTimer" type="Timer" parent="." index="11"] +wait_time = 0.1 +one_shot = true diff --git a/src/Tools/SelectionTools/SelectionTool.gd b/src/Tools/SelectionTools/SelectionTool.gd index 876eda351..0caafc847 100644 --- a/src/Tools/SelectionTools/SelectionTool.gd +++ b/src/Tools/SelectionTools/SelectionTool.gd @@ -5,6 +5,9 @@ var _move := false var _move_content := true var _start_pos := Vector2.ZERO var _offset := Vector2.ZERO +# For tools such as the Polygon selection tool where you have to +# click multiple times to create a selection +var _ongoing_selection := false var _add := false # Shift + Mouse Click var _subtract := false # Ctrl + Mouse Click @@ -71,7 +74,7 @@ func draw_start(position : Vector2) -> void: offsetted_pos.x -= selection_position.x if selection_position.y < 0: offsetted_pos.y -= selection_position.y - if offsetted_pos.x >= 0 and offsetted_pos.y >= 0 and project.selection_bitmap.get_bit(offsetted_pos) and (!Tools.control or Tools.alt) and !Tools.shift: + if offsetted_pos.x >= 0 and offsetted_pos.y >= 0 and project.selection_bitmap.get_bit(offsetted_pos) and (!Tools.control or Tools.alt) and !Tools.shift and !_ongoing_selection: # Move current selection _move = true if Tools.control and Tools.alt: # Move selection without content diff --git a/src/UI/ToolButtons.gd b/src/UI/ToolButtons.gd index 1ab337807..e7e65a7a8 100644 --- a/src/UI/ToolButtons.gd +++ b/src/UI/ToolButtons.gd @@ -5,6 +5,7 @@ extends GridContainer onready var tools := [ [$RectSelect, "rectangle_select"], [$EllipseSelect, "ellipse_select"], + [$PolygonSelect, "polygon_select"], [$ColorSelect, "color_select"], [$MagicWand, "magic_wand"], [$Lasso, "lasso"], diff --git a/src/UI/UI.tscn b/src/UI/UI.tscn index 142d280d5..c1a4f5798 100644 --- a/src/UI/UI.tscn +++ b/src/UI/UI.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=36 format=2] +[gd_scene load_steps=37 format=2] [ext_resource path="res://src/UI/ToolButtons.gd" type="Script" id=1] [ext_resource path="res://src/UI/Canvas/CanvasPreview.tscn" type="PackedScene" id=2] @@ -32,6 +32,7 @@ [ext_resource path="res://assets/graphics/dark_themes/tools/linetool.png" type="Texture" id=30] [ext_resource path="res://assets/graphics/dark_themes/tools/ellipseselect.png" type="Texture" id=31] [ext_resource path="res://assets/graphics/dark_themes/tools/lasso.png" type="Texture" id=32] +[ext_resource path="res://assets/graphics/dark_themes/tools/polygonselect.png" type="Texture" id=33] [sub_resource type="ShaderMaterial" id=1] shader = ExtResource( 9 ) @@ -96,7 +97,7 @@ __meta__ = { margin_left = 7.0 margin_top = 7.0 margin_right = 39.0 -margin_bottom = 579.0 +margin_bottom = 615.0 size_flags_horizontal = 4 size_flags_vertical = 0 script = ExtResource( 1 ) @@ -150,7 +151,7 @@ __meta__ = { "_edit_use_anchors_": false } -[node name="ColorSelect" type="Button" parent="ToolsAndCanvas/ToolPanel/PanelContainer/ToolButtons" groups=[ +[node name="PolygonSelect" type="Button" parent="ToolsAndCanvas/ToolPanel/PanelContainer/ToolButtons" groups=[ "UIButtons", ]] margin_top = 72.0 @@ -160,6 +161,31 @@ rect_min_size = Vector2( 32, 32 ) mouse_default_cursor_shape = 2 button_mask = 3 +[node name="Background" type="TextureRect" parent="ToolsAndCanvas/ToolPanel/PanelContainer/ToolButtons/PolygonSelect"] +margin_right = 32.0 +margin_bottom = 32.0 +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="ToolIcon" type="TextureRect" parent="ToolsAndCanvas/ToolPanel/PanelContainer/ToolButtons/PolygonSelect"] +margin_right = 32.0 +margin_bottom = 32.0 +texture = ExtResource( 33 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="ColorSelect" type="Button" parent="ToolsAndCanvas/ToolPanel/PanelContainer/ToolButtons" groups=[ +"UIButtons", +]] +margin_top = 108.0 +margin_right = 32.0 +margin_bottom = 140.0 +rect_min_size = Vector2( 32, 32 ) +mouse_default_cursor_shape = 2 +button_mask = 3 + [node name="Background" type="TextureRect" parent="ToolsAndCanvas/ToolPanel/PanelContainer/ToolButtons/ColorSelect"] margin_right = 32.0 margin_bottom = 32.0 @@ -178,9 +204,9 @@ __meta__ = { [node name="MagicWand" type="Button" parent="ToolsAndCanvas/ToolPanel/PanelContainer/ToolButtons" groups=[ "UIButtons", ]] -margin_top = 108.0 +margin_top = 144.0 margin_right = 32.0 -margin_bottom = 140.0 +margin_bottom = 176.0 rect_min_size = Vector2( 32, 32 ) mouse_default_cursor_shape = 2 button_mask = 3 @@ -203,9 +229,9 @@ __meta__ = { [node name="Lasso" type="Button" parent="ToolsAndCanvas/ToolPanel/PanelContainer/ToolButtons" groups=[ "UIButtons", ]] -margin_top = 144.0 +margin_top = 180.0 margin_right = 32.0 -margin_bottom = 176.0 +margin_bottom = 212.0 rect_min_size = Vector2( 32, 32 ) mouse_default_cursor_shape = 2 button_mask = 3 @@ -228,9 +254,9 @@ __meta__ = { [node name="Move" type="Button" parent="ToolsAndCanvas/ToolPanel/PanelContainer/ToolButtons" groups=[ "UIButtons", ]] -margin_top = 180.0 +margin_top = 216.0 margin_right = 32.0 -margin_bottom = 212.0 +margin_bottom = 248.0 rect_min_size = Vector2( 32, 32 ) mouse_default_cursor_shape = 2 button_mask = 3 @@ -253,9 +279,9 @@ __meta__ = { [node name="Zoom" type="Button" parent="ToolsAndCanvas/ToolPanel/PanelContainer/ToolButtons" groups=[ "UIButtons", ]] -margin_top = 216.0 +margin_top = 252.0 margin_right = 32.0 -margin_bottom = 248.0 +margin_bottom = 284.0 rect_min_size = Vector2( 32, 32 ) mouse_default_cursor_shape = 2 button_mask = 3 @@ -278,9 +304,9 @@ __meta__ = { [node name="Pan" type="Button" parent="ToolsAndCanvas/ToolPanel/PanelContainer/ToolButtons" groups=[ "UIButtons", ]] -margin_top = 252.0 +margin_top = 288.0 margin_right = 32.0 -margin_bottom = 284.0 +margin_bottom = 320.0 rect_min_size = Vector2( 32, 32 ) mouse_default_cursor_shape = 2 button_mask = 3 @@ -303,9 +329,9 @@ __meta__ = { [node name="ColorPicker" type="Button" parent="ToolsAndCanvas/ToolPanel/PanelContainer/ToolButtons" groups=[ "UIButtons", ]] -margin_top = 288.0 +margin_top = 324.0 margin_right = 32.0 -margin_bottom = 320.0 +margin_bottom = 356.0 rect_min_size = Vector2( 32, 32 ) mouse_default_cursor_shape = 2 button_mask = 3 @@ -328,9 +354,9 @@ __meta__ = { [node name="Pencil" type="Button" parent="ToolsAndCanvas/ToolPanel/PanelContainer/ToolButtons" groups=[ "UIButtons", ]] -margin_top = 324.0 +margin_top = 360.0 margin_right = 32.0 -margin_bottom = 356.0 +margin_bottom = 392.0 rect_min_size = Vector2( 32, 32 ) mouse_default_cursor_shape = 2 button_mask = 3 @@ -354,9 +380,9 @@ __meta__ = { [node name="Eraser" type="Button" parent="ToolsAndCanvas/ToolPanel/PanelContainer/ToolButtons" groups=[ "UIButtons", ]] -margin_top = 360.0 +margin_top = 396.0 margin_right = 32.0 -margin_bottom = 392.0 +margin_bottom = 428.0 rect_min_size = Vector2( 32, 32 ) mouse_default_cursor_shape = 2 button_mask = 3 @@ -380,9 +406,9 @@ __meta__ = { [node name="Bucket" type="Button" parent="ToolsAndCanvas/ToolPanel/PanelContainer/ToolButtons" groups=[ "UIButtons", ]] -margin_top = 396.0 +margin_top = 432.0 margin_right = 32.0 -margin_bottom = 428.0 +margin_bottom = 464.0 rect_min_size = Vector2( 32, 32 ) mouse_default_cursor_shape = 2 button_mask = 3 @@ -405,9 +431,9 @@ __meta__ = { [node name="LightenDarken" type="Button" parent="ToolsAndCanvas/ToolPanel/PanelContainer/ToolButtons" groups=[ "UIButtons", ]] -margin_top = 432.0 +margin_top = 468.0 margin_right = 32.0 -margin_bottom = 464.0 +margin_bottom = 500.0 rect_min_size = Vector2( 32, 32 ) mouse_default_cursor_shape = 2 button_mask = 3 @@ -430,9 +456,9 @@ __meta__ = { [node name="LineTool" type="Button" parent="ToolsAndCanvas/ToolPanel/PanelContainer/ToolButtons" groups=[ "UIButtons", ]] -margin_top = 468.0 +margin_top = 504.0 margin_right = 32.0 -margin_bottom = 500.0 +margin_bottom = 536.0 rect_min_size = Vector2( 32, 32 ) mouse_default_cursor_shape = 2 button_mask = 3 @@ -455,9 +481,9 @@ __meta__ = { [node name="RectangleTool" type="Button" parent="ToolsAndCanvas/ToolPanel/PanelContainer/ToolButtons" groups=[ "UIButtons", ]] -margin_top = 504.0 +margin_top = 540.0 margin_right = 32.0 -margin_bottom = 536.0 +margin_bottom = 572.0 rect_min_size = Vector2( 32, 32 ) mouse_default_cursor_shape = 2 button_mask = 3 @@ -480,9 +506,9 @@ __meta__ = { [node name="EllipseTool" type="Button" parent="ToolsAndCanvas/ToolPanel/PanelContainer/ToolButtons" groups=[ "UIButtons", ]] -margin_top = 540.0 +margin_top = 576.0 margin_right = 32.0 -margin_bottom = 572.0 +margin_bottom = 608.0 rect_min_size = Vector2( 32, 32 ) mouse_default_cursor_shape = 2 button_mask = 3