mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-01-31 07:29:49 +00:00
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.
This commit is contained in:
parent
5612064533
commit
1ce89c6577
|
@ -454,9 +454,9 @@ func generate_outline(image : Image, outline_color : Color, thickness : int, dia
|
||||||
Global.canvas.handle_redo("Draw")
|
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()
|
img.lock()
|
||||||
for i in Global.current_project.selected_pixels:
|
for i in pixels:
|
||||||
var c : Color = img.get_pixelv(i)
|
var c : Color = img.get_pixelv(i)
|
||||||
# Hue
|
# Hue
|
||||||
var hue = range_lerp(c.h,0,1,-180,180)
|
var hue = range_lerp(c.h,0,1,-180,180)
|
||||||
|
|
|
@ -129,50 +129,78 @@ func new_empty_frame(first_time := false, single_layer := false, size := Global.
|
||||||
return frame
|
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:
|
if !can_undo:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if layer_index <= -2:
|
||||||
|
layer_index = project.current_layer
|
||||||
|
if frame_index <= -2:
|
||||||
|
frame_index = project.current_frame
|
||||||
|
|
||||||
|
var cels := []
|
||||||
var frames := []
|
var frames := []
|
||||||
var frame_index := -1
|
var layers := []
|
||||||
var layer_index := -1
|
if frame_index == -1:
|
||||||
if Global.animation_timer.is_stopped(): # if we're not animating, store only the current canvas
|
frames = project.frames
|
||||||
frames.append(Global.current_project.frames[Global.current_project.current_frame])
|
else:
|
||||||
frame_index = Global.current_project.current_frame
|
frames.append(project.frames[frame_index])
|
||||||
layer_index = Global.current_project.current_layer
|
|
||||||
else: # If we're animating, store all frames
|
if layer_index == -1:
|
||||||
frames = Global.current_project.frames
|
layers = project.layers
|
||||||
Global.current_project.undos += 1
|
else:
|
||||||
Global.current_project.undo_redo.create_action(action)
|
layers.append(project.layers[layer_index])
|
||||||
|
|
||||||
for f in frames:
|
for f in frames:
|
||||||
# I'm not sure why I have to unlock it, but...
|
for l in layers:
|
||||||
# ...if I don't, it doesn't work properly
|
var index = project.layers.find(l)
|
||||||
f.cels[Global.current_project.current_layer].image.unlock()
|
cels.append(f.cels[index])
|
||||||
var data = f.cels[Global.current_project.current_layer].image.data
|
|
||||||
f.cels[Global.current_project.current_layer].image.lock()
|
project.undos += 1
|
||||||
Global.current_project.undo_redo.add_undo_property(f.cels[Global.current_project.current_layer].image, "data", data)
|
project.undo_redo.create_action(action)
|
||||||
Global.current_project.undo_redo.add_undo_method(Global, "undo", frame_index, layer_index)
|
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
|
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
|
can_undo = true
|
||||||
|
if project.undos < project.undo_redo.get_version():
|
||||||
if Global.current_project.undos < Global.current_project.undo_redo.get_version():
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if layer_index <= -2:
|
||||||
|
layer_index = project.current_layer
|
||||||
|
if frame_index <= -2:
|
||||||
|
frame_index = project.current_frame
|
||||||
|
|
||||||
|
var cels := []
|
||||||
var frames := []
|
var frames := []
|
||||||
var frame_index := -1
|
var layers := []
|
||||||
var layer_index := -1
|
if frame_index == -1:
|
||||||
if Global.animation_timer.is_stopped():
|
frames = project.frames
|
||||||
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:
|
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:
|
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)
|
for l in layers:
|
||||||
Global.current_project.undo_redo.add_do_method(Global, "redo", frame_index, layer_index)
|
var index = project.layers.find(l)
|
||||||
Global.current_project.undo_redo.commit_action()
|
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:
|
func update_texture(layer_index : int, frame_index := -1) -> void:
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
extends WindowDialog
|
extends WindowDialog
|
||||||
|
|
||||||
|
|
||||||
|
enum {CEL, FRAME, ALL_FRAMES, ALL_PROJECTS}
|
||||||
|
|
||||||
|
var affect : int = CEL
|
||||||
|
var pixels := []
|
||||||
var current_cel : Image
|
var current_cel : Image
|
||||||
var preview_image : Image
|
var preview_image : Image
|
||||||
var preview_texture : ImageTexture
|
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 val_spinbox = $MarginContainer/VBoxContainer/HBoxContainer/TextBoxes/Value
|
||||||
|
|
||||||
onready var preview = $MarginContainer/VBoxContainer/TextureRect
|
onready var preview = $MarginContainer/VBoxContainer/TextureRect
|
||||||
|
onready var selection_checkbox : CheckBox = $MarginContainer/VBoxContainer/AffectHBoxContainer/SelectionCheckBox
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
|
@ -25,6 +31,7 @@ func _ready() -> void:
|
||||||
func _on_HSVDialog_about_to_show() -> 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
|
current_cel = Global.current_project.frames[Global.current_project.current_frame].cels[Global.current_project.current_layer].image
|
||||||
preview_image.copy_from(current_cel)
|
preview_image.copy_from(current_cel)
|
||||||
|
_on_SelectionCheckBox_toggled(selection_checkbox.pressed)
|
||||||
update_preview()
|
update_preview()
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,10 +41,15 @@ func _on_Cancel_pressed() -> void:
|
||||||
|
|
||||||
|
|
||||||
func _on_Apply_pressed() -> void:
|
func _on_Apply_pressed() -> void:
|
||||||
|
if affect == CEL:
|
||||||
Global.canvas.handle_undo("Draw")
|
Global.canvas.handle_undo("Draw")
|
||||||
DrawingAlgos.adjust_hsv(current_cel, hue_slider.value, sat_slider.value, val_slider.value)
|
DrawingAlgos.adjust_hsv(current_cel, hue_slider.value, sat_slider.value, val_slider.value, pixels)
|
||||||
Global.canvas.update_texture(Global.current_project.current_layer)
|
|
||||||
Global.canvas.handle_redo("Draw")
|
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()
|
reset()
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
|
@ -55,7 +67,7 @@ func reset() -> void:
|
||||||
|
|
||||||
func update_preview() -> void:
|
func update_preview() -> void:
|
||||||
preview_image.copy_from(current_cel)
|
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.create_from_image(preview_image, 0)
|
||||||
preview.texture = preview_texture
|
preview.texture = preview_texture
|
||||||
|
|
||||||
|
@ -94,3 +106,19 @@ func _on_Value_value_changed(value : float) -> void:
|
||||||
val_spinbox.value = value
|
val_spinbox.value = value
|
||||||
val_slider.value = value
|
val_slider.value = value
|
||||||
update_preview()
|
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
|
||||||
|
|
|
@ -33,15 +33,15 @@ __meta__ = {
|
||||||
|
|
||||||
[node name="TextureRect" type="TextureRect" parent="MarginContainer/VBoxContainer"]
|
[node name="TextureRect" type="TextureRect" parent="MarginContainer/VBoxContainer"]
|
||||||
margin_right = 453.0
|
margin_right = 453.0
|
||||||
margin_bottom = 197.0
|
margin_bottom = 169.0
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
expand = true
|
expand = true
|
||||||
stretch_mode = 6
|
stretch_mode = 6
|
||||||
|
|
||||||
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer"]
|
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer"]
|
||||||
margin_top = 201.0
|
margin_top = 173.0
|
||||||
margin_right = 453.0
|
margin_right = 453.0
|
||||||
margin_bottom = 285.0
|
margin_bottom = 257.0
|
||||||
custom_constants/separation = 10
|
custom_constants/separation = 10
|
||||||
__meta__ = {
|
__meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
|
@ -132,6 +132,27 @@ margin_bottom = 84.0
|
||||||
mouse_default_cursor_shape = 1
|
mouse_default_cursor_shape = 1
|
||||||
min_value = -100.0
|
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"]
|
[node name="HBoxContainer2" type="HBoxContainer" parent="MarginContainer/VBoxContainer"]
|
||||||
margin_top = 289.0
|
margin_top = 289.0
|
||||||
margin_right = 453.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/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/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="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/Apply" to="." method="_on_Apply_pressed"]
|
||||||
[connection signal="pressed" from="MarginContainer/VBoxContainer/HBoxContainer2/Cancel" to="." method="_on_Cancel_pressed"]
|
[connection signal="pressed" from="MarginContainer/VBoxContainer/HBoxContainer2/Cancel" to="." method="_on_Cancel_pressed"]
|
||||||
|
|
Loading…
Reference in a new issue