Skip to content

Commit

Permalink
Improve handle syncing (#873)
Browse files Browse the repository at this point in the history
  • Loading branch information
MewPurPur authored Aug 21, 2024
1 parent a20b0c9 commit f232c8b
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 44 deletions.
11 changes: 6 additions & 5 deletions src/ui_parts/PathHandle.gd
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,22 @@ var command_index: int
var x_param: String
var y_param: String

func _init(new_element: Element, command_idx: int, x_name := "x", y_name := "y") -> void:

func _init(new_element: Element, command_idx: int, x_name: String, y_name: String) -> void:
element = new_element
command_index = command_idx
x_param = x_name
y_param = y_name
sync()

func set_pos(new_pos: Vector2) -> void:
var path_attribute: AttributePathdata = element.get_attribute(pathdata_name)
var command := path_attribute.get_command(command_index)
var new_coords := new_pos - command.start if command.relative else new_pos
if pos != new_pos:
pos = new_pos
var path_attribute: AttributePathdata = element.get_attribute(pathdata_name)
var command := path_attribute.get_command(command_index)
var new_coords := new_pos - command.start if command.relative else new_pos
path_attribute.set_command_property(command_index, x_param, new_coords.x)
path_attribute.set_command_property(command_index, y_param, new_coords.y)
sync()


func sync() -> void:
Expand Down
9 changes: 7 additions & 2 deletions src/ui_parts/XYHandle.gd
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,24 @@ class_name XYHandle extends Handle

var x_name: String
var y_name: String
var attached_handles: Array[Handle]

func _init(new_element: Element, xref: String, yref: String) -> void:
func _init(new_element: Element, xref: String, yref: String,
new_attached_handles: Array[Handle] = []) -> void:
element = new_element
x_name = xref
y_name = yref
attached_handles = new_attached_handles
sync()

func set_pos(new_pos: Vector2) -> void:
if pos != new_pos:
pos = new_pos
element.set_attribute(x_name, new_pos.x)
element.set_attribute(y_name, new_pos.y)
sync()

func sync() -> void:
pos = Vector2(element.get_attribute_num(x_name), element.get_attribute_num(y_name))
for handle in attached_handles:
handle.sync()
super()
78 changes: 41 additions & 37 deletions src/ui_parts/handles_manager.gd
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,7 @@ func _ready() -> void:
c.material = stroke_material
add_child(c, false, InternalMode.INTERNAL_MODE_BACK)

SVG.any_attribute_changed.connect(queue_redraw.unbind(1))
SVG.any_attribute_changed.connect(sync_handles.unbind(1))
SVG.any_attribute_changed.connect(sync_handles)
SVG.elements_layout_changed.connect(queue_update)
SVG.changed_unknown.connect(queue_update)
Indications.selection_changed.connect(queue_redraw)
Expand All @@ -111,22 +110,29 @@ func _process(_delta: float) -> void:
update_handles()
update_pending = false


func update_handles() -> void:
handles.clear()
for element in SVG.root_element.get_all_elements():
match element.name:
"circle":
handles.append(XYHandle.new(element, "cx", "cy"))
handles.append(DeltaHandle.new(element, "cx", "cy", "r", true))
var delta_handle := DeltaHandle.new(element, "cx", "cy", "r", true)
var delta_handle_arr: Array[Handle] = [delta_handle]
handles.append(XYHandle.new(element, "cx", "cy", delta_handle_arr))
handles.append(delta_handle)
"ellipse":
handles.append(XYHandle.new(element, "cx", "cy"))
handles.append(DeltaHandle.new(element, "cx", "cy", "rx", true))
handles.append(DeltaHandle.new(element, "cx", "cy", "ry", false))
var delta_handle_1 := DeltaHandle.new(element, "cx", "cy", "rx", true)
var delta_handle_2 := DeltaHandle.new(element, "cx", "cy", "ry", false)
var delta_handle_arr: Array[Handle] = [delta_handle_1, delta_handle_2]
handles.append(XYHandle.new(element, "cx", "cy", delta_handle_arr))
handles.append(delta_handle_1)
handles.append(delta_handle_2)
"rect":
handles.append(XYHandle.new(element, "x", "y"))
handles.append(DeltaHandle.new(element, "x", "y", "width", true))
handles.append(DeltaHandle.new(element, "x", "y", "height", false))
var delta_handle_1 := DeltaHandle.new(element, "x", "y", "width", true)
var delta_handle_2 := DeltaHandle.new(element, "x", "y", "height", false)
var delta_handle_arr: Array[Handle] = [delta_handle_1, delta_handle_2]
handles.append(XYHandle.new(element, "x", "y", delta_handle_arr))
handles.append(delta_handle_1)
handles.append(delta_handle_2)
"line":
handles.append(XYHandle.new(element, "x1", "y1"))
handles.append(XYHandle.new(element, "x2", "y2"))
Expand All @@ -136,38 +142,36 @@ func update_handles() -> void:
Utils.throw_mouse_motion_event()
queue_redraw()


func sync_handles() -> void:
# For XYHandles, sync them. For PathHandles, they can be added and removed as an
# attribute changes, so remove them and re-add them except for the dragged one.
for handle_idx in range(handles.size() - 1, -1, -1):
var handle := handles[handle_idx]
if handle is PathHandle:
if dragged_handle != handle:
handles.remove_at(handle_idx)
else:
handle.sync()
func sync_handles(xid: PackedInt32Array) -> void:
var element := SVG.root_element.get_element(xid)
if not element is ElementPath:
return

for element in SVG.root_element.get_all_elements():
if element.name == "path":
handles += generate_path_handles(element)
var new_handles: Array[Handle] = []
for handle in handles:
if handle.element != element:
new_handles.append(handle)
handles = new_handles
handles += generate_path_handles(element)
queue_redraw()

func generate_path_handles(element: Element) -> Array[Handle]:
var path_handles: Array[Handle] = []
var data_attrib: AttributePathdata = element.get_attribute("d")
for idx in data_attrib.get_command_count():
var path_handles: Array[Handle] = []
for idx in range(data_attrib.get_command_count() - 1, -1, -1):
var path_command := data_attrib.get_command(idx)
if not path_command.command_char in "Zz":
path_handles.append(PathHandle.new(element, idx))
if path_command.command_char in "CcQq":
var tangent := PathHandle.new(element, idx, "x1", "y1")
tangent.display_mode = Handle.Display.SMALL
path_handles.append(tangent)
if path_command.command_char in "CcSs":
var tangent := PathHandle.new(element, idx, "x2", "y2")
tangent.display_mode = Handle.Display.SMALL
path_handles.append(tangent)
if path_command.command_char in "Zz":
continue

if path_command.command_char in "CcQq":
var tangent := PathHandle.new(element, idx, "x1", "y1")
tangent.display_mode = Handle.Display.SMALL
path_handles.append(tangent)
if path_command.command_char in "CcSs":
var tangent := PathHandle.new(element, idx, "x2", "y2")
tangent.display_mode = Handle.Display.SMALL
path_handles.append(tangent)
path_handles.append(PathHandle.new(element, idx, "x", "y"))
return path_handles


Expand Down

0 comments on commit f232c8b

Please sign in to comment.