Skip to content

Commit

Permalink
Implement Convert To in path commands
Browse files Browse the repository at this point in the history
  • Loading branch information
MewPurPur committed Nov 28, 2023
1 parent 3f92ce6 commit da2848e
Show file tree
Hide file tree
Showing 29 changed files with 253 additions and 95 deletions.
4 changes: 3 additions & 1 deletion project.godot
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ config/tags=PackedStringArray("project")
run/main_scene="res://src/ui_parts/main_scene.tscn"
config/features=PackedStringArray("4.2", "Forward Plus")
run/low_processor_mode=true
boot_splash/bg_color=Color(0.123, 0.1275, 0.15, 1)
boot_splash/bg_color=Color(0.1065, 0.1181, 0.15, 1)
boot_splash/image="res://visual/splash.png"
boot_splash/fullsize=false
config/icon="res://visual/icon.png"

[audio]
Expand Down
23 changes: 18 additions & 5 deletions src/Utils.gd
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ static func defocus_control_on_outside_click(control: Control, event: InputEvent
not control.get_global_rect().has_point(event.position)):
control.release_focus()

static func popup_under_control(popup: Popup, control: Control, center := false) -> void:
static func popup_under_control(popup: Popup, control: Control) -> void:
var screen_h := control.get_viewport_rect().size.y
var popup_pos := Vector2.ZERO
var true_global_pos = control.global_position
Expand All @@ -171,17 +171,30 @@ static func popup_under_control(popup: Popup, control: Control, center := false)
popup_pos.y = true_global_pos.y + control.size.y
else:
popup_pos.y = true_global_pos.y - popup.size.y
# Align horizontally.
if center:
popup_pos.x = true_global_pos.x - popup.size.x / 2.0 + control.size.x / 2
# Horizontal alignment and other things.
popup_pos.x = true_global_pos.x
popup_pos += control.get_viewport().get_screen_transform().get_origin()
popup.popup(Rect2(popup_pos, popup.size))

static func popup_under_control_centered(popup: Popup, control: Control) -> void:
var screen_h := control.get_viewport_rect().size.y
var popup_pos := Vector2.ZERO
var true_global_pos = control.global_position
# Popup below if there's enough space or we're in the bottom half of the screen.
if true_global_pos.y + control.size.y + popup.size.y < screen_h or\
true_global_pos.y + control.size.y / 2 <= screen_h / 2.0:
popup_pos.y = true_global_pos.y + control.size.y
else:
popup_pos.x = true_global_pos.x
popup_pos.y = true_global_pos.y - popup.size.y
# Align horizontally and other things.
popup_pos.x = true_global_pos.x - popup.size.x / 2.0 + control.size.x / 2
popup_pos += control.get_viewport().get_screen_transform().get_origin()
popup.popup(Rect2(popup_pos, popup.size))

static func popup_under_mouse(popup: Popup, mouse_pos: Vector2) -> void:
popup.popup(Rect2(mouse_pos + Vector2(-popup.size.x / 2, 0), popup.size))


static func get_cubic_bezier_points(cp1: Vector2, cp2: Vector2,
cp3: Vector2, cp4: Vector2) -> PackedVector2Array:
var curve := Curve2D.new()
Expand Down
42 changes: 39 additions & 3 deletions src/data_classes/AttributePath.gd
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,56 @@ func insert_command(idx: int, command_char: String) -> void:
if Utils.is_string_lower(command_char):
commands[idx].toggle_relative()
locate_start_points()
command_changed.emit()
command_changed.emit(SyncMode.LOUD)

func convert_command(idx: int, command_char: String) -> void:
var old_command: PathCommand = commands[idx]
if old_command.command_char == command_char:
return

var new_command: PathCommand = PathCommand.translation_dict[command_char].new()
commands.remove_at(idx)
commands.insert(idx, new_command)
for property in [&"x", &"y", &"x1", &"y1", &"x2", &"y2"]:
if property in old_command and property in new_command:
new_command[property] = old_command[property]

if &"x" in new_command and not &"x" in old_command:
new_command.x = old_command.start.x
if &"y" in new_command and not &"y" in old_command:
new_command.y = old_command.start.y

