diff --git a/Translations/Translations.pot b/Translations/Translations.pot index 4407f0d6e..afe94cdf8 100644 --- a/Translations/Translations.pot +++ b/Translations/Translations.pot @@ -407,6 +407,21 @@ msgstr "" msgid "Light" msgstr "" +msgid "Only affect selection" +msgstr "" + +msgid "Current cel" +msgstr "" + +msgid "Current frame" +msgstr "" + +msgid "All frames" +msgstr "" + +msgid "All projects" +msgstr "" + msgid "Invert Colors" msgstr "" diff --git a/src/Autoload/DrawingAlgos.gd b/src/Autoload/DrawingAlgos.gd index 5e93cf95f..64710ae2c 100644 --- a/src/Autoload/DrawingAlgos.gd +++ b/src/Autoload/DrawingAlgos.gd @@ -504,7 +504,7 @@ func adjust_hsv(img: Image, delta_h : float, delta_s : float, delta_v : float, p img.unlock() -func generate_gradient(image : Image, colors : Array, steps := 2, direction : int = GradientDirection.TOP) -> void: +func generate_gradient(image : Image, colors : Array, steps := 2, direction : int = GradientDirection.TOP, pixels = Global.current_project.selected_pixels) -> void: if colors.size() < 2: return @@ -517,7 +517,9 @@ func generate_gradient(image : Image, colors : Array, steps := 2, direction : in image.unlock() if direction == GradientDirection.BOTTOM or direction == GradientDirection.RIGHT: colors.invert() - var size := image.get_size() + + var selection_rectangle := Rect2(pixels[0].x, pixels[0].y, pixels[-1].x - pixels[0].x + 1, pixels[-1].y - pixels[0].y + 1) + var size := selection_rectangle.size image.lock() var gradient_size @@ -528,7 +530,8 @@ func generate_gradient(image : Image, colors : Array, steps := 2, direction : in var start = i * gradient_size var end = (i + 1) * gradient_size for yy in range(start, end): - image.set_pixel(xx, yy, colors[i]) + var pos : Vector2 = Vector2(xx, yy) + pixels[0] + image.set_pixelv(pos, colors[i]) else: gradient_size = size.x / steps @@ -537,4 +540,5 @@ func generate_gradient(image : Image, colors : Array, steps := 2, direction : in var start = i * gradient_size var end = (i + 1) * gradient_size for xx in range(start, end): - image.set_pixel(xx, yy, colors[i]) + var pos : Vector2 = Vector2(xx, yy) + pixels[0] + image.set_pixelv(pos, colors[i]) diff --git a/src/UI/Dialogs/ImageEffects/FlipImageDialog.gd b/src/UI/Dialogs/ImageEffects/FlipImageDialog.gd index cfb7a9cb9..63e7f41b3 100644 --- a/src/UI/Dialogs/ImageEffects/FlipImageDialog.gd +++ b/src/UI/Dialogs/ImageEffects/FlipImageDialog.gd @@ -12,7 +12,7 @@ var preview_texture : ImageTexture onready var preview : TextureRect = $VBoxContainer/Preview onready var flip_h : CheckBox = $VBoxContainer/OptionsContainer/FlipHorizontal onready var flip_v : CheckBox = $VBoxContainer/OptionsContainer/FlipVertical -onready var selection_checkbox = $VBoxContainer/OptionsContainer/SelectionCheckBox +onready var selection_checkbox : CheckBox = $VBoxContainer/OptionsContainer/SelectionCheckBox func _ready() -> void: diff --git a/src/UI/Dialogs/ImageEffects/GradientDialog.gd b/src/UI/Dialogs/ImageEffects/GradientDialog.gd index c967d565b..a8cb9dbf1 100644 --- a/src/UI/Dialogs/ImageEffects/GradientDialog.gd +++ b/src/UI/Dialogs/ImageEffects/GradientDialog.gd @@ -1,15 +1,20 @@ extends ConfirmationDialog +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 onready var preview : TextureRect = $VBoxContainer/Preview -onready var color1 : ColorPickerButton = $VBoxContainer/ColorsContainer/ColorPickerButton -onready var color2 : ColorPickerButton = $VBoxContainer/ColorsContainer/ColorPickerButton2 -onready var steps : SpinBox = $VBoxContainer/StepsContainer/StepSpinBox -onready var direction : OptionButton = $VBoxContainer/DirectionContainer/DirectionOptionButton +onready var color1 : ColorPickerButton = $VBoxContainer/OptionsContainer/ColorsContainer/ColorPickerButton +onready var color2 : ColorPickerButton = $VBoxContainer/OptionsContainer/ColorsContainer/ColorPickerButton2 +onready var steps : SpinBox = $VBoxContainer/OptionsContainer/StepSpinBox +onready var direction : OptionButton = $VBoxContainer/OptionsContainer/DirectionOptionButton +onready var selection_checkbox : CheckBox = $VBoxContainer/OptionsContainer/SelectionCheckBox func _ready() -> void: @@ -21,12 +26,12 @@ func _ready() -> void: func _on_GradientDialog_about_to_show() -> void: current_cel = Global.current_project.frames[Global.current_project.current_frame].cels[Global.current_project.current_layer].image - update_preview() + _on_SelectionCheckBox_toggled(selection_checkbox.pressed) func update_preview() -> void: preview_image.copy_from(current_cel) - DrawingAlgos.generate_gradient(preview_image, [color1.color, color2.color], steps.value, direction.selected) + DrawingAlgos.generate_gradient(preview_image, [color1.color, color2.color], steps.value, direction.selected, pixels) preview_texture.create_from_image(preview_image, 0) preview.texture = preview_texture @@ -47,10 +52,55 @@ func _on_OptionButton_item_selected(_index : int) -> void: 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 + + func _on_GradientDialog_confirmed() -> void: - Global.canvas.handle_undo("Draw") - DrawingAlgos.generate_gradient(current_cel, [color1.color, color2.color], steps.value, direction.selected) - Global.canvas.handle_redo("Draw") + if affect == CEL: + Global.canvas.handle_undo("Draw") + DrawingAlgos.generate_gradient(current_cel, [color1.color, color2.color], steps.value, direction.selected, 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.generate_gradient(cel.image, [color1.color, color2.color], steps.value, direction.selected, pixels) + Global.canvas.handle_redo("Draw", Global.current_project, -1) + + elif affect == ALL_FRAMES: + Global.canvas.handle_undo("Draw", Global.current_project, -1, -1) + for frame in Global.current_project.frames: + for cel in frame.cels: + DrawingAlgos.generate_gradient(cel.image, [color1.color, color2.color], steps.value, direction.selected, pixels) + Global.canvas.handle_redo("Draw", Global.current_project, -1, -1) + + elif affect == ALL_PROJECTS: + for project in Global.projects: + var _pixels := [] + if selection_checkbox.pressed: + _pixels = project.selected_pixels.duplicate() + else: + for x in project.size.x: + for y in project.size.y: + _pixels.append(Vector2(x, y)) + + Global.canvas.handle_undo("Draw", project, -1, -1) + for frame in project.frames: + for cel in frame.cels: + DrawingAlgos.generate_gradient(cel.image, [color1.color, color2.color], steps.value, direction.selected, _pixels) + Global.canvas.handle_redo("Draw", project, -1, -1) func _on_GradientDialog_popup_hide() -> void: diff --git a/src/UI/Dialogs/ImageEffects/GradientDialog.tscn b/src/UI/Dialogs/ImageEffects/GradientDialog.tscn index c9f1c02a6..ad6a81cca 100644 --- a/src/UI/Dialogs/ImageEffects/GradientDialog.tscn +++ b/src/UI/Dialogs/ImageEffects/GradientDialog.tscn @@ -24,86 +24,97 @@ __meta__ = { } [node name="Preview" type="TextureRect" parent="VBoxContainer"] -margin_right = 188.0 +margin_right = 285.0 margin_bottom = 100.0 rect_min_size = Vector2( 0, 100 ) expand = true stretch_mode = 6 -[node name="ColorsContainer" type="HBoxContainer" parent="VBoxContainer"] +[node name="OptionsContainer" type="GridContainer" parent="VBoxContainer"] margin_top = 104.0 -margin_right = 188.0 -margin_bottom = 124.0 +margin_right = 285.0 +margin_bottom = 204.0 +columns = 2 -[node name="Label" type="Label" parent="VBoxContainer/ColorsContainer"] +[node name="Label" type="Label" parent="VBoxContainer/OptionsContainer"] margin_top = 3.0 -margin_right = 44.0 +margin_right = 160.0 margin_bottom = 17.0 text = "Colors:" -[node name="ColorPickerButton" type="ColorPickerButton" parent="VBoxContainer/ColorsContainer"] -margin_left = 48.0 -margin_right = 68.0 +[node name="ColorsContainer" type="HBoxContainer" parent="VBoxContainer/OptionsContainer"] +margin_left = 164.0 +margin_right = 285.0 +margin_bottom = 20.0 + +[node name="ColorPickerButton" type="ColorPickerButton" parent="VBoxContainer/OptionsContainer/ColorsContainer"] +margin_right = 20.0 margin_bottom = 20.0 rect_min_size = Vector2( 20, 0 ) mouse_default_cursor_shape = 2 -[node name="ColorPickerButton2" type="ColorPickerButton" parent="VBoxContainer/ColorsContainer"] -margin_left = 72.0 -margin_right = 92.0 +[node name="ColorPickerButton2" type="ColorPickerButton" parent="VBoxContainer/OptionsContainer/ColorsContainer"] +margin_left = 24.0 +margin_right = 44.0 margin_bottom = 20.0 rect_min_size = Vector2( 20, 0 ) mouse_default_cursor_shape = 2 color = Color( 1, 1, 1, 1 ) -[node name="StepsContainer" type="HBoxContainer" parent="VBoxContainer"] -margin_top = 128.0 -margin_right = 188.0 -margin_bottom = 152.0 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Label" type="Label" parent="VBoxContainer/StepsContainer"] -margin_top = 5.0 -margin_right = 39.0 -margin_bottom = 19.0 +[node name="Label2" type="Label" parent="VBoxContainer/OptionsContainer"] +margin_top = 29.0 +margin_right = 160.0 +margin_bottom = 43.0 text = "Steps:" -[node name="StepSpinBox" type="SpinBox" parent="VBoxContainer/StepsContainer"] -margin_left = 43.0 -margin_right = 117.0 -margin_bottom = 24.0 +[node name="StepSpinBox" type="SpinBox" parent="VBoxContainer/OptionsContainer"] +margin_left = 164.0 +margin_top = 24.0 +margin_right = 285.0 +margin_bottom = 48.0 mouse_default_cursor_shape = 2 min_value = 2.0 value = 2.0 -[node name="DirectionContainer" type="HBoxContainer" parent="VBoxContainer"] -margin_top = 156.0 -margin_right = 188.0 -margin_bottom = 176.0 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Label" type="Label" parent="VBoxContainer/DirectionContainer"] -margin_top = 3.0 -margin_right = 63.0 -margin_bottom = 17.0 +[node name="Label3" type="Label" parent="VBoxContainer/OptionsContainer"] +margin_top = 55.0 +margin_right = 160.0 +margin_bottom = 69.0 text = "Direction:" -[node name="DirectionOptionButton" type="OptionButton" parent="VBoxContainer/DirectionContainer"] -margin_left = 67.0 -margin_right = 188.0 -margin_bottom = 20.0 +[node name="DirectionOptionButton" type="OptionButton" parent="VBoxContainer/OptionsContainer"] +margin_left = 164.0 +margin_top = 52.0 +margin_right = 285.0 +margin_bottom = 72.0 mouse_default_cursor_shape = 2 text = "Top to Bottom" items = [ "Top to Bottom", null, false, 0, null, "Bottom to Top", null, false, 1, null, "Left to Right", null, false, 2, null, "Right to Left", null, false, 3, null ] selected = 0 + +[node name="SelectionCheckBox" type="CheckBox" parent="VBoxContainer/OptionsContainer"] +margin_top = 76.0 +margin_right = 160.0 +margin_bottom = 100.0 +mouse_default_cursor_shape = 2 +pressed = true +text = "Only affect selection" + +[node name="AffectOptionButton" type="OptionButton" parent="VBoxContainer/OptionsContainer"] +margin_left = 164.0 +margin_top = 76.0 +margin_right = 285.0 +margin_bottom = 100.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, false, 2, null, "All projects", null, false, 3, null ] +selected = 0 [connection signal="about_to_show" from="." to="." method="_on_GradientDialog_about_to_show"] [connection signal="confirmed" from="." to="." method="_on_GradientDialog_confirmed"] [connection signal="popup_hide" from="." to="." method="_on_GradientDialog_popup_hide"] -[connection signal="color_changed" from="VBoxContainer/ColorsContainer/ColorPickerButton" to="." method="_on_ColorPickerButton_color_changed"] -[connection signal="color_changed" from="VBoxContainer/ColorsContainer/ColorPickerButton2" to="." method="_on_ColorPickerButton2_color_changed"] -[connection signal="value_changed" from="VBoxContainer/StepsContainer/StepSpinBox" to="." method="_on_StepSpinBox_value_changed"] -[connection signal="item_selected" from="VBoxContainer/DirectionContainer/DirectionOptionButton" to="." method="_on_OptionButton_item_selected"] +[connection signal="color_changed" from="VBoxContainer/OptionsContainer/ColorsContainer/ColorPickerButton" to="." method="_on_ColorPickerButton_color_changed"] +[connection signal="color_changed" from="VBoxContainer/OptionsContainer/ColorsContainer/ColorPickerButton2" to="." method="_on_ColorPickerButton2_color_changed"] +[connection signal="value_changed" from="VBoxContainer/OptionsContainer/StepSpinBox" to="." method="_on_StepSpinBox_value_changed"] +[connection signal="item_selected" from="VBoxContainer/OptionsContainer/DirectionOptionButton" to="." method="_on_OptionButton_item_selected"] +[connection signal="toggled" from="VBoxContainer/OptionsContainer/SelectionCheckBox" to="." method="_on_SelectionCheckBox_toggled"] +[connection signal="item_selected" from="VBoxContainer/OptionsContainer/AffectOptionButton" to="." method="_on_AffectOptionButton_item_selected"]