diff --git a/CHANGELOG.md b/CHANGELOG.md index c7c1eceaa..cdee1f535 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Darshan Phaldesai (luiq54), Igor Santarek (jegor377), rob-a-bolton, Kinwailo ### Added - The Web (HTML5) is now a supported platform of Pixelorama! It is now possible to save .png and .pxo files, as well as load image and palette files in the Web version. Only limitation so far is that the users cannot load .pxo files. Also, this may not work on mobile. - Project tabs! You can now have multiple projects open at the same time, and access each one with tabs. +- Gradient generation. A new option under the "Image" menu that lets you generate a RGB gradient in the current cel. - Ability to remove the current palette. ([#239](https://github.com/Orama-Interactive/Pixelorama/pull/239)) - You can now drag & drop files into the program while it's running to open them. You can open .pxo files, image files and palette (json and gpl) files this way. - You can now draw on the tiling mode previews! ([#65](https://github.com/Orama-Interactive/Pixelorama/issues/65)) diff --git a/Translations/Translations.pot b/Translations/Translations.pot index 1efddbe3c..856a35e2d 100644 --- a/Translations/Translations.pot +++ b/Translations/Translations.pot @@ -434,6 +434,18 @@ msgstr "" msgid "Steps:" msgstr "" +msgid "Top to Bottom" +msgstr "" + +msgid "Bottom to Top" +msgstr "" + +msgid "Left to Right" +msgstr "" + +msgid "Right to Left" +msgstr "" + msgid "View Splash Screen" msgstr "" diff --git a/src/Autoload/DrawingAlgos.gd b/src/Autoload/DrawingAlgos.gd index 3a560e079..d33f8c8b9 100644 --- a/src/Autoload/DrawingAlgos.gd +++ b/src/Autoload/DrawingAlgos.gd @@ -1,6 +1,9 @@ extends Node +enum GradientDirection {TOP, BOTTOM, LEFT, RIGHT} + + func scale3X(sprite : Image, tol : float = 50) -> Image: var scaled = Image.new() scaled.create(sprite.get_width()*3, sprite.get_height()*3, false, Image.FORMAT_RGBA8) @@ -501,7 +504,7 @@ func adjust_hsv(img: Image, id : int, delta : float) -> void: img.unlock() -func generate_gradient(image : Image, colors : Array, steps := 2) -> void: +func generate_gradient(image : Image, colors : Array, steps := 2, direction : int = GradientDirection.TOP) -> void: if colors.size() < 2: return @@ -512,11 +515,25 @@ func generate_gradient(image : Image, colors : Array, steps := 2) -> void: colors.insert(1, color) image.lock() + if direction == GradientDirection.BOTTOM or direction == GradientDirection.RIGHT: + colors.invert() var size := image.get_size() - var gradient_height = size.y / steps - for i in steps: - for xx in size.x: - var start = i * gradient_height - var end = (i + 1) * gradient_height - for yy in range(start, end): - image.set_pixel(xx, yy, colors[i]) + var gradient_size + + if direction == GradientDirection.TOP or direction == GradientDirection.BOTTOM: + gradient_size = size.y / steps + for i in steps: + for xx in size.x: + var start = i * gradient_size + var end = (i + 1) * gradient_size + for yy in range(start, end): + image.set_pixel(xx, yy, colors[i]) + + else: + gradient_size = size.x / steps + for i in steps: + for yy in size.y: + var start = i * gradient_size + var end = (i + 1) * gradient_size + for xx in range(start, end): + image.set_pixel(xx, yy, colors[i]) diff --git a/src/UI/Dialogs/GradientDialog.gd b/src/UI/Dialogs/GradientDialog.gd index 76ab4c966..9c0ff7865 100644 --- a/src/UI/Dialogs/GradientDialog.gd +++ b/src/UI/Dialogs/GradientDialog.gd @@ -9,6 +9,7 @@ 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 func _on_GradientDialog_about_to_show() -> void: @@ -21,7 +22,7 @@ func _on_GradientDialog_about_to_show() -> void: func update_preview() -> void: preview_image.copy_from(current_cel) - DrawingAlgos.generate_gradient(preview_image, [color1.color, color2.color], steps.value) + DrawingAlgos.generate_gradient(preview_image, [color1.color, color2.color], steps.value, direction.selected) preview_texture.create_from_image(preview_image, 0) preview.texture = preview_texture @@ -38,8 +39,12 @@ func _on_StepSpinBox_value_changed(_value : int) -> void: update_preview() +func _on_OptionButton_item_selected(_index : int) -> void: + update_preview() + + func _on_GradientDialog_confirmed() -> void: Global.canvas.handle_undo("Draw") - DrawingAlgos.generate_gradient(current_cel, [color1.color, color2.color], steps.value) + DrawingAlgos.generate_gradient(current_cel, [color1.color, color2.color], steps.value, direction.selected) Global.canvas.update_texture(Global.current_project.current_layer) Global.canvas.handle_redo("Draw") diff --git a/src/UI/Dialogs/GradientDialog.tscn b/src/UI/Dialogs/GradientDialog.tscn index ac4a60508..f92ff911e 100644 --- a/src/UI/Dialogs/GradientDialog.tscn +++ b/src/UI/Dialogs/GradientDialog.tscn @@ -23,7 +23,7 @@ __meta__ = { } [node name="Preview" type="TextureRect" parent="VBoxContainer"] -margin_right = 184.0 +margin_right = 188.0 margin_bottom = 100.0 rect_min_size = Vector2( 0, 100 ) expand = true @@ -31,7 +31,7 @@ stretch_mode = 6 [node name="ColorsContainer" type="HBoxContainer" parent="VBoxContainer"] margin_top = 104.0 -margin_right = 184.0 +margin_right = 188.0 margin_bottom = 124.0 [node name="Label" type="Label" parent="VBoxContainer/ColorsContainer"] @@ -57,7 +57,7 @@ color = Color( 1, 1, 1, 1 ) [node name="StepsContainer" type="HBoxContainer" parent="VBoxContainer"] margin_top = 128.0 -margin_right = 184.0 +margin_right = 188.0 margin_bottom = 152.0 __meta__ = { "_edit_use_anchors_": false @@ -76,8 +76,32 @@ margin_bottom = 24.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 +text = "Direction:" + +[node name="DirectionOptionButton" type="OptionButton" parent="VBoxContainer/DirectionContainer"] +margin_left = 67.0 +margin_right = 188.0 +margin_bottom = 20.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 [connection signal="about_to_show" from="." to="." method="_on_GradientDialog_about_to_show"] [connection signal="confirmed" from="." to="." method="_on_GradientDialog_confirmed"] [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"]