locate_start_points()
if command_char == "C":
new_command.x1 = lerpf(new_command.start.x, new_command.x, 1/3.0)
new_command.y1 = lerpf(new_command.start.y, new_command.y, 1/3.0)
new_command.x2 = lerpf(new_command.start.x, new_command.x, 2/3.0)
new_command.y2 = lerpf(new_command.start.y, new_command.y, 2/3.0)
elif command_char == "c":
new_command.x1 = lerpf(new_command.start.x, new_command.x, 1/3.0)
new_command.y1 = lerpf(new_command.start.y, new_command.y, 1/3.0)
new_command.x2 = lerpf(new_command.start.x, new_command.x, 2/3.0)
new_command.y2 = lerpf(new_command.start.y, new_command.y, 2/3.0)

if Utils.is_string_lower(command_char):
commands[idx].toggle_relative()
command_changed.emit(SyncMode.LOUD)

func delete_commands(indices: Array[int]) -> void:
if indices.is_empty():
return

indices = indices.duplicate()
indices.sort()
indices.reverse()
for idx in indices:
commands.remove_at(idx)
locate_start_points()
command_changed.emit()
command_changed.emit(SyncMode.LOUD)

func toggle_relative_command(idx: int) -> void:
commands[idx].toggle_relative()
command_changed.emit()
command_changed.emit(SyncMode.LOUD)

func set_value(path_string: Variant, sync_mode := SyncMode.LOUD) -> void:
commands = PathDataParser.parse_path_data(path_string)
Expand Down
5 changes: 0 additions & 5 deletions src/ui_elements/BetterLineEdit.gd
Original file line number Diff line number Diff line change
Expand Up @@ -69,35 +69,30 @@ func _on_gui_input(event: InputEvent) -> void:

var undo_button := Button.new()
undo_button.text = tr(&"#undo")
undo_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
undo_button.alignment = HORIZONTAL_ALIGNMENT_LEFT
undo_button.pressed.connect(menu_option.bind(LineEdit.MENU_UNDO))
btn_arr.append(undo_button)

var redo_button := Button.new()
redo_button.text = tr(&"#redo")
redo_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
redo_button.alignment = HORIZONTAL_ALIGNMENT_LEFT
redo_button.pressed.connect(menu_option.bind(LineEdit.MENU_REDO))
btn_arr.append(redo_button)

var copy_button := Button.new()
copy_button.text = tr(&"#copy")
copy_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
copy_button.alignment = HORIZONTAL_ALIGNMENT_LEFT
copy_button.pressed.connect(menu_option.bind(LineEdit.MENU_COPY))
btn_arr.append(copy_button)

var paste_button := Button.new()
paste_button.text = tr(&"#paste")
paste_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
paste_button.alignment = HORIZONTAL_ALIGNMENT_LEFT
paste_button.pressed.connect(menu_option.bind(LineEdit.MENU_PASTE))
btn_arr.append(paste_button)

var cut_button := Button.new()
cut_button.text = tr(&"#cut")
cut_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
cut_button.alignment = HORIZONTAL_ALIGNMENT_LEFT
cut_button.pressed.connect(menu_option.bind(LineEdit.MENU_CUT))
btn_arr.append(cut_button)
Expand Down
14 changes: 2 additions & 12 deletions src/ui_elements/BetterTextEdit.gd
Original file line number Diff line number Diff line change
Expand Up @@ -58,44 +58,34 @@ func _on_gui_input(event: InputEvent) -> void:

var undo_button := Button.new()
undo_button.text = tr(&"#undo")
if has_undo():
undo_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
else:
if not has_undo():
undo_button.disabled = true
undo_button.mouse_default_cursor_shape = Control.CURSOR_ARROW
undo_button.alignment = HORIZONTAL_ALIGNMENT_LEFT
undo_button.pressed.connect(undo)
btn_arr.append(undo_button)

var redo_button := Button.new()
redo_button.text = tr(&"#redo")
if has_redo():
redo_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
else:
if not has_redo():
redo_button.disabled = true
redo_button.mouse_default_cursor_shape = Control.CURSOR_ARROW
redo_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
redo_button.alignment = HORIZONTAL_ALIGNMENT_LEFT
redo_button.pressed.connect(redo)
btn_arr.append(redo_button)

var copy_button := Button.new()
copy_button.text = tr(&"#copy")
copy_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
copy_button.alignment = HORIZONTAL_ALIGNMENT_LEFT
copy_button.pressed.connect(copy)
btn_arr.append(copy_button)

var paste_button := Button.new()
paste_button.text = tr(&"#paste")
paste_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
paste_button.alignment = HORIZONTAL_ALIGNMENT_LEFT
paste_button.pressed.connect(paste)
btn_arr.append(paste_button)

var cut_button := Button.new()
cut_button.text = tr(&"#cut")
cut_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
cut_button.alignment = HORIZONTAL_ALIGNMENT_LEFT
cut_button.pressed.connect(cut)
btn_arr.append(cut_button)
Expand Down
3 changes: 3 additions & 0 deletions src/ui_elements/context_popup.gd
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ func add_button(butt: Button, should_reset_size := true) -> void:
butt.add_theme_stylebox_override(&"disabled", disabled_stylebox)
butt.add_theme_stylebox_override(&"pressed", pressed_stylebox)
butt.pressed.connect(queue_free)
if not butt.disabled:
butt.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
butt.focus_mode = Control.FOCUS_NONE
main_container.add_child(butt)
if should_reset_size:
reset_size()
Expand Down
3 changes: 2 additions & 1 deletion src/ui_elements/dropdown.gd
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ func _on_button_pressed() -> void:
var button := Button.new()
button.text = value
button.pressed.connect(_on_value_chosen.bind(value))
button.mouse_default_cursor_shape = CURSOR_POINTING_HAND
button.alignment = HORIZONTAL_ALIGNMENT_CENTER
if value == current_value:
button.disabled = true
btn_arr.append(button)

var value_picker := ContextPopup.instantiate()
Expand Down
2 changes: 0 additions & 2 deletions src/ui_elements/enum_field.gd
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ func _on_button_pressed() -> void:
btn.pressed.connect(_on_option_pressed.bind(enum_constant))
if enum_constant == get_value():
btn.disabled = true
else:
btn.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
if attribute != null and enum_constant == attribute.default:
btn.add_theme_font_override(&"font", bold_font)
buttons_arr.append(btn)
Expand Down
39 changes: 31 additions & 8 deletions src/ui_elements/path_command_editor.gd
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ signal cmd_update_value(idx: int, new_value: float, property: StringName)
signal cmd_delete(idx: int)
signal cmd_toggle_relative(idx: int)
signal cmd_insert_after(idx: int, cmd_char: String)
signal cmd_convert_to(idx: int, cmd_char: String)

const ContextPopup = preload("res://src/ui_elements/context_popup.tscn")
const MiniNumberField = preload("mini_number_field.tscn")
const FlagField = preload("flag_field.tscn")
const PathCommandPopup = preload("path_command_popup.tscn")
const PathCommandPopup = preload("path_popup.tscn")

var tid := PackedInt32Array()
var cmd_char := ""
Expand Down Expand Up @@ -171,9 +172,22 @@ func toggle_relative() -> void:
func insert_after() -> void:
var command_picker := PathCommandPopup.instantiate()
add_child(command_picker)
command_picker.disable_invalid(cmd_char)
command_picker.path_command_picked.connect(_on_path_command_picked)
Utils.popup_under_control(command_picker, more_button, true)
match cmd_char.to_upper():
"M": command_picker.disable_invalid(["M", "Z", "T"])
"Z": command_picker.disable_invalid(["Z"])
"L", "H", "V", "A": command_picker.disable_invalid(["S", "T"])
"C", "S": command_picker.disable_invalid(["T"])
"Q", "T": command_picker.disable_invalid(["S"])
command_picker.path_command_picked.connect(_on_insert_path_command_picked)
Utils.popup_under_control_centered(command_picker, more_button)

func convert_to() -> void:
var command_picker := PathCommandPopup.instantiate()
add_child(command_picker)
command_picker.force_relativity(Utils.is_string_lower(cmd_char))
command_picker.disable_invalid([cmd_char.to_upper()])
command_picker.path_command_picked.connect(_on_convert_path_command_picked)
Utils.popup_under_control_centered(command_picker, more_button)

func open_actions(popup_from_mouse := false) -> void:
Indications.normal_select(tid, cmd_idx)
Expand All @@ -183,25 +197,31 @@ func open_actions(popup_from_mouse := false) -> void:
var delete_btn := Button.new()
delete_btn.text = tr(&"#delete")
delete_btn.icon = load("res://visual/icons/Delete.svg")
delete_btn.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
delete_btn.alignment = HORIZONTAL_ALIGNMENT_LEFT
delete_btn.pressed.connect(delete)
buttons_arr.append(delete_btn)

var insert_after_btn := Button.new()
insert_after_btn.text = tr(&"#insert_after")
insert_after_btn.icon = load("res://visual/icons/Plus.svg")
insert_after_btn.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
insert_after_btn.alignment = HORIZONTAL_ALIGNMENT_LEFT
insert_after_btn.pressed.connect(insert_after)
buttons_arr.append(insert_after_btn)

