From ddf704c336af230d6a61dfc650556fd3e425fe85 Mon Sep 17 00:00:00 2001 From: Emmanouil Papadeas <35376950+OverloadedOrama@users.noreply.github.com> Date: Sat, 18 Jan 2025 18:49:23 +0200 Subject: [PATCH] Implement the ability to save gradient presets Needs a way to delete them as well --- Translations/Translations.pot | 18 ++++++++++- assets/graphics/misc/save.svg | 1 + assets/graphics/misc/save.svg.import | 37 +++++++++++++++++++++++ src/UI/Nodes/GradientEdit.gd | 45 ++++++++++++++++++++++++++++ src/UI/Nodes/GradientEdit.tscn | 10 ++++++- 5 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 assets/graphics/misc/save.svg create mode 100644 assets/graphics/misc/save.svg.import diff --git a/Translations/Translations.pot b/Translations/Translations.pot index 50af342c3..fa56170b1 100644 --- a/Translations/Translations.pot +++ b/Translations/Translations.pot @@ -781,7 +781,7 @@ msgid "Constant" msgstr "" #. Refers to https://en.wikipedia.org/wiki/Color_space -msgid "Color space:" +msgid "Color space" msgstr "" #. A type of color space. @@ -1056,6 +1056,18 @@ msgstr "" msgid "Gradient Map" msgstr "" +msgid "Interpolation" +msgstr "" + +#. Verb, refers to the action of reversing something. +msgid "Reverse" +msgstr "" + +#. An option found in gradient edit widgets. When selected, all points of a gradient are being evenly ditributed across the gradient. +msgid "Evenly distribute points" +msgstr "" + +#. An option found in gradient edit widgets. When selected, the gradient is being split into equal parts. msgid "Divide into equal parts" msgstr "" @@ -1069,6 +1081,10 @@ msgid "If this is enabled, the last point gets added at the end of the gradient. "Disable this if you wish to convert the gradient to have constant interpolation, so that the last color will be taken into account." msgstr "" +#. A tooltip of a button found in gradient edit widgets. When the button is pressed, the gradient is saved to presets. +msgid "Save to presets" +msgstr "" + msgid "Shape:" msgstr "" diff --git a/assets/graphics/misc/save.svg b/assets/graphics/misc/save.svg new file mode 100644 index 000000000..ab8ffff89 --- /dev/null +++ b/assets/graphics/misc/save.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/graphics/misc/save.svg.import b/assets/graphics/misc/save.svg.import new file mode 100644 index 000000000..e4dc360e0 --- /dev/null +++ b/assets/graphics/misc/save.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cvc120a27s57m" +path="res://.godot/imported/save.svg-4b99ce717d52a4473a09bf06262e3b44.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/graphics/misc/save.svg" +dest_files=["res://.godot/imported/save.svg-4b99ce717d52a4473a09bf06262e3b44.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 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/src/UI/Nodes/GradientEdit.gd b/src/UI/Nodes/GradientEdit.gd index be11f9ef0..d61805f0d 100644 --- a/src/UI/Nodes/GradientEdit.gd +++ b/src/UI/Nodes/GradientEdit.gd @@ -6,6 +6,8 @@ extends Control signal updated(gradient: Gradient, cc: bool) +const GRADIENT_DIR := "user://gradients" + var continuous_change := true var active_cursor: GradientCursor: ## Showing a color picker popup to change a cursor's color set(value): @@ -139,6 +141,12 @@ func _init() -> void: presets.append(Gradient.new()) # Left to right presets.append(Gradient.new()) # Left to transparent presets.append(Gradient.new()) # Black to white + for file_name in DirAccess.get_files_at(GRADIENT_DIR): + var file := FileAccess.open(GRADIENT_DIR.path_join(file_name), FileAccess.READ) + var json := file.get_as_text() + var dict = JSON.parse_string(json) + if typeof(dict) == TYPE_DICTIONARY: + presets.append(deserialize_gradient(dict)) func _ready() -> void: @@ -228,6 +236,29 @@ func set_gradient_texture(new_texture: GradientTexture2D) -> void: gradient = texture.gradient +func serialize_gradient(grad: Gradient) -> Dictionary: + var dict := {} + dict["offsets"] = grad.offsets + dict["colors"] = var_to_str(grad.colors) + dict["interpolation_mode"] = grad.interpolation_mode + dict["interpolation_color_space"] = grad.interpolation_color_space + return dict + + +func deserialize_gradient(dict: Dictionary) -> Gradient: + var new_gradient := Gradient.new() + new_gradient.offsets = dict.get("offsets", new_gradient.offsets) + var colors = str_to_var(dict.get("colors")) + new_gradient.colors = colors + new_gradient.interpolation_mode = dict.get( + "interpolation_mode", new_gradient.interpolation_mode + ) + new_gradient.interpolation_color_space = dict.get( + "interpolation_color_space", new_gradient.interpolation_color_space + ) + return new_gradient + + func _on_ColorPicker_color_changed(color: Color) -> void: active_cursor.set_color(color) @@ -270,6 +301,20 @@ func _on_tools_menu_button_index_pressed(index: int) -> void: divide_dialog.popup_centered() +func _on_save_to_presets_button_pressed() -> void: + presets.append(gradient) + var grad_texture := GradientTexture2D.new() + grad_texture.height = 32 + grad_texture.gradient = gradient + presets_menu_button.get_popup().add_icon_item(grad_texture, "") + if not DirAccess.dir_exists_absolute(GRADIENT_DIR): + DirAccess.make_dir_absolute(GRADIENT_DIR) + var json := JSON.stringify(serialize_gradient(gradient)) + var file_name := GRADIENT_DIR.path_join(str(floori(Time.get_unix_time_from_system()))) + var file := FileAccess.open(file_name, FileAccess.WRITE) + file.store_string(json) + + func _on_presets_menu_button_about_to_popup() -> void: # Update left to right and left to transparent gradients presets[0].set_color(0, Tools.get_assigned_color(MOUSE_BUTTON_LEFT)) diff --git a/src/UI/Nodes/GradientEdit.tscn b/src/UI/Nodes/GradientEdit.tscn index d30382913..6727c22a9 100644 --- a/src/UI/Nodes/GradientEdit.tscn +++ b/src/UI/Nodes/GradientEdit.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=4 format=3 uid="uid://bn4aw27dj7pwi"] +[gd_scene load_steps=5 format=3 uid="uid://bn4aw27dj7pwi"] [ext_resource type="Script" path="res://src/UI/Nodes/GradientEdit.gd" id="1"] [ext_resource type="Texture2D" uid="uid://cis71foi5jt31" path="res://assets/graphics/misc/settings.svg" id="2_2dyyb"] [ext_resource type="Script" path="res://src/UI/Nodes/Sliders/ValueSlider.gd" id="2_y6708"] +[ext_resource type="Texture2D" uid="uid://cvc120a27s57m" path="res://assets/graphics/misc/save.svg" id="4_b5s6b"] [node name="GradientEdit" type="VBoxContainer"] anchors_preset = 15 @@ -77,6 +78,12 @@ popup/item_1/id = 1 popup/item_2/text = "Divide into equal parts" popup/item_2/id = 2 +[node name="SaveToPresetsButton" type="Button" parent="InterpolationContainer"] +layout_mode = 2 +tooltip_text = "Save to presets" +mouse_default_cursor_shape = 2 +icon = ExtResource("4_b5s6b") + [node name="PresetsMenuButton" type="MenuButton" parent="InterpolationContainer"] unique_name_in_owner = true layout_mode = 2 @@ -140,6 +147,7 @@ text = "Add point at the end" [connection signal="value_changed" from="InterpolationContainer/OffsetValueSlider" to="." method="_on_offset_value_slider_value_changed"] [connection signal="item_selected" from="InterpolationContainer/InterpolationOptionButton" to="." method="_on_InterpolationOptionButton_item_selected"] [connection signal="item_selected" from="InterpolationContainer/ColorSpaceOptionButton" to="." method="_on_color_space_option_button_item_selected"] +[connection signal="pressed" from="InterpolationContainer/SaveToPresetsButton" to="." method="_on_save_to_presets_button_pressed"] [connection signal="about_to_popup" from="InterpolationContainer/PresetsMenuButton" to="." method="_on_presets_menu_button_about_to_popup"] [connection signal="color_changed" from="Popup/ColorPicker" to="." method="_on_ColorPicker_color_changed"] [connection signal="confirmed" from="DivideConfirmationDialog" to="." method="_on_DivideConfirmationDialog_confirmed"]