From 239068d5db7653ee47cdb6833963c12222b10d7b Mon Sep 17 00:00:00 2001 From: TheLsbt Date: Fri, 15 Dec 2023 17:34:59 +0200 Subject: [PATCH 01/31] Reference Image Updates --- Translations/Translations.pot | 7 +- project.godot | 20 ++ src/Autoload/Global.gd | 5 + src/Autoload/OpenSave.gd | 4 +- src/Classes/Project.gd | 19 ++ src/Shaders/ReferenceImageShader.gdshader | 21 ++ src/Shaders/SilhouetteShader.gdshader | 14 - src/UI/Canvas/Canvas.gd | 51 ++- src/UI/Canvas/Canvas.tscn | 6 +- src/UI/Canvas/ReferenceImages.gd | 318 ++++++++++++++++++ src/UI/ReferenceImages/ReferenceEditPanel.gd | 261 ++++++++++++++ src/UI/ReferenceImages/ReferenceImage.gd | 71 ++-- .../ReferenceImages/ReferenceImageButton.gd | 98 ------ .../ReferenceImages/ReferenceImageButton.tscn | 128 ------- src/UI/ReferenceImages/ReferencesPanel.gd | 62 +++- src/UI/ReferenceImages/ReferencesPanel.tscn | 184 +++++++++- src/UI/UI.tscn | 4 +- 17 files changed, 956 insertions(+), 317 deletions(-) create mode 100644 src/Shaders/ReferenceImageShader.gdshader delete mode 100644 src/Shaders/SilhouetteShader.gdshader create mode 100644 src/UI/Canvas/ReferenceImages.gd create mode 100644 src/UI/ReferenceImages/ReferenceEditPanel.gd delete mode 100644 src/UI/ReferenceImages/ReferenceImageButton.gd delete mode 100644 src/UI/ReferenceImages/ReferenceImageButton.tscn diff --git a/Translations/Translations.pot b/Translations/Translations.pot index d8a6bd01fbf1..79fb16f25ed4 100644 --- a/Translations/Translations.pot +++ b/Translations/Translations.pot @@ -2740,11 +2740,12 @@ msgstr "" msgid "Spring towards the end" msgstr "" -msgid "Silhouette" +#. Used to turn images into a singular color +msgid "Monochrome" msgstr "" -msgid "Blacks out the image and makes all opaque pixels a dark color." -msgstr "" +#. A tooltip to tell users to hold the Shift key while clicking the remove button +msgid "Hold Shift while pressing to instantly remove" #. Used in checkbuttons (like on/off switches) that enable/disable something. msgid "Enabled" diff --git a/project.godot b/project.godot index 9fbaf1b27e07..de21933d06ad 100644 --- a/project.godot +++ b/project.godot @@ -816,6 +816,26 @@ onion_skinning_settings={ "deadzone": 0.5, "events": [] } +reference_rotate={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194326,"key_label":0,"unicode":0,"echo":false,"script":null) +] +} +reference_scale={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194328,"key_label":0,"unicode":0,"echo":false,"script":null) +] +} +reference_quick_menu={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":true,"ctrl_pressed":true,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":82,"key_label":0,"unicode":0,"echo":false,"script":null) +] +} +cancel_reference_transform={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"echo":false,"script":null) +] +} [internationalization] diff --git a/src/Autoload/Global.gd b/src/Autoload/Global.gd index dec4674dc193..9b3f7474288b 100644 --- a/src/Autoload/Global.gd +++ b/src/Autoload/Global.gd @@ -660,6 +660,10 @@ func _initialize_keychain() -> void: Keychain.InputAction.new("", "Transformation tools", false), "transform_copy_selection_content": Keychain.InputAction.new("", "Transformation tools", false), + "reference_rotate": Keychain.InputAction.new("", "Reference images", false), + "reference_scale": Keychain.InputAction.new("", "Reference images", false), + "reference_quick_menu": Keychain.InputAction.new("", "Reference images", false), + "cancel_reference_transform": Keychain.InputAction.new("", "Reference images", false) } Keychain.groups = { @@ -682,6 +686,7 @@ func _initialize_keychain() -> void: "Shape tools": Keychain.InputGroup.new("Tool modifiers"), "Selection tools": Keychain.InputGroup.new("Tool modifiers"), "Transformation tools": Keychain.InputGroup.new("Tool modifiers"), + "Reference images": Keychain.InputGroup.new("Canvas") } Keychain.ignore_actions = ["left_mouse", "right_mouse", "middle_mouse", "shift", "ctrl"] diff --git a/src/Autoload/OpenSave.gd b/src/Autoload/OpenSave.gd index 5b4daa86fc32..1a71c3e9f35f 100644 --- a/src/Autoload/OpenSave.gd +++ b/src/Autoload/OpenSave.gd @@ -757,7 +757,7 @@ func import_reference_image_from_path(path: String) -> void: var ri := ReferenceImage.new() ri.project = project ri.deserialize({"image_path": path}) - Global.canvas.add_child(ri) + Global.canvas.reference_image_container.add_child(ri) reference_image_imported.emit() @@ -767,7 +767,7 @@ func import_reference_image_from_image(image: Image) -> void: var ri := ReferenceImage.new() ri.project = project ri.create_from_image(image) - Global.canvas.add_child(ri) + Global.canvas.reference_image_container.add_child(ri) reference_image_imported.emit() diff --git a/src/Classes/Project.gd b/src/Classes/Project.gd index d64b2d76cbd9..f69101e98fe1 100644 --- a/src/Classes/Project.gd +++ b/src/Classes/Project.gd @@ -45,6 +45,7 @@ var animation_tags: Array[AnimationTag] = []: var guides: Array[Guide] = [] var brushes: Array[Image] = [] var reference_images: Array[ReferenceImage] = [] +var reference_index: int = -1 # The currently selected index ReferenceImage var vanishing_points := [] ## Array of Vanishing Points var fps := 6.0 @@ -868,3 +869,21 @@ func _update_layer_ui() -> void: for f in frames.size(): cel_hbox.get_child(f).layer = l cel_hbox.get_child(f).button_setup() + + +## Change the current reference image +func set_reference_image_index(new_index: int) -> void: + reference_index = new_index + Global.canvas.reference_image_container.update_index(new_index) + + +## Returns the reference image based on reference_index +func get_current_reference_image() -> ReferenceImage: + return get_reference_image(reference_index) + + +## Returns the reference image based on the index or null if index < 0 +func get_reference_image(index: int) -> ReferenceImage: + if index < 0 or index > reference_images.size() - 1: + return null + return reference_images[index] diff --git a/src/Shaders/ReferenceImageShader.gdshader b/src/Shaders/ReferenceImageShader.gdshader new file mode 100644 index 000000000000..294fec36e663 --- /dev/null +++ b/src/Shaders/ReferenceImageShader.gdshader @@ -0,0 +1,21 @@ +shader_type canvas_item; + +// This shader gets applied to every single reference image. + + +uniform bool monochrome = false; +// Used becuase modulate doesnt work when monochrome is true +uniform vec4 monchrome_color : source_color; +// Clamp the color by using the greyscale of the image to identify the brightness of each pixel +uniform float clamping : hint_range(0.0, 1.0, 0.01) = 0.0; + +void fragment() { + // The original color + vec4 color = texture(TEXTURE, UV); + // Get the greyscale based on the brightest channel + float greyscale = max(max(color.r, color.g), color.b); + // Dont Use Alpha Channel past this statement! + if (greyscale < clamping) COLOR.a = 0.0; + // If we want the image to be onochrome we just set that pixels rgb color. + if (monochrome) COLOR.rgb = monchrome_color.rgb; +} diff --git a/src/Shaders/SilhouetteShader.gdshader b/src/Shaders/SilhouetteShader.gdshader deleted file mode 100644 index a661cefa75b0..000000000000 --- a/src/Shaders/SilhouetteShader.gdshader +++ /dev/null @@ -1,14 +0,0 @@ -shader_type canvas_item; - -uniform vec4 silhouette_color; -uniform bool show_silhouette; - -void fragment() { - vec4 color = texture(TEXTURE, UV); - if (show_silhouette && color.a > 0.0) { - color.rgb = silhouette_color.rgb; - COLOR.rgb = color.rgb; - } else { - COLOR = color; - } -} diff --git a/src/UI/Canvas/Canvas.gd b/src/UI/Canvas/Canvas.gd index c6c8557162dd..e42995d16d16 100644 --- a/src/UI/Canvas/Canvas.gd +++ b/src/UI/Canvas/Canvas.gd @@ -26,11 +26,10 @@ var layer_metadata_texture := ImageTexture.new() @onready var mouse_guide_container := $MouseGuideContainer as Node2D @onready var gizmos_3d := $Gizmos3D as Node2D @onready var measurements := $Measurements as Node2D +@onready var reference_image_container := $ReferenceImages as Node2D func _ready() -> void: - material.set_shader_parameter("layers", layer_texture_array) - material.set_shader_parameter("metadata", layer_metadata_texture) Global.project_changed.connect(queue_redraw) onion_past.type = onion_past.PAST onion_past.blue_red_color = Global.onion_skinning_past_color @@ -126,7 +125,7 @@ func update_texture(layer_i: int, frame_i := -1, project := Global.current_proje cel_image.get_size() == Vector2i(layer_texture_array.get_width(), layer_texture_array.get_height()) ): - layer_texture_array.update_layer(cel_image, project.ordered_layers[layer_i]) + layer_texture_array.update_layer(cel_image, layer_i) func update_selected_cels_textures(project := Global.current_project) -> void: @@ -148,72 +147,60 @@ func draw_layers() -> void: ) if recreate_texture_array: var textures: Array[Image] = [] - textures.resize(project.layers.size()) # Nx3 texture, where N is the number of layers and the first row are the blend modes, # the second are the opacities and the third are the origins layer_metadata_image = Image.create(project.layers.size(), 3, false, Image.FORMAT_RG8) # Draw current frame layers for i in project.layers.size(): - var ordered_index := project.ordered_layers[i] var layer := project.layers[i] - var cel := current_cels[i] var cel_image: Image if Global.display_layer_effects: - cel_image = layer.display_effects(cel) + cel_image = layer.display_effects(current_cels[i]) else: - cel_image = cel.get_image() - textures[ordered_index] = cel_image + cel_image = current_cels[i].get_image() + textures.append(cel_image) # Store the blend mode - layer_metadata_image.set_pixel( - ordered_index, 0, Color(layer.blend_mode / 255.0, 0.0, 0.0, 0.0) - ) + layer_metadata_image.set_pixel(i, 0, Color(layer.blend_mode / 255.0, 0.0, 0.0, 0.0)) # Store the opacity if layer.is_visible_in_hierarchy(): - var opacity := cel.get_final_opacity(layer) - layer_metadata_image.set_pixel(ordered_index, 1, Color(opacity, 0.0, 0.0, 0.0)) + layer_metadata_image.set_pixel(i, 1, Color(current_cels[i].opacity, 0.0, 0.0, 0.0)) else: - layer_metadata_image.set_pixel(ordered_index, 1, Color()) + layer_metadata_image.set_pixel(i, 1, Color()) # Store the origin if [project.current_frame, i] in project.selected_cels: var origin := Vector2(move_preview_location).abs() / Vector2(cel_image.get_size()) - layer_metadata_image.set_pixel( - ordered_index, 2, Color(origin.x, origin.y, 0.0, 0.0) - ) + layer_metadata_image.set_pixel(i, 2, Color(origin.x, origin.y, 0.0, 0.0)) else: - layer_metadata_image.set_pixel(ordered_index, 2, Color()) + layer_metadata_image.set_pixel(i, 2, Color()) layer_texture_array.create_from_images(textures) layer_metadata_texture.set_image(layer_metadata_image) else: # Update the TextureArray if layer_texture_array.get_layers() > 0: for i in project.layers.size(): + var layer := project.layers[i] + var test_array := [project.current_frame, i] if not update_all_layers: - var test_array := [project.current_frame, i] if not test_array in project.selected_cels: continue - var ordered_index := project.ordered_layers[i] - var layer := project.layers[i] var cel := current_cels[i] var cel_image: Image if Global.display_layer_effects: cel_image = layer.display_effects(cel) else: cel_image = cel.get_image() - layer_texture_array.update_layer(cel_image, ordered_index) - layer_metadata_image.set_pixel( - ordered_index, 0, Color(layer.blend_mode / 255.0, 0.0, 0.0, 0.0) - ) + layer_texture_array.update_layer(cel_image, i) + layer_metadata_image.set_pixel(i, 0, Color(layer.blend_mode / 255.0, 0.0, 0.0, 0.0)) if layer.is_visible_in_hierarchy(): - var opacity := cel.get_final_opacity(layer) - layer_metadata_image.set_pixel(ordered_index, 1, Color(opacity, 0.0, 0.0, 0.0)) + layer_metadata_image.set_pixel(i, 1, Color(cel.opacity, 0.0, 0.0, 0.0)) else: - layer_metadata_image.set_pixel(ordered_index, 1, Color()) + layer_metadata_image.set_pixel(i, 1, Color()) var origin := Vector2(move_preview_location).abs() / Vector2(cel_image.get_size()) - layer_metadata_image.set_pixel( - ordered_index, 2, Color(origin.x, origin.y, 0.0, 0.0) - ) + layer_metadata_image.set_pixel(i, 2, Color(origin.x, origin.y, 0.0, 0.0)) layer_metadata_texture.update(layer_metadata_image) + material.set_shader_parameter("layers", layer_texture_array) + material.set_shader_parameter("metadata", layer_metadata_texture) material.set_shader_parameter("origin_x_positive", move_preview_location.x > 0) material.set_shader_parameter("origin_y_positive", move_preview_location.y > 0) update_all_layers = false diff --git a/src/UI/Canvas/Canvas.tscn b/src/UI/Canvas/Canvas.tscn index 276703040635..48c7441ded6e 100644 --- a/src/UI/Canvas/Canvas.tscn +++ b/src/UI/Canvas/Canvas.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=21 format=3 uid="uid://ba24iuv55m4l3"] +[gd_scene load_steps=22 format=3 uid="uid://ba24iuv55m4l3"] [ext_resource type="Script" path="res://src/UI/Canvas/Canvas.gd" id="1"] [ext_resource type="Shader" path="res://src/Shaders/BlendLayers.gdshader" id="1_253dh"] @@ -16,6 +16,7 @@ [ext_resource type="Script" path="res://src/UI/Canvas/CropRect.gd" id="13"] [ext_resource type="Script" path="res://src/UI/Canvas/Gizmos3D.gd" id="14"] [ext_resource type="Script" path="res://src/UI/Canvas/Measurements.gd" id="16_nxilb"] +[ext_resource type="Script" path="res://src/UI/Canvas/ReferenceImages.gd" id="17_qfjb4"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_6b0ox"] shader = ExtResource("1_253dh") @@ -93,3 +94,6 @@ script = ExtResource("14") [node name="Measurements" type="Node2D" parent="."] script = ExtResource("16_nxilb") + +[node name="ReferenceImages" type="Node2D" parent="."] +script = ExtResource("17_qfjb4") diff --git a/src/UI/Canvas/ReferenceImages.gd b/src/UI/Canvas/ReferenceImages.gd new file mode 100644 index 000000000000..1924393c6708 --- /dev/null +++ b/src/UI/Canvas/ReferenceImages.gd @@ -0,0 +1,318 @@ +extends Node2D + +## This node contains [ReferenceImage] nodes + +signal reference_image_changed(index: int) + +const MenuLabelMaxLength := 22 + +enum MenuPopulation {Mouse, All} + +var index: int: + get: return Global.current_project.reference_index +var drag_start_pos: Vector2 +var dragging := false +var lmb_held := false ## Holds whether the LBB is being held (use dragging for actual checks) + +# Original Transform +var og_pos: Vector2 +var og_scale: Vector2 +var og_rotation: float + +var undo_data : Dictionary + +var reference_menu:= PopupMenu.new() + + +func _ready() -> void: + Global.camera.zoom_changed.connect(_update_on_zoom) + Global.control.get_node("Dialogs").add_child(reference_menu) + + # Makes sure that the dark overlay disapears when the popup is hidden + reference_menu.visibility_changed.connect( + func(): Global.dialog_open(reference_menu.visible) + ) + # Emiited when a item is selected from the menu + reference_menu.id_pressed.connect(_reference_menu_id_pressed) + + +## Updates the index and configures the "gizmo" +func update_index(new_index: int) -> void: + index = new_index + reference_image_changed.emit(new_index) + queue_redraw() + +func _input(event: InputEvent) -> void: + var local_mouse_pos := get_local_mouse_position() + + # Check if that event was for the quick menu (opened by the shortcut) + if event.is_action_pressed("reference_quick_menu"): + var list: Array[ReferenceImage] = Global.current_project.reference_images + populate_reference_menu(list, true) + reference_menu.position = Global.control.get_global_mouse_position() + reference_menu.popup() + + var ri: ReferenceImage = Global.current_project.get_current_reference_image() + + if !ri: + Global.can_draw = true + return + + # Check if want to cancelthe reference transform + if event.is_action_pressed("cancel_reference_transform") and dragging: + ri.position = og_pos + ri.scale = og_scale + ri.rotation = og_rotation + dragging = false + Global.can_draw = true + commit_undo("Cancel Transform Content", undo_data) + #queue_redraw() + return + + if event is InputEventMouseButton: + if event.button_index == MOUSE_BUTTON_LEFT: + if event.is_pressed(): + dragging = false + lmb_held = true + undo_data = get_undo_data() + Global.can_draw = false + drag_start_pos = get_local_mouse_position() + # Set the original positions + og_pos = ri.position + og_scale = ri.scale + og_rotation = ri.rotation + + if !event.is_pressed(): + Global.can_draw = true + + if dragging: + commit_undo("Transform Content", undo_data) + else: + # Overlapping reference images + var overlapping : Array[ReferenceImage] = [] + + for idx: int in Global.current_project.reference_images.size(): + var r = Global.current_project.reference_images[idx] + # The bounding polygon + var p := get_reference_polygon(idx) + if Geometry2D.is_point_in_polygon(local_mouse_pos, p): + overlapping.append(r) + + # Some special cases + # 1. There is only one Reference Image + if overlapping.size() == 1: + var idx := overlapping[0].get_index() + Global.current_project.set_reference_image_index(idx) + # 2. There are more than 1 Reference Images + elif overlapping.size() > 1: + populate_reference_menu(overlapping, true) + reference_menu.position = Global.control.get_global_mouse_position() + reference_menu.popup() + # 3. There are no Reference Images + else: + Global.current_project.set_reference_image_index(-1) + + + undo_data.clear() + dragging = false + lmb_held = false + + + + if event is InputEventMouseMotion: + # We check if the LMB is pressed and if we're not dragging then we force the + # draggin state. + # We dont use timers becuase it makes more sense to wait fot the users mouse to move + # and thats what defines dragging. It would be smart to add a "deadzone" to determine + # if the mouse had moved enough. + if lmb_held and !dragging: + dragging = true + + if dragging: + var text := "" + + # Scale + if Input.is_action_pressed("reference_scale"): + scale_reference_image(local_mouse_pos, ri) + text = str("Moving: ", + (og_scale * 100).floor(), " -> ", (ri.scale * 100).floor() + ) + # Rotate + elif Input.is_action_pressed("reference_rotate"): + rotate_reference_image(local_mouse_pos, ri) + text = str("Rotating: ", + floorf(rad_to_deg(og_rotation)), "° -> ", floorf(rad_to_deg(ri.rotation)), "°" + ) + else: + move_reference_image(local_mouse_pos, ri) + text = str("Scaling to: ", + og_pos.floor(), " -> ", ri.position.floor() + ) + + Global.cursor_position_label.text = text + + # Getting the mouse cursor + queue_redraw() + +## Uniformly scales the [ReferenceImage] using this nodes "local_mouse_position". +func scale_reference_image(mouse_pos: Vector2, img: ReferenceImage) -> void: + var s = (Vector2.ONE + * minf( + float(mouse_pos.x - drag_start_pos.x), + float(mouse_pos.y - drag_start_pos.y), + ) + ) + + img.scale = (og_scale + (s / 100.0)) + +## Rotate the [ReferenceImage] using this nodes "local_mouse_position". +func rotate_reference_image(mouse_pos: Vector2, img: ReferenceImage) -> void: + var starting_angle = (og_rotation - og_pos.angle_to_point(drag_start_pos)) + var new_angle = img.position.angle_to_point(mouse_pos) + var angle = starting_angle + new_angle + angle = deg_to_rad(floorf(rad_to_deg(wrapf(angle, -PI, PI)))) + img.rotation = angle + +## Move the [ReferenceImage] using this nodes "local_mouse_position". +func move_reference_image(mouse_pos: Vector2, img: ReferenceImage) -> void: + img.position = (mouse_pos - (drag_start_pos - og_pos)).floor() + + +## Makes a polygon that matches the transformed [ReferenceImage] +func get_reference_polygon(i: int) -> PackedVector2Array: + if i < 0: + return [] + + var ri : ReferenceImage = Global.current_project.reference_images[i] + var rect := ri.get_rect() + var poly = get_transformed_rect_polygon(rect, ri.transform) + return poly + + +## Returns a [PackedVector2Array] based on the corners of the [Rect2]. +## This function also transforms the polygon. +func get_transformed_rect_polygon(rect: Rect2, t: Transform2D) -> PackedVector2Array: + # First we scale the Rect2 + rect.position *= t.get_scale() + rect.size *= t.get_scale() + + # We create a polygon based on the Rect2 + var p : PackedVector2Array = [ + rect.position, Vector2(rect.end.x, rect.position.y), + rect.end, Vector2(rect.position.x, rect.end.y) + ] + + # Finally rotate and move the polygon + var final : PackedVector2Array = [] + for v : Vector2 in p: + var vert := v.rotated(t.get_rotation()) + t.get_origin() + final.append(vert) + + return final + + +func populate_reference_menu(items: Array[ReferenceImage], default:= false): + reference_menu.clear() + # Default / Reset + if default: + reference_menu.add_item("None", 0) + reference_menu.add_separator() + + for ri: ReferenceImage in items: + var idx: int = ri.get_index() + 1 + var label: String = "(%o) %s" %[idx, ri.image_path] + # We trim the length of the title + label = label.left(MenuLabelMaxLength) + "..." + reference_menu.add_item(label, idx) + + +# When a id is pressed in the reference menu +func _reference_menu_id_pressed(id: int) -> void: + Global.can_draw = true + Global.current_project.set_reference_image_index(id - 1) + reference_menu.hide() + +func remove_reference_image(idx: int) -> void: + var ri: ReferenceImage = Global.current_project.get_reference_image(idx) + Global.current_project.reference_images.remove_at(idx) + ri.queue_free() + Global.current_project.set_reference_image_index(-1) + Global.current_project.change_project() + Global.control.ui.find_child("Reference Images")._on_references_changed() + +func _update_on_zoom() -> void: + queue_redraw() + +func get_undo_data() -> Dictionary: + var ri : ReferenceImage = Global.current_project.get_current_reference_image() + + if ri == null: + return {} + + var data := {} + data["position"] = ri.position + data["scale"] = ri.scale + data["rotation"] = ri.rotation + data["overlay_color"] = ri.overlay_color + data["filter"] = ri.filter + data["monochrome"] = ri.monochrome + data["color_clamping"] = ri.color_clamping + + return data + +func commit_undo(action: String, undo_data_tmp: Dictionary) -> void: + if !undo_data_tmp: + print("No undo data found for ReferenceImages.gd!") + return + + var ri: ReferenceImage = Global.current_project.get_current_reference_image() + if !ri: + print("No Reference Image ReferenceImages.gd!") + return + + var redo_data: Dictionary = get_undo_data() + var project := Global.current_project + + project.undos += 1 + project.undo_redo.create_action(action) + + for key in undo_data_tmp.keys(): + if redo_data.has(key): + project.undo_redo.add_do_property( + ri, key, redo_data.get(key) + ) + project.undo_redo.add_undo_property( + ri, key, undo_data_tmp.get(key) + ) + + print(redo_data.get("overlay_color")) + + project.undo_redo.add_do_method(Global.general_redo.bind(project)) + project.undo_redo.add_do_method(ri.change_properties) + project.undo_redo.add_undo_method(Global.general_undo.bind(project)) + project.undo_redo.add_undo_method(ri.change_properties) + + project.undo_redo.commit_action() + undo_data.clear() + + +func _draw() -> void: + if index < 0: + return + var line_width := 2.0 / Global.camera.zoom.x + # If we are dragging show where the Reference was comming from + if dragging: + var i: ReferenceImage = Global.current_project.get_current_reference_image() + var prev_transform = Transform2D(og_rotation, og_scale, 0.0, og_pos) + var prev_poly := get_transformed_rect_polygon(i.get_rect(), prev_transform) + prev_poly.append(prev_poly[0]) + draw_polyline(prev_poly, Color(1, 0.29, 0.29), line_width) + + # First we highlight the Reference Images under the mouse with yellow + for ri : ReferenceImage in Global.current_project.reference_images: + var p := get_transformed_rect_polygon(ri.get_rect(), ri.transform) + p.append(p[0]) + if ri.get_index() == index: + draw_polyline(p, Color(0.50, 0.99, 0.29), line_width) + elif Geometry2D.is_point_in_polygon(get_local_mouse_position(), p) and !dragging: + draw_polyline(p, Color(0.98, 0.80, 0.29), line_width) diff --git a/src/UI/ReferenceImages/ReferenceEditPanel.gd b/src/UI/ReferenceImages/ReferenceEditPanel.gd new file mode 100644 index 000000000000..8136f715095b --- /dev/null +++ b/src/UI/ReferenceImages/ReferenceEditPanel.gd @@ -0,0 +1,261 @@ +extends PanelContainer + +var _ignore_spinbox_changes: bool = false +var _prev_index: int = -1 + +var reference_image_container: Node2D: + get: + return Global.canvas.reference_image_container +var undo_data : Dictionary + +@onready var timer := $Timer as Timer + +func _ready() -> void: + Global.canvas.reference_image_container.reference_image_changed.connect(_on_reference_image_changed) + + +func _update_properties(): + var ri: ReferenceImage = Global.current_project.get_current_reference_image() + if !ri: + return + # This is because otherwise a little dance will occur. + # This also breaks non-uniform scales (not supported UI-wise, but...) + _ignore_spinbox_changes = true + + # Image Path + if OS.get_name() == "Web": + $ReferenceEdit/ImageOptions/ImagePath.disabled = true + else: + $ReferenceEdit/ImageOptions/ImagePath.disabled = false + + $ReferenceEdit/ImageOptions/ImagePath.text = ri.image_path + $ReferenceEdit/ImageOptions/ImagePath.tooltip_text = ri.image_path + + if !ri.texture: + $ReferenceEdit/ImageOptions/WarningLabel.visible = true + $ReferenceEdit/ImageOptions/ImagePath.visible = false + else: + $ReferenceEdit/ImageOptions/WarningLabel.visible = false + $ReferenceEdit/ImageOptions/ImagePath.visible = true + # Tools + $ReferenceEdit/Tools/Filter.button_pressed = ri.filter + # Transform + $ReferenceEdit/Options/Position/X.value = ri.position.x + $ReferenceEdit/Options/Position/Y.value = ri.position.y + $ReferenceEdit/Options/Position/X.max_value = ri.project.size.x + $ReferenceEdit/Options/Position/Y.max_value = ri.project.size.y + $ReferenceEdit/Options/Scale.value = ri.scale.x * 100 + $ReferenceEdit/Options/Rotation.value = ri.rotation_degrees + + # Color + $ReferenceEdit/Options/Monochrome.button_pressed = ri.monochrome + $ReferenceEdit/Options/Overlay.color = Color(ri.overlay_color, 1.0) + $ReferenceEdit/Options/Opacity.value = ri.overlay_color.a * 100 + $ReferenceEdit/Options/ColorClamping.value = ri.color_clamping * 100 + _ignore_spinbox_changes = false + + # Fore update the "gizmo" drawing + Global.canvas.reference_image_container.queue_redraw() + +func _reset_properties() -> void: + # This is because otherwise a little dance will occur. + # This also breaks non-uniform scales (not supported UI-wise, but...) + _ignore_spinbox_changes = true + $ReferenceEdit/ImageOptions/ImagePath.text = "None" + $ReferenceEdit/ImageOptions/ImagePath.tooltip_text = "None" + $ReferenceEdit/ImageOptions/ImagePath.disabled = true + + $ReferenceEdit/ImageOptions/WarningLabel.visible = false + $ReferenceEdit/ImageOptions/ImagePath.visible = true + + # Tools + $ReferenceEdit/Tools/Filter.button_pressed = false + # Transform + $ReferenceEdit/Options/Position/X.value = 0.0 + $ReferenceEdit/Options/Position/Y.value = 0.0 + $ReferenceEdit/Options/Position/X.max_value = 0.0 + $ReferenceEdit/Options/Position/Y.max_value = 0.0 + $ReferenceEdit/Options/Scale.value = 0.0 + $ReferenceEdit/Options/Rotation.value = 0.0 + # Color + $ReferenceEdit/Options/Monochrome.button_pressed = false + $ReferenceEdit/Options/Overlay.color = Color.WHITE + $ReferenceEdit/Options/Opacity.value = 0.0 + $ReferenceEdit/Options/ColorClamping.value = 0.0 + _ignore_spinbox_changes = false + + # Fore update the "gizmo" drawing + Global.canvas.reference_image_container.queue_redraw() + +func _on_Monochrome_toggled(pressed: bool) -> void: + if _ignore_spinbox_changes: + return + var ri: ReferenceImage = Global.current_project.get_current_reference_image() + if !ri: + return + if timer.is_stopped(): + undo_data = reference_image_container.get_undo_data() + timer.start() + ri.monochrome = pressed + +func _on_Filter_toggled(pressed: bool) -> void: + if _ignore_spinbox_changes: + return + var ri: ReferenceImage = Global.current_project.get_current_reference_image() + if !ri: + return + if timer.is_stopped(): + undo_data = reference_image_container.get_undo_data() + timer.start() + ri.filter = pressed + +func _on_Reset_pressed(): + var ri: ReferenceImage = Global.current_project.get_current_reference_image() + if !ri: + return + var undo_data_tmp = reference_image_container.get_undo_data() + ri.position_reset() + reference_image_container.commit_undo("Reset Reference Image Position", undo_data_tmp) + + +func _on_Remove_pressed(): + var ri: ReferenceImage = Global.current_project.get_current_reference_image() + if !ri: + return + var index : int = get_parent().list_btn_group.get_pressed_button().get_index() - 1 + if index > -1: + # If shift is pressed we just remove it without a dialog + if Input.is_action_pressed("shift"): + reference_image_container.remove_reference_image(index) + else: + var dialog = ConfirmationDialog.new() + dialog.dialog_text = " Are you sure you want to remove this image?" + dialog.ok_button_text = "Yes" + dialog.cancel_button_text = "No" + Global.control.get_node("Dialogs").add_child(dialog) + dialog.position = Global.control.get_global_mouse_position() + dialog.popup() + Global.dialog_open(true) + # Signals + dialog.confirmed.connect( + func(): + reference_image_container.remove_reference_image(index) + dialog.queue_free() + Global.dialog_open(false) + ) + dialog.canceled.connect( + func(): + dialog.queue_free() + Global.dialog_open(false) + ) + + +func _on_X_value_changed(value: float): + if _ignore_spinbox_changes: + return + var ri: ReferenceImage = Global.current_project.get_current_reference_image() + if !ri: + return + if timer.is_stopped(): + undo_data = reference_image_container.get_undo_data() + timer.start() + ri.position.x = value + + +func _on_Y_value_changed(value: float): + if _ignore_spinbox_changes: + return + var ri: ReferenceImage = Global.current_project.get_current_reference_image() + if !ri: + return + if timer.is_stopped(): + undo_data = reference_image_container.get_undo_data() + timer.start() + ri.position.y = value + +func _on_Scale_value_changed(value: float): + if _ignore_spinbox_changes: + return + var ri: ReferenceImage = Global.current_project.get_current_reference_image() + if !ri: + return + if timer.is_stopped(): + undo_data = reference_image_container.get_undo_data() + timer.start() + ri.scale.x = value / 100 + ri.scale.y = value / 100 + +func _on_Rotation_value_changed(value: float): + if _ignore_spinbox_changes: + return + var ri: ReferenceImage = Global.current_project.get_current_reference_image() + if !ri: + return + if timer.is_stopped(): + undo_data = reference_image_container.get_undo_data() + timer.start() + ri.rotation_degrees = value + + +func _on_Overlay_color_changed(color: Color): + if _ignore_spinbox_changes: + return + var ri: ReferenceImage = Global.current_project.get_current_reference_image() + if !ri: + return + if timer.is_stopped(): + undo_data = reference_image_container.get_undo_data() + timer.start() + ri.overlay_color = Color(color, ri.overlay_color.a) + + +func _on_Opacity_value_changed(value: float): + if _ignore_spinbox_changes: + return + var ri: ReferenceImage = Global.current_project.get_current_reference_image() + if !ri: + return + if timer.is_stopped(): + undo_data = reference_image_container.get_undo_data() + timer.start() + ri.overlay_color.a = value / 100 + +func _on_ColorClamping_value_changed(value: float): + if _ignore_spinbox_changes: + return + var ri : ReferenceImage = Global.current_project.get_current_reference_image() + if !ri: + return + if timer.is_stopped(): + undo_data = reference_image_container.get_undo_data() + timer.start() + ri.color_clamping = value / 100 + +func _on_timer_timeout() -> void: + reference_image_container.commit_undo("Reference Image Changed", undo_data) + + +func _on_reference_image_porperties_changed() -> void: + _update_properties() + + +func _on_reference_image_changed(index: int) -> void: + # This is a check to make sure that the index is not more than the amount of references + if _prev_index > Global.current_project.reference_images.size() - 1: + return + # Disconnect the previously selected one + if _prev_index > -1: + var prev_ri : ReferenceImage = Global.current_project.get_reference_image(_prev_index) + if prev_ri.properties_changed.is_connected(_on_reference_image_porperties_changed): + prev_ri.properties_changed.disconnect(_on_reference_image_porperties_changed) + # Connect the new Reference image (if it is one) + if index > -1: + Global.current_project.reference_images[index].properties_changed.connect( + _on_reference_image_porperties_changed) + + _prev_index = index + + if index < 0: + _reset_properties() + else: + _update_properties() diff --git a/src/UI/ReferenceImages/ReferenceImage.gd b/src/UI/ReferenceImages/ReferenceImage.gd index 60eec8fcd0c5..3600acedf40a 100644 --- a/src/UI/ReferenceImages/ReferenceImage.gd +++ b/src/UI/ReferenceImages/ReferenceImage.gd @@ -6,15 +6,38 @@ signal properties_changed var project := Global.current_project -var shader := preload("res://src/Shaders/SilhouetteShader.gdshader") +var shader := preload("res://src/Shaders/ReferenceImageShader.gdshader") var image_path := "" -var filter := false -var silhouette := false +var filter := false: + set(value): + filter = value + if value: + texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR + else: + texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST +var monochrome := false: + set(value): + monochrome = value + if material: + get_material().set_shader_parameter("monochrome", value) +var overlay_color := Color.WHITE: + set(value): + overlay_color = value + modulate = value + if material: + get_material().set_shader_parameter("monchrome_color", value) +var color_clamping := 0.0: + set(value): + color_clamping = value + if material: + get_material().set_shader_parameter("clamping", value) func _ready() -> void: project.reference_images.append(self) + # Make this show behind parent because we want to use _draw() to draw over it + show_behind_parent = true func change_properties() -> void: @@ -24,6 +47,7 @@ func change_properties() -> void: ## Resets the position and scale of the reference image. func position_reset() -> void: position = project.size / 2.0 + rotation_degrees = 0.0 if texture != null: scale = ( Vector2.ONE @@ -43,12 +67,14 @@ func serialize() -> Dictionary: "y": position.y, "scale_x": scale.x, "scale_y": scale.y, - "modulate_r": modulate.r, - "modulate_g": modulate.g, - "modulate_b": modulate.b, - "modulate_a": modulate.a, + "rotation_degrees": rotation_degrees, + "overlay_color_r": overlay_color.r, + "overlay_color_g": overlay_color.g, + "overlay_color_b": overlay_color.b, + "overlay_color_a": overlay_color.a, "filter": filter, - "silhouette": silhouette, + "monochrome": monochrome, + "color_clamping": color_clamping, "image_path": image_path } @@ -57,7 +83,7 @@ func serialize() -> Dictionary: ## Be aware that new ReferenceImages are created via deserialization. ## This is because deserialization sets up some nice defaults. func deserialize(d: Dictionary) -> void: - modulate = Color(1, 1, 1, 0.5) + overlay_color = Color(1, 1, 1, 0.5) if d.has("image_path"): # Note that reference images are referred to by path. # These images may be rather big. @@ -69,9 +95,6 @@ func deserialize(d: Dictionary) -> void: # Apply the silhouette shader var mat := ShaderMaterial.new() mat.shader = shader - # TODO: Lsbt - Add a option in prefrences to customize the color - # This color is almost black because it is less harsh - mat.set_shader_parameter("silhouette_color", Color(0.069, 0.069326, 0.074219)) set_material(mat) # Now that the image may have been established... @@ -82,20 +105,24 @@ func deserialize(d: Dictionary) -> void: position.y = d["y"] if d.has("scale_x"): scale.x = d["scale_x"] + if d.has("rotation_degrees"): + rotation_degrees = d["rotation_degrees"] if d.has("scale_y"): scale.y = d["scale_y"] - if d.has("modulate_r"): - modulate.r = d["modulate_r"] - if d.has("modulate_g"): - modulate.g = d["modulate_g"] - if d.has("modulate_b"): - modulate.b = d["modulate_b"] - if d.has("modulate_a"): - modulate.a = d["modulate_a"] + if d.has("overlay_color_r"): + overlay_color.r = d["overlay_color_r"] + if d.has("overlay_color_g"): + overlay_color.g = d["overlay_color_g"] + if d.has("overlay_color_b"): + overlay_color.b = d["overlay_color_b"] + if d.has("overlay_color_a"): + overlay_color.a = d["overlay_color_a"] if d.has("filter"): filter = d["filter"] - if d.has("silhouette"): - get_material().set_shader_parameter("show_silhouette", d["silhouette"]) + if d.has("monochrome"): + monochrome = d["monochrome"] + if d.has("color_clamping"): + color_clamping = d["color_clamping"] change_properties() diff --git a/src/UI/ReferenceImages/ReferenceImageButton.gd b/src/UI/ReferenceImages/ReferenceImageButton.gd deleted file mode 100644 index f162d99b3d1f..000000000000 --- a/src/UI/ReferenceImages/ReferenceImageButton.gd +++ /dev/null @@ -1,98 +0,0 @@ -extends Container -## UI to handle reference image editing. - -var element: ReferenceImage -var _ignore_spinbox_changes := false - - -func _ready(): - if OS.get_name() == "Web": - $Interior/PathHeader/Path.visible = false - $Interior/PathHeader/PathHTML.text = element.image_path - else: - $Interior/PathHeader/PathHTML.visible = false - $Interior/PathHeader/Path.text = element.image_path - - if !element.texture: - $Interior/PreviewAndOptions/PreviewPanel/Warning.text = "Image not found!" - else: - $Interior/PreviewAndOptions/PreviewPanel/Preview.texture = element.texture - element.properties_changed.connect(_update_properties) - _update_properties() - - -func _update_properties(): - # This is because otherwise a little dance will occur. - # This also breaks non-uniform scales (not supported UI-wise, but...) - _ignore_spinbox_changes = true - $Interior/PreviewAndOptions/Options/Scale.value = element.scale.x * 100 - $Interior/PreviewAndOptions/Options/Position/X.value = element.position.x - $Interior/PreviewAndOptions/Options/Position/Y.value = element.position.y - $Interior/PreviewAndOptions/Options/Position/X.max_value = element.project.size.x - $Interior/PreviewAndOptions/Options/Position/Y.max_value = element.project.size.y - $Interior/PreviewAndOptions/Options/Opacity.value = element.modulate.a * 100 - $Interior/OtherOptions/ApplyFilter.button_pressed = element.filter - _ignore_spinbox_changes = false - - -func _on_Reset_pressed(): - element.position_reset() - element.change_properties() - - -func _on_Remove_pressed(): - var index = Global.current_project.reference_images.find(element) - if index != -1: - queue_free() - element.queue_free() - Global.current_project.reference_images.remove_at(index) - OpenSave.reference_image_imported.emit() - - -func _on_Scale_value_changed(value: float): - if _ignore_spinbox_changes: - return - element.scale.x = value / 100 - element.scale.y = value / 100 - element.change_properties() - - -func _on_X_value_changed(value: float): - if _ignore_spinbox_changes: - return - element.position.x = value - element.change_properties() - - -func _on_Y_value_changed(value: float): - if _ignore_spinbox_changes: - return - element.position.y = value - element.change_properties() - - -func _on_Opacity_value_changed(value: float): - if _ignore_spinbox_changes: - return - element.modulate.a = value / 100 - element.change_properties() - - -func _on_Path_pressed() -> void: - OS.shell_open($Interior/PathHeader/Path.text.get_base_dir()) - - -func _on_Silhouette_toggled(button_pressed: bool) -> void: - element.silhouette = button_pressed - element.get_material().set_shader_parameter("show_silhouette", button_pressed) - element.change_properties() - - -func _on_ApplyFilter_toggled(button_pressed: bool) -> void: - element.filter = button_pressed - if element.texture: - if element.filter: - element.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR - else: - element.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST - element.change_properties() diff --git a/src/UI/ReferenceImages/ReferenceImageButton.tscn b/src/UI/ReferenceImages/ReferenceImageButton.tscn deleted file mode 100644 index 9ffa9d2f8bb8..000000000000 --- a/src/UI/ReferenceImages/ReferenceImageButton.tscn +++ /dev/null @@ -1,128 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://5quwfcfl5o1e"] - -[ext_resource type="PackedScene" uid="uid://yjhp0ssng2mp" path="res://src/UI/Nodes/ValueSlider.tscn" id="1"] -[ext_resource type="Script" path="res://src/UI/ReferenceImages/ReferenceImageButton.gd" id="2"] - -[node name="ReferenceImageButton" type="PanelContainer"] -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -offset_right = -969.0 -offset_bottom = -581.0 -size_flags_horizontal = 3 -script = ExtResource("2") - -[node name="Interior" type="VBoxContainer" parent="."] -layout_mode = 2 - -[node name="PathHeader" type="HBoxContainer" parent="Interior"] -layout_mode = 2 -theme_override_constants/separation = 0 - -[node name="Path" type="LinkButton" parent="Interior/PathHeader"] -modulate = Color(0.552941, 1, 0.298039, 1) -layout_mode = 2 -size_flags_horizontal = 3 -underline = 1 - -[node name="PathHTML" type="Label" parent="Interior/PathHeader"] -self_modulate = Color(0.552941, 1, 0.298039, 1) -layout_mode = 2 -size_flags_horizontal = 3 - -[node name="HSeparator" type="HSeparator" parent="Interior/PathHeader"] -layout_mode = 2 -size_flags_horizontal = 3 - -[node name="PreviewAndOptions" type="HBoxContainer" parent="Interior"] -layout_mode = 2 - -[node name="Options" type="GridContainer" parent="Interior/PreviewAndOptions"] -layout_mode = 2 -size_flags_horizontal = 3 -columns = 2 - -[node name="PosLabel" type="Label" parent="Interior/PreviewAndOptions/Options"] -layout_mode = 2 -text = "Position:" - -[node name="Position" type="HBoxContainer" parent="Interior/PreviewAndOptions/Options"] -layout_mode = 2 -size_flags_horizontal = 3 - -[node name="X" parent="Interior/PreviewAndOptions/Options/Position" instance=ExtResource("1")] -layout_mode = 2 -allow_greater = true -allow_lesser = true - -[node name="Y" parent="Interior/PreviewAndOptions/Options/Position" instance=ExtResource("1")] -layout_mode = 2 -allow_greater = true -allow_lesser = true - -[node name="ScaleLabel" type="Label" parent="Interior/PreviewAndOptions/Options"] -layout_mode = 2 -text = "Scale:" - -[node name="Scale" parent="Interior/PreviewAndOptions/Options" instance=ExtResource("1")] -layout_mode = 2 -allow_greater = true -allow_lesser = true - -[node name="OpacityLabel" type="Label" parent="Interior/PreviewAndOptions/Options"] -layout_mode = 2 -text = "Opacity:" - -[node name="Opacity" parent="Interior/PreviewAndOptions/Options" instance=ExtResource("1")] -layout_mode = 2 - -[node name="PreviewPanel" type="Panel" parent="Interior/PreviewAndOptions"] -custom_minimum_size = Vector2(80, 80) -layout_mode = 2 - -[node name="Warning" type="Label" parent="Interior/PreviewAndOptions/PreviewPanel"] -layout_mode = 0 -anchor_right = 1.0 -anchor_bottom = 1.0 - -[node name="Preview" type="TextureRect" parent="Interior/PreviewAndOptions/PreviewPanel"] -layout_mode = 0 -anchor_right = 1.0 -anchor_bottom = 1.0 -offset_left = 2.0 -offset_top = 2.0 -offset_right = -2.0 -offset_bottom = -2.0 -expand_mode = 1 - -[node name="OtherOptions" type="HBoxContainer" parent="Interior"] -layout_mode = 2 -alignment = 2 - -[node name="ApplyFilter" type="CheckBox" parent="Interior/OtherOptions"] -layout_mode = 2 -tooltip_text = "Uses a magnifying filter, to enable smooth zooming in of the texture." -text = "Apply Filter" - -[node name="Silhouette" type="CheckBox" parent="Interior/OtherOptions"] -layout_mode = 2 -text = "Silhouette" - -[node name="Reset" type="Button" parent="Interior/OtherOptions"] -layout_mode = 2 -text = "Reset" - -[node name="Remove" type="Button" parent="Interior/OtherOptions"] -layout_mode = 2 -theme_override_colors/font_color = Color(1, 0.266667, 0.266667, 1) -text = "Remove" - -[connection signal="pressed" from="Interior/PathHeader/Path" to="." method="_on_Path_pressed"] -[connection signal="value_changed" from="Interior/PreviewAndOptions/Options/Position/X" to="." method="_on_X_value_changed"] -[connection signal="value_changed" from="Interior/PreviewAndOptions/Options/Position/Y" to="." method="_on_Y_value_changed"] -[connection signal="value_changed" from="Interior/PreviewAndOptions/Options/Scale" to="." method="_on_Scale_value_changed"] -[connection signal="value_changed" from="Interior/PreviewAndOptions/Options/Opacity" to="." method="_on_Opacity_value_changed"] -[connection signal="toggled" from="Interior/OtherOptions/ApplyFilter" to="." method="_on_ApplyFilter_toggled"] -[connection signal="toggled" from="Interior/OtherOptions/Silhouette" to="." method="_on_Silhouette_toggled"] -[connection signal="pressed" from="Interior/OtherOptions/Reset" to="." method="_on_Reset_pressed"] -[connection signal="pressed" from="Interior/OtherOptions/Remove" to="." method="_on_Remove_pressed"] diff --git a/src/UI/ReferenceImages/ReferencesPanel.gd b/src/UI/ReferenceImages/ReferencesPanel.gd index 775074c0f4f8..462f4cc8ddbe 100644 --- a/src/UI/ReferenceImages/ReferencesPanel.gd +++ b/src/UI/ReferenceImages/ReferencesPanel.gd @@ -2,26 +2,68 @@ class_name ReferencesPanel extends VBoxContainer ## Panel for reference image management -var reference_image_button_tscn := preload("res://src/UI/ReferenceImages/ReferenceImageButton.tscn") -@onready var list = $"Scroll/List" +var list_btn_group := ButtonGroup.new() +@onready var list = $"ReferenceImages/List" func _ready() -> void: - Global.project_changed.connect(_update_reference_images) - OpenSave.reference_image_imported.connect(_update_reference_images) + list_btn_group.pressed.connect(_on_reference_image_button_pressed) + Global.canvas.reference_image_container.reference_image_changed.connect(_on_reference_image_changed) + + OpenSave.reference_image_imported.connect(_on_references_changed) + # We call this funtion to update the buttons + _on_references_changed() + +func _on_reference_image_button_pressed(button: Button) -> void: + # We subtract 1 because we already have a default button to "select no reference image + Global.current_project.set_reference_image_index(button.get_index() - 1) -func _update_reference_images(): +# In case the signal is emited for another node and not from a pressed button +func _on_reference_image_changed(index: int) -> void: + if list_btn_group.get_buttons().size() > 0: + # First we loop through the buttons to "unpress them all" + # There is a visual bug with BaseButton.set_pressed_no_signal() + for b: Button in list_btn_group.get_buttons(): + if (index + 1) == b.get_index(): + b.set_pressed_no_signal(true) + else: + b.set_pressed_no_signal(false) + + + +func _on_references_changed(): + # When we change the project we set the defualt + Global.current_project.set_reference_image_index(-1) + for c in list.get_children(): + if c is Button: + c.button_group = null c.queue_free() - # Just do this here because I'm not sure where it's done. - # By all means, change this! - for ref in Global.canvas.get_children(): + # Made it only look in the ReferenceImages Node for reference images + for ref in Global.canvas.reference_image_container.get_children(): if ref is ReferenceImage: ref.visible = false + + # The defualt button + var defualt = Button.new() + defualt.button_group = list_btn_group + defualt.text = "none" + defualt.custom_minimum_size = Vector2(64, 64) + defualt.toggle_mode = true + defualt.button_pressed = true + list.add_child(defualt) + # And update. for ref in Global.current_project.reference_images: ref.visible = true - var l = reference_image_button_tscn.instantiate() - l.element = ref + var l = Button.new() + l.button_group = list_btn_group + if ref.texture: + l.icon = ref.texture + l.expand_icon = true + l.icon_alignment = HORIZONTAL_ALIGNMENT_CENTER + l.vertical_icon_alignment = VERTICAL_ALIGNMENT_CENTER + l.custom_minimum_size = Vector2(64, 64) + l.toggle_mode = true list.add_child(l) diff --git a/src/UI/ReferenceImages/ReferencesPanel.tscn b/src/UI/ReferenceImages/ReferencesPanel.tscn index 05ccca9bc281..e287eb798cbe 100644 --- a/src/UI/ReferenceImages/ReferencesPanel.tscn +++ b/src/UI/ReferenceImages/ReferencesPanel.tscn @@ -1,6 +1,9 @@ -[gd_scene load_steps=2 format=3 uid="uid://b75xk2ix8xxml"] +[gd_scene load_steps=5 format=3 uid="uid://cxhs8qy5ilufv"] [ext_resource type="Script" path="res://src/UI/ReferenceImages/ReferencesPanel.gd" id="1"] +[ext_resource type="Script" path="res://src/UI/Nodes/ValueSlider.gd" id="2_1qu4x"] +[ext_resource type="Script" path="res://src/UI/ReferenceImages/ReferenceEditPanel.gd" id="2_xxb1y"] +[ext_resource type="PackedScene" uid="uid://yjhp0ssng2mp" path="res://src/UI/Nodes/ValueSlider.tscn" id="3_1w6gu"] [node name="Reference Images" type="VBoxContainer"] anchors_preset = 15 @@ -26,15 +29,186 @@ layout_mode = 2 size_flags_horizontal = 3 [node name="Label" type="Label" parent="."] +custom_minimum_size = Vector2(10, 0) layout_mode = 2 text = "When opening an image, it may be imported as a reference." +autowrap_mode = 2 -[node name="Scroll" type="ScrollContainer" parent="."] +[node name="ReferenceImages" type="ScrollContainer" parent="."] +layout_mode = 2 +horizontal_scroll_mode = 2 +vertical_scroll_mode = 0 + +[node name="List" type="HBoxContainer" parent="ReferenceImages"] +custom_minimum_size = Vector2(0, 64) +layout_mode = 2 + +[node name="ReferenceEditPanel" type="PanelContainer" parent="."] +layout_mode = 2 +script = ExtResource("2_xxb1y") + +[node name="ReferenceEdit" type="VBoxContainer" parent="ReferenceEditPanel"] +layout_mode = 2 + +[node name="ImageOptions" type="HBoxContainer" parent="ReferenceEditPanel/ReferenceEdit"] +layout_mode = 2 + +[node name="WarningLabel" type="Label" parent="ReferenceEditPanel/ReferenceEdit/ImageOptions"] +layout_mode = 2 +size_flags_horizontal = 3 +theme_override_colors/font_color = Color(0.972549, 1, 0.545098, 1) +text = "Image not found!" +text_overrun_behavior = 3 + +[node name="ImagePath" type="Button" parent="ReferenceEditPanel/ReferenceEdit/ImageOptions"] +visible = false +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 4 +text = "Image Path" +alignment = 0 +text_overrun_behavior = 3 + +[node name="Remove" type="Button" parent="ReferenceEditPanel/ReferenceEdit/ImageOptions"] +layout_mode = 2 +tooltip_text = "Hold Shift while pressing to instantly remove." +theme_override_colors/font_color = Color(1, 0.490196, 0.419608, 1) +text = "Remove" + +[node name="HSeparator" type="HSeparator" parent="ReferenceEditPanel/ReferenceEdit"] +layout_mode = 2 + +[node name="Tools" type="HBoxContainer" parent="ReferenceEditPanel/ReferenceEdit"] +layout_mode = 2 + +[node name="Filter" type="CheckButton" parent="ReferenceEditPanel/ReferenceEdit/Tools"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Filter" + +[node name="HSeparator2" type="HSeparator" parent="ReferenceEditPanel/ReferenceEdit"] +layout_mode = 2 + +[node name="Options" type="GridContainer" parent="ReferenceEditPanel/ReferenceEdit"] +layout_mode = 2 +size_flags_horizontal = 3 +columns = 2 + +[node name="TransformLabel" type="Label" parent="ReferenceEditPanel/ReferenceEdit/Options"] +layout_mode = 2 +text = "Transform" + +[node name="Reset" type="Button" parent="ReferenceEditPanel/ReferenceEdit/Options"] +layout_mode = 2 +text = "Reset Transform" + +[node name="PosLabel" type="Label" parent="ReferenceEditPanel/ReferenceEdit/Options"] +custom_minimum_size = Vector2(115, 0) +layout_mode = 2 +text = "Position" + +[node name="Position" type="HBoxContainer" parent="ReferenceEditPanel/ReferenceEdit/Options"] layout_mode = 2 size_flags_horizontal = 3 -size_flags_vertical = 3 -[node name="List" type="VBoxContainer" parent="Scroll"] +[node name="X" parent="ReferenceEditPanel/ReferenceEdit/Options/Position" instance=ExtResource("3_1w6gu")] +layout_mode = 2 +allow_greater = true +allow_lesser = true + +[node name="Y" parent="ReferenceEditPanel/ReferenceEdit/Options/Position" instance=ExtResource("3_1w6gu")] +layout_mode = 2 +allow_greater = true +allow_lesser = true + +[node name="ScaleLabel" type="Label" parent="ReferenceEditPanel/ReferenceEdit/Options"] +custom_minimum_size = Vector2(115, 0) +layout_mode = 2 +text = "Scale" + +[node name="Scale" parent="ReferenceEditPanel/ReferenceEdit/Options" instance=ExtResource("3_1w6gu")] +layout_mode = 2 +allow_greater = true +allow_lesser = true + +[node name="RotationLabel" type="Label" parent="ReferenceEditPanel/ReferenceEdit/Options"] +custom_minimum_size = Vector2(115, 0) +layout_mode = 2 +text = "Rotation" + +[node name="Rotation" parent="ReferenceEditPanel/ReferenceEdit/Options" instance=ExtResource("3_1w6gu")] +layout_mode = 2 +min_value = -180.0 +max_value = 180.0 + +[node name="ColorLabel" type="Label" parent="ReferenceEditPanel/ReferenceEdit/Options"] +layout_mode = 2 +text = "Color Options" + +[node name="Spacer2" type="Control" parent="ReferenceEditPanel/ReferenceEdit/Options"] +layout_mode = 2 + +[node name="MonochromeLabel" type="Label" parent="ReferenceEditPanel/ReferenceEdit/Options"] +custom_minimum_size = Vector2(115, 0) +layout_mode = 2 +text = "Monochrome" + +[node name="Monochrome" type="CheckButton" parent="ReferenceEditPanel/ReferenceEdit/Options"] layout_mode = 2 size_flags_horizontal = 3 -size_flags_vertical = 3 +text = "Enabled" + +[node name="OverlayLabel" type="Label" parent="ReferenceEditPanel/ReferenceEdit/Options"] +custom_minimum_size = Vector2(115, 0) +layout_mode = 2 +text = "Overlay" + +[node name="Overlay" type="ColorPickerButton" parent="ReferenceEditPanel/ReferenceEdit/Options"] +custom_minimum_size = Vector2(48, 28) +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_stretch_ratio = 0.25 +edit_alpha = false + +[node name="OpacityLabel" type="Label" parent="ReferenceEditPanel/ReferenceEdit/Options"] +custom_minimum_size = Vector2(115, 0) +layout_mode = 2 +text = "Opacity" + +[node name="Opacity" parent="ReferenceEditPanel/ReferenceEdit/Options" instance=ExtResource("3_1w6gu")] +layout_mode = 2 + +[node name="ColorClampingLabel" type="Label" parent="ReferenceEditPanel/ReferenceEdit/Options"] +custom_minimum_size = Vector2(115, 0) +layout_mode = 2 +text = "Color Clamping" + +[node name="ColorClamping" type="TextureProgressBar" parent="ReferenceEditPanel/ReferenceEdit/Options"] +custom_minimum_size = Vector2(0, 24) +layout_mode = 2 +size_flags_horizontal = 3 +focus_mode = 2 +theme_type_variation = &"ValueSlider" +nine_patch_stretch = true +stretch_margin_left = 3 +stretch_margin_top = 3 +stretch_margin_right = 3 +stretch_margin_bottom = 3 +script = ExtResource("2_1qu4x") + +[node name="Timer" type="Timer" parent="ReferenceEditPanel"] +wait_time = 0.2 +one_shot = true + +[connection signal="pressed" from="ReferenceEditPanel/ReferenceEdit/ImageOptions/Remove" to="ReferenceEditPanel" method="_on_Remove_pressed"] +[connection signal="toggled" from="ReferenceEditPanel/ReferenceEdit/Tools/Filter" to="ReferenceEditPanel" method="_on_Filter_toggled"] +[connection signal="pressed" from="ReferenceEditPanel/ReferenceEdit/Options/Reset" to="ReferenceEditPanel" method="_on_Reset_pressed"] +[connection signal="value_changed" from="ReferenceEditPanel/ReferenceEdit/Options/Position/X" to="ReferenceEditPanel" method="_on_X_value_changed"] +[connection signal="value_changed" from="ReferenceEditPanel/ReferenceEdit/Options/Position/Y" to="ReferenceEditPanel" method="_on_Y_value_changed"] +[connection signal="value_changed" from="ReferenceEditPanel/ReferenceEdit/Options/Scale" to="ReferenceEditPanel" method="_on_Scale_value_changed"] +[connection signal="value_changed" from="ReferenceEditPanel/ReferenceEdit/Options/Rotation" to="ReferenceEditPanel" method="_on_Rotation_value_changed"] +[connection signal="toggled" from="ReferenceEditPanel/ReferenceEdit/Options/Monochrome" to="ReferenceEditPanel" method="_on_Monochrome_toggled"] +[connection signal="color_changed" from="ReferenceEditPanel/ReferenceEdit/Options/Overlay" to="ReferenceEditPanel" method="_on_Overlay_color_changed"] +[connection signal="value_changed" from="ReferenceEditPanel/ReferenceEdit/Options/Opacity" to="ReferenceEditPanel" method="_on_Opacity_value_changed"] +[connection signal="value_changed" from="ReferenceEditPanel/ReferenceEdit/Options/ColorClamping" to="ReferenceEditPanel" method="_on_ColorClamping_value_changed"] +[connection signal="timeout" from="ReferenceEditPanel/Timer" to="ReferenceEditPanel" method="_on_timer_timeout"] diff --git a/src/UI/UI.tscn b/src/UI/UI.tscn index ece1f6f1e355..e3fe6401f760 100644 --- a/src/UI/UI.tscn +++ b/src/UI/UI.tscn @@ -10,7 +10,7 @@ [ext_resource type="Shader" path="res://src/Shaders/Greyscale.gdshader" id="8"] [ext_resource type="Shader" path="res://src/Shaders/TransparentChecker.gdshader" id="9"] [ext_resource type="PackedScene" uid="uid://wo0hqxkst808" path="res://src/UI/GlobalToolOptions/GlobalToolOptions.tscn" id="10"] -[ext_resource type="PackedScene" uid="uid://b75xk2ix8xxml" path="res://src/UI/ReferenceImages/ReferencesPanel.tscn" id="11"] +[ext_resource type="PackedScene" uid="uid://cxhs8qy5ilufv" path="res://src/UI/ReferenceImages/ReferencesPanel.tscn" id="11"] [ext_resource type="PackedScene" uid="uid://cap1bhavhi33g" path="res://src/UI/PerspectiveEditor/PerspectiveEditor.tscn" id="12"] [ext_resource type="PackedScene" uid="uid://dl6ook010q86o" path="res://src/UI/Recorder/Recorder.tscn" id="13"] [ext_resource type="Script" path="res://addons/dockable_container/layout.gd" id="14"] @@ -310,7 +310,7 @@ camera_path = NodePath("SubViewport/Camera2D") [node name="SubViewport" type="SubViewport" parent="DockableContainer/Main Canvas/ViewportandVerticalRuler/SubViewportContainer"] handle_input_locally = false canvas_item_default_texture_filter = 0 -size = Vector2i(867, 513) +size = Vector2i(862, 515) render_target_update_mode = 4 [node name="TransparentChecker" parent="DockableContainer/Main Canvas/ViewportandVerticalRuler/SubViewportContainer/SubViewport" instance=ExtResource("5")] From 201c9e46b78771197e3a00308588a448fa476bc2 Mon Sep 17 00:00:00 2001 From: TheLsbt Date: Mon, 18 Dec 2023 22:48:53 +0200 Subject: [PATCH 02/31] Fixed static typing Fixed static typing in "src\UI \ReferenceImages\ReferenceEditPanel.gd" Changed "ri == null" to "!ri" in "src\UI\Canvas\ReferenceImages.gd" --- src/UI/Canvas/ReferenceImages.gd | 2 +- src/UI/ReferenceImages/ReferenceEditPanel.gd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/UI/Canvas/ReferenceImages.gd b/src/UI/Canvas/ReferenceImages.gd index 1924393c6708..acebe1809948 100644 --- a/src/UI/Canvas/ReferenceImages.gd +++ b/src/UI/Canvas/ReferenceImages.gd @@ -246,7 +246,7 @@ func _update_on_zoom() -> void: func get_undo_data() -> Dictionary: var ri : ReferenceImage = Global.current_project.get_current_reference_image() - if ri == null: + if !ri: return {} var data := {} diff --git a/src/UI/ReferenceImages/ReferenceEditPanel.gd b/src/UI/ReferenceImages/ReferenceEditPanel.gd index 8136f715095b..74db1d89deba 100644 --- a/src/UI/ReferenceImages/ReferenceEditPanel.gd +++ b/src/UI/ReferenceImages/ReferenceEditPanel.gd @@ -128,7 +128,7 @@ func _on_Remove_pressed(): if Input.is_action_pressed("shift"): reference_image_container.remove_reference_image(index) else: - var dialog = ConfirmationDialog.new() + var dialog := ConfirmationDialog.new() dialog.dialog_text = " Are you sure you want to remove this image?" dialog.ok_button_text = "Yes" dialog.cancel_button_text = "No" From fdec874563ba20f9769aefd8c045d295b56b4e00 Mon Sep 17 00:00:00 2001 From: TheLsbt Date: Mon, 18 Dec 2023 23:39:15 +0200 Subject: [PATCH 03/31] Tried fixing the static typing again Removed lambda functions for the confirmation dialog. Removed irrelevant print statement. --- src/UI/Canvas/ReferenceImages.gd | 1 - src/UI/ReferenceImages/ReferenceEditPanel.gd | 34 ++++++++------------ src/UI/ReferenceImages/ReferencesPanel.tscn | 7 ++++ 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/UI/Canvas/ReferenceImages.gd b/src/UI/Canvas/ReferenceImages.gd index acebe1809948..7d762319ba5e 100644 --- a/src/UI/Canvas/ReferenceImages.gd +++ b/src/UI/Canvas/ReferenceImages.gd @@ -285,7 +285,6 @@ func commit_undo(action: String, undo_data_tmp: Dictionary) -> void: ri, key, undo_data_tmp.get(key) ) - print(redo_data.get("overlay_color")) project.undo_redo.add_do_method(Global.general_redo.bind(project)) project.undo_redo.add_do_method(ri.change_properties) diff --git a/src/UI/ReferenceImages/ReferenceEditPanel.gd b/src/UI/ReferenceImages/ReferenceEditPanel.gd index 74db1d89deba..1e6f77c0af24 100644 --- a/src/UI/ReferenceImages/ReferenceEditPanel.gd +++ b/src/UI/ReferenceImages/ReferenceEditPanel.gd @@ -3,6 +3,8 @@ extends PanelContainer var _ignore_spinbox_changes: bool = false var _prev_index: int = -1 +@onready var confirm_remove_dialog := $ConfirmRemoveDialog as ConfirmationDialog + var reference_image_container: Node2D: get: return Global.canvas.reference_image_container @@ -128,27 +130,10 @@ func _on_Remove_pressed(): if Input.is_action_pressed("shift"): reference_image_container.remove_reference_image(index) else: - var dialog := ConfirmationDialog.new() - dialog.dialog_text = " Are you sure you want to remove this image?" - dialog.ok_button_text = "Yes" - dialog.cancel_button_text = "No" - Global.control.get_node("Dialogs").add_child(dialog) - dialog.position = Global.control.get_global_mouse_position() - dialog.popup() + confirm_remove_dialog.position = Global.control.get_global_mouse_position() + confirm_remove_dialog.popup() Global.dialog_open(true) - # Signals - dialog.confirmed.connect( - func(): - reference_image_container.remove_reference_image(index) - dialog.queue_free() - Global.dialog_open(false) - ) - dialog.canceled.connect( - func(): - dialog.queue_free() - Global.dialog_open(false) - ) - + func _on_X_value_changed(value: float): if _ignore_spinbox_changes: @@ -234,6 +219,15 @@ func _on_ColorClamping_value_changed(value: float): func _on_timer_timeout() -> void: reference_image_container.commit_undo("Reference Image Changed", undo_data) +func _on_remove_confirm_dialog_confirmed() -> void: + var index : int = get_parent().list_btn_group.get_pressed_button().get_index() - 1 + if index > -1: + reference_image_container.remove_reference_image(index) + Global.dialog_open(false) + +func _on_confirm_remove_dialog_canceled() -> void: + Global.dialog_open(false) + func _on_reference_image_porperties_changed() -> void: _update_properties() diff --git a/src/UI/ReferenceImages/ReferencesPanel.tscn b/src/UI/ReferenceImages/ReferencesPanel.tscn index e287eb798cbe..ab171e1c1ef3 100644 --- a/src/UI/ReferenceImages/ReferencesPanel.tscn +++ b/src/UI/ReferenceImages/ReferencesPanel.tscn @@ -200,6 +200,11 @@ script = ExtResource("2_1qu4x") wait_time = 0.2 one_shot = true +[node name="ConfirmRemoveDialog" type="ConfirmationDialog" parent="ReferenceEditPanel"] +size = Vector2i(443, 100) +visible = true +dialog_text = "Are you sure you want to remove this reference image?" + [connection signal="pressed" from="ReferenceEditPanel/ReferenceEdit/ImageOptions/Remove" to="ReferenceEditPanel" method="_on_Remove_pressed"] [connection signal="toggled" from="ReferenceEditPanel/ReferenceEdit/Tools/Filter" to="ReferenceEditPanel" method="_on_Filter_toggled"] [connection signal="pressed" from="ReferenceEditPanel/ReferenceEdit/Options/Reset" to="ReferenceEditPanel" method="_on_Reset_pressed"] @@ -212,3 +217,5 @@ one_shot = true [connection signal="value_changed" from="ReferenceEditPanel/ReferenceEdit/Options/Opacity" to="ReferenceEditPanel" method="_on_Opacity_value_changed"] [connection signal="value_changed" from="ReferenceEditPanel/ReferenceEdit/Options/ColorClamping" to="ReferenceEditPanel" method="_on_ColorClamping_value_changed"] [connection signal="timeout" from="ReferenceEditPanel/Timer" to="ReferenceEditPanel" method="_on_timer_timeout"] +[connection signal="canceled" from="ReferenceEditPanel/ConfirmRemoveDialog" to="ReferenceEditPanel" method="_on_confirm_remove_dialog_canceled"] +[connection signal="confirmed" from="ReferenceEditPanel/ConfirmRemoveDialog" to="ReferenceEditPanel" method="_on_remove_confirm_dialog_confirmed"] From 51afd129773caac2abbfe90c3b035a2d38c7aba4 Mon Sep 17 00:00:00 2001 From: TheLsbt Date: Tue, 19 Dec 2023 00:11:15 +0200 Subject: [PATCH 04/31] Tried fixing static typing again I think its fixed now --- src/Classes/Project.gd | 2 +- src/UI/Canvas/ReferenceImages.gd | 88 ++++++++++---------- src/UI/ReferenceImages/ReferenceEditPanel.gd | 26 ++++-- src/UI/ReferenceImages/ReferencesPanel.gd | 8 +- 4 files changed, 71 insertions(+), 53 deletions(-) diff --git a/src/Classes/Project.gd b/src/Classes/Project.gd index f69101e98fe1..19da0883816c 100644 --- a/src/Classes/Project.gd +++ b/src/Classes/Project.gd @@ -45,7 +45,7 @@ var animation_tags: Array[AnimationTag] = []: var guides: Array[Guide] = [] var brushes: Array[Image] = [] var reference_images: Array[ReferenceImage] = [] -var reference_index: int = -1 # The currently selected index ReferenceImage +var reference_index: int = -1 # The currently selected index ReferenceImage var vanishing_points := [] ## Array of Vanishing Points var fps := 6.0 diff --git a/src/UI/Canvas/ReferenceImages.gd b/src/UI/Canvas/ReferenceImages.gd index 7d762319ba5e..9e942bdcb71a 100644 --- a/src/UI/Canvas/ReferenceImages.gd +++ b/src/UI/Canvas/ReferenceImages.gd @@ -6,35 +6,34 @@ signal reference_image_changed(index: int) const MenuLabelMaxLength := 22 -enum MenuPopulation {Mouse, All} +enum MenuPopulation { Mouse, All } var index: int: - get: return Global.current_project.reference_index + get: + return Global.current_project.reference_index var drag_start_pos: Vector2 var dragging := false -var lmb_held := false ## Holds whether the LBB is being held (use dragging for actual checks) +var lmb_held := false ## Holds whether the LBB is being held (use dragging for actual checks) # Original Transform var og_pos: Vector2 var og_scale: Vector2 var og_rotation: float -var undo_data : Dictionary +var undo_data: Dictionary var reference_menu:= PopupMenu.new() func _ready() -> void: Global.camera.zoom_changed.connect(_update_on_zoom) - Global.control.get_node("Dialogs").add_child(reference_menu) + Global.control.get_node("Dialogs").add_child(reference_menu) # Makes sure that the dark overlay disapears when the popup is hidden - reference_menu.visibility_changed.connect( - func(): Global.dialog_open(reference_menu.visible) - ) + reference_menu.visibility_changed.connect(func(): Global.dialog_open(reference_menu.visible)) # Emiited when a item is selected from the menu reference_menu.id_pressed.connect(_reference_menu_id_pressed) - + ## Updates the index and configures the "gizmo" func update_index(new_index: int) -> void: @@ -42,6 +41,7 @@ func update_index(new_index: int) -> void: reference_image_changed.emit(new_index) queue_redraw() + func _input(event: InputEvent) -> void: var local_mouse_pos := get_local_mouse_position() @@ -111,20 +111,17 @@ func _input(event: InputEvent) -> void: # 3. There are no Reference Images else: Global.current_project.set_reference_image_index(-1) - undo_data.clear() dragging = false lmb_held = false - - if event is InputEventMouseMotion: # We check if the LMB is pressed and if we're not dragging then we force the # draggin state. # We dont use timers becuase it makes more sense to wait fot the users mouse to move # and thats what defines dragging. It would be smart to add a "deadzone" to determine - # if the mouse had moved enough. + # if the mouse had moved enough. if lmb_held and !dragging: dragging = true @@ -134,29 +131,30 @@ func _input(event: InputEvent) -> void: # Scale if Input.is_action_pressed("reference_scale"): scale_reference_image(local_mouse_pos, ri) - text = str("Moving: ", - (og_scale * 100).floor(), " -> ", (ri.scale * 100).floor() - ) + text = str("Moving: ", (og_scale * 100).floor(), " -> ", (ri.scale * 100).floor()) # Rotate elif Input.is_action_pressed("reference_rotate"): rotate_reference_image(local_mouse_pos, ri) - text = str("Rotating: ", - floorf(rad_to_deg(og_rotation)), "° -> ", floorf(rad_to_deg(ri.rotation)), "°" - ) + text = str( + "Rotating: ", + floorf(rad_to_deg(og_rotation)), + "° -> ", + floorf(rad_to_deg(ri.rotation)), + "°" + ) else: move_reference_image(local_mouse_pos, ri) - text = str("Scaling to: ", - og_pos.floor(), " -> ", ri.position.floor() - ) + text = str("Scaling to: ", og_pos.floor(), " -> ", ri.position.floor()) Global.cursor_position_label.text = text - # Getting the mouse cursor queue_redraw() + ## Uniformly scales the [ReferenceImage] using this nodes "local_mouse_position". func scale_reference_image(mouse_pos: Vector2, img: ReferenceImage) -> void: - var s = (Vector2.ONE + var s = ( + Vector2.ONE * minf( float(mouse_pos.x - drag_start_pos.x), float(mouse_pos.y - drag_start_pos.y), @@ -165,14 +163,16 @@ func scale_reference_image(mouse_pos: Vector2, img: ReferenceImage) -> void: img.scale = (og_scale + (s / 100.0)) + ## Rotate the [ReferenceImage] using this nodes "local_mouse_position". func rotate_reference_image(mouse_pos: Vector2, img: ReferenceImage) -> void: - var starting_angle = (og_rotation - og_pos.angle_to_point(drag_start_pos)) + var starting_angle = og_rotation - og_pos.angle_to_point(drag_start_pos) var new_angle = img.position.angle_to_point(mouse_pos) var angle = starting_angle + new_angle angle = deg_to_rad(floorf(rad_to_deg(wrapf(angle, -PI, PI)))) img.rotation = angle + ## Move the [ReferenceImage] using this nodes "local_mouse_position". func move_reference_image(mouse_pos: Vector2, img: ReferenceImage) -> void: img.position = (mouse_pos - (drag_start_pos - og_pos)).floor() @@ -183,7 +183,7 @@ func get_reference_polygon(i: int) -> PackedVector2Array: if i < 0: return [] - var ri : ReferenceImage = Global.current_project.reference_images[i] + var ri: ReferenceImage = Global.current_project.reference_images[i] var rect := ri.get_rect() var poly = get_transformed_rect_polygon(rect, ri.transform) return poly @@ -197,21 +197,23 @@ func get_transformed_rect_polygon(rect: Rect2, t: Transform2D) -> PackedVector2A rect.size *= t.get_scale() # We create a polygon based on the Rect2 - var p : PackedVector2Array = [ - rect.position, Vector2(rect.end.x, rect.position.y), - rect.end, Vector2(rect.position.x, rect.end.y) + var p: PackedVector2Array = [ + rect.position, + Vector2(rect.end.x, rect.position.y), + rect.end, + Vector2(rect.position.x, rect.end.y) ] - # Finally rotate and move the polygon - var final : PackedVector2Array = [] - for v : Vector2 in p: + # Finally rotate and move the polygon + var final: PackedVector2Array = [] + for v: Vector2 in p: var vert := v.rotated(t.get_rotation()) + t.get_origin() final.append(vert) return final -func populate_reference_menu(items: Array[ReferenceImage], default:= false): +func populate_reference_menu(items: Array[ReferenceImage], default := false): reference_menu.clear() # Default / Reset if default: @@ -220,7 +222,7 @@ func populate_reference_menu(items: Array[ReferenceImage], default:= false): for ri: ReferenceImage in items: var idx: int = ri.get_index() + 1 - var label: String = "(%o) %s" %[idx, ri.image_path] + var label: String = "(%o) %s" % [idx, ri.image_path] # We trim the length of the title label = label.left(MenuLabelMaxLength) + "..." reference_menu.add_item(label, idx) @@ -232,6 +234,7 @@ func _reference_menu_id_pressed(id: int) -> void: Global.current_project.set_reference_image_index(id - 1) reference_menu.hide() + func remove_reference_image(idx: int) -> void: var ri: ReferenceImage = Global.current_project.get_reference_image(idx) Global.current_project.reference_images.remove_at(idx) @@ -240,11 +243,13 @@ func remove_reference_image(idx: int) -> void: Global.current_project.change_project() Global.control.ui.find_child("Reference Images")._on_references_changed() + func _update_on_zoom() -> void: queue_redraw() + func get_undo_data() -> Dictionary: - var ri : ReferenceImage = Global.current_project.get_current_reference_image() + var ri: ReferenceImage = Global.current_project.get_current_reference_image() if !ri: return {} @@ -260,6 +265,7 @@ func get_undo_data() -> Dictionary: return data + func commit_undo(action: String, undo_data_tmp: Dictionary) -> void: if !undo_data_tmp: print("No undo data found for ReferenceImages.gd!") @@ -278,12 +284,8 @@ func commit_undo(action: String, undo_data_tmp: Dictionary) -> void: for key in undo_data_tmp.keys(): if redo_data.has(key): - project.undo_redo.add_do_property( - ri, key, redo_data.get(key) - ) - project.undo_redo.add_undo_property( - ri, key, undo_data_tmp.get(key) - ) + project.undo_redo.add_do_property(ri, key, redo_data.get(key)) + project.undo_redo.add_undo_property(ri, key, undo_data_tmp.get(key)) project.undo_redo.add_do_method(Global.general_redo.bind(project)) @@ -293,7 +295,7 @@ func commit_undo(action: String, undo_data_tmp: Dictionary) -> void: project.undo_redo.commit_action() undo_data.clear() - + func _draw() -> void: if index < 0: @@ -308,7 +310,7 @@ func _draw() -> void: draw_polyline(prev_poly, Color(1, 0.29, 0.29), line_width) # First we highlight the Reference Images under the mouse with yellow - for ri : ReferenceImage in Global.current_project.reference_images: + for ri: ReferenceImage in Global.current_project.reference_images: var p := get_transformed_rect_polygon(ri.get_rect(), ri.transform) p.append(p[0]) if ri.get_index() == index: diff --git a/src/UI/ReferenceImages/ReferenceEditPanel.gd b/src/UI/ReferenceImages/ReferenceEditPanel.gd index 1e6f77c0af24..dada9eb8b1ef 100644 --- a/src/UI/ReferenceImages/ReferenceEditPanel.gd +++ b/src/UI/ReferenceImages/ReferenceEditPanel.gd @@ -8,12 +8,15 @@ var _prev_index: int = -1 var reference_image_container: Node2D: get: return Global.canvas.reference_image_container -var undo_data : Dictionary +var undo_data: Dictionary @onready var timer := $Timer as Timer + func _ready() -> void: - Global.canvas.reference_image_container.reference_image_changed.connect(_on_reference_image_changed) + Global.canvas.reference_image_container.reference_image_changed.connect( + _on_reference_image_changed + ) func _update_properties(): @@ -59,6 +62,7 @@ func _update_properties(): # Fore update the "gizmo" drawing Global.canvas.reference_image_container.queue_redraw() + func _reset_properties() -> void: # This is because otherwise a little dance will occur. # This also breaks non-uniform scales (not supported UI-wise, but...) @@ -89,6 +93,7 @@ func _reset_properties() -> void: # Fore update the "gizmo" drawing Global.canvas.reference_image_container.queue_redraw() + func _on_Monochrome_toggled(pressed: bool) -> void: if _ignore_spinbox_changes: return @@ -100,6 +105,7 @@ func _on_Monochrome_toggled(pressed: bool) -> void: timer.start() ri.monochrome = pressed + func _on_Filter_toggled(pressed: bool) -> void: if _ignore_spinbox_changes: return @@ -111,6 +117,7 @@ func _on_Filter_toggled(pressed: bool) -> void: timer.start() ri.filter = pressed + func _on_Reset_pressed(): var ri: ReferenceImage = Global.current_project.get_current_reference_image() if !ri: @@ -124,7 +131,7 @@ func _on_Remove_pressed(): var ri: ReferenceImage = Global.current_project.get_current_reference_image() if !ri: return - var index : int = get_parent().list_btn_group.get_pressed_button().get_index() - 1 + var index: int = get_parent().list_btn_group.get_pressed_button().get_index() - 1 if index > -1: # If shift is pressed we just remove it without a dialog if Input.is_action_pressed("shift"): @@ -158,6 +165,7 @@ func _on_Y_value_changed(value: float): timer.start() ri.position.y = value + func _on_Scale_value_changed(value: float): if _ignore_spinbox_changes: return @@ -170,6 +178,7 @@ func _on_Scale_value_changed(value: float): ri.scale.x = value / 100 ri.scale.y = value / 100 + func _on_Rotation_value_changed(value: float): if _ignore_spinbox_changes: return @@ -205,6 +214,7 @@ func _on_Opacity_value_changed(value: float): timer.start() ri.overlay_color.a = value / 100 + func _on_ColorClamping_value_changed(value: float): if _ignore_spinbox_changes: return @@ -216,15 +226,18 @@ func _on_ColorClamping_value_changed(value: float): timer.start() ri.color_clamping = value / 100 + func _on_timer_timeout() -> void: reference_image_container.commit_undo("Reference Image Changed", undo_data) + func _on_remove_confirm_dialog_confirmed() -> void: - var index : int = get_parent().list_btn_group.get_pressed_button().get_index() - 1 + var index: int = get_parent().list_btn_group.get_pressed_button().get_index() - 1 if index > -1: reference_image_container.remove_reference_image(index) Global.dialog_open(false) + func _on_confirm_remove_dialog_canceled() -> void: Global.dialog_open(false) @@ -239,13 +252,14 @@ func _on_reference_image_changed(index: int) -> void: return # Disconnect the previously selected one if _prev_index > -1: - var prev_ri : ReferenceImage = Global.current_project.get_reference_image(_prev_index) + var prev_ri: ReferenceImage = Global.current_project.get_reference_image(_prev_index) if prev_ri.properties_changed.is_connected(_on_reference_image_porperties_changed): prev_ri.properties_changed.disconnect(_on_reference_image_porperties_changed) # Connect the new Reference image (if it is one) if index > -1: Global.current_project.reference_images[index].properties_changed.connect( - _on_reference_image_porperties_changed) + _on_reference_image_porperties_changed + ) _prev_index = index diff --git a/src/UI/ReferenceImages/ReferencesPanel.gd b/src/UI/ReferenceImages/ReferencesPanel.gd index 462f4cc8ddbe..27c5967d28a8 100644 --- a/src/UI/ReferenceImages/ReferencesPanel.gd +++ b/src/UI/ReferenceImages/ReferencesPanel.gd @@ -8,17 +8,20 @@ var list_btn_group := ButtonGroup.new() func _ready() -> void: list_btn_group.pressed.connect(_on_reference_image_button_pressed) - Global.canvas.reference_image_container.reference_image_changed.connect(_on_reference_image_changed) + Global.canvas.reference_image_container.reference_image_changed.connect( + _on_reference_image_changed + ) OpenSave.reference_image_imported.connect(_on_references_changed) # We call this funtion to update the buttons _on_references_changed() - + func _on_reference_image_button_pressed(button: Button) -> void: # We subtract 1 because we already have a default button to "select no reference image Global.current_project.set_reference_image_index(button.get_index() - 1) + # In case the signal is emited for another node and not from a pressed button func _on_reference_image_changed(index: int) -> void: if list_btn_group.get_buttons().size() > 0: @@ -29,7 +32,6 @@ func _on_reference_image_changed(index: int) -> void: b.set_pressed_no_signal(true) else: b.set_pressed_no_signal(false) - func _on_references_changed(): From f3a0525f58b9aca40886e14c47407e866aa50ae7 Mon Sep 17 00:00:00 2001 From: TheLsbt Date: Tue, 19 Dec 2023 01:00:31 +0200 Subject: [PATCH 05/31] Changed Spacing --- src/UI/Canvas/ReferenceImages.gd | 55 +++++++++----------- src/UI/ReferenceImages/ReferenceEditPanel.gd | 19 +++---- src/UI/ReferenceImages/ReferencesPanel.gd | 7 ++- 3 files changed, 37 insertions(+), 44 deletions(-) diff --git a/src/UI/Canvas/ReferenceImages.gd b/src/UI/Canvas/ReferenceImages.gd index 9e942bdcb71a..d212da34b833 100644 --- a/src/UI/Canvas/ReferenceImages.gd +++ b/src/UI/Canvas/ReferenceImages.gd @@ -22,7 +22,7 @@ var og_rotation: float var undo_data: Dictionary -var reference_menu:= PopupMenu.new() +var reference_menu := PopupMenu.new() func _ready() -> void: @@ -57,7 +57,7 @@ func _input(event: InputEvent) -> void: if !ri: Global.can_draw = true return - + # Check if want to cancelthe reference transform if event.is_action_pressed("cancel_reference_transform") and dragging: ri.position = og_pos @@ -66,9 +66,8 @@ func _input(event: InputEvent) -> void: dragging = false Global.can_draw = true commit_undo("Cancel Transform Content", undo_data) - #queue_redraw() return - + if event is InputEventMouseButton: if event.button_index == MOUSE_BUTTON_LEFT: if event.is_pressed(): @@ -89,7 +88,7 @@ func _input(event: InputEvent) -> void: commit_undo("Transform Content", undo_data) else: # Overlapping reference images - var overlapping : Array[ReferenceImage] = [] + var overlapping: Array[ReferenceImage] = [] for idx: int in Global.current_project.reference_images.size(): var r = Global.current_project.reference_images[idx] @@ -97,7 +96,7 @@ func _input(event: InputEvent) -> void: var p := get_reference_polygon(idx) if Geometry2D.is_point_in_polygon(local_mouse_pos, p): overlapping.append(r) - + # Some special cases # 1. There is only one Reference Image if overlapping.size() == 1: @@ -111,11 +110,11 @@ func _input(event: InputEvent) -> void: # 3. There are no Reference Images else: Global.current_project.set_reference_image_index(-1) - + undo_data.clear() dragging = false lmb_held = false - + if event is InputEventMouseMotion: # We check if the LMB is pressed and if we're not dragging then we force the # draggin state. @@ -124,10 +123,10 @@ func _input(event: InputEvent) -> void: # if the mouse had moved enough. if lmb_held and !dragging: dragging = true - + if dragging: var text := "" - + # Scale if Input.is_action_pressed("reference_scale"): scale_reference_image(local_mouse_pos, ri) @@ -141,13 +140,13 @@ func _input(event: InputEvent) -> void: "° -> ", floorf(rad_to_deg(ri.rotation)), "°" - ) + ) else: move_reference_image(local_mouse_pos, ri) text = str("Scaling to: ", og_pos.floor(), " -> ", ri.position.floor()) - + Global.cursor_position_label.text = text - + queue_redraw() @@ -160,7 +159,7 @@ func scale_reference_image(mouse_pos: Vector2, img: ReferenceImage) -> void: float(mouse_pos.y - drag_start_pos.y), ) ) - + img.scale = (og_scale + (s / 100.0)) @@ -182,7 +181,7 @@ func move_reference_image(mouse_pos: Vector2, img: ReferenceImage) -> void: func get_reference_polygon(i: int) -> PackedVector2Array: if i < 0: return [] - + var ri: ReferenceImage = Global.current_project.reference_images[i] var rect := ri.get_rect() var poly = get_transformed_rect_polygon(rect, ri.transform) @@ -195,7 +194,7 @@ func get_transformed_rect_polygon(rect: Rect2, t: Transform2D) -> PackedVector2A # First we scale the Rect2 rect.position *= t.get_scale() rect.size *= t.get_scale() - + # We create a polygon based on the Rect2 var p: PackedVector2Array = [ rect.position, @@ -203,13 +202,13 @@ func get_transformed_rect_polygon(rect: Rect2, t: Transform2D) -> PackedVector2A rect.end, Vector2(rect.position.x, rect.end.y) ] - + # Finally rotate and move the polygon var final: PackedVector2Array = [] for v: Vector2 in p: var vert := v.rotated(t.get_rotation()) + t.get_origin() final.append(vert) - + return final @@ -219,7 +218,7 @@ func populate_reference_menu(items: Array[ReferenceImage], default := false): if default: reference_menu.add_item("None", 0) reference_menu.add_separator() - + for ri: ReferenceImage in items: var idx: int = ri.get_index() + 1 var label: String = "(%o) %s" % [idx, ri.image_path] @@ -250,10 +249,10 @@ func _update_on_zoom() -> void: func get_undo_data() -> Dictionary: var ri: ReferenceImage = Global.current_project.get_current_reference_image() - + if !ri: return {} - + var data := {} data["position"] = ri.position data["scale"] = ri.scale @@ -262,7 +261,6 @@ func get_undo_data() -> Dictionary: data["filter"] = ri.filter data["monochrome"] = ri.monochrome data["color_clamping"] = ri.color_clamping - return data @@ -270,29 +268,28 @@ func commit_undo(action: String, undo_data_tmp: Dictionary) -> void: if !undo_data_tmp: print("No undo data found for ReferenceImages.gd!") return - + var ri: ReferenceImage = Global.current_project.get_current_reference_image() if !ri: print("No Reference Image ReferenceImages.gd!") return - + var redo_data: Dictionary = get_undo_data() var project := Global.current_project project.undos += 1 project.undo_redo.create_action(action) - + for key in undo_data_tmp.keys(): if redo_data.has(key): project.undo_redo.add_do_property(ri, key, redo_data.get(key)) project.undo_redo.add_undo_property(ri, key, undo_data_tmp.get(key)) - - + project.undo_redo.add_do_method(Global.general_redo.bind(project)) project.undo_redo.add_do_method(ri.change_properties) project.undo_redo.add_undo_method(Global.general_undo.bind(project)) project.undo_redo.add_undo_method(ri.change_properties) - + project.undo_redo.commit_action() undo_data.clear() @@ -308,7 +305,7 @@ func _draw() -> void: var prev_poly := get_transformed_rect_polygon(i.get_rect(), prev_transform) prev_poly.append(prev_poly[0]) draw_polyline(prev_poly, Color(1, 0.29, 0.29), line_width) - + # First we highlight the Reference Images under the mouse with yellow for ri: ReferenceImage in Global.current_project.reference_images: var p := get_transformed_rect_polygon(ri.get_rect(), ri.transform) diff --git a/src/UI/ReferenceImages/ReferenceEditPanel.gd b/src/UI/ReferenceImages/ReferenceEditPanel.gd index dada9eb8b1ef..09875324d008 100644 --- a/src/UI/ReferenceImages/ReferenceEditPanel.gd +++ b/src/UI/ReferenceImages/ReferenceEditPanel.gd @@ -26,16 +26,16 @@ func _update_properties(): # This is because otherwise a little dance will occur. # This also breaks non-uniform scales (not supported UI-wise, but...) _ignore_spinbox_changes = true - + # Image Path if OS.get_name() == "Web": $ReferenceEdit/ImageOptions/ImagePath.disabled = true else: $ReferenceEdit/ImageOptions/ImagePath.disabled = false - + $ReferenceEdit/ImageOptions/ImagePath.text = ri.image_path $ReferenceEdit/ImageOptions/ImagePath.tooltip_text = ri.image_path - + if !ri.texture: $ReferenceEdit/ImageOptions/WarningLabel.visible = true $ReferenceEdit/ImageOptions/ImagePath.visible = false @@ -51,14 +51,14 @@ func _update_properties(): $ReferenceEdit/Options/Position/Y.max_value = ri.project.size.y $ReferenceEdit/Options/Scale.value = ri.scale.x * 100 $ReferenceEdit/Options/Rotation.value = ri.rotation_degrees - + # Color $ReferenceEdit/Options/Monochrome.button_pressed = ri.monochrome $ReferenceEdit/Options/Overlay.color = Color(ri.overlay_color, 1.0) $ReferenceEdit/Options/Opacity.value = ri.overlay_color.a * 100 $ReferenceEdit/Options/ColorClamping.value = ri.color_clamping * 100 _ignore_spinbox_changes = false - + # Fore update the "gizmo" drawing Global.canvas.reference_image_container.queue_redraw() @@ -70,10 +70,8 @@ func _reset_properties() -> void: $ReferenceEdit/ImageOptions/ImagePath.text = "None" $ReferenceEdit/ImageOptions/ImagePath.tooltip_text = "None" $ReferenceEdit/ImageOptions/ImagePath.disabled = true - $ReferenceEdit/ImageOptions/WarningLabel.visible = false $ReferenceEdit/ImageOptions/ImagePath.visible = true - # Tools $ReferenceEdit/Tools/Filter.button_pressed = false # Transform @@ -89,7 +87,6 @@ func _reset_properties() -> void: $ReferenceEdit/Options/Opacity.value = 0.0 $ReferenceEdit/Options/ColorClamping.value = 0.0 _ignore_spinbox_changes = false - # Fore update the "gizmo" drawing Global.canvas.reference_image_container.queue_redraw() @@ -218,7 +215,7 @@ func _on_Opacity_value_changed(value: float): func _on_ColorClamping_value_changed(value: float): if _ignore_spinbox_changes: return - var ri : ReferenceImage = Global.current_project.get_current_reference_image() + var ri: ReferenceImage = Global.current_project.get_current_reference_image() if !ri: return if timer.is_stopped(): @@ -260,9 +257,9 @@ func _on_reference_image_changed(index: int) -> void: Global.current_project.reference_images[index].properties_changed.connect( _on_reference_image_porperties_changed ) - + _prev_index = index - + if index < 0: _reset_properties() else: diff --git a/src/UI/ReferenceImages/ReferencesPanel.gd b/src/UI/ReferenceImages/ReferencesPanel.gd index 27c5967d28a8..dc8b1d2ee18d 100644 --- a/src/UI/ReferenceImages/ReferencesPanel.gd +++ b/src/UI/ReferenceImages/ReferencesPanel.gd @@ -11,7 +11,6 @@ func _ready() -> void: Global.canvas.reference_image_container.reference_image_changed.connect( _on_reference_image_changed ) - OpenSave.reference_image_imported.connect(_on_references_changed) # We call this funtion to update the buttons _on_references_changed() @@ -37,7 +36,7 @@ func _on_reference_image_changed(index: int) -> void: func _on_references_changed(): # When we change the project we set the defualt Global.current_project.set_reference_image_index(-1) - + for c in list.get_children(): if c is Button: c.button_group = null @@ -46,7 +45,7 @@ func _on_references_changed(): for ref in Global.canvas.reference_image_container.get_children(): if ref is ReferenceImage: ref.visible = false - + # The defualt button var defualt = Button.new() defualt.button_group = list_btn_group @@ -55,7 +54,7 @@ func _on_references_changed(): defualt.toggle_mode = true defualt.button_pressed = true list.add_child(defualt) - + # And update. for ref in Global.current_project.reference_images: ref.visible = true From cfcddf69fa7e97ea5035cba9d4a3430cddfffeef Mon Sep 17 00:00:00 2001 From: TheLsbt Date: Tue, 19 Dec 2023 01:12:25 +0200 Subject: [PATCH 06/31] Fixed Trailing Whitespaces and tabs --- src/UI/Canvas/ReferenceImages.gd | 16 ++++++++-------- src/UI/ReferenceImages/ReferenceEditPanel.gd | 1 - 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/UI/Canvas/ReferenceImages.gd b/src/UI/Canvas/ReferenceImages.gd index d212da34b833..658f753a51d9 100644 --- a/src/UI/Canvas/ReferenceImages.gd +++ b/src/UI/Canvas/ReferenceImages.gd @@ -28,7 +28,7 @@ var reference_menu := PopupMenu.new() func _ready() -> void: Global.camera.zoom_changed.connect(_update_on_zoom) Global.control.get_node("Dialogs").add_child(reference_menu) - + # Makes sure that the dark overlay disapears when the popup is hidden reference_menu.visibility_changed.connect(func(): Global.dialog_open(reference_menu.visible)) # Emiited when a item is selected from the menu @@ -44,16 +44,16 @@ func update_index(new_index: int) -> void: func _input(event: InputEvent) -> void: var local_mouse_pos := get_local_mouse_position() - + # Check if that event was for the quick menu (opened by the shortcut) if event.is_action_pressed("reference_quick_menu"): var list: Array[ReferenceImage] = Global.current_project.reference_images populate_reference_menu(list, true) reference_menu.position = Global.control.get_global_mouse_position() reference_menu.popup() - + var ri: ReferenceImage = Global.current_project.get_current_reference_image() - + if !ri: Global.can_draw = true return @@ -66,7 +66,7 @@ func _input(event: InputEvent) -> void: dragging = false Global.can_draw = true commit_undo("Cancel Transform Content", undo_data) - return + return if event is InputEventMouseButton: if event.button_index == MOUSE_BUTTON_LEFT: @@ -80,16 +80,16 @@ func _input(event: InputEvent) -> void: og_pos = ri.position og_scale = ri.scale og_rotation = ri.rotation - + if !event.is_pressed(): Global.can_draw = true - + if dragging: commit_undo("Transform Content", undo_data) else: # Overlapping reference images var overlapping: Array[ReferenceImage] = [] - + for idx: int in Global.current_project.reference_images.size(): var r = Global.current_project.reference_images[idx] # The bounding polygon diff --git a/src/UI/ReferenceImages/ReferenceEditPanel.gd b/src/UI/ReferenceImages/ReferenceEditPanel.gd index 09875324d008..8f18d6bc21ca 100644 --- a/src/UI/ReferenceImages/ReferenceEditPanel.gd +++ b/src/UI/ReferenceImages/ReferenceEditPanel.gd @@ -51,7 +51,6 @@ func _update_properties(): $ReferenceEdit/Options/Position/Y.max_value = ri.project.size.y $ReferenceEdit/Options/Scale.value = ri.scale.x * 100 $ReferenceEdit/Options/Rotation.value = ri.rotation_degrees - # Color $ReferenceEdit/Options/Monochrome.button_pressed = ri.monochrome $ReferenceEdit/Options/Overlay.color = Color(ri.overlay_color, 1.0) From 6d2d5af4c07f4ebb83de4d1d79de662cb5041caf Mon Sep 17 00:00:00 2001 From: TheLsbt Date: Tue, 19 Dec 2023 01:20:22 +0200 Subject: [PATCH 07/31] Fixed Final Trailing Whitespace --- src/UI/Canvas/ReferenceImages.gd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UI/Canvas/ReferenceImages.gd b/src/UI/Canvas/ReferenceImages.gd index 658f753a51d9..e8926363fb99 100644 --- a/src/UI/Canvas/ReferenceImages.gd +++ b/src/UI/Canvas/ReferenceImages.gd @@ -141,7 +141,7 @@ func _input(event: InputEvent) -> void: floorf(rad_to_deg(ri.rotation)), "°" ) - else: + else: move_reference_image(local_mouse_pos, ri) text = str("Scaling to: ", og_pos.floor(), " -> ", ri.position.floor()) From d9d7c71c392989b853034717cbc9c689a5ae3629 Mon Sep 17 00:00:00 2001 From: TheLsbt Date: Tue, 19 Dec 2023 01:38:53 +0200 Subject: [PATCH 08/31] Fixed styling and removed useless enum --- src/UI/Canvas/ReferenceImages.gd | 5 +---- src/UI/ReferenceImages/ReferenceEditPanel.gd | 7 ++++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/UI/Canvas/ReferenceImages.gd b/src/UI/Canvas/ReferenceImages.gd index e8926363fb99..8a89850658e0 100644 --- a/src/UI/Canvas/ReferenceImages.gd +++ b/src/UI/Canvas/ReferenceImages.gd @@ -4,9 +4,6 @@ extends Node2D signal reference_image_changed(index: int) -const MenuLabelMaxLength := 22 - -enum MenuPopulation { Mouse, All } var index: int: get: @@ -223,7 +220,7 @@ func populate_reference_menu(items: Array[ReferenceImage], default := false): var idx: int = ri.get_index() + 1 var label: String = "(%o) %s" % [idx, ri.image_path] # We trim the length of the title - label = label.left(MenuLabelMaxLength) + "..." + label = label.left(22) + "..." reference_menu.add_item(label, idx) diff --git a/src/UI/ReferenceImages/ReferenceEditPanel.gd b/src/UI/ReferenceImages/ReferenceEditPanel.gd index 8f18d6bc21ca..3aa2ad204492 100644 --- a/src/UI/ReferenceImages/ReferenceEditPanel.gd +++ b/src/UI/ReferenceImages/ReferenceEditPanel.gd @@ -1,15 +1,16 @@ extends PanelContainer -var _ignore_spinbox_changes: bool = false -var _prev_index: int = -1 -@onready var confirm_remove_dialog := $ConfirmRemoveDialog as ConfirmationDialog +var _prev_index: int = -1 +var _ignore_spinbox_changes: bool = false var reference_image_container: Node2D: get: return Global.canvas.reference_image_container + var undo_data: Dictionary +@onready var confirm_remove_dialog := $ConfirmRemoveDialog as ConfirmationDialog @onready var timer := $Timer as Timer From f6cf4460f84c790b46aaccada97353515652b8bf Mon Sep 17 00:00:00 2001 From: TheLsbt Date: Tue, 19 Dec 2023 01:50:10 +0200 Subject: [PATCH 09/31] Removed double tabs left over from previous commit --- src/UI/Canvas/ReferenceImages.gd | 1 - src/UI/ReferenceImages/ReferenceEditPanel.gd | 1 - 2 files changed, 2 deletions(-) diff --git a/src/UI/Canvas/ReferenceImages.gd b/src/UI/Canvas/ReferenceImages.gd index 8a89850658e0..cc6f358cd960 100644 --- a/src/UI/Canvas/ReferenceImages.gd +++ b/src/UI/Canvas/ReferenceImages.gd @@ -4,7 +4,6 @@ extends Node2D signal reference_image_changed(index: int) - var index: int: get: return Global.current_project.reference_index diff --git a/src/UI/ReferenceImages/ReferenceEditPanel.gd b/src/UI/ReferenceImages/ReferenceEditPanel.gd index 3aa2ad204492..c0e7a2c8ac8a 100644 --- a/src/UI/ReferenceImages/ReferenceEditPanel.gd +++ b/src/UI/ReferenceImages/ReferenceEditPanel.gd @@ -1,6 +1,5 @@ extends PanelContainer - var _prev_index: int = -1 var _ignore_spinbox_changes: bool = false From d010e97c40755cf1c5804f5c94581e7f4eea49a0 Mon Sep 17 00:00:00 2001 From: TheLsbt Date: Tue, 19 Dec 2023 11:50:31 +0200 Subject: [PATCH 10/31] Fixed remove ConfirmDialog Showing on startusp --- src/UI/ReferenceImages/ReferenceEditPanel.gd | 5 +---- src/UI/ReferenceImages/ReferencesPanel.tscn | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/UI/ReferenceImages/ReferenceEditPanel.gd b/src/UI/ReferenceImages/ReferenceEditPanel.gd index c0e7a2c8ac8a..23a1e0d0b668 100644 --- a/src/UI/ReferenceImages/ReferenceEditPanel.gd +++ b/src/UI/ReferenceImages/ReferenceEditPanel.gd @@ -3,14 +3,11 @@ extends PanelContainer var _prev_index: int = -1 var _ignore_spinbox_changes: bool = false -var reference_image_container: Node2D: - get: - return Global.canvas.reference_image_container - var undo_data: Dictionary @onready var confirm_remove_dialog := $ConfirmRemoveDialog as ConfirmationDialog @onready var timer := $Timer as Timer +@onready var reference_image_container := Global.canvas.reference_image_container as Node2D func _ready() -> void: diff --git a/src/UI/ReferenceImages/ReferencesPanel.tscn b/src/UI/ReferenceImages/ReferencesPanel.tscn index ab171e1c1ef3..8e5e540dae64 100644 --- a/src/UI/ReferenceImages/ReferencesPanel.tscn +++ b/src/UI/ReferenceImages/ReferencesPanel.tscn @@ -202,7 +202,6 @@ one_shot = true [node name="ConfirmRemoveDialog" type="ConfirmationDialog" parent="ReferenceEditPanel"] size = Vector2i(443, 100) -visible = true dialog_text = "Are you sure you want to remove this reference image?" [connection signal="pressed" from="ReferenceEditPanel/ReferenceEdit/ImageOptions/Remove" to="ReferenceEditPanel" method="_on_Remove_pressed"] From 366d5061eef3faf0b8cf96b84c783ddb3f730dbb Mon Sep 17 00:00:00 2001 From: TheLsbt Date: Tue, 19 Dec 2023 12:16:44 +0200 Subject: [PATCH 11/31] Tried Fixing gdlint issues --- src/UI/ReferenceImages/ReferenceEditPanel.gd | 31 ++++++++++---------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/UI/ReferenceImages/ReferenceEditPanel.gd b/src/UI/ReferenceImages/ReferenceEditPanel.gd index 23a1e0d0b668..bc7593644adc 100644 --- a/src/UI/ReferenceImages/ReferenceEditPanel.gd +++ b/src/UI/ReferenceImages/ReferenceEditPanel.gd @@ -7,7 +7,6 @@ var undo_data: Dictionary @onready var confirm_remove_dialog := $ConfirmRemoveDialog as ConfirmationDialog @onready var timer := $Timer as Timer -@onready var reference_image_container := Global.canvas.reference_image_container as Node2D func _ready() -> void: @@ -94,7 +93,7 @@ func _on_Monochrome_toggled(pressed: bool) -> void: if !ri: return if timer.is_stopped(): - undo_data = reference_image_container.get_undo_data() + undo_data = Global.canvas.reference_image_container.get_undo_data() timer.start() ri.monochrome = pressed @@ -106,7 +105,7 @@ func _on_Filter_toggled(pressed: bool) -> void: if !ri: return if timer.is_stopped(): - undo_data = reference_image_container.get_undo_data() + undo_data = Global.canvas.reference_image_container.get_undo_data() timer.start() ri.filter = pressed @@ -115,9 +114,11 @@ func _on_Reset_pressed(): var ri: ReferenceImage = Global.current_project.get_current_reference_image() if !ri: return - var undo_data_tmp = reference_image_container.get_undo_data() + var undo_data_tmp = Global.canvas.reference_image_container.get_undo_data() ri.position_reset() - reference_image_container.commit_undo("Reset Reference Image Position", undo_data_tmp) + Global.canvas.reference_image_container.commit_undo( + "Reset Reference Image Position", undo_data_tmp + ) func _on_Remove_pressed(): @@ -128,7 +129,7 @@ func _on_Remove_pressed(): if index > -1: # If shift is pressed we just remove it without a dialog if Input.is_action_pressed("shift"): - reference_image_container.remove_reference_image(index) + Global.canvas.reference_image_container.remove_reference_image(index) else: confirm_remove_dialog.position = Global.control.get_global_mouse_position() confirm_remove_dialog.popup() @@ -142,7 +143,7 @@ func _on_X_value_changed(value: float): if !ri: return if timer.is_stopped(): - undo_data = reference_image_container.get_undo_data() + undo_data = Global.canvas.reference_image_container.get_undo_data() timer.start() ri.position.x = value @@ -154,7 +155,7 @@ func _on_Y_value_changed(value: float): if !ri: return if timer.is_stopped(): - undo_data = reference_image_container.get_undo_data() + undo_data = Global.canvas.reference_image_container.get_undo_data() timer.start() ri.position.y = value @@ -166,7 +167,7 @@ func _on_Scale_value_changed(value: float): if !ri: return if timer.is_stopped(): - undo_data = reference_image_container.get_undo_data() + undo_data = Global.canvas.reference_image_container.get_undo_data() timer.start() ri.scale.x = value / 100 ri.scale.y = value / 100 @@ -179,7 +180,7 @@ func _on_Rotation_value_changed(value: float): if !ri: return if timer.is_stopped(): - undo_data = reference_image_container.get_undo_data() + undo_data = Global.canvas.reference_image_container.get_undo_data() timer.start() ri.rotation_degrees = value @@ -191,7 +192,7 @@ func _on_Overlay_color_changed(color: Color): if !ri: return if timer.is_stopped(): - undo_data = reference_image_container.get_undo_data() + undo_data = Global.canvas.reference_image_container.get_undo_data() timer.start() ri.overlay_color = Color(color, ri.overlay_color.a) @@ -203,7 +204,7 @@ func _on_Opacity_value_changed(value: float): if !ri: return if timer.is_stopped(): - undo_data = reference_image_container.get_undo_data() + undo_data = Global.canvas.reference_image_container.get_undo_data() timer.start() ri.overlay_color.a = value / 100 @@ -215,19 +216,19 @@ func _on_ColorClamping_value_changed(value: float): if !ri: return if timer.is_stopped(): - undo_data = reference_image_container.get_undo_data() + undo_data = Global.canvas.reference_image_container.get_undo_data() timer.start() ri.color_clamping = value / 100 func _on_timer_timeout() -> void: - reference_image_container.commit_undo("Reference Image Changed", undo_data) + Global.canvas.reference_image_container.commit_undo("Reference Image Changed", undo_data) func _on_remove_confirm_dialog_confirmed() -> void: var index: int = get_parent().list_btn_group.get_pressed_button().get_index() - 1 if index > -1: - reference_image_container.remove_reference_image(index) + Global.canvas.reference_image_container.remove_reference_image(index) Global.dialog_open(false) From 76155cd3cb44e5b41a23de014606df397911658e Mon Sep 17 00:00:00 2001 From: TheLsbt Date: Tue, 19 Dec 2023 12:40:13 +0200 Subject: [PATCH 12/31] Fixed Linting --- src/UI/ReferenceImages/ReferenceEditPanel.gd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/UI/ReferenceImages/ReferenceEditPanel.gd b/src/UI/ReferenceImages/ReferenceEditPanel.gd index bc7593644adc..f0ff7821b1ce 100644 --- a/src/UI/ReferenceImages/ReferenceEditPanel.gd +++ b/src/UI/ReferenceImages/ReferenceEditPanel.gd @@ -1,10 +1,10 @@ extends PanelContainer +var undo_data: Dictionary + var _prev_index: int = -1 var _ignore_spinbox_changes: bool = false -var undo_data: Dictionary - @onready var confirm_remove_dialog := $ConfirmRemoveDialog as ConfirmationDialog @onready var timer := $Timer as Timer From c0a25aa09a48480358541fafdbaf0aac87184a0f Mon Sep 17 00:00:00 2001 From: TheLsbt Date: Tue, 19 Dec 2023 12:59:37 +0200 Subject: [PATCH 13/31] Fixed Spelling issues --- src/Shaders/ReferenceImageShader.gdshader | 2 +- src/UI/Canvas/ReferenceImages.gd | 10 +++++----- src/UI/ReferenceImages/ReferencesPanel.gd | 22 +++++++++++----------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/Shaders/ReferenceImageShader.gdshader b/src/Shaders/ReferenceImageShader.gdshader index 294fec36e663..5a1eefb2f531 100644 --- a/src/Shaders/ReferenceImageShader.gdshader +++ b/src/Shaders/ReferenceImageShader.gdshader @@ -4,7 +4,7 @@ shader_type canvas_item; uniform bool monochrome = false; -// Used becuase modulate doesnt work when monochrome is true +// Used because modulate does not work when monochrome is true uniform vec4 monchrome_color : source_color; // Clamp the color by using the greyscale of the image to identify the brightness of each pixel uniform float clamping : hint_range(0.0, 1.0, 0.01) = 0.0; diff --git a/src/UI/Canvas/ReferenceImages.gd b/src/UI/Canvas/ReferenceImages.gd index cc6f358cd960..e9bbaa552fae 100644 --- a/src/UI/Canvas/ReferenceImages.gd +++ b/src/UI/Canvas/ReferenceImages.gd @@ -25,9 +25,9 @@ func _ready() -> void: Global.camera.zoom_changed.connect(_update_on_zoom) Global.control.get_node("Dialogs").add_child(reference_menu) - # Makes sure that the dark overlay disapears when the popup is hidden + # Makes sure that the dark overlay disappears when the popup is hidden reference_menu.visibility_changed.connect(func(): Global.dialog_open(reference_menu.visible)) - # Emiited when a item is selected from the menu + # Emitted when a item is selected from the menu reference_menu.id_pressed.connect(_reference_menu_id_pressed) @@ -114,8 +114,8 @@ func _input(event: InputEvent) -> void: if event is InputEventMouseMotion: # We check if the LMB is pressed and if we're not dragging then we force the # draggin state. - # We dont use timers becuase it makes more sense to wait fot the users mouse to move - # and thats what defines dragging. It would be smart to add a "deadzone" to determine + # We dont use timers because it makes more sense to wait for the users mouse to move + # and that's what defines dragging. It would be smart to add a "deadzone" to determine # if the mouse had moved enough. if lmb_held and !dragging: dragging = true @@ -294,7 +294,7 @@ func _draw() -> void: if index < 0: return var line_width := 2.0 / Global.camera.zoom.x - # If we are dragging show where the Reference was comming from + # If we are dragging show where the Reference was coming from if dragging: var i: ReferenceImage = Global.current_project.get_current_reference_image() var prev_transform = Transform2D(og_rotation, og_scale, 0.0, og_pos) diff --git a/src/UI/ReferenceImages/ReferencesPanel.gd b/src/UI/ReferenceImages/ReferencesPanel.gd index dc8b1d2ee18d..bd519502903c 100644 --- a/src/UI/ReferenceImages/ReferencesPanel.gd +++ b/src/UI/ReferenceImages/ReferencesPanel.gd @@ -12,7 +12,7 @@ func _ready() -> void: _on_reference_image_changed ) OpenSave.reference_image_imported.connect(_on_references_changed) - # We call this funtion to update the buttons + # We call this function to update the buttons _on_references_changed() @@ -21,7 +21,7 @@ func _on_reference_image_button_pressed(button: Button) -> void: Global.current_project.set_reference_image_index(button.get_index() - 1) -# In case the signal is emited for another node and not from a pressed button +# In case the signal is emitted for another node and not from a pressed button func _on_reference_image_changed(index: int) -> void: if list_btn_group.get_buttons().size() > 0: # First we loop through the buttons to "unpress them all" @@ -34,7 +34,7 @@ func _on_reference_image_changed(index: int) -> void: func _on_references_changed(): - # When we change the project we set the defualt + # When we change the project we set the default Global.current_project.set_reference_image_index(-1) for c in list.get_children(): @@ -46,14 +46,14 @@ func _on_references_changed(): if ref is ReferenceImage: ref.visible = false - # The defualt button - var defualt = Button.new() - defualt.button_group = list_btn_group - defualt.text = "none" - defualt.custom_minimum_size = Vector2(64, 64) - defualt.toggle_mode = true - defualt.button_pressed = true - list.add_child(defualt) + # The default button + var default = Button.new() + default.button_group = list_btn_group + default.text = "none" + default.custom_minimum_size = Vector2(64, 64) + default.toggle_mode = true + default.button_pressed = true + list.add_child(default) # And update. for ref in Global.current_project.reference_images: From 0ba5a8be8e7e01b2d417dc87c23b03b154764ede Mon Sep 17 00:00:00 2001 From: TheLsbt Date: Thu, 21 Dec 2023 19:25:12 +0200 Subject: [PATCH 14/31] Drag and drop to rearrange reference images Added the ability to drag and drop Reference Images similar to dragging and dropping layers. These can be dragged or used with buttons (similar to the buttons that move frames). With full undo/redo support. Added tool buttons these should help people who draw on tablets that cannot use keyboard shortcuts (icons still need to be created) Renamed ReferenceEditPanel.gd to ReferenceEdit.gd (because it is no longer the script of a panel) and changed the base class of the Reference Panel. Added some more translations. Remade ReferenceImageButton.tscn to allow for drag and drop Added drag highlight --- Translations/Translations.pot | 9 + src/Autoload/Global.gd | 2 + src/Classes/Project.gd | 11 +- src/Shaders/ReferenceImageShader.gdshader | 2 +- src/UI/Canvas/ReferenceImages.gd | 50 +++- ...ReferenceEditPanel.gd => ReferenceEdit.gd} | 122 ++++----- .../ReferenceImages/ReferenceImageButton.gd | 67 +++++ .../ReferenceImages/ReferenceImageButton.tscn | 21 ++ src/UI/ReferenceImages/ReferencesPanel.gd | 125 +++++++-- src/UI/ReferenceImages/ReferencesPanel.tscn | 249 ++++++++++++------ 10 files changed, 490 insertions(+), 168 deletions(-) rename src/UI/ReferenceImages/{ReferenceEditPanel.gd => ReferenceEdit.gd} (58%) create mode 100644 src/UI/ReferenceImages/ReferenceImageButton.gd create mode 100644 src/UI/ReferenceImages/ReferenceImageButton.tscn diff --git a/Translations/Translations.pot b/Translations/Translations.pot index 79fb16f25ed4..601ed6e2eb60 100644 --- a/Translations/Translations.pot +++ b/Translations/Translations.pot @@ -2746,6 +2746,15 @@ msgstr "" #. A tooltip to tell users to hold the Shift key while clicking the remove button msgid "Hold Shift while pressing to instantly remove" +msgstr "" + +#. Moves the reference image up in the list +msgid "Move the selected reference image to the right" +msgstr "" + +#. Moves the reference image down in the list +msgid "Move the selected reference image to the left" +msgstr "" #. Used in checkbuttons (like on/off switches) that enable/disable something. msgid "Enabled" diff --git a/src/Autoload/Global.gd b/src/Autoload/Global.gd index 9b3f7474288b..a2ec3b690bee 100644 --- a/src/Autoload/Global.gd +++ b/src/Autoload/Global.gd @@ -467,6 +467,8 @@ var cel_button_scene: PackedScene = load("res://src/UI/Timeline/CelButton.tscn") @onready var palette_panel: PalettePanel = control.find_child("Palettes") ## The perspectice editor. It has the [param PerspectiveEditor.gd] script attached. @onready var perspective_editor := control.find_child("Perspective Editor") +## The reference panel. It has the [param ReferencesPanel.gd] script attached. +@onready var reference_panel: ReferencesPanel = control.find_child("Reference Images") ## The top menu container. It has the [param TopMenuContainer.gd] script attached. @onready var top_menu_container: Panel = control.find_child("TopMenuContainer") diff --git a/src/Classes/Project.gd b/src/Classes/Project.gd index 19da0883816c..8a54d86d7da3 100644 --- a/src/Classes/Project.gd +++ b/src/Classes/Project.gd @@ -873,8 +873,8 @@ func _update_layer_ui() -> void: ## Change the current reference image func set_reference_image_index(new_index: int) -> void: - reference_index = new_index - Global.canvas.reference_image_container.update_index(new_index) + reference_index = clamp(-1, new_index, reference_images.size() - 1) + Global.canvas.reference_image_container.update_index(reference_index) ## Returns the reference image based on reference_index @@ -887,3 +887,10 @@ func get_reference_image(index: int) -> ReferenceImage: if index < 0 or index > reference_images.size() - 1: return null return reference_images[index] + + +## Reorders the position of the reference image in the tree / reference_images array +func reorder_reference_image(from: int, to: int) -> void: + var ri : ReferenceImage = reference_images.pop_at(from) + reference_images.insert(to, ri) + Global.canvas.reference_image_container.move_child(ri, to) diff --git a/src/Shaders/ReferenceImageShader.gdshader b/src/Shaders/ReferenceImageShader.gdshader index 5a1eefb2f531..d1dc16bf3f45 100644 --- a/src/Shaders/ReferenceImageShader.gdshader +++ b/src/Shaders/ReferenceImageShader.gdshader @@ -6,7 +6,7 @@ shader_type canvas_item; uniform bool monochrome = false; // Used because modulate does not work when monochrome is true uniform vec4 monchrome_color : source_color; -// Clamp the color by using the greyscale of the image to identify the brightness of each pixel +// Clamp the color by using the greyscale of the image to identify the brightness of each pixel uniform float clamping : hint_range(0.0, 1.0, 0.01) = 0.0; void fragment() { diff --git a/src/UI/Canvas/ReferenceImages.gd b/src/UI/Canvas/ReferenceImages.gd index e9bbaa552fae..2fc7345abb28 100644 --- a/src/UI/Canvas/ReferenceImages.gd +++ b/src/UI/Canvas/ReferenceImages.gd @@ -4,6 +4,10 @@ extends Node2D signal reference_image_changed(index: int) +enum Mode { Select, Move, Rotate, Scale } + +var mode: Mode = Mode.Select + var index: int: get: return Global.current_project.reference_index @@ -123,12 +127,30 @@ func _input(event: InputEvent) -> void: if dragging: var text := "" - # Scale - if Input.is_action_pressed("reference_scale"): - scale_reference_image(local_mouse_pos, ri) - text = str("Moving: ", (og_scale * 100).floor(), " -> ", (ri.scale * 100).floor()) - # Rotate - elif Input.is_action_pressed("reference_rotate"): + if mode == Mode.Select: + # Scale + if Input.is_action_pressed("reference_scale"): + scale_reference_image(local_mouse_pos, ri) + text = str( + "Moving: ", (og_scale * 100).floor(), " -> ", (ri.scale * 100).floor() + ) + # Rotate + elif Input.is_action_pressed("reference_rotate"): + rotate_reference_image(local_mouse_pos, ri) + text = str( + "Rotating: ", + floorf(rad_to_deg(og_rotation)), + "° -> ", + floorf(rad_to_deg(ri.rotation)), + "°" + ) + else: + move_reference_image(local_mouse_pos, ri) + text = str("Moving to: ", og_pos.floor(), " -> ", ri.position.floor()) + elif mode == Mode.Move: + move_reference_image(local_mouse_pos, ri) + text = str("Moving to: ", og_pos.floor(), " -> ", ri.position.floor()) + elif mode == Mode.Rotate: rotate_reference_image(local_mouse_pos, ri) text = str( "Rotating: ", @@ -137,9 +159,11 @@ func _input(event: InputEvent) -> void: floorf(rad_to_deg(ri.rotation)), "°" ) - else: - move_reference_image(local_mouse_pos, ri) - text = str("Scaling to: ", og_pos.floor(), " -> ", ri.position.floor()) + elif mode == Mode.Scale: + scale_reference_image(local_mouse_pos, ri) + text = str( + "Moving: ", (og_scale * 100).floor(), " -> ", (ri.scale * 100).floor() + ) Global.cursor_position_label.text = text @@ -310,3 +334,11 @@ func _draw() -> void: draw_polyline(p, Color(0.50, 0.99, 0.29), line_width) elif Geometry2D.is_point_in_polygon(get_local_mouse_position(), p) and !dragging: draw_polyline(p, Color(0.98, 0.80, 0.29), line_width) + + +## This function creates random images with random colors +func generate_random_images(amount: int, size: Vector2) -> void: + for i in range(amount): + var image = Image.create(size.x, size.y, false, Image.FORMAT_RGBA8) + image.fill(Color(randf(), randf(), randf())) + OpenSave.import_reference_image_from_image(image) diff --git a/src/UI/ReferenceImages/ReferenceEditPanel.gd b/src/UI/ReferenceImages/ReferenceEdit.gd similarity index 58% rename from src/UI/ReferenceImages/ReferenceEditPanel.gd rename to src/UI/ReferenceImages/ReferenceEdit.gd index f0ff7821b1ce..adc82a87048f 100644 --- a/src/UI/ReferenceImages/ReferenceEditPanel.gd +++ b/src/UI/ReferenceImages/ReferenceEdit.gd @@ -1,4 +1,4 @@ -extends PanelContainer +extends VBoxContainer var undo_data: Dictionary @@ -7,10 +7,11 @@ var _ignore_spinbox_changes: bool = false @onready var confirm_remove_dialog := $ConfirmRemoveDialog as ConfirmationDialog @onready var timer := $Timer as Timer +@onready var references_container := Global.canvas.reference_image_container as Node2D func _ready() -> void: - Global.canvas.reference_image_container.reference_image_changed.connect( + references_container.reference_image_changed.connect( _on_reference_image_changed ) @@ -25,65 +26,67 @@ func _update_properties(): # Image Path if OS.get_name() == "Web": - $ReferenceEdit/ImageOptions/ImagePath.disabled = true + $ImageOptions/ImagePath.disabled = true else: - $ReferenceEdit/ImageOptions/ImagePath.disabled = false + $ImageOptions/ImagePath.disabled = false - $ReferenceEdit/ImageOptions/ImagePath.text = ri.image_path - $ReferenceEdit/ImageOptions/ImagePath.tooltip_text = ri.image_path + if ri.image_path.is_empty(): + $ImageOptions/ImagePath.text = "(No Path)" + $ImageOptions/ImagePath.tooltip_text = "(No Path)" + else: + $ImageOptions/ImagePath.text = ri.image_path + $ImageOptions/ImagePath.tooltip_text = ri.image_path if !ri.texture: - $ReferenceEdit/ImageOptions/WarningLabel.visible = true - $ReferenceEdit/ImageOptions/ImagePath.visible = false + $ImageOptions/WarningLabel.visible = true + $ImageOptions/ImagePath.visible = false else: - $ReferenceEdit/ImageOptions/WarningLabel.visible = false - $ReferenceEdit/ImageOptions/ImagePath.visible = true - # Tools - $ReferenceEdit/Tools/Filter.button_pressed = ri.filter + $ImageOptions/WarningLabel.visible = false + $ImageOptions/ImagePath.visible = true # Transform - $ReferenceEdit/Options/Position/X.value = ri.position.x - $ReferenceEdit/Options/Position/Y.value = ri.position.y - $ReferenceEdit/Options/Position/X.max_value = ri.project.size.x - $ReferenceEdit/Options/Position/Y.max_value = ri.project.size.y - $ReferenceEdit/Options/Scale.value = ri.scale.x * 100 - $ReferenceEdit/Options/Rotation.value = ri.rotation_degrees + $Options/Position/X.value = ri.position.x + $Options/Position/Y.value = ri.position.y + $Options/Position/X.max_value = ri.project.size.x + $Options/Position/Y.max_value = ri.project.size.y + $Options/Scale.value = ri.scale.x * 100 + $Options/Rotation.value = ri.rotation_degrees # Color - $ReferenceEdit/Options/Monochrome.button_pressed = ri.monochrome - $ReferenceEdit/Options/Overlay.color = Color(ri.overlay_color, 1.0) - $ReferenceEdit/Options/Opacity.value = ri.overlay_color.a * 100 - $ReferenceEdit/Options/ColorClamping.value = ri.color_clamping * 100 + $Options/Filter.button_pressed = ri.filter + $Options/Monochrome.button_pressed = ri.monochrome + $Options/Overlay.color = Color(ri.overlay_color, 1.0) + $Options/Opacity.value = ri.overlay_color.a * 100 + $Options/ColorClamping.value = ri.color_clamping * 100 _ignore_spinbox_changes = false # Fore update the "gizmo" drawing - Global.canvas.reference_image_container.queue_redraw() + references_container.queue_redraw() func _reset_properties() -> void: # This is because otherwise a little dance will occur. # This also breaks non-uniform scales (not supported UI-wise, but...) _ignore_spinbox_changes = true - $ReferenceEdit/ImageOptions/ImagePath.text = "None" - $ReferenceEdit/ImageOptions/ImagePath.tooltip_text = "None" - $ReferenceEdit/ImageOptions/ImagePath.disabled = true - $ReferenceEdit/ImageOptions/WarningLabel.visible = false - $ReferenceEdit/ImageOptions/ImagePath.visible = true - # Tools - $ReferenceEdit/Tools/Filter.button_pressed = false + $ImageOptions/ImagePath.text = "None" + $ImageOptions/ImagePath.tooltip_text = "None" + $ImageOptions/ImagePath.disabled = true + $ImageOptions/WarningLabel.visible = false + $ImageOptions/ImagePath.visible = true # Transform - $ReferenceEdit/Options/Position/X.value = 0.0 - $ReferenceEdit/Options/Position/Y.value = 0.0 - $ReferenceEdit/Options/Position/X.max_value = 0.0 - $ReferenceEdit/Options/Position/Y.max_value = 0.0 - $ReferenceEdit/Options/Scale.value = 0.0 - $ReferenceEdit/Options/Rotation.value = 0.0 + $Options/Position/X.value = 0.0 + $Options/Position/Y.value = 0.0 + $Options/Position/X.max_value = 0.0 + $Options/Position/Y.max_value = 0.0 + $Options/Scale.value = 0.0 + $Options/Rotation.value = 0.0 # Color - $ReferenceEdit/Options/Monochrome.button_pressed = false - $ReferenceEdit/Options/Overlay.color = Color.WHITE - $ReferenceEdit/Options/Opacity.value = 0.0 - $ReferenceEdit/Options/ColorClamping.value = 0.0 + $Options/Filter.button_pressed = false + $Options/Monochrome.button_pressed = false + $Options/Overlay.color = Color.WHITE + $Options/Opacity.value = 0.0 + $Options/ColorClamping.value = 0.0 _ignore_spinbox_changes = false # Fore update the "gizmo" drawing - Global.canvas.reference_image_container.queue_redraw() + references_container.queue_redraw() func _on_Monochrome_toggled(pressed: bool) -> void: @@ -93,7 +96,7 @@ func _on_Monochrome_toggled(pressed: bool) -> void: if !ri: return if timer.is_stopped(): - undo_data = Global.canvas.reference_image_container.get_undo_data() + undo_data = references_container.get_undo_data() timer.start() ri.monochrome = pressed @@ -105,7 +108,7 @@ func _on_Filter_toggled(pressed: bool) -> void: if !ri: return if timer.is_stopped(): - undo_data = Global.canvas.reference_image_container.get_undo_data() + undo_data = references_container.get_undo_data() timer.start() ri.filter = pressed @@ -114,22 +117,20 @@ func _on_Reset_pressed(): var ri: ReferenceImage = Global.current_project.get_current_reference_image() if !ri: return - var undo_data_tmp = Global.canvas.reference_image_container.get_undo_data() + var undo_data_tmp = references_container.get_undo_data() ri.position_reset() - Global.canvas.reference_image_container.commit_undo( - "Reset Reference Image Position", undo_data_tmp - ) + references_container.commit_undo("Reset Reference Image Position", undo_data_tmp) func _on_Remove_pressed(): var ri: ReferenceImage = Global.current_project.get_current_reference_image() if !ri: return - var index: int = get_parent().list_btn_group.get_pressed_button().get_index() - 1 + var index: int = Global.current_project.reference_index if index > -1: # If shift is pressed we just remove it without a dialog if Input.is_action_pressed("shift"): - Global.canvas.reference_image_container.remove_reference_image(index) + references_container.remove_reference_image(index) else: confirm_remove_dialog.position = Global.control.get_global_mouse_position() confirm_remove_dialog.popup() @@ -143,7 +144,7 @@ func _on_X_value_changed(value: float): if !ri: return if timer.is_stopped(): - undo_data = Global.canvas.reference_image_container.get_undo_data() + undo_data = references_container.get_undo_data() timer.start() ri.position.x = value @@ -155,7 +156,7 @@ func _on_Y_value_changed(value: float): if !ri: return if timer.is_stopped(): - undo_data = Global.canvas.reference_image_container.get_undo_data() + undo_data = references_container.get_undo_data() timer.start() ri.position.y = value @@ -167,7 +168,7 @@ func _on_Scale_value_changed(value: float): if !ri: return if timer.is_stopped(): - undo_data = Global.canvas.reference_image_container.get_undo_data() + undo_data = references_container.get_undo_data() timer.start() ri.scale.x = value / 100 ri.scale.y = value / 100 @@ -180,7 +181,7 @@ func _on_Rotation_value_changed(value: float): if !ri: return if timer.is_stopped(): - undo_data = Global.canvas.reference_image_container.get_undo_data() + undo_data = references_container.get_undo_data() timer.start() ri.rotation_degrees = value @@ -192,7 +193,7 @@ func _on_Overlay_color_changed(color: Color): if !ri: return if timer.is_stopped(): - undo_data = Global.canvas.reference_image_container.get_undo_data() + undo_data = references_container.get_undo_data() timer.start() ri.overlay_color = Color(color, ri.overlay_color.a) @@ -204,7 +205,7 @@ func _on_Opacity_value_changed(value: float): if !ri: return if timer.is_stopped(): - undo_data = Global.canvas.reference_image_container.get_undo_data() + undo_data = references_container.get_undo_data() timer.start() ri.overlay_color.a = value / 100 @@ -216,19 +217,19 @@ func _on_ColorClamping_value_changed(value: float): if !ri: return if timer.is_stopped(): - undo_data = Global.canvas.reference_image_container.get_undo_data() + undo_data = references_container.get_undo_data() timer.start() ri.color_clamping = value / 100 func _on_timer_timeout() -> void: - Global.canvas.reference_image_container.commit_undo("Reference Image Changed", undo_data) + references_container.commit_undo("Reference Image Changed", undo_data) -func _on_remove_confirm_dialog_confirmed() -> void: - var index: int = get_parent().list_btn_group.get_pressed_button().get_index() - 1 +func _on_confirm_remove_dialog_confirmed() -> void: + var index: int = Global.current_project.reference_index if index > -1: - Global.canvas.reference_image_container.remove_reference_image(index) + references_container.remove_reference_image(index) Global.dialog_open(false) @@ -261,3 +262,4 @@ func _on_reference_image_changed(index: int) -> void: _reset_properties() else: _update_properties() + diff --git a/src/UI/ReferenceImages/ReferenceImageButton.gd b/src/UI/ReferenceImages/ReferenceImageButton.gd new file mode 100644 index 000000000000..24e17fee7c0f --- /dev/null +++ b/src/UI/ReferenceImages/ReferenceImageButton.gd @@ -0,0 +1,67 @@ +extends Button + + +func _get_drag_data(at_position: Vector2) -> Variant: + var index := get_index() - 1 + # If the index < 0 then that means this button is the "reset button" + if index < 0: + return null + + set_drag_preview(self.duplicate()) + + var data := ["ReferenceImage", index] + + return data + + +func _can_drop_data(at_position: Vector2, data: Variant) -> bool: + if typeof(data) != TYPE_ARRAY: + Global.reference_panel.drag_highlight.visible = false + return false + if data[0] != "ReferenceImage": + Global.reference_panel.drag_highlight.visible = false + return false + + var index := get_index() - 1 + var from_index : int = data[1] + # If the index < 0 then that means this button is the "reset button" + # Or we are trying to drop on the same button + if index < 0 or index == from_index: + Global.reference_panel.drag_highlight.visible = false + return false + + var side : int = -1 + if get_local_mouse_position().x > size.x / 2: + side = 1 + + var region := Rect2(global_position + Vector2(3, 0), Vector2(6, size.y)) + + # Get the side + if side == 1: + region.position.x = (size.x + global_position.x) - 3 + + Global.reference_panel.drag_highlight.visible = true + Global.reference_panel.drag_highlight.position = region.position + Global.reference_panel.drag_highlight.size = region.size + + return true + + +func _drop_data(at_position: Vector2, data: Variant) -> void: + var from_index : int = data[1] + var to_index := get_index() + + if get_local_mouse_position().x > size.x / 2: + if from_index > to_index: + to_index += 1 + print("Help mee") + else: + if from_index < to_index: + to_index -= 1 + + Global.reference_panel.reorder_reference_image(from_index, to_index - 1, false) + + #Global.current_project.reorder_reference_image(from_index, to_index - 1) + #Global.reference_panel._on_references_changed() + + #Global.reference_panel.drag_highlight.visible = false diff --git a/src/UI/ReferenceImages/ReferenceImageButton.tscn b/src/UI/ReferenceImages/ReferenceImageButton.tscn new file mode 100644 index 000000000000..be95b65851e1 --- /dev/null +++ b/src/UI/ReferenceImages/ReferenceImageButton.tscn @@ -0,0 +1,21 @@ +[gd_scene load_steps=4 format=3 uid="uid://by3300fom3plf"] + +[ext_resource type="Script" path="res://src/UI/ReferenceImages/ReferenceImageButton.gd" id="1_nf0dd"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_53xjd"] +draw_center = false +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_tuwm6"] + +[node name="ReferenceImageButton" type="Button"] +custom_minimum_size = Vector2(64, 64) +theme_override_styles/pressed = SubResource("StyleBoxFlat_53xjd") +theme_override_styles/focus = SubResource("StyleBoxEmpty_tuwm6") +toggle_mode = true +icon_alignment = 1 +expand_icon = true +script = ExtResource("1_nf0dd") diff --git a/src/UI/ReferenceImages/ReferencesPanel.gd b/src/UI/ReferenceImages/ReferencesPanel.gd index bd519502903c..6fb0f1473929 100644 --- a/src/UI/ReferenceImages/ReferencesPanel.gd +++ b/src/UI/ReferenceImages/ReferencesPanel.gd @@ -1,12 +1,21 @@ class_name ReferencesPanel -extends VBoxContainer +extends PanelContainer ## Panel for reference image management +const ReferenceImageButton = preload("res://src/UI/ReferenceImages/ReferenceImageButton.tscn") + var list_btn_group := ButtonGroup.new() -@onready var list = $"ReferenceImages/List" +var transform_button_group : ButtonGroup +var _ignore_ui_updates := false +@onready var list := %List as HBoxContainer +@onready var drag_highlight := $Overlay/DragHighlight as ColorRect +@onready var remove_btn := $ScrollContainer/Container/ReferenceEdit/ImageOptions/Remove as Button +@onready var transform_tools_btns := $ScrollContainer/Container/Tools/TransformTools func _ready() -> void: + transform_button_group = transform_tools_btns.get_child(0).button_group + transform_button_group.pressed.connect(_on_transform_tool_button_group_pressed) list_btn_group.pressed.connect(_on_reference_image_button_pressed) Global.canvas.reference_image_container.reference_image_changed.connect( _on_reference_image_changed @@ -14,6 +23,98 @@ func _ready() -> void: OpenSave.reference_image_imported.connect(_on_references_changed) # We call this function to update the buttons _on_references_changed() + _update_ui() + Global.canvas.reference_image_container.generate_random_images(3, Vector2(100, 100)) + + +func _notification(what: int) -> void: + if what == NOTIFICATION_DRAG_END: + drag_highlight.hide() + + +func _on_transform_tool_button_group_pressed(button: Button) -> void: + Global.canvas.reference_image_container.mode = button.get_index() + + +func _on_move_image_left_pressed() -> void: + var index : int = Global.current_project.reference_index + reorder_reference_image(index, index - 1) + + +func _on_move_image_right_pressed() -> void: + var index : int = Global.current_project.reference_index + reorder_reference_image(index, index + 1) + + +## This method allows you to reoreder reference image with undo redo support +## Please use this and not the method with the same name in project.gd +func reorder_reference_image(from: int, to: int, update_reference_index := true) -> void: + var project := Global.current_project + project.undo_redo.create_action("Reorder Reference Image") + project.undo_redo.add_do_method(project.reorder_reference_image.bind(from, to)) + project.undo_redo.add_do_method(Global.reference_panel._on_references_changed) + if update_reference_index: + project.undo_redo.add_do_method(project.set_reference_image_index.bind(to)) + else: + project.undo_redo.add_undo_method( + project.set_reference_image_index.bind(project.reference_index) + ) + project.undo_redo.add_do_method(_update_ui) + + project.undo_redo.add_undo_method(project.reorder_reference_image.bind(to, from)) + project.undo_redo.add_undo_method(Global.reference_panel._on_references_changed) + if update_reference_index: + project.undo_redo.add_undo_method(project.set_reference_image_index.bind(from)) + else: + project.undo_redo.add_undo_method( + project.set_reference_image_index.bind(project.reference_index) + ) + + project.undo_redo.add_undo_method(_update_ui) + + project.undo_redo.commit_action() + + +func _update_ui() -> void: + var index : int = Global.current_project.reference_index + print("Updating ui: ", index) + + # Enable the buttons as a default + %MoveImageRightBtn.disabled = false + %MoveImageLeftBtn.disabled = false + + if index == -1: + %MoveImageLeftBtn.disabled = true + %MoveImageRightBtn.disabled = true + if index == 0: + %MoveImageLeftBtn.disabled = true + if index == Global.current_project.reference_images.size() - 1: + %MoveImageRightBtn.disabled = true + + if %MoveImageLeftBtn.disabled: + %MoveImageLeftBtn.mouse_default_cursor_shape = CURSOR_FORBIDDEN + else: + %MoveImageLeftBtn.mouse_default_cursor_shape = CURSOR_POINTING_HAND + + if %MoveImageRightBtn.disabled: + %MoveImageRightBtn.mouse_default_cursor_shape = CURSOR_FORBIDDEN + else: + %MoveImageRightBtn.mouse_default_cursor_shape = CURSOR_POINTING_HAND + + # Update the buttons to show which one is pressed + if list_btn_group.get_buttons().size() > 0: + # First we loop through the buttons to "unpress them all" + for b: Button in list_btn_group.get_buttons(): + b.set_pressed_no_signal(false) + # Then we get the wanted button and we press it + list_btn_group.get_buttons()[index + 1].set_pressed_no_signal(true) + + # Update the remove button + remove_btn.disabled = index == -1 + if remove_btn.disabled: + remove_btn.mouse_default_cursor_shape = CURSOR_FORBIDDEN + else: + remove_btn.mouse_default_cursor_shape = CURSOR_POINTING_HAND func _on_reference_image_button_pressed(button: Button) -> void: @@ -23,14 +124,7 @@ func _on_reference_image_button_pressed(button: Button) -> void: # In case the signal is emitted for another node and not from a pressed button func _on_reference_image_changed(index: int) -> void: - if list_btn_group.get_buttons().size() > 0: - # First we loop through the buttons to "unpress them all" - # There is a visual bug with BaseButton.set_pressed_no_signal() - for b: Button in list_btn_group.get_buttons(): - if (index + 1) == b.get_index(): - b.set_pressed_no_signal(true) - else: - b.set_pressed_no_signal(false) + _update_ui() func _on_references_changed(): @@ -47,24 +141,17 @@ func _on_references_changed(): ref.visible = false # The default button - var default = Button.new() + var default = ReferenceImageButton.instantiate() default.button_group = list_btn_group default.text = "none" - default.custom_minimum_size = Vector2(64, 64) - default.toggle_mode = true default.button_pressed = true list.add_child(default) # And update. for ref in Global.current_project.reference_images: ref.visible = true - var l = Button.new() + var l : Button = ReferenceImageButton.instantiate() l.button_group = list_btn_group if ref.texture: l.icon = ref.texture - l.expand_icon = true - l.icon_alignment = HORIZONTAL_ALIGNMENT_CENTER - l.vertical_icon_alignment = VERTICAL_ALIGNMENT_CENTER - l.custom_minimum_size = Vector2(64, 64) - l.toggle_mode = true list.add_child(l) diff --git a/src/UI/ReferenceImages/ReferencesPanel.tscn b/src/UI/ReferenceImages/ReferencesPanel.tscn index 8e5e540dae64..effd47aefa81 100644 --- a/src/UI/ReferenceImages/ReferencesPanel.tscn +++ b/src/UI/ReferenceImages/ReferencesPanel.tscn @@ -1,66 +1,156 @@ -[gd_scene load_steps=5 format=3 uid="uid://cxhs8qy5ilufv"] +[gd_scene load_steps=9 format=3 uid="uid://cxhs8qy5ilufv"] [ext_resource type="Script" path="res://src/UI/ReferenceImages/ReferencesPanel.gd" id="1"] [ext_resource type="Script" path="res://src/UI/Nodes/ValueSlider.gd" id="2_1qu4x"] -[ext_resource type="Script" path="res://src/UI/ReferenceImages/ReferenceEditPanel.gd" id="2_xxb1y"] +[ext_resource type="Texture2D" uid="uid://d1oxrkwndy5fi" path="res://assets/graphics/timeline/move_arrow.png" id="2_uqbp6"] [ext_resource type="PackedScene" uid="uid://yjhp0ssng2mp" path="res://src/UI/Nodes/ValueSlider.tscn" id="3_1w6gu"] +[ext_resource type="Script" path="res://src/UI/ReferenceImages/ReferenceEdit.gd" id="3_skjtb"] -[node name="Reference Images" type="VBoxContainer"] +[sub_resource type="InputEventAction" id="InputEventAction_unp5j"] +action = &"move_frame_right" + +[sub_resource type="Shortcut" id="Shortcut_uucm4"] +events = [SubResource("InputEventAction_unp5j")] + +[sub_resource type="ButtonGroup" id="ButtonGroup_w2sra"] + +[node name="Reference Images" type="PanelContainer"] +custom_minimum_size = Vector2(300, 0) anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 script = ExtResource("1") -[node name="Header" type="HBoxContainer" parent="."] +[node name="ScrollContainer" type="ScrollContainer" parent="."] layout_mode = 2 -theme_override_constants/separation = 0 -[node name="HSeparator2" type="HSeparator" parent="Header"] +[node name="Container" type="VBoxContainer" parent="ScrollContainer"] layout_mode = 2 size_flags_horizontal = 3 +size_flags_vertical = 3 -[node name="Label" type="Label" parent="Header"] +[node name="Header" type="HBoxContainer" parent="ScrollContainer/Container"] layout_mode = 2 -theme_type_variation = &"HeaderSmall" -text = "Reference Images" +theme_override_constants/separation = 0 -[node name="HSeparator" type="HSeparator" parent="Header"] +[node name="Label" type="Label" parent="ScrollContainer/Container/Header"] layout_mode = 2 -size_flags_horizontal = 3 +theme_type_variation = &"HeaderSmall" +text = "My Reference Images" -[node name="Label" type="Label" parent="."] +[node name="Tip" type="Label" parent="ScrollContainer/Container"] custom_minimum_size = Vector2(10, 0) layout_mode = 2 text = "When opening an image, it may be imported as a reference." autowrap_mode = 2 -[node name="ReferenceImages" type="ScrollContainer" parent="."] +[node name="Tools" type="HBoxContainer" parent="ScrollContainer/Container"] +layout_mode = 2 + +[node name="MoveImageLeftBtn" type="Button" parent="ScrollContainer/Container/Tools" groups=["UIButtons"]] +unique_name_in_owner = true +custom_minimum_size = Vector2(31, 31) +layout_mode = 2 +size_flags_horizontal = 0 +tooltip_text = "Move the selected reference image to the left." +focus_mode = 0 +mouse_default_cursor_shape = 2 +shortcut = SubResource("Shortcut_uucm4") + +[node name="TextureRect" type="TextureRect" parent="ScrollContainer/Container/Tools/MoveImageLeftBtn"] +layout_mode = 0 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -7.5 +offset_top = -5.5 +offset_right = 7.5 +offset_bottom = 5.5 +texture = ExtResource("2_uqbp6") +flip_h = true + +[node name="MoveImageRightBtn" type="Button" parent="ScrollContainer/Container/Tools" groups=["UIButtons"]] +unique_name_in_owner = true +custom_minimum_size = Vector2(31, 31) +layout_mode = 2 +size_flags_horizontal = 0 +tooltip_text = "Move the selected reference image to the right" +focus_mode = 0 +mouse_default_cursor_shape = 2 +shortcut = SubResource("Shortcut_uucm4") + +[node name="TextureRect" type="TextureRect" parent="ScrollContainer/Container/Tools/MoveImageRightBtn"] +layout_mode = 0 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -7.5 +offset_top = -5.5 +offset_right = 7.5 +offset_bottom = 5.5 +texture = ExtResource("2_uqbp6") + +[node name="Spacer" type="Control" parent="ScrollContainer/Container/Tools"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="TransformTools" type="HBoxContainer" parent="ScrollContainer/Container/Tools"] +layout_mode = 2 + +[node name="Select" type="Button" parent="ScrollContainer/Container/Tools/TransformTools"] +custom_minimum_size = Vector2(31, 31) +layout_mode = 2 +toggle_mode = true +button_pressed = true +button_group = SubResource("ButtonGroup_w2sra") + +[node name="Move" type="Button" parent="ScrollContainer/Container/Tools/TransformTools"] +custom_minimum_size = Vector2(31, 31) +layout_mode = 2 +toggle_mode = true +button_group = SubResource("ButtonGroup_w2sra") + +[node name="Rotate" type="Button" parent="ScrollContainer/Container/Tools/TransformTools"] +custom_minimum_size = Vector2(31, 31) +layout_mode = 2 +toggle_mode = true +button_group = SubResource("ButtonGroup_w2sra") + +[node name="Scale" type="Button" parent="ScrollContainer/Container/Tools/TransformTools"] +custom_minimum_size = Vector2(31, 31) +layout_mode = 2 +toggle_mode = true +button_group = SubResource("ButtonGroup_w2sra") + +[node name="ReferenceImages" type="ScrollContainer" parent="ScrollContainer/Container"] layout_mode = 2 horizontal_scroll_mode = 2 vertical_scroll_mode = 0 -[node name="List" type="HBoxContainer" parent="ReferenceImages"] +[node name="List" type="HBoxContainer" parent="ScrollContainer/Container/ReferenceImages"] +unique_name_in_owner = true custom_minimum_size = Vector2(0, 64) layout_mode = 2 -[node name="ReferenceEditPanel" type="PanelContainer" parent="."] +[node name="ReferenceEdit" type="VBoxContainer" parent="ScrollContainer/Container"] layout_mode = 2 -script = ExtResource("2_xxb1y") +script = ExtResource("3_skjtb") -[node name="ReferenceEdit" type="VBoxContainer" parent="ReferenceEditPanel"] +[node name="ImageOptions" type="HBoxContainer" parent="ScrollContainer/Container/ReferenceEdit"] layout_mode = 2 -[node name="ImageOptions" type="HBoxContainer" parent="ReferenceEditPanel/ReferenceEdit"] -layout_mode = 2 - -[node name="WarningLabel" type="Label" parent="ReferenceEditPanel/ReferenceEdit/ImageOptions"] +[node name="WarningLabel" type="Label" parent="ScrollContainer/Container/ReferenceEdit/ImageOptions"] layout_mode = 2 size_flags_horizontal = 3 theme_override_colors/font_color = Color(0.972549, 1, 0.545098, 1) text = "Image not found!" text_overrun_behavior = 3 -[node name="ImagePath" type="Button" parent="ReferenceEditPanel/ReferenceEdit/ImageOptions"] +[node name="ImagePath" type="Button" parent="ScrollContainer/Container/ReferenceEdit/ImageOptions"] visible = false layout_mode = 2 size_flags_horizontal = 3 @@ -69,121 +159,117 @@ text = "Image Path" alignment = 0 text_overrun_behavior = 3 -[node name="Remove" type="Button" parent="ReferenceEditPanel/ReferenceEdit/ImageOptions"] +[node name="Remove" type="Button" parent="ScrollContainer/Container/ReferenceEdit/ImageOptions"] layout_mode = 2 tooltip_text = "Hold Shift while pressing to instantly remove." theme_override_colors/font_color = Color(1, 0.490196, 0.419608, 1) text = "Remove" -[node name="HSeparator" type="HSeparator" parent="ReferenceEditPanel/ReferenceEdit"] -layout_mode = 2 - -[node name="Tools" type="HBoxContainer" parent="ReferenceEditPanel/ReferenceEdit"] -layout_mode = 2 - -[node name="Filter" type="CheckButton" parent="ReferenceEditPanel/ReferenceEdit/Tools"] -layout_mode = 2 -size_flags_horizontal = 3 -text = "Filter" - -[node name="HSeparator2" type="HSeparator" parent="ReferenceEditPanel/ReferenceEdit"] -layout_mode = 2 - -[node name="Options" type="GridContainer" parent="ReferenceEditPanel/ReferenceEdit"] +[node name="Options" type="GridContainer" parent="ScrollContainer/Container/ReferenceEdit"] layout_mode = 2 size_flags_horizontal = 3 columns = 2 -[node name="TransformLabel" type="Label" parent="ReferenceEditPanel/ReferenceEdit/Options"] +[node name="TransformLabel" type="Label" parent="ScrollContainer/Container/ReferenceEdit/Options"] layout_mode = 2 text = "Transform" -[node name="Reset" type="Button" parent="ReferenceEditPanel/ReferenceEdit/Options"] +[node name="Reset" type="Button" parent="ScrollContainer/Container/ReferenceEdit/Options"] layout_mode = 2 text = "Reset Transform" -[node name="PosLabel" type="Label" parent="ReferenceEditPanel/ReferenceEdit/Options"] +[node name="PosLabel" type="Label" parent="ScrollContainer/Container/ReferenceEdit/Options"] custom_minimum_size = Vector2(115, 0) layout_mode = 2 text = "Position" -[node name="Position" type="HBoxContainer" parent="ReferenceEditPanel/ReferenceEdit/Options"] +[node name="Position" type="HBoxContainer" parent="ScrollContainer/Container/ReferenceEdit/Options"] layout_mode = 2 size_flags_horizontal = 3 -[node name="X" parent="ReferenceEditPanel/ReferenceEdit/Options/Position" instance=ExtResource("3_1w6gu")] +[node name="X" parent="ScrollContainer/Container/ReferenceEdit/Options/Position" instance=ExtResource("3_1w6gu")] layout_mode = 2 allow_greater = true allow_lesser = true -[node name="Y" parent="ReferenceEditPanel/ReferenceEdit/Options/Position" instance=ExtResource("3_1w6gu")] +[node name="Y" parent="ScrollContainer/Container/ReferenceEdit/Options/Position" instance=ExtResource("3_1w6gu")] layout_mode = 2 allow_greater = true allow_lesser = true -[node name="ScaleLabel" type="Label" parent="ReferenceEditPanel/ReferenceEdit/Options"] +[node name="ScaleLabel" type="Label" parent="ScrollContainer/Container/ReferenceEdit/Options"] custom_minimum_size = Vector2(115, 0) layout_mode = 2 text = "Scale" -[node name="Scale" parent="ReferenceEditPanel/ReferenceEdit/Options" instance=ExtResource("3_1w6gu")] +[node name="Scale" parent="ScrollContainer/Container/ReferenceEdit/Options" instance=ExtResource("3_1w6gu")] layout_mode = 2 allow_greater = true allow_lesser = true -[node name="RotationLabel" type="Label" parent="ReferenceEditPanel/ReferenceEdit/Options"] +[node name="RotationLabel" type="Label" parent="ScrollContainer/Container/ReferenceEdit/Options"] custom_minimum_size = Vector2(115, 0) layout_mode = 2 text = "Rotation" -[node name="Rotation" parent="ReferenceEditPanel/ReferenceEdit/Options" instance=ExtResource("3_1w6gu")] +[node name="Rotation" parent="ScrollContainer/Container/ReferenceEdit/Options" instance=ExtResource("3_1w6gu")] layout_mode = 2 min_value = -180.0 max_value = 180.0 -[node name="ColorLabel" type="Label" parent="ReferenceEditPanel/ReferenceEdit/Options"] +[node name="ColorLabel" type="Label" parent="ScrollContainer/Container/ReferenceEdit/Options"] layout_mode = 2 text = "Color Options" -[node name="Spacer2" type="Control" parent="ReferenceEditPanel/ReferenceEdit/Options"] +[node name="Spacer2" type="Control" parent="ScrollContainer/Container/ReferenceEdit/Options"] +layout_mode = 2 + +[node name="FilterLabel" type="Label" parent="ScrollContainer/Container/ReferenceEdit/Options"] +custom_minimum_size = Vector2(115, 0) +layout_mode = 2 +text = "Filter" + +[node name="Filter" type="CheckButton" parent="ScrollContainer/Container/ReferenceEdit/Options"] layout_mode = 2 +size_flags_horizontal = 3 +text = "Enabled" -[node name="MonochromeLabel" type="Label" parent="ReferenceEditPanel/ReferenceEdit/Options"] +[node name="MonochromeLabel" type="Label" parent="ScrollContainer/Container/ReferenceEdit/Options"] custom_minimum_size = Vector2(115, 0) layout_mode = 2 text = "Monochrome" -[node name="Monochrome" type="CheckButton" parent="ReferenceEditPanel/ReferenceEdit/Options"] +[node name="Monochrome" type="CheckButton" parent="ScrollContainer/Container/ReferenceEdit/Options"] layout_mode = 2 size_flags_horizontal = 3 text = "Enabled" -[node name="OverlayLabel" type="Label" parent="ReferenceEditPanel/ReferenceEdit/Options"] +[node name="OverlayLabel" type="Label" parent="ScrollContainer/Container/ReferenceEdit/Options"] custom_minimum_size = Vector2(115, 0) layout_mode = 2 text = "Overlay" -[node name="Overlay" type="ColorPickerButton" parent="ReferenceEditPanel/ReferenceEdit/Options"] +[node name="Overlay" type="ColorPickerButton" parent="ScrollContainer/Container/ReferenceEdit/Options"] custom_minimum_size = Vector2(48, 28) layout_mode = 2 size_flags_horizontal = 3 size_flags_stretch_ratio = 0.25 edit_alpha = false -[node name="OpacityLabel" type="Label" parent="ReferenceEditPanel/ReferenceEdit/Options"] +[node name="OpacityLabel" type="Label" parent="ScrollContainer/Container/ReferenceEdit/Options"] custom_minimum_size = Vector2(115, 0) layout_mode = 2 text = "Opacity" -[node name="Opacity" parent="ReferenceEditPanel/ReferenceEdit/Options" instance=ExtResource("3_1w6gu")] +[node name="Opacity" parent="ScrollContainer/Container/ReferenceEdit/Options" instance=ExtResource("3_1w6gu")] layout_mode = 2 -[node name="ColorClampingLabel" type="Label" parent="ReferenceEditPanel/ReferenceEdit/Options"] +[node name="ColorClampingLabel" type="Label" parent="ScrollContainer/Container/ReferenceEdit/Options"] custom_minimum_size = Vector2(115, 0) layout_mode = 2 text = "Color Clamping" -[node name="ColorClamping" type="TextureProgressBar" parent="ReferenceEditPanel/ReferenceEdit/Options"] +[node name="ColorClamping" type="TextureProgressBar" parent="ScrollContainer/Container/ReferenceEdit/Options"] custom_minimum_size = Vector2(0, 24) layout_mode = 2 size_flags_horizontal = 3 @@ -196,25 +282,34 @@ stretch_margin_right = 3 stretch_margin_bottom = 3 script = ExtResource("2_1qu4x") -[node name="Timer" type="Timer" parent="ReferenceEditPanel"] +[node name="Timer" type="Timer" parent="ScrollContainer/Container/ReferenceEdit"] wait_time = 0.2 one_shot = true -[node name="ConfirmRemoveDialog" type="ConfirmationDialog" parent="ReferenceEditPanel"] -size = Vector2i(443, 100) -dialog_text = "Are you sure you want to remove this reference image?" - -[connection signal="pressed" from="ReferenceEditPanel/ReferenceEdit/ImageOptions/Remove" to="ReferenceEditPanel" method="_on_Remove_pressed"] -[connection signal="toggled" from="ReferenceEditPanel/ReferenceEdit/Tools/Filter" to="ReferenceEditPanel" method="_on_Filter_toggled"] -[connection signal="pressed" from="ReferenceEditPanel/ReferenceEdit/Options/Reset" to="ReferenceEditPanel" method="_on_Reset_pressed"] -[connection signal="value_changed" from="ReferenceEditPanel/ReferenceEdit/Options/Position/X" to="ReferenceEditPanel" method="_on_X_value_changed"] -[connection signal="value_changed" from="ReferenceEditPanel/ReferenceEdit/Options/Position/Y" to="ReferenceEditPanel" method="_on_Y_value_changed"] -[connection signal="value_changed" from="ReferenceEditPanel/ReferenceEdit/Options/Scale" to="ReferenceEditPanel" method="_on_Scale_value_changed"] -[connection signal="value_changed" from="ReferenceEditPanel/ReferenceEdit/Options/Rotation" to="ReferenceEditPanel" method="_on_Rotation_value_changed"] -[connection signal="toggled" from="ReferenceEditPanel/ReferenceEdit/Options/Monochrome" to="ReferenceEditPanel" method="_on_Monochrome_toggled"] -[connection signal="color_changed" from="ReferenceEditPanel/ReferenceEdit/Options/Overlay" to="ReferenceEditPanel" method="_on_Overlay_color_changed"] -[connection signal="value_changed" from="ReferenceEditPanel/ReferenceEdit/Options/Opacity" to="ReferenceEditPanel" method="_on_Opacity_value_changed"] -[connection signal="value_changed" from="ReferenceEditPanel/ReferenceEdit/Options/ColorClamping" to="ReferenceEditPanel" method="_on_ColorClamping_value_changed"] -[connection signal="timeout" from="ReferenceEditPanel/Timer" to="ReferenceEditPanel" method="_on_timer_timeout"] -[connection signal="canceled" from="ReferenceEditPanel/ConfirmRemoveDialog" to="ReferenceEditPanel" method="_on_confirm_remove_dialog_canceled"] -[connection signal="confirmed" from="ReferenceEditPanel/ConfirmRemoveDialog" to="ReferenceEditPanel" method="_on_remove_confirm_dialog_confirmed"] +[node name="ConfirmRemoveDialog" type="ConfirmationDialog" parent="ScrollContainer/Container/ReferenceEdit"] +position = Vector2i(0, 36) +size = Vector2i(454, 106) +dialog_text = "Are you sure you want to remove this reference image? It will not be deleted from your file system." +dialog_autowrap = true + +[node name="Overlay" type="CanvasLayer" parent="."] + +[node name="DragHighlight" type="ColorRect" parent="Overlay"] +color = Color(0, 0.741176, 1, 0.501961) + +[connection signal="pressed" from="ScrollContainer/Container/Tools/MoveImageLeftBtn" to="." method="_on_move_image_left_pressed"] +[connection signal="pressed" from="ScrollContainer/Container/Tools/MoveImageRightBtn" to="." method="_on_move_image_right_pressed"] +[connection signal="pressed" from="ScrollContainer/Container/ReferenceEdit/ImageOptions/Remove" to="ScrollContainer/Container/ReferenceEdit" method="_on_Remove_pressed"] +[connection signal="pressed" from="ScrollContainer/Container/ReferenceEdit/Options/Reset" to="ScrollContainer/Container/ReferenceEdit" method="_on_Reset_pressed"] +[connection signal="value_changed" from="ScrollContainer/Container/ReferenceEdit/Options/Position/X" to="ScrollContainer/Container/ReferenceEdit" method="_on_X_value_changed"] +[connection signal="value_changed" from="ScrollContainer/Container/ReferenceEdit/Options/Position/Y" to="ScrollContainer/Container/ReferenceEdit" method="_on_Y_value_changed"] +[connection signal="value_changed" from="ScrollContainer/Container/ReferenceEdit/Options/Scale" to="ScrollContainer/Container/ReferenceEdit" method="_on_Scale_value_changed"] +[connection signal="value_changed" from="ScrollContainer/Container/ReferenceEdit/Options/Rotation" to="ScrollContainer/Container/ReferenceEdit" method="_on_Rotation_value_changed"] +[connection signal="toggled" from="ScrollContainer/Container/ReferenceEdit/Options/Filter" to="ScrollContainer/Container/ReferenceEdit" method="_on_Filter_toggled"] +[connection signal="toggled" from="ScrollContainer/Container/ReferenceEdit/Options/Monochrome" to="ScrollContainer/Container/ReferenceEdit" method="_on_Monochrome_toggled"] +[connection signal="color_changed" from="ScrollContainer/Container/ReferenceEdit/Options/Overlay" to="ScrollContainer/Container/ReferenceEdit" method="_on_Overlay_color_changed"] +[connection signal="value_changed" from="ScrollContainer/Container/ReferenceEdit/Options/Opacity" to="ScrollContainer/Container/ReferenceEdit" method="_on_Opacity_value_changed"] +[connection signal="value_changed" from="ScrollContainer/Container/ReferenceEdit/Options/ColorClamping" to="ScrollContainer/Container/ReferenceEdit" method="_on_ColorClamping_value_changed"] +[connection signal="timeout" from="ScrollContainer/Container/ReferenceEdit/Timer" to="ScrollContainer/Container/ReferenceEdit" method="_on_timer_timeout"] +[connection signal="canceled" from="ScrollContainer/Container/ReferenceEdit/ConfirmRemoveDialog" to="ScrollContainer/Container/ReferenceEdit" method="_on_confirm_remove_dialog_canceled"] +[connection signal="confirmed" from="ScrollContainer/Container/ReferenceEdit/ConfirmRemoveDialog" to="ScrollContainer/Container/ReferenceEdit" method="_on_confirm_remove_dialog_confirmed"] From a6c86d5824036ac9a793947bc500f7b4057ee7cd Mon Sep 17 00:00:00 2001 From: TheLsbt Date: Thu, 21 Dec 2023 22:23:13 +0200 Subject: [PATCH 15/31] Added Icons Added icons for the tools of the Reference Images --- assets/graphics/reference_images/Move.png | Bin 0 -> 192 bytes .../graphics/reference_images/Move.png.import | 34 ++++++++++++++++++ assets/graphics/reference_images/Rotate.png | Bin 0 -> 215 bytes .../reference_images/Rotate.png.import | 34 ++++++++++++++++++ assets/graphics/reference_images/Scale.png | Bin 0 -> 204 bytes .../reference_images/Scale.png.import | 34 ++++++++++++++++++ assets/graphics/reference_images/Select.png | Bin 0 -> 194 bytes .../reference_images/Select.png.import | 34 ++++++++++++++++++ 8 files changed, 136 insertions(+) create mode 100644 assets/graphics/reference_images/Move.png create mode 100644 assets/graphics/reference_images/Move.png.import create mode 100644 assets/graphics/reference_images/Rotate.png create mode 100644 assets/graphics/reference_images/Rotate.png.import create mode 100644 assets/graphics/reference_images/Scale.png create mode 100644 assets/graphics/reference_images/Scale.png.import create mode 100644 assets/graphics/reference_images/Select.png create mode 100644 assets/graphics/reference_images/Select.png.import diff --git a/assets/graphics/reference_images/Move.png b/assets/graphics/reference_images/Move.png new file mode 100644 index 0000000000000000000000000000000000000000..94cb1b21370b738c1a7384213cccb2b606e54ea1 GIT binary patch literal 192 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|sytmBLp(a4 zhC1>cP~Z^$_y763O}c)L2?upj_DXtbCv4an sDI!>}BDAw8R^{zAIpN6(TaQG0 z#&$eqbco-T&X#okSM1WjE?fUg>&s2d~ln;`K+P6r5{}CU9t9=Gd;c pO@H_M>s!+{r7pLSXE8RurOkSF})kA_IM|V%7YUQzSJ$IY>GT7~M7No7Y_u^q_ zYv_VYq#St;trCT(fiEz80-yV7SuMQL+E^D(73h5_*h&7Q8zi znjH9coUKe?OIVT&sA{v@*Fx=+m-k`qI>W_RWQ;x2S+QPRclYlN_@O1TaS?83{1OTbO BOCbON literal 0 HcmV?d00001 diff --git a/assets/graphics/reference_images/Scale.png.import b/assets/graphics/reference_images/Scale.png.import new file mode 100644 index 000000000000..25120c3db47b --- /dev/null +++ b/assets/graphics/reference_images/Scale.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://nfabwr5mgdir" +path="res://.godot/imported/Scale.png-a36dbe605e7db190575d43180968ebf0.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/graphics/reference_images/Scale.png" +dest_files=["res://.godot/imported/Scale.png-a36dbe605e7db190575d43180968ebf0.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/graphics/reference_images/Select.png b/assets/graphics/reference_images/Select.png new file mode 100644 index 0000000000000000000000000000000000000000..62f811be77951b72d6fa76f02264ea8f4008e8e8 GIT binary patch literal 194 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|YCK&WLp(a~ zPVweDpupj>@a5n2KIX9*uCggUQt8~Ee)x!3`lY3vsj^~PktMvGNn!!F=czTkvldhd z%vt8uSJKrqjZuSR*FlfVQ{5(|e_FPX$tIx6b>1nr{IZYlXJs_Zn|-O_|BaG%S68#0 r8Y~X~<^=kEKXLO=@0+Vxe`0KRSGdT^6@OC#x`V;f)z4*}Q$iB}4Y5hk literal 0 HcmV?d00001 diff --git a/assets/graphics/reference_images/Select.png.import b/assets/graphics/reference_images/Select.png.import new file mode 100644 index 000000000000..139f2a09179e --- /dev/null +++ b/assets/graphics/reference_images/Select.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d2m7enib3dplc" +path="res://.godot/imported/Select.png-ffb31c976f80e8581fb7101ad43dfb5a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/graphics/reference_images/Select.png" +dest_files=["res://.godot/imported/Select.png-ffb31c976f80e8581fb7101ad43dfb5a.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 From 7b988d41e91aef3b8be1d0bbf573255ef938f0b0 Mon Sep 17 00:00:00 2001 From: TheLsbt Date: Fri, 22 Dec 2023 00:35:38 +0200 Subject: [PATCH 16/31] Applied the icons to the UI --- src/UI/ReferenceImages/ReferenceEdit.gd | 10 ++ src/UI/ReferenceImages/ReferencesPanel.tscn | 104 ++++++++++++++++++-- src/UI/UI.tscn | 2 +- 3 files changed, 105 insertions(+), 11 deletions(-) diff --git a/src/UI/ReferenceImages/ReferenceEdit.gd b/src/UI/ReferenceImages/ReferenceEdit.gd index adc82a87048f..24ba3d581018 100644 --- a/src/UI/ReferenceImages/ReferenceEdit.gd +++ b/src/UI/ReferenceImages/ReferenceEdit.gd @@ -89,6 +89,16 @@ func _reset_properties() -> void: references_container.queue_redraw() +func _on_image_path_pressed() -> void: + var ri: ReferenceImage = Global.current_project.get_current_reference_image() + if !ri: + return + if ri.image_path.is_empty(): + print("No path for this image") + return + OS.shell_open(ri.image_path.get_base_dir()) + + func _on_Monochrome_toggled(pressed: bool) -> void: if _ignore_spinbox_changes: return diff --git a/src/UI/ReferenceImages/ReferencesPanel.tscn b/src/UI/ReferenceImages/ReferencesPanel.tscn index effd47aefa81..a177934272ec 100644 --- a/src/UI/ReferenceImages/ReferencesPanel.tscn +++ b/src/UI/ReferenceImages/ReferencesPanel.tscn @@ -1,10 +1,14 @@ -[gd_scene load_steps=9 format=3 uid="uid://cxhs8qy5ilufv"] +[gd_scene load_steps=13 format=3 uid="uid://cxhs8qy5ilufv"] [ext_resource type="Script" path="res://src/UI/ReferenceImages/ReferencesPanel.gd" id="1"] [ext_resource type="Script" path="res://src/UI/Nodes/ValueSlider.gd" id="2_1qu4x"] [ext_resource type="Texture2D" uid="uid://d1oxrkwndy5fi" path="res://assets/graphics/timeline/move_arrow.png" id="2_uqbp6"] [ext_resource type="PackedScene" uid="uid://yjhp0ssng2mp" path="res://src/UI/Nodes/ValueSlider.tscn" id="3_1w6gu"] +[ext_resource type="Texture2D" uid="uid://d2m7enib3dplc" path="res://assets/graphics/reference_images/Select.png" id="3_ikegk"] [ext_resource type="Script" path="res://src/UI/ReferenceImages/ReferenceEdit.gd" id="3_skjtb"] +[ext_resource type="Texture2D" uid="uid://cedsyi8gf2n2i" path="res://assets/graphics/reference_images/Move.png" id="4_iskr4"] +[ext_resource type="Texture2D" uid="uid://dtd43nvphu3jj" path="res://assets/graphics/reference_images/Rotate.png" id="5_p8kax"] +[ext_resource type="Texture2D" uid="uid://nfabwr5mgdir" path="res://assets/graphics/reference_images/Scale.png" id="6_62aqj"] [sub_resource type="InputEventAction" id="InputEventAction_unp5j"] action = &"move_frame_right" @@ -12,7 +16,7 @@ action = &"move_frame_right" [sub_resource type="Shortcut" id="Shortcut_uucm4"] events = [SubResource("InputEventAction_unp5j")] -[sub_resource type="ButtonGroup" id="ButtonGroup_w2sra"] +[sub_resource type="ButtonGroup" id="ButtonGroup_adw61"] [node name="Reference Images" type="PanelContainer"] custom_minimum_size = Vector2(300, 0) @@ -101,30 +105,110 @@ size_flags_horizontal = 3 [node name="TransformTools" type="HBoxContainer" parent="ScrollContainer/Container/Tools"] layout_mode = 2 -[node name="Select" type="Button" parent="ScrollContainer/Container/Tools/TransformTools"] +[node name="Select" type="Button" parent="ScrollContainer/Container/Tools/TransformTools" groups=["UIButtons"]] custom_minimum_size = Vector2(31, 31) layout_mode = 2 +size_flags_horizontal = 0 +tooltip_text = "Move the selected reference image to the right" +focus_mode = 0 +mouse_default_cursor_shape = 2 toggle_mode = true button_pressed = true -button_group = SubResource("ButtonGroup_w2sra") +button_group = SubResource("ButtonGroup_adw61") +shortcut = SubResource("Shortcut_uucm4") + +[node name="TextureRect" type="TextureRect" parent="ScrollContainer/Container/Tools/TransformTools/Select"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -12.0 +offset_top = -12.0 +offset_right = 12.0 +offset_bottom = 12.0 +grow_horizontal = 2 +grow_vertical = 2 +texture = ExtResource("3_ikegk") -[node name="Move" type="Button" parent="ScrollContainer/Container/Tools/TransformTools"] +[node name="Move" type="Button" parent="ScrollContainer/Container/Tools/TransformTools" groups=["UIButtons"]] custom_minimum_size = Vector2(31, 31) layout_mode = 2 +size_flags_horizontal = 0 +tooltip_text = "Move the selected reference image to the right" +focus_mode = 0 +mouse_default_cursor_shape = 2 toggle_mode = true -button_group = SubResource("ButtonGroup_w2sra") +button_group = SubResource("ButtonGroup_adw61") +shortcut = SubResource("Shortcut_uucm4") + +[node name="TextureRect" type="TextureRect" parent="ScrollContainer/Container/Tools/TransformTools/Move"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -12.0 +offset_top = -12.0 +offset_right = 12.0 +offset_bottom = 12.0 +grow_horizontal = 2 +grow_vertical = 2 +texture = ExtResource("4_iskr4") -[node name="Rotate" type="Button" parent="ScrollContainer/Container/Tools/TransformTools"] +[node name="Rotate" type="Button" parent="ScrollContainer/Container/Tools/TransformTools" groups=["UIButtons"]] custom_minimum_size = Vector2(31, 31) layout_mode = 2 +size_flags_horizontal = 0 +tooltip_text = "Move the selected reference image to the right" +focus_mode = 0 +mouse_default_cursor_shape = 2 toggle_mode = true -button_group = SubResource("ButtonGroup_w2sra") +button_group = SubResource("ButtonGroup_adw61") +shortcut = SubResource("Shortcut_uucm4") + +[node name="TextureRect" type="TextureRect" parent="ScrollContainer/Container/Tools/TransformTools/Rotate"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -12.0 +offset_top = -12.0 +offset_right = 12.0 +offset_bottom = 12.0 +grow_horizontal = 2 +grow_vertical = 2 +texture = ExtResource("5_p8kax") -[node name="Scale" type="Button" parent="ScrollContainer/Container/Tools/TransformTools"] +[node name="Scale" type="Button" parent="ScrollContainer/Container/Tools/TransformTools" groups=["UIButtons"]] custom_minimum_size = Vector2(31, 31) layout_mode = 2 +size_flags_horizontal = 0 +tooltip_text = "Move the selected reference image to the right" +focus_mode = 0 +mouse_default_cursor_shape = 2 toggle_mode = true -button_group = SubResource("ButtonGroup_w2sra") +button_group = SubResource("ButtonGroup_adw61") +shortcut = SubResource("Shortcut_uucm4") + +[node name="TextureRect" type="TextureRect" parent="ScrollContainer/Container/Tools/TransformTools/Scale"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -12.0 +offset_top = -12.0 +offset_right = 12.0 +offset_bottom = 12.0 +grow_horizontal = 2 +grow_vertical = 2 +texture = ExtResource("6_62aqj") [node name="ReferenceImages" type="ScrollContainer" parent="ScrollContainer/Container"] layout_mode = 2 diff --git a/src/UI/UI.tscn b/src/UI/UI.tscn index e3fe6401f760..ca1e93e96d84 100644 --- a/src/UI/UI.tscn +++ b/src/UI/UI.tscn @@ -310,7 +310,7 @@ camera_path = NodePath("SubViewport/Camera2D") [node name="SubViewport" type="SubViewport" parent="DockableContainer/Main Canvas/ViewportandVerticalRuler/SubViewportContainer"] handle_input_locally = false canvas_item_default_texture_filter = 0 -size = Vector2i(862, 515) +size = Vector2i(2, 2) render_target_update_mode = 4 [node name="TransparentChecker" parent="DockableContainer/Main Canvas/ViewportandVerticalRuler/SubViewportContainer/SubViewport" instance=ExtResource("5")] From c2e59a494e2babe7f4bf28f48d9f2bec5d58f320 Mon Sep 17 00:00:00 2001 From: TheLsbt Date: Fri, 22 Dec 2023 01:22:39 +0200 Subject: [PATCH 17/31] Fix Scripting Issues --- src/Classes/Project.gd | 2 +- src/UI/Canvas/ReferenceImages.gd | 12 +----------- src/UI/ReferenceImages/ReferenceEdit.gd | 5 +---- src/UI/ReferenceImages/ReferenceImageButton.gd | 6 +++--- src/UI/ReferenceImages/ReferencesPanel.gd | 13 ++++++------- 5 files changed, 12 insertions(+), 26 deletions(-) diff --git a/src/Classes/Project.gd b/src/Classes/Project.gd index 8a54d86d7da3..4dbb4b8c8bbd 100644 --- a/src/Classes/Project.gd +++ b/src/Classes/Project.gd @@ -891,6 +891,6 @@ func get_reference_image(index: int) -> ReferenceImage: ## Reorders the position of the reference image in the tree / reference_images array func reorder_reference_image(from: int, to: int) -> void: - var ri : ReferenceImage = reference_images.pop_at(from) + var ri: ReferenceImage = reference_images.pop_at(from) reference_images.insert(to, ri) Global.canvas.reference_image_container.move_child(ri, to) diff --git a/src/UI/Canvas/ReferenceImages.gd b/src/UI/Canvas/ReferenceImages.gd index 2fc7345abb28..7b7d3684f147 100644 --- a/src/UI/Canvas/ReferenceImages.gd +++ b/src/UI/Canvas/ReferenceImages.gd @@ -161,9 +161,7 @@ func _input(event: InputEvent) -> void: ) elif mode == Mode.Scale: scale_reference_image(local_mouse_pos, ri) - text = str( - "Moving: ", (og_scale * 100).floor(), " -> ", (ri.scale * 100).floor() - ) + text = str("Moving: ", (og_scale * 100).floor(), " -> ", (ri.scale * 100).floor()) Global.cursor_position_label.text = text @@ -334,11 +332,3 @@ func _draw() -> void: draw_polyline(p, Color(0.50, 0.99, 0.29), line_width) elif Geometry2D.is_point_in_polygon(get_local_mouse_position(), p) and !dragging: draw_polyline(p, Color(0.98, 0.80, 0.29), line_width) - - -## This function creates random images with random colors -func generate_random_images(amount: int, size: Vector2) -> void: - for i in range(amount): - var image = Image.create(size.x, size.y, false, Image.FORMAT_RGBA8) - image.fill(Color(randf(), randf(), randf())) - OpenSave.import_reference_image_from_image(image) diff --git a/src/UI/ReferenceImages/ReferenceEdit.gd b/src/UI/ReferenceImages/ReferenceEdit.gd index 24ba3d581018..d48bcba2edbe 100644 --- a/src/UI/ReferenceImages/ReferenceEdit.gd +++ b/src/UI/ReferenceImages/ReferenceEdit.gd @@ -11,9 +11,7 @@ var _ignore_spinbox_changes: bool = false func _ready() -> void: - references_container.reference_image_changed.connect( - _on_reference_image_changed - ) + references_container.reference_image_changed.connect(_on_reference_image_changed) func _update_properties(): @@ -272,4 +270,3 @@ func _on_reference_image_changed(index: int) -> void: _reset_properties() else: _update_properties() - diff --git a/src/UI/ReferenceImages/ReferenceImageButton.gd b/src/UI/ReferenceImages/ReferenceImageButton.gd index 24e17fee7c0f..61ea643b68d3 100644 --- a/src/UI/ReferenceImages/ReferenceImageButton.gd +++ b/src/UI/ReferenceImages/ReferenceImageButton.gd @@ -23,14 +23,14 @@ func _can_drop_data(at_position: Vector2, data: Variant) -> bool: return false var index := get_index() - 1 - var from_index : int = data[1] + var from_index: int = data[1] # If the index < 0 then that means this button is the "reset button" # Or we are trying to drop on the same button if index < 0 or index == from_index: Global.reference_panel.drag_highlight.visible = false return false - var side : int = -1 + var side: int = -1 if get_local_mouse_position().x > size.x / 2: side = 1 @@ -48,7 +48,7 @@ func _can_drop_data(at_position: Vector2, data: Variant) -> bool: func _drop_data(at_position: Vector2, data: Variant) -> void: - var from_index : int = data[1] + var from_index: int = data[1] var to_index := get_index() if get_local_mouse_position().x > size.x / 2: diff --git a/src/UI/ReferenceImages/ReferencesPanel.gd b/src/UI/ReferenceImages/ReferencesPanel.gd index 6fb0f1473929..744aa9f480ce 100644 --- a/src/UI/ReferenceImages/ReferencesPanel.gd +++ b/src/UI/ReferenceImages/ReferencesPanel.gd @@ -5,7 +5,7 @@ extends PanelContainer const ReferenceImageButton = preload("res://src/UI/ReferenceImages/ReferenceImageButton.tscn") var list_btn_group := ButtonGroup.new() -var transform_button_group : ButtonGroup +var transform_button_group: ButtonGroup var _ignore_ui_updates := false @onready var list := %List as HBoxContainer @@ -13,6 +13,7 @@ var _ignore_ui_updates := false @onready var remove_btn := $ScrollContainer/Container/ReferenceEdit/ImageOptions/Remove as Button @onready var transform_tools_btns := $ScrollContainer/Container/Tools/TransformTools + func _ready() -> void: transform_button_group = transform_tools_btns.get_child(0).button_group transform_button_group.pressed.connect(_on_transform_tool_button_group_pressed) @@ -24,7 +25,6 @@ func _ready() -> void: # We call this function to update the buttons _on_references_changed() _update_ui() - Global.canvas.reference_image_container.generate_random_images(3, Vector2(100, 100)) func _notification(what: int) -> void: @@ -37,12 +37,12 @@ func _on_transform_tool_button_group_pressed(button: Button) -> void: func _on_move_image_left_pressed() -> void: - var index : int = Global.current_project.reference_index + var index: int = Global.current_project.reference_index reorder_reference_image(index, index - 1) func _on_move_image_right_pressed() -> void: - var index : int = Global.current_project.reference_index + var index: int = Global.current_project.reference_index reorder_reference_image(index, index + 1) @@ -76,8 +76,7 @@ func reorder_reference_image(from: int, to: int, update_reference_index := true) func _update_ui() -> void: - var index : int = Global.current_project.reference_index - print("Updating ui: ", index) + var index: int = Global.current_project.reference_index # Enable the buttons as a default %MoveImageRightBtn.disabled = false @@ -150,7 +149,7 @@ func _on_references_changed(): # And update. for ref in Global.current_project.reference_images: ref.visible = true - var l : Button = ReferenceImageButton.instantiate() + var l: Button = ReferenceImageButton.instantiate() l.button_group = list_btn_group if ref.texture: l.icon = ref.texture From 07e90b448c485994bb59fd24757026e3611d5796 Mon Sep 17 00:00:00 2001 From: TheLsbt Date: Fri, 22 Dec 2023 01:37:19 +0200 Subject: [PATCH 18/31] Fixed Linting --- src/UI/Canvas/ReferenceImages.gd | 12 ++++++------ src/UI/ReferenceImages/ReferenceImageButton.gd | 6 +++--- src/UI/ReferenceImages/ReferencesPanel.gd | 15 +++++++-------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/UI/Canvas/ReferenceImages.gd b/src/UI/Canvas/ReferenceImages.gd index 7b7d3684f147..727b2e1f8a3b 100644 --- a/src/UI/Canvas/ReferenceImages.gd +++ b/src/UI/Canvas/ReferenceImages.gd @@ -4,9 +4,9 @@ extends Node2D signal reference_image_changed(index: int) -enum Mode { Select, Move, Rotate, Scale } +enum Mode { SELECT, MOVE, ROTATE, SCALE } -var mode: Mode = Mode.Select +var mode: Mode = Mode.SELECT var index: int: get: @@ -127,7 +127,7 @@ func _input(event: InputEvent) -> void: if dragging: var text := "" - if mode == Mode.Select: + if mode == Mode.SELECT: # Scale if Input.is_action_pressed("reference_scale"): scale_reference_image(local_mouse_pos, ri) @@ -147,10 +147,10 @@ func _input(event: InputEvent) -> void: else: move_reference_image(local_mouse_pos, ri) text = str("Moving to: ", og_pos.floor(), " -> ", ri.position.floor()) - elif mode == Mode.Move: + elif mode == Mode.MOVE: move_reference_image(local_mouse_pos, ri) text = str("Moving to: ", og_pos.floor(), " -> ", ri.position.floor()) - elif mode == Mode.Rotate: + elif mode == Mode.ROTATE: rotate_reference_image(local_mouse_pos, ri) text = str( "Rotating: ", @@ -159,7 +159,7 @@ func _input(event: InputEvent) -> void: floorf(rad_to_deg(ri.rotation)), "°" ) - elif mode == Mode.Scale: + elif mode == Mode.SCALE: scale_reference_image(local_mouse_pos, ri) text = str("Moving: ", (og_scale * 100).floor(), " -> ", (ri.scale * 100).floor()) diff --git a/src/UI/ReferenceImages/ReferenceImageButton.gd b/src/UI/ReferenceImages/ReferenceImageButton.gd index 61ea643b68d3..79f4984da442 100644 --- a/src/UI/ReferenceImages/ReferenceImageButton.gd +++ b/src/UI/ReferenceImages/ReferenceImageButton.gd @@ -1,7 +1,7 @@ extends Button -func _get_drag_data(at_position: Vector2) -> Variant: +func _get_drag_data(_at_position: Vector2) -> Variant: var index := get_index() - 1 # If the index < 0 then that means this button is the "reset button" if index < 0: @@ -14,7 +14,7 @@ func _get_drag_data(at_position: Vector2) -> Variant: return data -func _can_drop_data(at_position: Vector2, data: Variant) -> bool: +func _can_drop_data(_at_position: Vector2, data: Variant) -> bool: if typeof(data) != TYPE_ARRAY: Global.reference_panel.drag_highlight.visible = false return false @@ -47,7 +47,7 @@ func _can_drop_data(at_position: Vector2, data: Variant) -> bool: return true -func _drop_data(at_position: Vector2, data: Variant) -> void: +func _drop_data(_at_position: Vector2, data: Variant) -> void: var from_index: int = data[1] var to_index := get_index() diff --git a/src/UI/ReferenceImages/ReferencesPanel.gd b/src/UI/ReferenceImages/ReferencesPanel.gd index 744aa9f480ce..a06733c409fb 100644 --- a/src/UI/ReferenceImages/ReferencesPanel.gd +++ b/src/UI/ReferenceImages/ReferencesPanel.gd @@ -100,14 +100,6 @@ func _update_ui() -> void: else: %MoveImageRightBtn.mouse_default_cursor_shape = CURSOR_POINTING_HAND - # Update the buttons to show which one is pressed - if list_btn_group.get_buttons().size() > 0: - # First we loop through the buttons to "unpress them all" - for b: Button in list_btn_group.get_buttons(): - b.set_pressed_no_signal(false) - # Then we get the wanted button and we press it - list_btn_group.get_buttons()[index + 1].set_pressed_no_signal(true) - # Update the remove button remove_btn.disabled = index == -1 if remove_btn.disabled: @@ -124,6 +116,13 @@ func _on_reference_image_button_pressed(button: Button) -> void: # In case the signal is emitted for another node and not from a pressed button func _on_reference_image_changed(index: int) -> void: _update_ui() + # Update the buttons to show which one is pressed + if list_btn_group.get_buttons().size() > 0: + # First we loop through the buttons to "unpress them all" + for b: Button in list_btn_group.get_buttons(): + b.set_pressed_no_signal(false) + # Then we get the wanted button and we press it + list_btn_group.get_buttons()[index + 1].set_pressed_no_signal(true) func _on_references_changed(): From fae90bade0e25d8c087800a589974d9965122f01 Mon Sep 17 00:00:00 2001 From: TheLsbt <141819348+TheLsbt@users.noreply.github.com> Date: Tue, 26 Dec 2023 21:04:28 +0200 Subject: [PATCH 19/31] Rename Move.png to move.png --- .../reference_images/{Move.png => move.png} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename assets/graphics/reference_images/{Move.png => move.png} (100%) diff --git a/assets/graphics/reference_images/Move.png b/assets/graphics/reference_images/move.png similarity index 100% rename from assets/graphics/reference_images/Move.png rename to assets/graphics/reference_images/move.png From f604da046967fa6f7cb5142d430ddef40cf0ec17 Mon Sep 17 00:00:00 2001 From: TheLsbt Date: Tue, 26 Dec 2023 21:13:30 +0200 Subject: [PATCH 20/31] Update Canvas.gd --- src/UI/Canvas/Canvas.gd | 50 ++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/src/UI/Canvas/Canvas.gd b/src/UI/Canvas/Canvas.gd index 59039887ea8e..2ec91a9e12e2 100644 --- a/src/UI/Canvas/Canvas.gd +++ b/src/UI/Canvas/Canvas.gd @@ -30,6 +30,8 @@ var layer_metadata_texture := ImageTexture.new() func _ready() -> void: + material.set_shader_parameter("layers", layer_texture_array) + material.set_shader_parameter("metadata", layer_metadata_texture) Global.project_changed.connect(queue_redraw) onion_past.type = onion_past.PAST onion_past.blue_red_color = Global.onion_skinning_past_color @@ -128,7 +130,7 @@ func update_texture(layer_i: int, frame_i := -1, project := Global.current_proje cel_image.get_size() == Vector2i(layer_texture_array.get_width(), layer_texture_array.get_height()) ): - layer_texture_array.update_layer(cel_image, layer_i) + layer_texture_array.update_layer(cel_image, project.ordered_layers[layer_i]) func update_selected_cels_textures(project := Global.current_project) -> void: @@ -150,60 +152,72 @@ func draw_layers() -> void: ) if recreate_texture_array: var textures: Array[Image] = [] + textures.resize(project.layers.size()) # Nx3 texture, where N is the number of layers and the first row are the blend modes, # the second are the opacities and the third are the origins layer_metadata_image = Image.create(project.layers.size(), 3, false, Image.FORMAT_RG8) # Draw current frame layers for i in project.layers.size(): + var ordered_index := project.ordered_layers[i] var layer := project.layers[i] + var cel := current_cels[i] var cel_image: Image if Global.display_layer_effects: - cel_image = layer.display_effects(current_cels[i]) + cel_image = layer.display_effects(cel) else: - cel_image = current_cels[i].get_image() - textures.append(cel_image) + cel_image = cel.get_image() + textures[ordered_index] = cel_image # Store the blend mode - layer_metadata_image.set_pixel(i, 0, Color(layer.blend_mode / 255.0, 0.0, 0.0, 0.0)) + layer_metadata_image.set_pixel( + ordered_index, 0, Color(layer.blend_mode / 255.0, 0.0, 0.0, 0.0) + ) # Store the opacity if layer.is_visible_in_hierarchy(): - layer_metadata_image.set_pixel(i, 1, Color(current_cels[i].opacity, 0.0, 0.0, 0.0)) + var opacity := cel.get_final_opacity(layer) + layer_metadata_image.set_pixel(ordered_index, 1, Color(opacity, 0.0, 0.0, 0.0)) else: - layer_metadata_image.set_pixel(i, 1, Color()) + layer_metadata_image.set_pixel(ordered_index, 1, Color()) # Store the origin if [project.current_frame, i] in project.selected_cels: var origin := Vector2(move_preview_location).abs() / Vector2(cel_image.get_size()) - layer_metadata_image.set_pixel(i, 2, Color(origin.x, origin.y, 0.0, 0.0)) + layer_metadata_image.set_pixel( + ordered_index, 2, Color(origin.x, origin.y, 0.0, 0.0) + ) else: - layer_metadata_image.set_pixel(i, 2, Color()) + layer_metadata_image.set_pixel(ordered_index, 2, Color()) layer_texture_array.create_from_images(textures) layer_metadata_texture.set_image(layer_metadata_image) else: # Update the TextureArray if layer_texture_array.get_layers() > 0: for i in project.layers.size(): - var layer := project.layers[i] - var test_array := [project.current_frame, i] if not update_all_layers: + var test_array := [project.current_frame, i] if not test_array in project.selected_cels: continue + var ordered_index := project.ordered_layers[i] + var layer := project.layers[i] var cel := current_cels[i] var cel_image: Image if Global.display_layer_effects: cel_image = layer.display_effects(cel) else: cel_image = cel.get_image() - layer_texture_array.update_layer(cel_image, i) - layer_metadata_image.set_pixel(i, 0, Color(layer.blend_mode / 255.0, 0.0, 0.0, 0.0)) + layer_texture_array.update_layer(cel_image, ordered_index) + layer_metadata_image.set_pixel( + ordered_index, 0, Color(layer.blend_mode / 255.0, 0.0, 0.0, 0.0) + ) if layer.is_visible_in_hierarchy(): - layer_metadata_image.set_pixel(i, 1, Color(cel.opacity, 0.0, 0.0, 0.0)) + var opacity := cel.get_final_opacity(layer) + layer_metadata_image.set_pixel(ordered_index, 1, Color(opacity, 0.0, 0.0, 0.0)) else: - layer_metadata_image.set_pixel(i, 1, Color()) + layer_metadata_image.set_pixel(ordered_index, 1, Color()) var origin := Vector2(move_preview_location).abs() / Vector2(cel_image.get_size()) - layer_metadata_image.set_pixel(i, 2, Color(origin.x, origin.y, 0.0, 0.0)) + layer_metadata_image.set_pixel( + ordered_index, 2, Color(origin.x, origin.y, 0.0, 0.0) + ) layer_metadata_texture.update(layer_metadata_image) - material.set_shader_parameter("layers", layer_texture_array) - material.set_shader_parameter("metadata", layer_metadata_texture) material.set_shader_parameter("origin_x_positive", move_preview_location.x > 0) material.set_shader_parameter("origin_y_positive", move_preview_location.y > 0) update_all_layers = false From 3f1469a98f1ded4a40625fb34f5a8e335ef08545 Mon Sep 17 00:00:00 2001 From: TheLsbt Date: Tue, 26 Dec 2023 21:24:54 +0200 Subject: [PATCH 21/31] Updated the tooltips Also added the correct translations --- Translations/Translations.pot | 16 +++++++++++++ src/UI/ReferenceImages/ReferencesPanel.tscn | 26 ++++++++++----------- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/Translations/Translations.pot b/Translations/Translations.pot index c48f0c26b5fd..d2dc4a488652 100644 --- a/Translations/Translations.pot +++ b/Translations/Translations.pot @@ -2796,6 +2796,22 @@ msgstr "" msgid "Move the selected reference image to the left" msgstr "" +#. Select a reference on the canvas +msgid "Selects a reference image on the canvas" +msgstr "" + +#. Moves the reference on the canvas +msgid "Move the selected reference image" +msgstr "" + +#. Rotates the reference on the canvas +msgid "Rotate the selected reference image" +msgstr "" + +#. Rotates the reference on the canvas +msgid "Scale the selected reference image" +msgstr "" + #. Used in checkbuttons (like on/off switches) that enable/disable something. msgid "Enabled" msgstr "" diff --git a/src/UI/ReferenceImages/ReferencesPanel.tscn b/src/UI/ReferenceImages/ReferencesPanel.tscn index a177934272ec..b735ee78c2f0 100644 --- a/src/UI/ReferenceImages/ReferencesPanel.tscn +++ b/src/UI/ReferenceImages/ReferencesPanel.tscn @@ -4,11 +4,11 @@ [ext_resource type="Script" path="res://src/UI/Nodes/ValueSlider.gd" id="2_1qu4x"] [ext_resource type="Texture2D" uid="uid://d1oxrkwndy5fi" path="res://assets/graphics/timeline/move_arrow.png" id="2_uqbp6"] [ext_resource type="PackedScene" uid="uid://yjhp0ssng2mp" path="res://src/UI/Nodes/ValueSlider.tscn" id="3_1w6gu"] -[ext_resource type="Texture2D" uid="uid://d2m7enib3dplc" path="res://assets/graphics/reference_images/Select.png" id="3_ikegk"] [ext_resource type="Script" path="res://src/UI/ReferenceImages/ReferenceEdit.gd" id="3_skjtb"] -[ext_resource type="Texture2D" uid="uid://cedsyi8gf2n2i" path="res://assets/graphics/reference_images/Move.png" id="4_iskr4"] -[ext_resource type="Texture2D" uid="uid://dtd43nvphu3jj" path="res://assets/graphics/reference_images/Rotate.png" id="5_p8kax"] -[ext_resource type="Texture2D" uid="uid://nfabwr5mgdir" path="res://assets/graphics/reference_images/Scale.png" id="6_62aqj"] +[ext_resource type="Texture2D" uid="uid://d2m7enib3dplc" path="res://assets/graphics/reference_images/select.png" id="3_us8st"] +[ext_resource type="Texture2D" uid="uid://cedsyi8gf2n2i" path="res://assets/graphics/reference_images/move.png" id="4_8mlcg"] +[ext_resource type="Texture2D" uid="uid://dtd43nvphu3jj" path="res://assets/graphics/reference_images/rotate.png" id="5_ifey7"] +[ext_resource type="Texture2D" uid="uid://nfabwr5mgdir" path="res://assets/graphics/reference_images/scale.png" id="6_7v0q5"] [sub_resource type="InputEventAction" id="InputEventAction_unp5j"] action = &"move_frame_right" @@ -58,7 +58,7 @@ unique_name_in_owner = true custom_minimum_size = Vector2(31, 31) layout_mode = 2 size_flags_horizontal = 0 -tooltip_text = "Move the selected reference image to the left." +tooltip_text = "Move the selected reference image to the left" focus_mode = 0 mouse_default_cursor_shape = 2 shortcut = SubResource("Shortcut_uucm4") @@ -109,7 +109,7 @@ layout_mode = 2 custom_minimum_size = Vector2(31, 31) layout_mode = 2 size_flags_horizontal = 0 -tooltip_text = "Move the selected reference image to the right" +tooltip_text = "Selects a reference image on the canvas" focus_mode = 0 mouse_default_cursor_shape = 2 toggle_mode = true @@ -130,13 +130,13 @@ offset_right = 12.0 offset_bottom = 12.0 grow_horizontal = 2 grow_vertical = 2 -texture = ExtResource("3_ikegk") +texture = ExtResource("3_us8st") [node name="Move" type="Button" parent="ScrollContainer/Container/Tools/TransformTools" groups=["UIButtons"]] custom_minimum_size = Vector2(31, 31) layout_mode = 2 size_flags_horizontal = 0 -tooltip_text = "Move the selected reference image to the right" +tooltip_text = "Move the selected reference image" focus_mode = 0 mouse_default_cursor_shape = 2 toggle_mode = true @@ -156,13 +156,13 @@ offset_right = 12.0 offset_bottom = 12.0 grow_horizontal = 2 grow_vertical = 2 -texture = ExtResource("4_iskr4") +texture = ExtResource("4_8mlcg") [node name="Rotate" type="Button" parent="ScrollContainer/Container/Tools/TransformTools" groups=["UIButtons"]] custom_minimum_size = Vector2(31, 31) layout_mode = 2 size_flags_horizontal = 0 -tooltip_text = "Move the selected reference image to the right" +tooltip_text = "Rotate the selected image" focus_mode = 0 mouse_default_cursor_shape = 2 toggle_mode = true @@ -182,13 +182,13 @@ offset_right = 12.0 offset_bottom = 12.0 grow_horizontal = 2 grow_vertical = 2 -texture = ExtResource("5_p8kax") +texture = ExtResource("5_ifey7") [node name="Scale" type="Button" parent="ScrollContainer/Container/Tools/TransformTools" groups=["UIButtons"]] custom_minimum_size = Vector2(31, 31) layout_mode = 2 size_flags_horizontal = 0 -tooltip_text = "Move the selected reference image to the right" +tooltip_text = "Scale the selected reference image" focus_mode = 0 mouse_default_cursor_shape = 2 toggle_mode = true @@ -208,7 +208,7 @@ offset_right = 12.0 offset_bottom = 12.0 grow_horizontal = 2 grow_vertical = 2 -texture = ExtResource("6_62aqj") +texture = ExtResource("6_7v0q5") [node name="ReferenceImages" type="ScrollContainer" parent="ScrollContainer/Container"] layout_mode = 2 From a02bc8c6936e71e78f274a71accf84a84ad4a7e7 Mon Sep 17 00:00:00 2001 From: TheLsbt <141819348+TheLsbt@users.noreply.github.com> Date: Tue, 26 Dec 2023 21:29:31 +0200 Subject: [PATCH 22/31] Rename Select.png to select.png --- .../reference_images/{Select.png => select.png} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename assets/graphics/reference_images/{Select.png => select.png} (100%) diff --git a/assets/graphics/reference_images/Select.png b/assets/graphics/reference_images/select.png similarity index 100% rename from assets/graphics/reference_images/Select.png rename to assets/graphics/reference_images/select.png From 4b21876996c277093cea81592d1d1985e2553548 Mon Sep 17 00:00:00 2001 From: TheLsbt <141819348+TheLsbt@users.noreply.github.com> Date: Tue, 26 Dec 2023 21:33:07 +0200 Subject: [PATCH 23/31] Rename Select.png.import to select.png.import --- .../reference_images/{Select.png.import => select.png.import} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename assets/graphics/reference_images/{Select.png.import => select.png.import} (100%) diff --git a/assets/graphics/reference_images/Select.png.import b/assets/graphics/reference_images/select.png.import similarity index 100% rename from assets/graphics/reference_images/Select.png.import rename to assets/graphics/reference_images/select.png.import From 0ce54817f6e43bf8b4d016bb01ac6ef3133bea05 Mon Sep 17 00:00:00 2001 From: TheLsbt <141819348+TheLsbt@users.noreply.github.com> Date: Tue, 26 Dec 2023 21:33:42 +0200 Subject: [PATCH 24/31] Rename Move.png.import to move.png.import --- .../reference_images/{Move.png.import => move.png.import} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename assets/graphics/reference_images/{Move.png.import => move.png.import} (100%) diff --git a/assets/graphics/reference_images/Move.png.import b/assets/graphics/reference_images/move.png.import similarity index 100% rename from assets/graphics/reference_images/Move.png.import rename to assets/graphics/reference_images/move.png.import From 6d3613844ec6f750f7997b2ae0cda6500ba708df Mon Sep 17 00:00:00 2001 From: TheLsbt <141819348+TheLsbt@users.noreply.github.com> Date: Tue, 26 Dec 2023 21:33:57 +0200 Subject: [PATCH 25/31] Rename Rotate.png to rotate.png --- .../reference_images/{Rotate.png => rotate.png} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename assets/graphics/reference_images/{Rotate.png => rotate.png} (100%) diff --git a/assets/graphics/reference_images/Rotate.png b/assets/graphics/reference_images/rotate.png similarity index 100% rename from assets/graphics/reference_images/Rotate.png rename to assets/graphics/reference_images/rotate.png From d1b8d651f380f45fa804f5d1d9fc0d439bf0fd93 Mon Sep 17 00:00:00 2001 From: TheLsbt <141819348+TheLsbt@users.noreply.github.com> Date: Tue, 26 Dec 2023 21:34:18 +0200 Subject: [PATCH 26/31] Rename Rotate.png.import to rotate.png.import --- .../reference_images/{Rotate.png.import => rotate.png.import} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename assets/graphics/reference_images/{Rotate.png.import => rotate.png.import} (100%) diff --git a/assets/graphics/reference_images/Rotate.png.import b/assets/graphics/reference_images/rotate.png.import similarity index 100% rename from assets/graphics/reference_images/Rotate.png.import rename to assets/graphics/reference_images/rotate.png.import From d86bd6f391e60707d41558a8ba109b2a5e21733b Mon Sep 17 00:00:00 2001 From: TheLsbt Date: Tue, 26 Dec 2023 21:36:36 +0200 Subject: [PATCH 27/31] Fixed import files --- assets/graphics/reference_images/Move.png.import | 6 +++--- assets/graphics/reference_images/Rotate.png.import | 6 +++--- assets/graphics/reference_images/Scale.png.import | 6 +++--- assets/graphics/reference_images/Select.png.import | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/assets/graphics/reference_images/Move.png.import b/assets/graphics/reference_images/Move.png.import index d4f9e2cdf971..947b7c8b30fd 100644 --- a/assets/graphics/reference_images/Move.png.import +++ b/assets/graphics/reference_images/Move.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://cedsyi8gf2n2i" -path="res://.godot/imported/Move.png-8bf553cb7d6122de2b4d9be7bc3058da.ctex" +path="res://.godot/imported/move.png-ed702c0a346cd77f0de30a0cba128fc7.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/graphics/reference_images/Move.png" -dest_files=["res://.godot/imported/Move.png-8bf553cb7d6122de2b4d9be7bc3058da.ctex"] +source_file="res://assets/graphics/reference_images/move.png" +dest_files=["res://.godot/imported/move.png-ed702c0a346cd77f0de30a0cba128fc7.ctex"] [params] diff --git a/assets/graphics/reference_images/Rotate.png.import b/assets/graphics/reference_images/Rotate.png.import index fa348dccecc4..7db7ba35f51c 100644 --- a/assets/graphics/reference_images/Rotate.png.import +++ b/assets/graphics/reference_images/Rotate.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://dtd43nvphu3jj" -path="res://.godot/imported/Rotate.png-2791a6426c1bdfad969c88e7697da3a5.ctex" +path="res://.godot/imported/rotate.png-456db7ada5d7cd37fa30dc5557b226be.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/graphics/reference_images/Rotate.png" -dest_files=["res://.godot/imported/Rotate.png-2791a6426c1bdfad969c88e7697da3a5.ctex"] +source_file="res://assets/graphics/reference_images/rotate.png" +dest_files=["res://.godot/imported/rotate.png-456db7ada5d7cd37fa30dc5557b226be.ctex"] [params] diff --git a/assets/graphics/reference_images/Scale.png.import b/assets/graphics/reference_images/Scale.png.import index 25120c3db47b..704b5d2f0ca0 100644 --- a/assets/graphics/reference_images/Scale.png.import +++ b/assets/graphics/reference_images/Scale.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://nfabwr5mgdir" -path="res://.godot/imported/Scale.png-a36dbe605e7db190575d43180968ebf0.ctex" +path="res://.godot/imported/scale.png-475926e4af79bb726ef59440df6e6f71.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/graphics/reference_images/Scale.png" -dest_files=["res://.godot/imported/Scale.png-a36dbe605e7db190575d43180968ebf0.ctex"] +source_file="res://assets/graphics/reference_images/scale.png" +dest_files=["res://.godot/imported/scale.png-475926e4af79bb726ef59440df6e6f71.ctex"] [params] diff --git a/assets/graphics/reference_images/Select.png.import b/assets/graphics/reference_images/Select.png.import index 139f2a09179e..732423eba859 100644 --- a/assets/graphics/reference_images/Select.png.import +++ b/assets/graphics/reference_images/Select.png.import @@ -3,15 +3,15 @@ importer="texture" type="CompressedTexture2D" uid="uid://d2m7enib3dplc" -path="res://.godot/imported/Select.png-ffb31c976f80e8581fb7101ad43dfb5a.ctex" +path="res://.godot/imported/select.png-7c7e96d5ba897a73341e1d0445a3c991.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://assets/graphics/reference_images/Select.png" -dest_files=["res://.godot/imported/Select.png-ffb31c976f80e8581fb7101ad43dfb5a.ctex"] +source_file="res://assets/graphics/reference_images/select.png" +dest_files=["res://.godot/imported/select.png-7c7e96d5ba897a73341e1d0445a3c991.ctex"] [params] From d516912ee30a2bab31192cce7bec7eab1a1d940e Mon Sep 17 00:00:00 2001 From: TheLsbt <141819348+TheLsbt@users.noreply.github.com> Date: Tue, 26 Dec 2023 21:37:47 +0200 Subject: [PATCH 28/31] Rename Scale.png to scale.png --- .../reference_images/{Scale.png => scale.png} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename assets/graphics/reference_images/{Scale.png => scale.png} (100%) diff --git a/assets/graphics/reference_images/Scale.png b/assets/graphics/reference_images/scale.png similarity index 100% rename from assets/graphics/reference_images/Scale.png rename to assets/graphics/reference_images/scale.png From b6776e19c7486fd325a32f1bcb166a983c8b71a3 Mon Sep 17 00:00:00 2001 From: TheLsbt <141819348+TheLsbt@users.noreply.github.com> Date: Tue, 26 Dec 2023 21:38:03 +0200 Subject: [PATCH 29/31] Rename Scale.png.import to scale.png.import --- .../reference_images/{Scale.png.import => scale.png.import} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename assets/graphics/reference_images/{Scale.png.import => scale.png.import} (100%) diff --git a/assets/graphics/reference_images/Scale.png.import b/assets/graphics/reference_images/scale.png.import similarity index 100% rename from assets/graphics/reference_images/Scale.png.import rename to assets/graphics/reference_images/scale.png.import From 6aa274fe3e996de45f517fe5443f74d01b81c4c0 Mon Sep 17 00:00:00 2001 From: TheLsbt Date: Wed, 27 Dec 2023 13:39:34 +0200 Subject: [PATCH 30/31] Added logic to update the reference panel when the project changes Also fixed visual bugs related to highlighting the current reference image. Made it so the reference image that was selected in a project get selected again when the project opens instead of going back to -1 (nothing) --- src/Classes/Project.gd | 17 +++++++++++++++++ src/UI/ReferenceImages/ReferencesPanel.gd | 12 +++++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/Classes/Project.gd b/src/Classes/Project.gd index abfa3d3ff1b6..91d68965de05 100644 --- a/src/Classes/Project.gd +++ b/src/Classes/Project.gd @@ -251,6 +251,23 @@ func change_project() -> void: var edit_menu_popup: PopupMenu = Global.top_menu_container.edit_menu edit_menu_popup.set_item_disabled(Global.EditMenu.NEW_BRUSH, !has_selection) + # We loop through all the reference image nodes and the ones that are not apart + # of the current project we remove from the tree + # They will still be in memory though + for ri: ReferenceImage in Global.canvas.reference_image_container.get_children(): + if !reference_images.has(ri): + Global.canvas.reference_image_container.remove_child(ri) + # Now we loop through this projects reference images and add them back to the tree + var canvas_references := Global.canvas.reference_image_container.get_children() + for ri: ReferenceImage in reference_images: + if !canvas_references.has(ri) and !ri.is_inside_tree(): + Global.canvas.reference_image_container.add_child(ri) + + + + # Tell the reference images that the project changed + Global.reference_panel.project_changed() + var i := 0 for camera in Global.cameras: camera.rotation = cameras_rotation[i] diff --git a/src/UI/ReferenceImages/ReferencesPanel.gd b/src/UI/ReferenceImages/ReferencesPanel.gd index a06733c409fb..27a55b44c354 100644 --- a/src/UI/ReferenceImages/ReferencesPanel.gd +++ b/src/UI/ReferenceImages/ReferencesPanel.gd @@ -125,6 +125,13 @@ func _on_reference_image_changed(index: int) -> void: list_btn_group.get_buttons()[index + 1].set_pressed_no_signal(true) +func project_changed() -> void: + var project_reference_index := Global.current_project.reference_index + _on_references_changed() + _update_ui() + Global.current_project.set_reference_image_index(project_reference_index) + + func _on_references_changed(): # When we change the project we set the default Global.current_project.set_reference_image_index(-1) @@ -133,10 +140,6 @@ func _on_references_changed(): if c is Button: c.button_group = null c.queue_free() - # Made it only look in the ReferenceImages Node for reference images - for ref in Global.canvas.reference_image_container.get_children(): - if ref is ReferenceImage: - ref.visible = false # The default button var default = ReferenceImageButton.instantiate() @@ -147,7 +150,6 @@ func _on_references_changed(): # And update. for ref in Global.current_project.reference_images: - ref.visible = true var l: Button = ReferenceImageButton.instantiate() l.button_group = list_btn_group if ref.texture: From ef87d10dac9a4097db27364996b953e46bf5e2de Mon Sep 17 00:00:00 2001 From: TheLsbt Date: Thu, 28 Dec 2023 01:05:34 +0200 Subject: [PATCH 31/31] Update Project.gd --- src/Classes/Project.gd | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Classes/Project.gd b/src/Classes/Project.gd index 91d68965de05..648939cb14f4 100644 --- a/src/Classes/Project.gd +++ b/src/Classes/Project.gd @@ -263,8 +263,6 @@ func change_project() -> void: if !canvas_references.has(ri) and !ri.is_inside_tree(): Global.canvas.reference_image_container.add_child(ri) - - # Tell the reference images that the project changed Global.reference_panel.project_changed()