mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-01-18 09:09:47 +00:00
Add presets to the curve edit widget
This commit is contained in:
parent
cf8dacf0f5
commit
482dbecd13
|
@ -2,19 +2,19 @@
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://bybqhhayl5ay5" path="res://src/UI/Dialogs/ImageEffects/ImageEffectParent.tscn" id="1_4g7xo"]
|
[ext_resource type="PackedScene" uid="uid://bybqhhayl5ay5" path="res://src/UI/Dialogs/ImageEffects/ImageEffectParent.tscn" id="1_4g7xo"]
|
||||||
[ext_resource type="Script" path="res://src/UI/Dialogs/ImageEffects/ColorCurvesDialog.gd" id="2_xkivc"]
|
[ext_resource type="Script" path="res://src/UI/Dialogs/ImageEffects/ColorCurvesDialog.gd" id="2_xkivc"]
|
||||||
[ext_resource type="Script" path="res://src/UI/Nodes/CurveEditor/CurveEdit.gd" id="3_fp0lm"]
|
[ext_resource type="Script" path="res://src/UI/Nodes/CurveEditor/CurveEdit.gd" id="3_3yyhs"]
|
||||||
|
|
||||||
[sub_resource type="Curve" id="Curve_p6hdh"]
|
[sub_resource type="Curve" id="Curve_gvi51"]
|
||||||
_data = [Vector2(0, 0), 0.0, 1.0, 0, 1, Vector2(1, 1), 1.0, 0.0, 1, 0]
|
_data = [Vector2(0, 0), 0.0, 1.0, 0, 1, Vector2(1, 1), 1.0, 0.0, 1, 0]
|
||||||
point_count = 2
|
point_count = 2
|
||||||
|
|
||||||
[node name="ColorCurvesDialog" instance=ExtResource("1_4g7xo")]
|
[node name="ColorCurvesDialog" instance=ExtResource("1_4g7xo")]
|
||||||
title = "Color Curves"
|
title = "Color Curves"
|
||||||
size = Vector2i(362, 440)
|
size = Vector2i(362, 481)
|
||||||
script = ExtResource("2_xkivc")
|
script = ExtResource("2_xkivc")
|
||||||
|
|
||||||
[node name="VBoxContainer" parent="." index="3"]
|
[node name="VBoxContainer" parent="." index="3"]
|
||||||
offset_bottom = 391.0
|
offset_bottom = 432.0
|
||||||
|
|
||||||
[node name="ShowAnimate" parent="VBoxContainer" index="0"]
|
[node name="ShowAnimate" parent="VBoxContainer" index="0"]
|
||||||
visible = false
|
visible = false
|
||||||
|
@ -51,10 +51,11 @@ popup/item_6/id = 6
|
||||||
popup/item_7/text = "Value"
|
popup/item_7/text = "Value"
|
||||||
popup/item_7/id = 7
|
popup/item_7/id = 7
|
||||||
|
|
||||||
[node name="CurveEdit" type="Control" parent="VBoxContainer" index="4"]
|
[node name="CurveEdit" type="VBoxContainer" parent="VBoxContainer" index="4"]
|
||||||
|
custom_minimum_size = Vector2(32, 150)
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_vertical = 3
|
size_flags_vertical = 3
|
||||||
script = ExtResource("3_fp0lm")
|
script = ExtResource("3_3yyhs")
|
||||||
curve = SubResource("Curve_p6hdh")
|
curve = SubResource("Curve_gvi51")
|
||||||
|
|
||||||
[connection signal="item_selected" from="VBoxContainer/ColorOptions/ChannelOptionButton" to="." method="_on_channel_option_button_item_selected"]
|
[connection signal="item_selected" from="VBoxContainer/ColorOptions/ChannelOptionButton" to="." method="_on_channel_option_button_item_selected"]
|
||||||
|
|
|
@ -18,7 +18,8 @@ var max_y: float
|
||||||
var left_slope: CurveEditTangentPoint
|
var left_slope: CurveEditTangentPoint
|
||||||
var right_slope: CurveEditTangentPoint
|
var right_slope: CurveEditTangentPoint
|
||||||
|
|
||||||
@onready var parent := get_parent() as CurveEdit
|
@onready var parent := get_parent() as Control
|
||||||
|
@onready var grandparent := parent.get_parent() as CurveEdit
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
|
@ -45,7 +46,7 @@ func _draw() -> void:
|
||||||
func initialize(curve: Curve, index: int) -> void:
|
func initialize(curve: Curve, index: int) -> void:
|
||||||
if not is_instance_valid(parent):
|
if not is_instance_valid(parent):
|
||||||
await ready
|
await ready
|
||||||
position = parent.transform_point(curve.get_point_position(index)) - OFFSET
|
position = grandparent.transform_point(curve.get_point_position(index)) - OFFSET
|
||||||
var left_tangent := curve.get_point_left_tangent(index)
|
var left_tangent := curve.get_point_left_tangent(index)
|
||||||
var right_tangent := curve.get_point_right_tangent(index)
|
var right_tangent := curve.get_point_right_tangent(index)
|
||||||
if left_tangent != INF:
|
if left_tangent != INF:
|
||||||
|
@ -81,7 +82,7 @@ func _on_gui_input(event: InputEvent) -> void:
|
||||||
moving = true
|
moving = true
|
||||||
else:
|
else:
|
||||||
moving = false
|
moving = false
|
||||||
parent.update_controls()
|
grandparent.update_controls()
|
||||||
elif event.button_index == MOUSE_BUTTON_RIGHT and event.pressed:
|
elif event.button_index == MOUSE_BUTTON_RIGHT and event.pressed:
|
||||||
removed.emit(get_index())
|
removed.emit(get_index())
|
||||||
elif moving and event is InputEventMouseMotion:
|
elif moving and event is InputEventMouseMotion:
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# https://github.com/RodZill4/material-maker/blob/master/material_maker/widgets/curve_edit/curve_editor.gd
|
# https://github.com/RodZill4/material-maker/blob/master/material_maker/widgets/curve_edit/curve_editor.gd
|
||||||
@tool
|
@tool
|
||||||
class_name CurveEdit
|
class_name CurveEdit
|
||||||
extends Control
|
extends VBoxContainer
|
||||||
|
|
||||||
signal value_changed(value: Curve)
|
signal value_changed(value: Curve)
|
||||||
|
|
||||||
|
@ -17,23 +17,111 @@ signal value_changed(value: Curve)
|
||||||
queue_redraw()
|
queue_redraw()
|
||||||
update_controls()
|
update_controls()
|
||||||
|
|
||||||
|
## Array of dictionaries of key [String] and value [Array] of type [CurveEdit.CurvePoint].
|
||||||
|
var presets: Array[Dictionary] = [
|
||||||
|
{"Linear": [CurvePoint.new(0.0, 0.0, 0.0, 1.0), CurvePoint.new(1.0, 1.0, 1.0, 0.0)]},
|
||||||
|
{
|
||||||
|
"Ease out":
|
||||||
|
[
|
||||||
|
CurvePoint.new(0.0, 0.0, 0.0, 4.0),
|
||||||
|
CurvePoint.new(0.292893, 0.707107, 1.0, 1.0),
|
||||||
|
CurvePoint.new(1.0, 1.0, 0.0, 0.0)
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Ease in out":
|
||||||
|
[
|
||||||
|
CurvePoint.new(0.0, 0.0, 0.0, 0.0),
|
||||||
|
CurvePoint.new(0.5, 0.5, 3.0, 3.0),
|
||||||
|
CurvePoint.new(1.0, 1.0, 0.0, 0.0)
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Ease in":
|
||||||
|
[
|
||||||
|
CurvePoint.new(0.0, 0.0, 0.0, 0.0),
|
||||||
|
CurvePoint.new(0.707107, 0.292893, 1.0, 1.0),
|
||||||
|
CurvePoint.new(1.0, 1.0, 4.0, 0.0)
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sawtooth":
|
||||||
|
[
|
||||||
|
CurvePoint.new(0.0, 0.0, 0.0, 2.0),
|
||||||
|
CurvePoint.new(0.5, 1.0, 2.0, -2.0),
|
||||||
|
CurvePoint.new(1.0, 0.0, -2.0, 0.0)
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Bounce":
|
||||||
|
[
|
||||||
|
CurvePoint.new(0.0, 0.0, 0.0, 5.0),
|
||||||
|
CurvePoint.new(0.15, 0.65, 2.45201, 2.45201),
|
||||||
|
CurvePoint.new(0.5, 1.0, 0.0, 0.0),
|
||||||
|
CurvePoint.new(0.85, 0.65, -2.45201, -2.45201),
|
||||||
|
CurvePoint.new(1.0, 0.0, -5.0, 0.0)
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Bevel":
|
||||||
|
[
|
||||||
|
CurvePoint.new(0.0, 0.0, 0.0, 2.38507),
|
||||||
|
CurvePoint.new(0.292893, 0.707107, 2.34362, 0.428147),
|
||||||
|
CurvePoint.new(1.0, 1.0, 0.410866, 0.0)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
var curve_editor := Control.new()
|
||||||
|
var hbox := HBoxContainer.new()
|
||||||
|
|
||||||
|
|
||||||
|
class CurvePoint:
|
||||||
|
var pos: Vector2
|
||||||
|
var left_tangent: float
|
||||||
|
var right_tangent: float
|
||||||
|
|
||||||
|
func _init(x: float, y: float, _left_tangent := 0.0, _right_tangent := 0.0) -> void:
|
||||||
|
pos = Vector2(x, y)
|
||||||
|
left_tangent = _left_tangent
|
||||||
|
right_tangent = _right_tangent
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
if not is_instance_valid(curve):
|
if not is_instance_valid(curve):
|
||||||
curve = Curve.new()
|
curve = Curve.new()
|
||||||
gui_input.connect(_on_gui_input)
|
if custom_minimum_size.is_zero_approx():
|
||||||
|
custom_minimum_size = Vector2(32, 150)
|
||||||
|
curve_editor.gui_input.connect(_on_gui_input)
|
||||||
resized.connect(_on_resize)
|
resized.connect(_on_resize)
|
||||||
queue_redraw()
|
curve_editor.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||||
update_controls()
|
add_child(curve_editor)
|
||||||
|
add_child(hbox)
|
||||||
|
var presets_button := MenuButton.new()
|
||||||
|
presets_button.text = "Presets"
|
||||||
|
presets_button.flat = false
|
||||||
|
presets_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
|
||||||
|
presets_button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
|
presets_button.get_popup().id_pressed.connect(_on_presets_item_selected)
|
||||||
|
for preset in presets:
|
||||||
|
presets_button.get_popup().add_item(preset.keys()[0])
|
||||||
|
var invert_button := Button.new()
|
||||||
|
invert_button.text = "Invert"
|
||||||
|
invert_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
|
||||||
|
invert_button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
|
invert_button.pressed.connect(_on_invert_button_pressed)
|
||||||
|
hbox.add_child(presets_button)
|
||||||
|
hbox.add_child(invert_button)
|
||||||
|
_on_resize.call_deferred()
|
||||||
|
|
||||||
|
|
||||||
func update_controls() -> void:
|
func update_controls() -> void:
|
||||||
for c in get_children():
|
for c in curve_editor.get_children():
|
||||||
c.queue_free()
|
if c is CurveEditControlPoint:
|
||||||
|
c.queue_free()
|
||||||
for i in curve.point_count:
|
for i in curve.point_count:
|
||||||
var p := curve.get_point_position(i)
|
var p := curve.get_point_position(i)
|
||||||
var control_point := CurveEditControlPoint.new()
|
var control_point := CurveEditControlPoint.new()
|
||||||
add_child(control_point)
|
curve_editor.add_child(control_point)
|
||||||
control_point.initialize(curve, i)
|
control_point.initialize(curve, i)
|
||||||
control_point.position = transform_point(p) - control_point.OFFSET
|
control_point.position = transform_point(p) - control_point.OFFSET
|
||||||
if i == 0 or i == curve.point_count - 1:
|
if i == 0 or i == curve.point_count - 1:
|
||||||
|
@ -41,7 +129,7 @@ func update_controls() -> void:
|
||||||
control_point.position.x,
|
control_point.position.x,
|
||||||
control_point.position.x,
|
control_point.position.x,
|
||||||
-control_point.OFFSET.y,
|
-control_point.OFFSET.y,
|
||||||
size.y - control_point.OFFSET.y
|
available_size().y - control_point.OFFSET.y
|
||||||
)
|
)
|
||||||
if i == 0:
|
if i == 0:
|
||||||
control_point.set_control_point_visibility(true, false)
|
control_point.set_control_point_visibility(true, false)
|
||||||
|
@ -51,7 +139,7 @@ func update_controls() -> void:
|
||||||
var min_x := transform_point(curve.get_point_position(i - 1)).x + 1
|
var min_x := transform_point(curve.get_point_position(i - 1)).x + 1
|
||||||
var max_x := transform_point(curve.get_point_position(i + 1)).x - 1
|
var max_x := transform_point(curve.get_point_position(i + 1)).x - 1
|
||||||
control_point.set_constraint(
|
control_point.set_constraint(
|
||||||
min_x, max_x, -control_point.OFFSET.y, size.y - control_point.OFFSET.y
|
min_x, max_x, -control_point.OFFSET.y, available_size().y - control_point.OFFSET.y
|
||||||
)
|
)
|
||||||
control_point.moved.connect(_on_control_point_moved)
|
control_point.moved.connect(_on_control_point_moved)
|
||||||
control_point.removed.connect(_on_control_point_removed)
|
control_point.removed.connect(_on_control_point_removed)
|
||||||
|
@ -66,12 +154,18 @@ static func to_texture(from_curve: Curve, width := 256) -> CurveTexture:
|
||||||
return texture
|
return texture
|
||||||
|
|
||||||
|
|
||||||
|
func available_size() -> Vector2:
|
||||||
|
if curve_editor.size.is_zero_approx():
|
||||||
|
return Vector2.ONE
|
||||||
|
return curve_editor.size
|
||||||
|
|
||||||
|
|
||||||
func transform_point(p: Vector2) -> Vector2:
|
func transform_point(p: Vector2) -> Vector2:
|
||||||
return (Vector2(0.0, 1.0) + Vector2(1.0, -1.0) * p) * size
|
return (Vector2(0.0, 1.0) + Vector2(1.0, -1.0) * p) * available_size()
|
||||||
|
|
||||||
|
|
||||||
func reverse_transform_point(p: Vector2) -> Vector2:
|
func reverse_transform_point(p: Vector2) -> Vector2:
|
||||||
return Vector2(0.0, 1.0) + Vector2(1.0, -1.0) * p / size
|
return Vector2(0.0, 1.0) + Vector2(1.0, -1.0) * p / available_size()
|
||||||
|
|
||||||
|
|
||||||
func _draw() -> void:
|
func _draw() -> void:
|
||||||
|
@ -89,8 +183,8 @@ func _draw() -> void:
|
||||||
if show_axes:
|
if show_axes:
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
var p := transform_point(0.25 * Vector2(i, i))
|
var p := transform_point(0.25 * Vector2(i, i))
|
||||||
draw_line(Vector2(p.x, 0), Vector2(p.x, size.y - 1), axes_color)
|
draw_line(Vector2(p.x, 0), Vector2(p.x, available_size().y - 1), axes_color)
|
||||||
draw_line(Vector2(0, p.y), Vector2(size.x - 1, p.y), axes_color)
|
draw_line(Vector2(0, p.y), Vector2(available_size().x - 1, p.y), axes_color)
|
||||||
var points := PackedVector2Array()
|
var points := PackedVector2Array()
|
||||||
for i in range(curve.point_count - 1):
|
for i in range(curve.point_count - 1):
|
||||||
var p1 := curve.get_point_position(i)
|
var p1 := curve.get_point_position(i)
|
||||||
|
@ -117,16 +211,16 @@ func _draw() -> void:
|
||||||
|
|
||||||
|
|
||||||
func _on_control_point_moved(index: int) -> void:
|
func _on_control_point_moved(index: int) -> void:
|
||||||
var control_point := get_child(index) as CurveEditControlPoint
|
var control_point := curve_editor.get_child(index) as CurveEditControlPoint
|
||||||
var new_point := reverse_transform_point(control_point.position + control_point.OFFSET)
|
var new_point := reverse_transform_point(control_point.position + control_point.OFFSET)
|
||||||
curve.set_point_offset(index, new_point.x)
|
curve.set_point_offset(index, new_point.x)
|
||||||
curve.set_point_value(index, new_point.y)
|
curve.set_point_value(index, new_point.y)
|
||||||
if is_instance_valid(control_point.left_slope):
|
if is_instance_valid(control_point.left_slope):
|
||||||
var slope_vector := control_point.left_slope.position / size
|
var slope_vector := control_point.left_slope.position / available_size()
|
||||||
if slope_vector.x != 0:
|
if slope_vector.x != 0:
|
||||||
curve.set_point_left_tangent(index, -slope_vector.y / slope_vector.x)
|
curve.set_point_left_tangent(index, -slope_vector.y / slope_vector.x)
|
||||||
if is_instance_valid(control_point.right_slope):
|
if is_instance_valid(control_point.right_slope):
|
||||||
var slope_vector := control_point.right_slope.position / size
|
var slope_vector := control_point.right_slope.position / available_size()
|
||||||
if slope_vector.x != 0:
|
if slope_vector.x != 0:
|
||||||
curve.set_point_right_tangent(index, -slope_vector.y / slope_vector.x)
|
curve.set_point_right_tangent(index, -slope_vector.y / slope_vector.x)
|
||||||
queue_redraw()
|
queue_redraw()
|
||||||
|
@ -151,3 +245,23 @@ func _on_gui_input(event: InputEvent) -> void:
|
||||||
func _on_resize() -> void:
|
func _on_resize() -> void:
|
||||||
queue_redraw()
|
queue_redraw()
|
||||||
update_controls()
|
update_controls()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_presets_item_selected(index: int) -> void:
|
||||||
|
curve.clear_points()
|
||||||
|
var preset_points: Array = presets[index].values()[0]
|
||||||
|
for point: CurvePoint in preset_points:
|
||||||
|
curve.add_point(point.pos, point.left_tangent, point.right_tangent)
|
||||||
|
curve = curve # Call setter
|
||||||
|
|
||||||
|
|
||||||
|
func _on_invert_button_pressed() -> void:
|
||||||
|
var copy_curve := curve.duplicate() as Curve
|
||||||
|
curve.clear_points()
|
||||||
|
for i in copy_curve.point_count:
|
||||||
|
var point := copy_curve.get_point_position(i)
|
||||||
|
point.y = 1.0 - point.y
|
||||||
|
var left_tangent := -copy_curve.get_point_left_tangent(i)
|
||||||
|
var right_tangent := -copy_curve.get_point_right_tangent(i)
|
||||||
|
curve.add_point(point, left_tangent, right_tangent)
|
||||||
|
curve = curve # Call setter
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
class_name CurveEditTangentPoint
|
class_name CurveEditTangentPoint
|
||||||
extends Control
|
extends Control
|
||||||
|
|
||||||
const OFFSET := -Vector2(0, 0)
|
const OFFSET := Vector2(0, 0)
|
||||||
|
|
||||||
@export var distance := 30
|
@export var distance := 30
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue