From 1ce89c65774d81db98b1e13a777d5f9ef071cbc3 Mon Sep 17 00:00:00 2001 From: OverloadedOrama <35376950+OverloadedOrama@users.noreply.github.com> Date: Fri, 24 Jul 2020 03:22:12 +0300 Subject: [PATCH] Added affecting options to the HSVDialog First option is to affect the selected pixels only. The second it to affect the current cel, or the entire frame (all cels of the frame). Options to affect all frames and all projects will be added next. I also made changes to Canvas.handle_undo() and handle_redo() to make this work. Once all these options are added successfully in HSVDialog, they will also be added in the rest of the Image effect dialogs. --- src/Autoload/DrawingAlgos.gd | 4 +- src/Canvas.gd | 90 +++++++++++++++++++++++------------ src/UI/Dialogs/HSVDialog.gd | 38 +++++++++++++-- src/UI/Dialogs/HSVDialog.tscn | 29 +++++++++-- 4 files changed, 120 insertions(+), 41 deletions(-) diff --git a/src/Autoload/DrawingAlgos.gd b/src/Autoload/DrawingAlgos.gd index acd3b97c0..995189958 100644 --- a/src/Autoload/DrawingAlgos.gd +++ b/src/Autoload/DrawingAlgos.gd @@ -454,9 +454,9 @@ func generate_outline(image : Image, outline_color : Color, thickness : int, dia Global.canvas.handle_redo("Draw") -func adjust_hsv(img: Image, delta_h : float, delta_s : float, delta_v : float) -> void: +func adjust_hsv(img: Image, delta_h : float, delta_s : float, delta_v : float, pixels : Array) -> void: img.lock() - for i in Global.current_project.selected_pixels: + for i in pixels: var c : Color = img.get_pixelv(i) # Hue var hue = range_lerp(c.h,0,1,-180,180) diff --git a/src/Canvas.gd b/src/Canvas.gd index 593ba31f7..899f83e7f 100644 --- a/src/Canvas.gd +++ b/src/Canvas.gd @@ -129,50 +129,78 @@ func new_empty_frame(first_time := false, single_layer := false, size := Global. return frame -func handle_undo(action : String) -> void: +func handle_undo(action : String, project : Project = Global.current_project, layer_index := -2, frame_index := -2) -> void: if !can_undo: return + + if layer_index <= -2: + layer_index = project.current_layer + if frame_index <= -2: + frame_index = project.current_frame + + var cels := [] var frames := [] - var frame_index := -1 - var layer_index := -1 - if Global.animation_timer.is_stopped(): # if we're not animating, store only the current canvas - frames.append(Global.current_project.frames[Global.current_project.current_frame]) - frame_index = Global.current_project.current_frame - layer_index = Global.current_project.current_layer - else: # If we're animating, store all frames - frames = Global.current_project.frames - Global.current_project.undos += 1 - Global.current_project.undo_redo.create_action(action) + var layers := [] + if frame_index == -1: + frames = project.frames + else: + frames.append(project.frames[frame_index]) + + if layer_index == -1: + layers = project.layers + else: + layers.append(project.layers[layer_index]) + for f in frames: - # I'm not sure why I have to unlock it, but... - # ...if I don't, it doesn't work properly - f.cels[Global.current_project.current_layer].image.unlock() - var data = f.cels[Global.current_project.current_layer].image.data - f.cels[Global.current_project.current_layer].image.lock() - Global.current_project.undo_redo.add_undo_property(f.cels[Global.current_project.current_layer].image, "data", data) - Global.current_project.undo_redo.add_undo_method(Global, "undo", frame_index, layer_index) + for l in layers: + var index = project.layers.find(l) + cels.append(f.cels[index]) + + project.undos += 1 + project.undo_redo.create_action(action) + for cel in cels: + # If we don't unlock the image, it doesn't work properly + cel.image.unlock() + var data = cel.image.data + cel.image.lock() + project.undo_redo.add_undo_property(cel.image, "data", data) + project.undo_redo.add_undo_method(Global, "undo", frame_index, layer_index) can_undo = false -func handle_redo(_action : String) -> void: +func handle_redo(_action : String, project : Project = Global.current_project, layer_index := -2, frame_index := -2) -> void: can_undo = true - - if Global.current_project.undos < Global.current_project.undo_redo.get_version(): + if project.undos < project.undo_redo.get_version(): return + + if layer_index <= -2: + layer_index = project.current_layer + if frame_index <= -2: + frame_index = project.current_frame + + var cels := [] var frames := [] - var frame_index := -1 - var layer_index := -1 - if Global.animation_timer.is_stopped(): - frames.append(Global.current_project.frames[Global.current_project.current_frame]) - frame_index = Global.current_project.current_frame - layer_index = Global.current_project.current_layer + var layers := [] + if frame_index == -1: + frames = project.frames else: - frames = Global.current_project.frames + frames.append(project.frames[frame_index]) + + if layer_index == -1: + layers = project.layers + else: + layers.append(project.layers[layer_index]) + for f in frames: - Global.current_project.undo_redo.add_do_property(f.cels[Global.current_project.current_layer].image, "data", f.cels[Global.current_project.current_layer].image.data) - Global.current_project.undo_redo.add_do_method(Global, "redo", frame_index, layer_index) - Global.current_project.undo_redo.commit_action() + for l in layers: + var index = project.layers.find(l) + cels.append(f.cels[index]) + + for cel in cels: + project.undo_redo.add_do_property(cel.image, "data", cel.image.data) + project.undo_redo.add_do_method(Global, "redo", frame_index, layer_index) + project.undo_redo.commit_action() func update_texture(layer_index : int, frame_index := -1) -> void: diff --git a/src/UI/Dialogs/HSVDialog.gd b/src/UI/Dialogs/HSVDialog.gd index a67345859..768196859 100644 --- a/src/UI/Dialogs/HSVDialog.gd +++ b/src/UI/Dialogs/HSVDialog.gd @@ -1,5 +1,10 @@ extends WindowDialog + +enum {CEL, FRAME, ALL_FRAMES, ALL_PROJECTS} + +var affect : int = CEL +var pixels := [] var current_cel : Image var preview_image : Image var preview_texture : ImageTexture @@ -13,6 +18,7 @@ onready var sat_spinbox = $MarginContainer/VBoxContainer/HBoxContainer/TextBoxes onready var val_spinbox = $MarginContainer/VBoxContainer/HBoxContainer/TextBoxes/Value onready var preview = $MarginContainer/VBoxContainer/TextureRect +onready var selection_checkbox : CheckBox = $MarginContainer/VBoxContainer/AffectHBoxContainer/SelectionCheckBox func _ready() -> void: @@ -25,6 +31,7 @@ func _ready() -> void: func _on_HSVDialog_about_to_show() -> void: current_cel = Global.current_project.frames[Global.current_project.current_frame].cels[Global.current_project.current_layer].image preview_image.copy_from(current_cel) + _on_SelectionCheckBox_toggled(selection_checkbox.pressed) update_preview() @@ -34,10 +41,15 @@ func _on_Cancel_pressed() -> void: func _on_Apply_pressed() -> void: - Global.canvas.handle_undo("Draw") - DrawingAlgos.adjust_hsv(current_cel, hue_slider.value, sat_slider.value, val_slider.value) - Global.canvas.update_texture(Global.current_project.current_layer) - Global.canvas.handle_redo("Draw") + if affect == CEL: + Global.canvas.handle_undo("Draw") + DrawingAlgos.adjust_hsv(current_cel, hue_slider.value, sat_slider.value, val_slider.value, pixels) + Global.canvas.handle_redo("Draw") + elif affect == FRAME: + Global.canvas.handle_undo("Draw", Global.current_project, -1) + for cel in Global.current_project.frames[Global.current_project.current_frame].cels: + DrawingAlgos.adjust_hsv(cel.image, hue_slider.value, sat_slider.value, val_slider.value, pixels) + Global.canvas.handle_redo("Draw", Global.current_project, -1) reset() visible = false @@ -55,7 +67,7 @@ func reset() -> void: func update_preview() -> void: preview_image.copy_from(current_cel) - DrawingAlgos.adjust_hsv(preview_image, hue_slider.value, sat_slider.value, val_slider.value) + DrawingAlgos.adjust_hsv(preview_image, hue_slider.value, sat_slider.value, val_slider.value, pixels) preview_texture.create_from_image(preview_image, 0) preview.texture = preview_texture @@ -94,3 +106,19 @@ func _on_Value_value_changed(value : float) -> void: val_spinbox.value = value val_slider.value = value update_preview() + + +func _on_SelectionCheckBox_toggled(button_pressed : bool) -> void: + pixels.clear() + if button_pressed: + pixels = Global.current_project.selected_pixels.duplicate() + else: + for x in Global.current_project.size.x: + for y in Global.current_project.size.y: + pixels.append(Vector2(x, y)) + + update_preview() + + +func _on_AffectOptionButton_item_selected(index : int) -> void: + affect = index diff --git a/src/UI/Dialogs/HSVDialog.tscn b/src/UI/Dialogs/HSVDialog.tscn index da9fc3fc1..fbbb3eb4e 100644 --- a/src/UI/Dialogs/HSVDialog.tscn +++ b/src/UI/Dialogs/HSVDialog.tscn @@ -33,15 +33,15 @@ __meta__ = { [node name="TextureRect" type="TextureRect" parent="MarginContainer/VBoxContainer"] margin_right = 453.0 -margin_bottom = 197.0 +margin_bottom = 169.0 size_flags_vertical = 3 expand = true stretch_mode = 6 [node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer"] -margin_top = 201.0 +margin_top = 173.0 margin_right = 453.0 -margin_bottom = 285.0 +margin_bottom = 257.0 custom_constants/separation = 10 __meta__ = { "_edit_use_anchors_": false @@ -132,6 +132,27 @@ margin_bottom = 84.0 mouse_default_cursor_shape = 1 min_value = -100.0 +[node name="AffectHBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer"] +margin_top = 261.0 +margin_right = 453.0 +margin_bottom = 285.0 + +[node name="SelectionCheckBox" type="CheckBox" parent="MarginContainer/VBoxContainer/AffectHBoxContainer"] +margin_right = 160.0 +margin_bottom = 24.0 +mouse_default_cursor_shape = 2 +pressed = true +text = "Only affect selection" + +[node name="AffectOptionButton" type="OptionButton" parent="MarginContainer/VBoxContainer/AffectHBoxContainer"] +margin_left = 164.0 +margin_right = 263.0 +margin_bottom = 24.0 +mouse_default_cursor_shape = 2 +text = "Current cel" +items = [ "Current cel", null, false, 0, null, "Current frame", null, false, 1, null, "All frames", null, true, 2, null, "All projects", null, true, 3, null ] +selected = 0 + [node name="HBoxContainer2" type="HBoxContainer" parent="MarginContainer/VBoxContainer"] margin_top = 289.0 margin_right = 453.0 @@ -162,5 +183,7 @@ text = "Cancel" [connection signal="value_changed" from="MarginContainer/VBoxContainer/HBoxContainer/TextBoxes/Hue" to="." method="_on_Hue_value_changed"] [connection signal="value_changed" from="MarginContainer/VBoxContainer/HBoxContainer/TextBoxes/Saturation" to="." method="_on_Saturation_value_changed"] [connection signal="value_changed" from="MarginContainer/VBoxContainer/HBoxContainer/TextBoxes/Value" to="." method="_on_Value_value_changed"] +[connection signal="toggled" from="MarginContainer/VBoxContainer/AffectHBoxContainer/SelectionCheckBox" to="." method="_on_SelectionCheckBox_toggled"] +[connection signal="item_selected" from="MarginContainer/VBoxContainer/AffectHBoxContainer/AffectOptionButton" to="." method="_on_AffectOptionButton_item_selected"] [connection signal="pressed" from="MarginContainer/VBoxContainer/HBoxContainer2/Apply" to="." method="_on_Apply_pressed"] [connection signal="pressed" from="MarginContainer/VBoxContainer/HBoxContainer2/Cancel" to="." method="_on_Cancel_pressed"]