diff --git a/CHANGELOG.md b/CHANGELOG.md index e0d20f0ce..be5199d19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ This update has been brought to you by the contributions of: PinyaColada, RĂ©mi Verschelde (akien-mga), dasimonde ### Added +- The lighten/darken tool now has a hue shifting mode. It lets users configure the shift in hue, saturation and value of the new shaded pixels. ([#189](https://github.com/Orama-Interactive/Pixelorama/issues/189)) - Added a "frame properties" option on the popup menu that appears when right-clicking on a cel. This lets the user choose a custom frame delay for that specific frame. ([#357](https://github.com/Orama-Interactive/Pixelorama/pull/357)) - You can now select if you want rotation to apply in the selection, the current cel, the entire frame, all frames or even all projects (tabs)! - You can now change the transparency of the Tile Mode in the Preferences. ([#368](https://github.com/Orama-Interactive/Pixelorama/pull/368)) diff --git a/Translations/Translations.pot b/Translations/Translations.pot index afd9d7d7d..f16379798 100644 --- a/Translations/Translations.pot +++ b/Translations/Translations.pot @@ -900,6 +900,12 @@ msgstr "" msgid "Offset" msgstr "" +msgid "Simple Shading" +msgstr "" + +msgid "Hue Shifting" +msgstr "" + msgid "Lighten" msgstr "" diff --git a/src/Tools/LightenDarken.gd b/src/Tools/LightenDarken.gd index 31c328b72..3f54b4814 100644 --- a/src/Tools/LightenDarken.gd +++ b/src/Tools/LightenDarken.gd @@ -1,60 +1,128 @@ extends "res://src/Tools/Draw.gd" +enum ShadingMode {SIMPLE, HUE_SHIFTING} +enum LightenDarken {LIGHTEN, DARKEN} + + var _last_position := Vector2.INF var _changed := false -var _mode := 0 +var _shading_mode : int = ShadingMode.SIMPLE +var _mode : int = LightenDarken.LIGHTEN var _amount := 10 +var _hue_amount := 10 +var _sat_amount := 10 +var _value_amount := 10 class LightenDarkenOp extends Drawer.ColorOp: var changed := false + var shading_mode : int = ShadingMode.SIMPLE + var lighten_or_darken : int = LightenDarken.LIGHTEN + var hue_amount := 10.0 + var sat_amount := 10.0 + var value_amount := 10.0 func process(_src: Color, dst: Color) -> Color: changed = true - if strength > 0: - return dst.lightened(strength) - elif strength < 0: - return dst.darkened(-strength) + if shading_mode == ShadingMode.SIMPLE: + if strength > 0: + dst = dst.lightened(strength) +# dst.h += strength/8 + elif strength < 0: + dst = dst.darkened(-strength) +# dst.h += strength/8 else: - return dst + if lighten_or_darken == LightenDarken.LIGHTEN: + dst.h += (hue_amount / 359) + dst.s -= (sat_amount / 100) + dst.v += (value_amount / 100) + else: + dst.h -= (hue_amount / 359) + dst.s += (sat_amount / 100) + dst.v -= (value_amount / 100) + + return dst func _init() -> void: _drawer.color_op = LightenDarkenOp.new() -func _on_LightenDarken_item_selected(id : int): - _mode = id +func _on_ShadingMode_item_selected(id : int) -> void: + _shading_mode = id + _drawer.color_op.shading_mode = id update_config() save_config() -func _on_LightenDarken_value_changed(value : float): +func _on_LightenDarken_item_selected(id : int) -> void: + _mode = id + _drawer.color_op.lighten_or_darken = id + update_config() + save_config() + + +func _on_LightenDarken_value_changed(value : float) -> void: _amount = int(value) update_config() save_config() +func _on_LightenDarken_hue_value_changed(value : float) -> void: + _hue_amount = int(value) + update_config() + save_config() + + +func _on_LightenDarken_sat_value_changed(value : float) -> void: + _sat_amount = int(value) + update_config() + save_config() + + +func _on_LightenDarken_value_value_changed(value : float) -> void: + _value_amount = int(value) + update_config() + save_config() + + func get_config() -> Dictionary: var config := .get_config() + config["shading_mode"] = _shading_mode config["mode"] = _mode config["amount"] = _amount + config["hue_amount"] = _hue_amount + config["sat_amount"] = _sat_amount + config["value_amount"] = _value_amount return config func set_config(config : Dictionary) -> void: .set_config(config) + _shading_mode = config.get("shading_mode", _shading_mode) _mode = config.get("mode", _mode) _amount = config.get("amount", _amount) + _hue_amount = config.get("hue_amount", _hue_amount) + _sat_amount = config.get("sat_amount", _sat_amount) + _value_amount = config.get("value_amount", _value_amount) func update_config() -> void: .update_config() + $ShadingMode.selected = _shading_mode $LightenDarken.selected = _mode $Amount/Spinbox.value = _amount $Amount/Slider.value = _amount + $HueShiftingOptions/AmountHue/Spinbox.value = _hue_amount + $HueShiftingOptions/AmountHue/Slider.value = _hue_amount + $HueShiftingOptions/AmountSat/Spinbox.value = _sat_amount + $HueShiftingOptions/AmountSat/Slider.value = _sat_amount + $HueShiftingOptions/AmountValue/Spinbox.value = _value_amount + $HueShiftingOptions/AmountValue/Slider.value = _value_amount + $Amount.visible = _shading_mode == ShadingMode.SIMPLE + $HueShiftingOptions.visible = _shading_mode == ShadingMode.HUE_SHIFTING update_strength() @@ -62,6 +130,10 @@ func update_strength() -> void: var factor = 1 if _mode == 0 else -1 _strength = _amount * factor / 100.0 + _drawer.color_op.hue_amount = _hue_amount + _drawer.color_op.sat_amount = _sat_amount + _drawer.color_op.value_amount = _value_amount + func draw_start(position : Vector2) -> void: update_mask() diff --git a/src/Tools/LightenDarken.tscn b/src/Tools/LightenDarken.tscn index 7f781fdcd..8d39f0cf4 100644 --- a/src/Tools/LightenDarken.tscn +++ b/src/Tools/LightenDarken.tscn @@ -6,11 +6,42 @@ [node name="ToolOptions" instance=ExtResource( 1 )] script = ExtResource( 2 ) -[node name="LightenDarken" type="OptionButton" parent="." index="4"] -margin_left = 12.0 +[node name="Label" parent="." index="0"] +margin_right = 126.0 + +[node name="Brush" parent="." index="1"] +margin_right = 126.0 + +[node name="Type" parent="Brush" index="0"] +margin_left = 8.0 +margin_right = 40.0 + +[node name="Size" parent="Brush" index="1"] +margin_left = 44.0 +margin_right = 118.0 + +[node name="BrushSize" parent="." index="2"] +margin_left = 17.0 +margin_right = 109.0 + +[node name="PixelPerfect" parent="." index="3"] +margin_left = 9.0 +margin_right = 117.0 + +[node name="ShadingMode" type="OptionButton" parent="." index="4"] margin_top = 102.0 -margin_right = 104.0 +margin_right = 126.0 margin_bottom = 122.0 +mouse_default_cursor_shape = 2 +text = "Simple Shading" +items = [ "Simple Shading", null, false, 0, null, "Hue Shifting", null, false, 1, null ] +selected = 0 + +[node name="LightenDarken" type="OptionButton" parent="." index="5"] +margin_left = 17.0 +margin_top = 126.0 +margin_right = 109.0 +margin_bottom = 146.0 rect_min_size = Vector2( 92, 0 ) mouse_default_cursor_shape = 2 size_flags_horizontal = 4 @@ -18,23 +49,23 @@ text = "Lighten" items = [ "Lighten", null, false, 0, null, "Darken", null, false, 1, null ] selected = 0 -[node name="Amount" type="VBoxContainer" parent="." index="5"] -margin_top = 126.0 -margin_right = 116.0 -margin_bottom = 188.0 +[node name="Amount" type="VBoxContainer" parent="." index="6"] +margin_top = 150.0 +margin_right = 126.0 +margin_bottom = 212.0 alignment = 1 [node name="Label" type="Label" parent="Amount" index="0"] -margin_left = 30.0 -margin_right = 85.0 +margin_left = 35.0 +margin_right = 90.0 margin_bottom = 14.0 size_flags_horizontal = 4 text = "Amount:" [node name="Spinbox" type="SpinBox" parent="Amount" index="1"] -margin_left = 21.0 +margin_left = 26.0 margin_top = 18.0 -margin_right = 95.0 +margin_right = 100.0 margin_bottom = 42.0 hint_tooltip = "Lighten/Darken amount" mouse_default_cursor_shape = 2 @@ -43,9 +74,9 @@ value = 10.0 align = 1 [node name="Slider" type="HSlider" parent="Amount" index="2"] -margin_left = 12.0 +margin_left = 17.0 margin_top = 46.0 -margin_right = 104.0 +margin_right = 109.0 margin_bottom = 62.0 rect_min_size = Vector2( 92, 0 ) hint_tooltip = "Lighten/Darken amount" @@ -56,13 +87,172 @@ size_flags_vertical = 1 value = 10.0 ticks_on_borders = true -[node name="EmptySpacer" parent="." index="7"] -margin_top = 192.0 -margin_bottom = 204.0 +[node name="HueShiftingOptions" type="VBoxContainer" parent="." index="7"] +visible = false +margin_top = 216.0 +margin_right = 126.0 +margin_bottom = 410.0 -[node name="Mirror" parent="." index="8"] -margin_top = 208.0 -margin_bottom = 225.0 +[node name="AmountHue" type="VBoxContainer" parent="HueShiftingOptions" index="0"] +margin_right = 126.0 +margin_bottom = 62.0 +alignment = 1 + +[node name="Label" type="Label" parent="HueShiftingOptions/AmountHue" index="0"] +margin_left = 48.0 +margin_right = 78.0 +margin_bottom = 14.0 +size_flags_horizontal = 4 +text = "Hue:" + +[node name="Spinbox" type="SpinBox" parent="HueShiftingOptions/AmountHue" index="1"] +margin_left = 26.0 +margin_top = 18.0 +margin_right = 100.0 +margin_bottom = 42.0 +hint_tooltip = "Lighten/Darken amount" +mouse_default_cursor_shape = 2 +size_flags_horizontal = 4 +max_value = 359.0 +value = 10.0 +align = 1 + +[node name="Slider" type="HSlider" parent="HueShiftingOptions/AmountHue" index="2"] +margin_left = 17.0 +margin_top = 46.0 +margin_right = 109.0 +margin_bottom = 62.0 +rect_min_size = Vector2( 92, 0 ) +hint_tooltip = "Lighten/Darken amount" +focus_mode = 0 +mouse_default_cursor_shape = 2 +size_flags_horizontal = 4 +size_flags_vertical = 1 +max_value = 359.0 +value = 10.0 +ticks_on_borders = true + +[node name="AmountSat" type="VBoxContainer" parent="HueShiftingOptions" index="1"] +margin_top = 66.0 +margin_right = 126.0 +margin_bottom = 128.0 +alignment = 1 + +[node name="Label" type="Label" parent="HueShiftingOptions/AmountSat" index="0"] +margin_left = 29.0 +margin_right = 97.0 +margin_bottom = 14.0 +size_flags_horizontal = 4 +text = "Saturation:" + +[node name="Spinbox" type="SpinBox" parent="HueShiftingOptions/AmountSat" index="1"] +margin_left = 26.0 +margin_top = 18.0 +margin_right = 100.0 +margin_bottom = 42.0 +hint_tooltip = "Lighten/Darken amount" +mouse_default_cursor_shape = 2 +size_flags_horizontal = 4 +max_value = 100.0 +value = 10.0 +align = 1 + +[node name="Slider" type="HSlider" parent="HueShiftingOptions/AmountSat" index="2"] +margin_left = 17.0 +margin_top = 46.0 +margin_right = 109.0 +margin_bottom = 62.0 +rect_min_size = Vector2( 92, 0 ) +hint_tooltip = "Lighten/Darken amount" +focus_mode = 0 +mouse_default_cursor_shape = 2 +size_flags_horizontal = 4 +size_flags_vertical = 1 +max_value = 100.0 +value = 10.0 +ticks_on_borders = true + +[node name="AmountValue" type="VBoxContainer" parent="HueShiftingOptions" index="2"] +margin_top = 132.0 +margin_right = 126.0 +margin_bottom = 194.0 +alignment = 1 + +[node name="Label" type="Label" parent="HueShiftingOptions/AmountValue" index="0"] +margin_left = 43.0 +margin_right = 82.0 +margin_bottom = 14.0 +size_flags_horizontal = 4 +text = "Value:" + +[node name="Spinbox" type="SpinBox" parent="HueShiftingOptions/AmountValue" index="1"] +margin_left = 26.0 +margin_top = 18.0 +margin_right = 100.0 +margin_bottom = 42.0 +hint_tooltip = "Lighten/Darken amount" +mouse_default_cursor_shape = 2 +size_flags_horizontal = 4 +max_value = 100.0 +value = 10.0 +align = 1 + +[node name="Slider" type="HSlider" parent="HueShiftingOptions/AmountValue" index="2"] +margin_left = 17.0 +margin_top = 46.0 +margin_right = 109.0 +margin_bottom = 62.0 +rect_min_size = Vector2( 92, 0 ) +hint_tooltip = "Lighten/Darken amount" +focus_mode = 0 +mouse_default_cursor_shape = 2 +size_flags_horizontal = 4 +size_flags_vertical = 1 +max_value = 100.0 +value = 10.0 +ticks_on_borders = true + +[node name="ColorInterpolation" parent="." index="8"] +margin_top = 216.0 +margin_right = 126.0 +margin_bottom = 278.0 + +[node name="Label" parent="ColorInterpolation" index="0"] +margin_left = 9.0 +margin_right = 116.0 + +[node name="Factor" parent="ColorInterpolation" index="1"] +margin_left = 26.0 +margin_right = 100.0 + +[node name="Slider" parent="ColorInterpolation" index="2"] +margin_left = 17.0 +margin_right = 109.0 + +[node name="EmptySpacer" parent="." index="9"] +margin_top = 216.0 +margin_right = 126.0 +margin_bottom = 228.0 + +[node name="Mirror" parent="." index="10"] +margin_top = 232.0 +margin_right = 126.0 +margin_bottom = 249.0 + +[node name="Horizontal" parent="Mirror" index="0"] +margin_left = 25.0 +margin_right = 40.0 + +[node name="Vertical" parent="Mirror" index="1"] +margin_left = 84.0 +margin_right = 101.0 +[connection signal="item_selected" from="ShadingMode" to="." method="_on_ShadingMode_item_selected"] [connection signal="item_selected" from="LightenDarken" to="." method="_on_LightenDarken_item_selected"] [connection signal="value_changed" from="Amount/Spinbox" to="." method="_on_LightenDarken_value_changed"] [connection signal="value_changed" from="Amount/Slider" to="." method="_on_LightenDarken_value_changed"] +[connection signal="value_changed" from="HueShiftingOptions/AmountHue/Spinbox" to="." method="_on_LightenDarken_hue_value_changed"] +[connection signal="value_changed" from="HueShiftingOptions/AmountHue/Slider" to="." method="_on_LightenDarken_hue_value_changed"] +[connection signal="value_changed" from="HueShiftingOptions/AmountSat/Spinbox" to="." method="_on_LightenDarken_sat_value_changed"] +[connection signal="value_changed" from="HueShiftingOptions/AmountSat/Slider" to="." method="_on_LightenDarken_sat_value_changed"] +[connection signal="value_changed" from="HueShiftingOptions/AmountValue/Spinbox" to="." method="_on_LightenDarken_value_value_changed"] +[connection signal="value_changed" from="HueShiftingOptions/AmountValue/Slider" to="." method="_on_LightenDarken_value_value_changed"]