1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-01-18 17:19:50 +00:00

Added lasso / free select tool

Temporary icon, probably. Should work without problems, but more testing would be nice.
This commit is contained in:
Manolis Papadeas 2021-05-16 03:52:13 +03:00
parent 909f9480cc
commit b8d055fe01
15 changed files with 355 additions and 23 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/lasso.png-2d7bb4691ebff786d4d5b222e66bbf1a.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/blue_themes/tools/lasso.png"
dest_files=[ "res://.import/lasso.png-2d7bb4691ebff786d4d5b222e66bbf1a.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

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

View file

@ -0,0 +1,13 @@
[remap]
importer="image"
type="Image"
path="res://.import/lasso_cursor.png-f521b7296434da45c8ee9811a0a897a8.image"
[deps]
source_file="res://assets/graphics/cursor_icons/lasso_cursor.png"
dest_files=[ "res://.import/lasso_cursor.png-f521b7296434da45c8ee9811a0a897a8.image" ]
[params]

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/lasso.png-c0e22b291252cddaf44d885fa1a874e9.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/dark_themes/tools/lasso.png"
dest_files=[ "res://.import/lasso.png-c0e22b291252cddaf44d885fa1a874e9.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

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/lasso.png-7f6bc6d622f35bb308d3e3f86a3a2b30.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/graphics/light_themes/tools/lasso.png"
dest_files=[ "res://.import/lasso.png-7f6bc6d622f35bb308d3e3f86a3a2b30.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

View file

@ -576,6 +576,16 @@ right_ellipse_select_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":89,"unicode":0,"echo":false,"script":null)
]
}
left_lasso_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":70,"unicode":0,"echo":false,"script":null)
]
}
right_lasso_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":70,"unicode":0,"echo":false,"script":null)
]
}
[locale]

View file

@ -498,6 +498,13 @@ func update_hint_tooltips() -> void:
%s for right mouse button""") % [InputMap.get_action_list("left_magic_wand_tool")[0].as_text(), InputMap.get_action_list("right_magic_wand_tool")[0].as_text()]
var lasso : BaseButton = tool_buttons.find_node("Lasso")
lasso.hint_tooltip = tr("""Lasso / Free Select Tool
%s for left mouse button
%s for right mouse button""") % [InputMap.get_action_list("left_lasso_tool")[0].as_text(), InputMap.get_action_list("right_lasso_tool")[0].as_text()]
var move_select : BaseButton = tool_buttons.find_node("Move")
move_select.hint_tooltip = tr("""Move

View file

@ -43,6 +43,7 @@ var _tools = {
"EllipseSelect" : "res://src/Tools/SelectionTools/EllipseSelect.tscn",
"ColorSelect" : "res://src/Tools/SelectionTools/ColorSelect.tscn",
"MagicWand" : "res://src/Tools/SelectionTools/MagicWand.tscn",
"Lasso" : "res://src/Tools/SelectionTools/Lasso.tscn",
"Move" : "res://src/Tools/Move.tscn",
"Zoom" : "res://src/Tools/Zoom.tscn",
"Pan" : "res://src/Tools/Pan.tscn",

View file

@ -0,0 +1,165 @@
extends SelectionTool
var _last_position := Vector2.INF
var _draw_points := []
func draw_start(position : Vector2) -> void:
.draw_start(position)
if !_move:
_draw_points.append(position)
_last_position = position
func draw_move(position : Vector2) -> void:
if selection_node.arrow_key_move:
return
.draw_move(position)
if !_move:
append_gap(_last_position, position)
_last_position = position
_draw_points.append(position)
_offset = position
func draw_end(position : Vector2) -> void:
if selection_node.arrow_key_move:
return
if !_move:
_draw_points.append(position)
.draw_end(position)
func draw_preview() -> void:
if !_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
canvas.draw_set_transform(_position, canvas.rotation, _scale)
var indicator := _fill_bitmap_with_points(_draw_points, Global.current_project.size)
for line in _create_polylines(indicator):
canvas.draw_polyline(PoolVector2Array(line), Color.black)
# Handle mirroring
if tool_slot.horizontal_mirror:
for line in _create_polylines(_fill_bitmap_with_points(mirror_array(_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(_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(_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:
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)
_draw_points.clear()
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) -> 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
_draw_points.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

View file

@ -0,0 +1,7 @@
[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/Lasso.gd" type="Script" id=2]
[node name="ToolOptions" instance=ExtResource( 1 )]
script = ExtResource( 2 )

View file

@ -7,6 +7,7 @@ onready var tools := [
[$EllipseSelect, "ellipse_select"],
[$ColorSelect, "color_select"],
[$MagicWand, "magic_wand"],
[$Lasso, "lasso"],
[$Move, "move"],
[$Zoom, "zoom"],
[$Pan, "pan"],

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=35 format=2]
[gd_scene load_steps=36 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]
@ -31,6 +31,7 @@
[ext_resource path="res://assets/graphics/dark_themes/tools/magicwand.png" type="Texture" id=29]
[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]
[sub_resource type="ShaderMaterial" id=1]
shader = ExtResource( 9 )
@ -95,7 +96,7 @@ __meta__ = {
margin_left = 7.0
margin_top = 7.0
margin_right = 39.0
margin_bottom = 543.0
margin_bottom = 579.0
size_flags_horizontal = 4
size_flags_vertical = 0
script = ExtResource( 1 )
@ -199,7 +200,7 @@ __meta__ = {
"_edit_use_anchors_": false
}
[node name="Move" type="Button" parent="ToolsAndCanvas/ToolPanel/PanelContainer/ToolButtons" groups=[
[node name="Lasso" type="Button" parent="ToolsAndCanvas/ToolPanel/PanelContainer/ToolButtons" groups=[
"UIButtons",
]]
margin_top = 144.0
@ -209,6 +210,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/Lasso"]
margin_right = 32.0
margin_bottom = 32.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="ToolIcon" type="TextureRect" parent="ToolsAndCanvas/ToolPanel/PanelContainer/ToolButtons/Lasso"]
margin_right = 32.0
margin_bottom = 32.0
texture = ExtResource( 32 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Move" type="Button" parent="ToolsAndCanvas/ToolPanel/PanelContainer/ToolButtons" groups=[
"UIButtons",
]]
margin_top = 180.0
margin_right = 32.0
margin_bottom = 212.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/Move"]
margin_right = 32.0
margin_bottom = 32.0
@ -227,9 +253,9 @@ __meta__ = {
[node name="Zoom" 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
@ -252,9 +278,9 @@ __meta__ = {
[node name="Pan" 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
@ -277,9 +303,9 @@ __meta__ = {
[node name="ColorPicker" 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
@ -302,9 +328,9 @@ __meta__ = {
[node name="Pencil" 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="Eraser" 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="Bucket" 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
@ -379,9 +405,9 @@ __meta__ = {
[node name="LightenDarken" 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
@ -404,9 +430,9 @@ __meta__ = {
[node name="LineTool" 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
@ -429,9 +455,9 @@ __meta__ = {
[node name="RectangleTool" 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
@ -454,9 +480,9 @@ __meta__ = {
[node name="EllipseTool" 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