1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-01-30 23:19:49 +00:00

Add a new custom node, ValueSliderV2

ValueSliderV2 is a container for two ValueSliders and an optional lock ratio button, that helps with handling Vector2 values in the UI.
This commit is contained in:
Emmanouil Papadeas 2023-03-20 00:56:43 +02:00
parent 5ed91c6d8a
commit e174f6e942
6 changed files with 284 additions and 82 deletions

View file

@ -1517,6 +1517,22 @@ msgstr ""
msgid "100% Zoom"
msgstr ""
#. One of the modes of a selection tool. Found in the tool options, when a selection tool is active.
msgid "Replace selection"
msgstr ""
#. One of the modes of a selection tool. Found in the tool options, when a selection tool is active.
msgid "Add to selection"
msgstr ""
#. One of the modes of a selection tool. Found in the tool options, when a selection tool is active.
msgid "Subtract from selection"
msgstr ""
#. One of the modes of a selection tool. Found in the tool options, when a selection tool is active.
msgid "Intersection of selections"
msgstr ""
msgid "Mirroring"
msgstr ""

View file

@ -233,6 +233,11 @@ _global_script_classes=[ {
"class": "ValueSlider",
"language": "GDScript",
"path": "res://src/UI/Nodes/ValueSlider.gd"
}, {
"base": "HBoxContainer",
"class": "ValueSliderV2",
"language": "GDScript",
"path": "res://src/UI/Nodes/ValueSliderV2.gd"
} ]
_global_script_class_icons={
"AImgIOAPNGExporter": "",
@ -279,7 +284,8 @@ _global_script_class_icons={
"ShortcutProfile": "",
"SymmetryGuide": "",
"Tiles": "",
"ValueSlider": ""
"ValueSlider": "",
"ValueSliderV2": ""
}
[application]

View file

@ -22,11 +22,9 @@ var _intersect := false # Shift + Ctrl + Mouse Click
var _content_transformation_check := false
onready var selection_node: Node2D = Global.canvas.selection
onready var xspinbox: ValueSlider = $XSpinBox
onready var yspinbox: ValueSlider = $YSpinBox
onready var wspinbox: ValueSlider = $WSpinBox
onready var hspinbox: ValueSlider = $HSpinBox
onready var timer: Timer = $Timer
onready var position_sliders := $Position as ValueSliderV2
onready var size_sliders := $Size as ValueSliderV2
onready var timer := $Timer as Timer
func _ready() -> void:
@ -34,14 +32,14 @@ func _ready() -> void:
refresh_options()
func refresh_options():
func refresh_options() -> void:
# The existence of this function is to ensure all items
# are added when we are selecting an option (Bad things will happen if i dont do this...)
# are added when we are selecting an option (bad things will happen otherwise)
$Modes.clear()
$Modes.add_item("Default (New Selection)")
$Modes.add_item("Add to Selection")
$Modes.add_item("Subtract from Selection")
$Modes.add_item("Intersection of Selections")
$Modes.add_item("Replace selection")
$Modes.add_item("Add to selection")
$Modes.add_item("Subtract from selection")
$Modes.add_item("Intersection of selections")
$Modes.select(_mode_selected)
@ -61,15 +59,10 @@ func update_config() -> void:
func set_spinbox_values() -> void:
var select_rect: Rect2 = selection_node.big_bounding_rectangle
xspinbox.editable = !select_rect.has_no_area()
yspinbox.editable = xspinbox.editable
wspinbox.editable = xspinbox.editable
hspinbox.editable = xspinbox.editable
xspinbox.value = select_rect.position.x
yspinbox.value = select_rect.position.y
wspinbox.value = select_rect.size.x
hspinbox.value = select_rect.size.y
position_sliders.editable = !select_rect.has_no_area()
position_sliders.value = select_rect.position
size_sliders.editable = position_sliders.editable
size_sliders.value = select_rect.size
func draw_start(position: Vector2) -> void:
@ -228,13 +221,7 @@ func _set_cursor_text(rect: Rect2) -> void:
cursor_text += " (%s, %s)" % [rect.size.x, rect.size.y]
func _on_position_value_changed(value: float, horizontal: bool) -> void:
if horizontal:
if selection_node.big_bounding_rectangle.position.x == value:
return
else:
if selection_node.big_bounding_rectangle.position.y == value:
return
func _on_Position_value_changed(value: Vector2) -> void:
var project: Project = Global.current_project
if !project.has_selection:
return
@ -242,10 +229,7 @@ func _on_position_value_changed(value: float, horizontal: bool) -> void:
if timer.is_stopped():
undo_data = selection_node.get_undo_data(false)
timer.start()
if horizontal:
selection_node.big_bounding_rectangle.position.x = value
else:
selection_node.big_bounding_rectangle.position.y = value
selection_node.big_bounding_rectangle.position = value
var selection_map_copy := SelectionMap.new()
selection_map_copy.copy_from(project.selection_map)
@ -254,29 +238,14 @@ func _on_position_value_changed(value: float, horizontal: bool) -> void:
project.selection_map_changed()
func _on_size_value_changed(value: float, horizontal: bool) -> void:
if horizontal:
if (
selection_node.big_bounding_rectangle.size.x == value
or selection_node.big_bounding_rectangle.size.x <= 0
):
return
else:
if (
selection_node.big_bounding_rectangle.size.y == value
or selection_node.big_bounding_rectangle.size.y <= 0
):
return
func _on_Size_value_changed(value: Vector2) -> void:
if !Global.current_project.has_selection:
return
if timer.is_stopped():
undo_data = selection_node.get_undo_data(false)
timer.start()
if horizontal:
selection_node.big_bounding_rectangle.size.x = value
else:
selection_node.big_bounding_rectangle.size.y = value
selection_node.big_bounding_rectangle.size = value
selection_node.resize_selection()

View file

@ -2,7 +2,7 @@
[ext_resource path="res://src/Tools/BaseTool.tscn" type="PackedScene" id=1]
[ext_resource path="res://src/Tools/SelectionTools/SelectionTool.gd" type="Script" id=2]
[ext_resource path="res://src/UI/Nodes/ValueSlider.tscn" type="PackedScene" id=3]
[ext_resource path="res://src/UI/Nodes/ValueSliderV2.tscn" type="PackedScene" id=4]
[node name="ToolOptions" instance=ExtResource( 1 )]
script = ExtResource( 2 )
@ -17,6 +17,7 @@ text = "Mode:"
margin_top = 44.0
margin_right = 116.0
margin_bottom = 64.0
mouse_default_cursor_shape = 2
align = 1
[node name="PositionLabel" type="Label" parent="." index="4"]
@ -25,57 +26,35 @@ margin_right = 116.0
margin_bottom = 82.0
text = "Position:"
[node name="XSpinBox" parent="." index="5" instance=ExtResource( 3 )]
[node name="Position" parent="." index="5" instance=ExtResource( 4 )]
margin_top = 86.0
margin_right = 116.0
margin_bottom = 110.0
hint_tooltip = "X coordinate of the top left corner"
allow_greater = true
allow_lesser = true
prefix = "X:"
[node name="YSpinBox" parent="." index="6" instance=ExtResource( 3 )]
margin_top = 114.0
margin_right = 116.0
margin_bottom = 138.0
hint_tooltip = "Y coordinate of the top left corner"
allow_greater = true
allow_lesser = true
prefix = "Y:"
[node name="SizeLabel" type="Label" parent="." index="7"]
[node name="SizeLabel" type="Label" parent="." index="6"]
margin_top = 142.0
margin_right = 116.0
margin_bottom = 156.0
text = "Size:"
[node name="WSpinBox" parent="." index="8" instance=ExtResource( 3 )]
[node name="Size" parent="." index="7" instance=ExtResource( 4 )]
margin_top = 160.0
margin_right = 116.0
margin_bottom = 184.0
hint_tooltip = "Width of selection"
min_value = 1.0
value = 1.0
allow_greater = true
prefix = "W:"
[node name="HSpinBox" parent="." index="9" instance=ExtResource( 3 )]
margin_top = 188.0
margin_right = 116.0
margin_bottom = 212.0
hint_tooltip = "Height of selection"
value = Vector2( 1, 1 )
min_value = 1.0
value = 1.0
allow_greater = true
prefix = "H:"
show_ratio = true
prefix_x = "Width:"
prefix_y = "Height:"
[node name="Timer" type="Timer" parent="." index="10"]
[node name="Timer" type="Timer" parent="." index="8"]
wait_time = 0.2
one_shot = true
[connection signal="item_selected" from="Modes" to="." method="_on_Modes_item_selected"]
[connection signal="value_changed" from="XSpinBox" to="." method="_on_position_value_changed" binds= [ true ]]
[connection signal="value_changed" from="YSpinBox" to="." method="_on_position_value_changed" binds= [ false ]]
[connection signal="value_changed" from="WSpinBox" to="." method="_on_size_value_changed" binds= [ true ]]
[connection signal="value_changed" from="HSpinBox" to="." method="_on_size_value_changed" binds= [ false ]]
[connection signal="value_changed" from="Position" to="." method="_on_Position_value_changed"]
[connection signal="value_changed" from="Size" to="." method="_on_Size_value_changed"]
[connection signal="timeout" from="Timer" to="." method="_on_Timer_timeout"]

View file

@ -0,0 +1,157 @@
tool
class_name ValueSliderV2
extends HBoxContainer
signal value_changed(value)
export var editable := true setget _set_editable
export var value := Vector2.ZERO setget _set_value
export var min_value := 0.0 setget _set_min_value
export var max_value := 100.0 setget _set_max_value
export var step := 1.0 setget _set_step
export var allow_greater := false setget _set_allow_greater
export var allow_lesser := false setget _set_allow_lesser
export var show_ratio := false setget _set_show_ratio
export(int, 1, 2) var grid_columns := 1 setget _set_grid_columns
export var slider_min_size := Vector2(32, 24) setget _set_slider_min_size
export var snap_step := 1.0 setget _set_snap_step
export var snap_by_default := false setget _set_snap_by_default
export var prefix_x := "X:" setget _set_prefix_x
export var prefix_y := "Y:" setget _set_prefix_y
export var suffix_x := "" setget _set_suffix_x
export var suffix_y := "" setget _set_suffix_y
var ratio := Vector2.ONE
var _locked_ratio := false
var _can_emit_signal := true
func _ready() -> void:
if not Engine.editor_hint: # Pixelorama specific code
$Ratio.modulate = Global.modulate_icon_color
func get_sliders() -> Array:
return [$GridContainer/X, $GridContainer/Y]
# Greatest common divisor
func _gcd(a: int, b: int) -> int:
return a if b == 0 else _gcd(b, a % b)
func _on_X_value_changed(val: float) -> void:
value.x = val
if _locked_ratio:
value.y = max(min_value, (value.x / ratio.x) * ratio.y)
if _can_emit_signal:
emit_signal("value_changed", value)
func _on_Y_value_changed(val: float) -> void:
value.y = val
if _locked_ratio:
value.x = max(min_value, (value.y / ratio.y) * ratio.x)
if _can_emit_signal:
emit_signal("value_changed", value)
func _on_RatioButton_toggled(button_pressed: bool) -> void:
_locked_ratio = button_pressed
var divisor := _gcd(value.x, value.y)
ratio = value / divisor
# Setters
func _set_editable(val: bool) -> void:
editable = val
for slider in get_sliders():
slider.editable = val
func _set_value(val: Vector2) -> void:
value = val
_can_emit_signal = false
$GridContainer/X.value = value.x
$GridContainer/Y.value = value.y
_can_emit_signal = true
func _set_min_value(val: float) -> void:
min_value = val
for slider in get_sliders():
slider.min_value = val
func _set_max_value(val: float) -> void:
max_value = val
for slider in get_sliders():
slider.max_value = val
func _set_step(val: float) -> void:
step = val
for slider in get_sliders():
slider.step = val
func _set_allow_greater(val: bool) -> void:
allow_greater = val
for slider in get_sliders():
slider.allow_greater = val
func _set_allow_lesser(val: bool) -> void:
allow_lesser = val
for slider in get_sliders():
slider.allow_lesser = val
func _set_show_ratio(val: bool) -> void:
show_ratio = val
$Ratio.visible = val
func _set_grid_columns(val: int) -> void:
grid_columns = val
$GridContainer.columns = val
func _set_slider_min_size(val: Vector2) -> void:
slider_min_size = val
for slider in get_sliders():
slider.rect_min_size = val
func _set_snap_step(val: float) -> void:
snap_step = val
for slider in get_sliders():
slider.snap_step = val
func _set_snap_by_default(val: bool) -> void:
snap_by_default = val
for slider in get_sliders():
slider.snap_by_default = val
func _set_prefix_x(val: String) -> void:
prefix_x = val
$GridContainer/X.prefix = val
func _set_prefix_y(val: String) -> void:
prefix_y = val
$GridContainer/Y.prefix = val
func _set_suffix_x(val: String) -> void:
suffix_x = val
$GridContainer/X.suffix = val
func _set_suffix_y(val: String) -> void:
suffix_y = val
$GridContainer/Y.suffix = val

View file

@ -0,0 +1,75 @@
[gd_scene load_steps=6 format=2]
[ext_resource path="res://src/UI/Nodes/ValueSlider.gd" type="Script" id=1]
[ext_resource path="res://src/UI/Nodes/ValueSliderV2.gd" type="Script" id=2]
[ext_resource path="res://assets/graphics/misc/lock_aspect_2.png" type="Texture" id=3]
[ext_resource path="res://assets/graphics/misc/lock_aspect_guides.png" type="Texture" id=4]
[ext_resource path="res://assets/graphics/misc/lock_aspect.png" type="Texture" id=5]
[node name="ValueSliderV2" type="HBoxContainer"]
margin_right = 40.0
margin_bottom = 40.0
script = ExtResource( 2 )
[node name="GridContainer" type="GridContainer" parent="."]
margin_right = 40.0
margin_bottom = 52.0
size_flags_horizontal = 3
[node name="X" type="TextureProgress" parent="GridContainer"]
margin_right = 40.0
margin_bottom = 24.0
rect_min_size = Vector2( 32, 24 )
mouse_default_cursor_shape = 2
size_flags_horizontal = 3
theme_type_variation = "ValueSlider"
nine_patch_stretch = true
stretch_margin_left = 3
stretch_margin_top = 3
stretch_margin_right = 3
stretch_margin_bottom = 3
script = ExtResource( 1 )
prefix = "X:"
[node name="Y" type="TextureProgress" parent="GridContainer"]
margin_top = 28.0
margin_right = 40.0
margin_bottom = 52.0
rect_min_size = Vector2( 32, 24 )
mouse_default_cursor_shape = 2
size_flags_horizontal = 3
theme_type_variation = "ValueSlider"
nine_patch_stretch = true
stretch_margin_left = 3
stretch_margin_top = 3
stretch_margin_right = 3
stretch_margin_bottom = 3
script = ExtResource( 1 )
prefix = "Y:"
[node name="Ratio" type="TextureRect" parent="." groups=["UIButtons"]]
visible = false
margin_left = 36.0
margin_right = 52.0
margin_bottom = 52.0
rect_min_size = Vector2( 16, 0 )
texture = ExtResource( 4 )
[node name="RatioButton" type="TextureButton" parent="Ratio" groups=["UIButtons"]]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -8.0
margin_top = -10.0
margin_right = 8.0
margin_bottom = 6.0
hint_tooltip = "Lock aspect ratio"
mouse_default_cursor_shape = 2
toggle_mode = true
texture_normal = ExtResource( 3 )
texture_pressed = ExtResource( 5 )
[connection signal="value_changed" from="GridContainer/X" to="." method="_on_X_value_changed"]
[connection signal="value_changed" from="GridContainer/Y" to="." method="_on_Y_value_changed"]
[connection signal="toggled" from="Ratio/RatioButton" to="." method="_on_RatioButton_toggled"]