if cmd_idx != 0:
var convert_btn := Button.new()
convert_btn.text = tr(&"#convert_to")
convert_btn.icon = load("res://visual/icons/Reload.svg")
convert_btn.alignment = HORIZONTAL_ALIGNMENT_LEFT
convert_btn.pressed.connect(convert_to)
buttons_arr.append(convert_btn)

add_child(action_popup)
action_popup.set_btn_array(buttons_arr)
if popup_from_mouse:
Utils.popup_under_mouse(action_popup, get_global_mouse_position())
else:
Utils.popup_under_control(action_popup, more_button, true)
Utils.popup_under_control_centered(action_popup, more_button)


func _ready() -> void:
Expand Down Expand Up @@ -259,9 +279,12 @@ func _on_relative_button_pressed() -> void:
else cmd_char.to_lower()
setup_relative_button()

func _on_path_command_picked(new_command: String) -> void:
func _on_insert_path_command_picked(new_command: String) -> void:
cmd_insert_after.emit(cmd_idx + 1, new_command)

func _on_convert_path_command_picked(new_command: String) -> void:
cmd_convert_to.emit(cmd_idx, new_command)

func _on_gui_input(event: InputEvent) -> void:
if event is InputEventMouseButton and event.is_pressed():
if event.button_index == MOUSE_BUTTON_LEFT:
Expand Down
4 changes: 4 additions & 0 deletions src/ui_elements/path_field.gd
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func rebuild_commands() -> void:
command_editor.cmd_delete.connect(_delete)
command_editor.cmd_toggle_relative.connect(_toggle_relative)
command_editor.cmd_insert_after.connect(_insert_after)
command_editor.cmd_convert_to.connect(_convert_to)
commands_container.add_child(command_editor)
command_editor.update_type()
command_idx += 1
Expand All @@ -84,6 +85,9 @@ func _toggle_relative(idx: int) -> void:
func _insert_after(idx: int, cmd_type: String) -> void:
attribute.insert_command(idx, cmd_type)

func _convert_to(idx: int, new_type: String) -> void:
attribute.convert_command(idx, new_type)


func _on_line_edit_text_submitted(new_text: String) -> void:
set_value(new_text)
Expand Down
31 changes: 20 additions & 11 deletions src/ui_elements/path_popup.gd
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ signal path_command_picked(new_command: String)

@onready var command_container: VBoxContainer = %CommandContainer
@onready var relative_toggle: CheckButton = %RelativeToggle
@onready var vbox: VBoxContainer = $PanelContainer/VBoxContainer
@onready var top_margin: MarginContainer = $PanelContainer/VBoxContainer/MarginContainer

func _ready() -> void:
relative_toggle.toggled.connect(_on_relative_toggle_toggled)
for command_button in command_container.get_children():
command_button.pressed.connect(emit_picked.bind(command_button.command_char))

func emit_picked(cmd_char: String) -> void:
print(cmd_char)
path_command_picked.emit(cmd_char)
hide()

Expand All @@ -24,14 +27,20 @@ func _on_relative_toggle_toggled(toggled_on: bool) -> void:
command_button.command_char = command_button.command_char.to_upper()
command_button.update_text()

func disable_invalid(cmd_char: String) -> void:
var cmd_char_upper := cmd_char.to_upper()
if cmd_char_upper == "M":
command_container.get_node(^"Z").set_invalid()
command_container.get_node(^"M").set_invalid()
if cmd_char_upper == "Z":
command_container.get_node(^"Z").set_invalid()
if cmd_char_upper != "C" and cmd_char_upper != "S":
command_container.get_node(^"S").set_invalid()
if cmd_char_upper != "Q" and cmd_char_upper != "T":
command_container.get_node(^"T").set_invalid()
func disable_invalid(cmd_chars: Array) -> void:
for cmd_char in cmd_chars:
var cmd_char_upper: String = cmd_char.to_upper()
command_container.get_node(cmd_char_upper).set_invalid()

func force_relativity(relative: bool) -> void:
relative_toggle.hide()
vbox.add_theme_constant_override(&"separation", 0)
top_margin.add_theme_constant_override(&"margin_top", 0)
for command_button in command_container.get_children():
if relative:
command_button.command_char = command_button.command_char.to_lower()
command_button.update_text()
else:
command_button.command_char = command_button.command_char.to_upper()
command_button.update_text()
reset_size()
Loading

0 comments on commit da2848e

Please sign in to comment.