mirror of
https://github.com/Relintai/material-maker.git
synced 2024-12-23 21:16:54 +01:00
Gradient and serialization related updates
Added a class for gradient (that handles serialization and shader generation), and updated the GradientEditor. Added a "Types" class that handles values serialization. Updated linked_control and config_control to link to GradientEditors.
This commit is contained in:
parent
95a737029a
commit
9dc6d4b18a
@ -20,6 +20,8 @@ var generated_variants = []
|
|||||||
|
|
||||||
var property_widgets = []
|
var property_widgets = []
|
||||||
|
|
||||||
|
const Types = preload("res://addons/material_maker/types/types.gd")
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -46,6 +48,11 @@ func initialize_properties(object_list):
|
|||||||
elif o is ColorPickerButton:
|
elif o is ColorPickerButton:
|
||||||
set(o.name, o.color)
|
set(o.name, o.color)
|
||||||
o.connect("color_changed", self, "_on_color_changed", [ o.name ])
|
o.connect("color_changed", self, "_on_color_changed", [ o.name ])
|
||||||
|
elif o is Control and o.filename == "res://addons/material_maker/widgets/gradient_editor.tscn":
|
||||||
|
set(o.name, o.value)
|
||||||
|
o.connect("updated", self, "_on_gradient_changed", [ o.name ])
|
||||||
|
else:
|
||||||
|
print("unsupported widget "+str(o))
|
||||||
|
|
||||||
func get_seed():
|
func get_seed():
|
||||||
return int(offset.x)*3+int(offset.y)*5
|
return int(offset.x)*3+int(offset.y)*5
|
||||||
@ -64,6 +71,10 @@ func update_property_widgets():
|
|||||||
o.pressed = get(o.name)
|
o.pressed = get(o.name)
|
||||||
elif o is ColorPickerButton:
|
elif o is ColorPickerButton:
|
||||||
o.color = get(o.name)
|
o.color = get(o.name)
|
||||||
|
elif o is Control and o.filename == "res://addons/material_maker/widgets/gradient_editor.tscn":
|
||||||
|
o.value = get(o.name)
|
||||||
|
else:
|
||||||
|
print("Failed to update "+o.name)
|
||||||
|
|
||||||
func update_shaders():
|
func update_shaders():
|
||||||
get_parent().send_changed_signal()
|
get_parent().send_changed_signal()
|
||||||
@ -80,6 +91,10 @@ func _on_color_changed(new_color, variable):
|
|||||||
set(variable, new_color)
|
set(variable, new_color)
|
||||||
update_shaders()
|
update_shaders()
|
||||||
|
|
||||||
|
func _on_gradient_changed(new_gradient, variable):
|
||||||
|
set(variable, new_gradient)
|
||||||
|
update_shaders()
|
||||||
|
|
||||||
func get_source(index = 0):
|
func get_source(index = 0):
|
||||||
for c in get_parent().get_connection_list():
|
for c in get_parent().get_connection_list():
|
||||||
if c.to == name and c.to_port == index:
|
if c.to == name and c.to_port == index:
|
||||||
@ -153,6 +168,10 @@ func deserialize_element(e):
|
|||||||
if typeof(e) == TYPE_DICTIONARY:
|
if typeof(e) == TYPE_DICTIONARY:
|
||||||
if e.has("type") and e.type == "Color":
|
if e.has("type") and e.type == "Color":
|
||||||
return Color(e.r, e.g, e.b, e.a)
|
return Color(e.r, e.g, e.b, e.a)
|
||||||
|
elif typeof(e) == TYPE_ARRAY:
|
||||||
|
var gradient = preload("res://addons/material_maker/types/gradient.gd").new()
|
||||||
|
gradient.deserialize(e)
|
||||||
|
return gradient
|
||||||
return e
|
return e
|
||||||
|
|
||||||
func generate_shader(slot = 0):
|
func generate_shader(slot = 0):
|
||||||
@ -169,7 +188,7 @@ func serialize():
|
|||||||
var data = { name=name, type=type, node_position={x=offset.x, y=offset.y} }
|
var data = { name=name, type=type, node_position={x=offset.x, y=offset.y} }
|
||||||
for w in property_widgets:
|
for w in property_widgets:
|
||||||
var v = w.name
|
var v = w.name
|
||||||
data[v] = serialize_element(get(v))
|
data[v] = Types.serialize_value(get(v)) # serialize_element(get(v))
|
||||||
return data
|
return data
|
||||||
|
|
||||||
func deserialize(data):
|
func deserialize(data):
|
||||||
@ -178,7 +197,7 @@ func deserialize(data):
|
|||||||
for w in property_widgets:
|
for w in property_widgets:
|
||||||
var variable = w.name
|
var variable = w.name
|
||||||
if data.has(variable):
|
if data.has(variable):
|
||||||
var value = deserialize_element(data[variable])
|
var value = Types.deserialize_value(data[variable]) #deserialize_element(data[variable])
|
||||||
set(variable, value)
|
set(variable, value)
|
||||||
update_property_widgets()
|
update_property_widgets()
|
||||||
|
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
tool
|
tool
|
||||||
extends "res://addons/material_maker/node_base.gd"
|
extends "res://addons/material_maker/node_base.gd"
|
||||||
|
|
||||||
|
var gradient
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
initialize_properties([ $gradient ])
|
||||||
|
|
||||||
func _get_shader_code(uv):
|
func _get_shader_code(uv):
|
||||||
var rv = { defs="", code="" }
|
var rv = { defs="", code="" }
|
||||||
var src = get_source()
|
var src = get_source()
|
||||||
@ -8,7 +13,7 @@ func _get_shader_code(uv):
|
|||||||
return rv
|
return rv
|
||||||
var src_code = src.get_shader_code(uv)
|
var src_code = src.get_shader_code(uv)
|
||||||
if generated_variants.empty():
|
if generated_variants.empty():
|
||||||
rv.defs = src_code.defs+$Control.get_shader("%s_gradient" % name);
|
rv.defs = src_code.defs+gradient.get_shader("%s_gradient" % name);
|
||||||
var variant_index = generated_variants.find(uv)
|
var variant_index = generated_variants.find(uv)
|
||||||
if variant_index == -1:
|
if variant_index == -1:
|
||||||
variant_index = generated_variants.size()
|
variant_index = generated_variants.size()
|
||||||
@ -17,12 +22,6 @@ func _get_shader_code(uv):
|
|||||||
rv.rgb = "%s_%d_rgb" % [ name, variant_index ]
|
rv.rgb = "%s_%d_rgb" % [ name, variant_index ]
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
func serialize():
|
func _on_Control_updated(v):
|
||||||
var data = .serialize()
|
gradient = v
|
||||||
data.gradient = $Control.serialize()
|
update_shaders()
|
||||||
return data
|
|
||||||
|
|
||||||
func deserialize(data):
|
|
||||||
if data.has("gradient"):
|
|
||||||
$Control.deserialize(data.gradient)
|
|
||||||
.deserialize(data)
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
[sub_resource type="Theme" id=1]
|
[sub_resource type="Theme" id=1]
|
||||||
|
|
||||||
|
|
||||||
[node name="Colorize" type="GraphNode" index="0"]
|
[node name="Colorize" type="GraphNode"]
|
||||||
|
|
||||||
anchor_left = 0.0
|
anchor_left = 0.0
|
||||||
anchor_top = 0.0
|
anchor_top = 0.0
|
||||||
@ -39,13 +39,13 @@ slot/0/right_color = Color( 0.5, 0.5, 1, 1 )
|
|||||||
script = ExtResource( 1 )
|
script = ExtResource( 1 )
|
||||||
_sections_unfolded = [ "Theme", "slot", "slot/0" ]
|
_sections_unfolded = [ "Theme", "slot", "slot/0" ]
|
||||||
|
|
||||||
[node name="Control" parent="." index="0" instance=ExtResource( 2 )]
|
[node name="gradient" parent="." index="0" instance=ExtResource( 2 )]
|
||||||
|
|
||||||
margin_left = 16.0
|
margin_left = 16.0
|
||||||
margin_top = 24.0
|
margin_top = 24.0
|
||||||
margin_right = 136.0
|
margin_right = 136.0
|
||||||
margin_bottom = 54.0
|
margin_bottom = 54.0
|
||||||
|
|
||||||
[connection signal="updated" from="Control" to="." method="update_shaders"]
|
[connection signal="updated" from="gradient" to="." method="_on_Control_updated"]
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
[sub_resource type="Theme" id=1]
|
[sub_resource type="Theme" id=1]
|
||||||
|
|
||||||
|
|
||||||
[node name="Remote" type="GraphNode"]
|
[node name="Remote" type="GraphNode" index="0"]
|
||||||
|
|
||||||
anchor_left = 0.0
|
anchor_left = 0.0
|
||||||
anchor_top = 0.0
|
anchor_top = 0.0
|
||||||
|
86
addons/material_maker/types/gradient.gd
Normal file
86
addons/material_maker/types/gradient.gd
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
extends Object
|
||||||
|
|
||||||
|
class CustomSorter:
|
||||||
|
static func compare(a, b):
|
||||||
|
return a.v < b.v
|
||||||
|
|
||||||
|
var points = [ { v=0.0, c=Color(0.0, 0.0, 0.0) }, { v=1.0, c=Color(1.0, 1.0, 1.0) } ]
|
||||||
|
var sorted = true
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
pass
|
||||||
|
|
||||||
|
func duplicate():
|
||||||
|
var copy = get_script().new()
|
||||||
|
copy.clear()
|
||||||
|
for p in points:
|
||||||
|
copy.add_point(p.v, p.c)
|
||||||
|
return copy
|
||||||
|
|
||||||
|
func clear():
|
||||||
|
points.clear()
|
||||||
|
sorted = true
|
||||||
|
|
||||||
|
func add_point(v, c):
|
||||||
|
points.append({ v=v, c=c })
|
||||||
|
sorted = false
|
||||||
|
|
||||||
|
func sort():
|
||||||
|
if !sorted:
|
||||||
|
points.sort_custom(CustomSorter, "compare")
|
||||||
|
sorted = true
|
||||||
|
|
||||||
|
func get_color(x):
|
||||||
|
sort()
|
||||||
|
if x < points[0].v:
|
||||||
|
return points[0].c
|
||||||
|
var s = points.size()-1
|
||||||
|
for i in range(s):
|
||||||
|
if x < points[i+1].v:
|
||||||
|
var p0 = points[i].v
|
||||||
|
var c0 = points[i].c
|
||||||
|
var p1 = points[i+1].v
|
||||||
|
var c1 = points[i+1].c
|
||||||
|
return c0 + (c1-c0) * (x-p0) / (p1-p0)
|
||||||
|
return points[s].c
|
||||||
|
|
||||||
|
# get_color_in_shader
|
||||||
|
func gcis(color):
|
||||||
|
return "vec3(%.9f,%.9f,%.9f)" % [color.r, color.g, color.b]
|
||||||
|
|
||||||
|
func get_shader(name):
|
||||||
|
sort()
|
||||||
|
var shader
|
||||||
|
shader = "vec3 "+name+"(float x) {\n"
|
||||||
|
shader += " if (x < %.9f) {\n" % points[0].v
|
||||||
|
shader += " return "+gcis(points[0].c)+";\n"
|
||||||
|
var s = points.size()-1
|
||||||
|
for i in range(s):
|
||||||
|
var p0 = points[i].v
|
||||||
|
var c0 = points[i].c
|
||||||
|
var p1mp0 = points[i+1].v-p0
|
||||||
|
var c1mc0 = points[i+1].c-c0
|
||||||
|
if p1mp0 > 0:
|
||||||
|
shader += " } else if (x < %.9f) {\n" % points[i+1].v
|
||||||
|
shader += " return %s+x*%s;\n" % [gcis(c0-c1mc0*(p0/p1mp0)), gcis(c1mc0/p1mp0)]
|
||||||
|
shader += " }\n"
|
||||||
|
shader += " return "+gcis(points[s].c)+";\n"
|
||||||
|
shader += "}\n"
|
||||||
|
return shader
|
||||||
|
|
||||||
|
func serialize():
|
||||||
|
sort()
|
||||||
|
var rv = []
|
||||||
|
for p in points:
|
||||||
|
rv.append({ pos=p.v, r=p.c.r, g=p.c.g, b=p.c.b })
|
||||||
|
rv = { type="Gradient", points=rv }
|
||||||
|
return rv
|
||||||
|
|
||||||
|
func deserialize(v):
|
||||||
|
clear()
|
||||||
|
if typeof(v) == TYPE_ARRAY:
|
||||||
|
for i in v:
|
||||||
|
add_point(i.pos, Color(i.r, i.g, i.b))
|
||||||
|
elif typeof(v) == TYPE_DICTIONARY && v.has("type") && v.type == "Gradient":
|
||||||
|
for i in v.points:
|
||||||
|
add_point(i.pos, Color(i.r, i.g, i.b))
|
26
addons/material_maker/types/types.gd
Normal file
26
addons/material_maker/types/types.gd
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
const Gradient = preload("res://addons/material_maker/types/gradient.gd")
|
||||||
|
|
||||||
|
static func serialize_value(value):
|
||||||
|
if typeof(value) == TYPE_COLOR:
|
||||||
|
return { type= "Color", r=value.r, g=value.g, b=value.b, a=value.a }
|
||||||
|
elif typeof(value) == TYPE_OBJECT && value.has_method("serialize"):
|
||||||
|
return value.serialize()
|
||||||
|
return value
|
||||||
|
|
||||||
|
static func deserialize_value(data):
|
||||||
|
if typeof(data) == TYPE_DICTIONARY:
|
||||||
|
if data.has("type"):
|
||||||
|
if data.type == "Color":
|
||||||
|
return Color(data.r, data.g, data.b, data.a)
|
||||||
|
elif data.type == "Gradient":
|
||||||
|
var gradient = Gradient.new()
|
||||||
|
gradient.deserialize(data)
|
||||||
|
return gradient
|
||||||
|
# in previous releases, Gradients were serialized as arrays
|
||||||
|
elif typeof(data) == TYPE_ARRAY:
|
||||||
|
var gradient = Gradient.new()
|
||||||
|
gradient.deserialize(data)
|
||||||
|
return gradient
|
||||||
|
return data
|
@ -8,7 +8,7 @@ class GradientCursor:
|
|||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
rect_position = Vector2(0, 15)
|
rect_position = Vector2(0, 15)
|
||||||
rect_size = Vector2(WIDTH, 20)
|
rect_size = Vector2(WIDTH, 15)
|
||||||
|
|
||||||
func _gui_input(ev):
|
func _gui_input(ev):
|
||||||
if ev is InputEventMouseButton:
|
if ev is InputEventMouseButton:
|
||||||
@ -17,43 +17,63 @@ class GradientCursor:
|
|||||||
elif ev.button_index == BUTTON_RIGHT && get_parent().get_sorted_cursors().size() > 2:
|
elif ev.button_index == BUTTON_RIGHT && get_parent().get_sorted_cursors().size() > 2:
|
||||||
var parent = get_parent()
|
var parent = get_parent()
|
||||||
parent.remove_child(self)
|
parent.remove_child(self)
|
||||||
parent.update_shader()
|
parent.update_value()
|
||||||
queue_free()
|
queue_free()
|
||||||
elif ev is InputEventMouseMotion && (ev.button_mask & 1) != 0:
|
elif ev is InputEventMouseMotion && (ev.button_mask & 1) != 0:
|
||||||
rect_position.x += ev.relative.x
|
rect_position.x += ev.relative.x
|
||||||
rect_position.x = min(max(0, rect_position.x), get_parent().rect_size.x-rect_size.x)
|
rect_position.x = min(max(0, rect_position.x), get_parent().rect_size.x-rect_size.x)
|
||||||
get_parent().update_shader()
|
get_parent().update_value()
|
||||||
|
|
||||||
func get_position():
|
func get_position():
|
||||||
return rect_position.x / (get_parent().rect_size.x - WIDTH)
|
return rect_position.x / (get_parent().rect_size.x - WIDTH)
|
||||||
|
|
||||||
func set_color(c):
|
func set_color(c):
|
||||||
color = c
|
color = c
|
||||||
get_parent().update_shader()
|
get_parent().update_value()
|
||||||
|
|
||||||
static func sort(a, b):
|
static func sort(a, b):
|
||||||
if a.get_position() < b.get_position():
|
if a.get_position() < b.get_position():
|
||||||
return true
|
return true
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
var value = null setget set_value
|
||||||
|
|
||||||
|
const Gradient = preload("res://addons/material_maker/types/gradient.gd")
|
||||||
|
|
||||||
signal updated
|
signal updated
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
$Gradient.material = $Gradient.material.duplicate(true)
|
$Gradient.material = $Gradient.material.duplicate(true)
|
||||||
add_cursor(0, Color(0, 0, 0))
|
set_value(Gradient.new())
|
||||||
add_cursor(rect_size.x-GradientCursor.WIDTH, Color(1, 1, 1))
|
|
||||||
|
func set_value(v):
|
||||||
|
value = v
|
||||||
|
for c in get_children():
|
||||||
|
if c != $Gradient:
|
||||||
|
remove_child(c)
|
||||||
|
c.free()
|
||||||
|
for p in value.points:
|
||||||
|
add_cursor(p.v*(rect_size.x-GradientCursor.WIDTH), p.c)
|
||||||
|
update_shader()
|
||||||
|
|
||||||
|
func update_value():
|
||||||
|
value.clear()
|
||||||
|
for p in get_children():
|
||||||
|
if p != $Gradient:
|
||||||
|
value.add_point(p.rect_position.x/(rect_size.x-GradientCursor.WIDTH), p.color)
|
||||||
|
update_shader()
|
||||||
|
|
||||||
func add_cursor(x, color):
|
func add_cursor(x, color):
|
||||||
var cursor = GradientCursor.new()
|
var cursor = GradientCursor.new()
|
||||||
add_child(cursor)
|
add_child(cursor)
|
||||||
cursor.rect_position.x = x
|
cursor.rect_position.x = x
|
||||||
cursor.color = color
|
cursor.color = color
|
||||||
update_shader()
|
|
||||||
|
|
||||||
func _gui_input(ev):
|
func _gui_input(ev):
|
||||||
if ev is InputEventMouseButton && ev.button_index == 1 && ev.doubleclick && ev.position.y > 15:
|
if ev is InputEventMouseButton && ev.button_index == 1 && ev.doubleclick && ev.position.y > 15:
|
||||||
var p = max(0, min(ev.position.x, rect_size.x-GradientCursor.WIDTH))
|
var p = max(0, min(ev.position.x, rect_size.x-GradientCursor.WIDTH))
|
||||||
add_cursor(p, get_color(p))
|
add_cursor(p, get_color(p))
|
||||||
|
update_value()
|
||||||
|
|
||||||
# Showing a color picker popup to change a cursor's color
|
# Showing a color picker popup to change a cursor's color
|
||||||
|
|
||||||
@ -78,59 +98,12 @@ func get_sorted_cursors():
|
|||||||
return array
|
return array
|
||||||
|
|
||||||
func get_color(x):
|
func get_color(x):
|
||||||
var array = get_sorted_cursors()
|
return value.get_color(x / (rect_size.x - GradientCursor.WIDTH))
|
||||||
x = x / (rect_size.x - array[0].rect_size.x)
|
|
||||||
if x < array[0].get_position():
|
|
||||||
return array[0].color
|
|
||||||
for i in range(array.size()-1):
|
|
||||||
if x < array[i+1].get_position():
|
|
||||||
var p0 = array[i].get_position()
|
|
||||||
var c0 = array[i].color
|
|
||||||
var p1 = array[i+1].get_position()
|
|
||||||
var c1 = array[i+1].color
|
|
||||||
return c0 + (c1-c0) * (x-p0) / (p1-p0)
|
|
||||||
return array[array.size()-1].color
|
|
||||||
|
|
||||||
# get_color_in_shader
|
|
||||||
func gcis(color):
|
|
||||||
return "vec3(%.9f,%.9f,%.9f)" % [color.r, color.g, color.b]
|
|
||||||
|
|
||||||
func get_shader(name):
|
|
||||||
var array = get_sorted_cursors()
|
|
||||||
var shader
|
|
||||||
shader = "vec3 "+name+"(float x) {\n"
|
|
||||||
shader += " if (x < %.9f) {\n" % array[0].get_position()
|
|
||||||
shader += " return "+gcis(array[0].color)+";\n"
|
|
||||||
for i in range(array.size()-1):
|
|
||||||
var p0 = array[i].get_position()
|
|
||||||
var c0 = array[i].color
|
|
||||||
var p1mp0 = array[i+1].get_position()-p0
|
|
||||||
var c1mc0 = array[i+1].color-c0
|
|
||||||
if p1mp0 > 0:
|
|
||||||
shader += " } else if (x < %.9f) {\n" % array[i+1].get_position()
|
|
||||||
shader += " return %s+x*%s;\n" % [gcis(c0-c1mc0*(p0/p1mp0)), gcis(c1mc0/p1mp0)]
|
|
||||||
shader += " }\n"
|
|
||||||
shader += " return "+gcis(array[array.size()-1].color)+";\n"
|
|
||||||
shader += "}\n"
|
|
||||||
return shader
|
|
||||||
|
|
||||||
func update_shader():
|
func update_shader():
|
||||||
var shader
|
var shader
|
||||||
shader = "shader_type canvas_item;\n"
|
shader = "shader_type canvas_item;\n"
|
||||||
shader += get_shader("gradient")
|
shader += value.get_shader("gradient")
|
||||||
shader += "void fragment() { COLOR = vec4(gradient((UV.x-%.9f)*%.9f), 1.0); }" % [ float(GradientCursor.WIDTH)*0.5/float(rect_size.x), rect_size.x/(rect_size.x-GradientCursor.WIDTH) ]
|
shader += "void fragment() { COLOR = vec4(gradient(UV.x), 1.0); }"
|
||||||
$Gradient.material.shader.set_code(shader)
|
$Gradient.material.shader.set_code(shader)
|
||||||
emit_signal("updated")
|
emit_signal("updated", value)
|
||||||
|
|
||||||
func serialize():
|
|
||||||
var rv = []
|
|
||||||
for c in get_sorted_cursors():
|
|
||||||
rv.append({ pos= c.get_position(), r= c.color.r, g= c.color.g, b= c.color.b })
|
|
||||||
return rv
|
|
||||||
|
|
||||||
func deserialize(v):
|
|
||||||
for c in get_sorted_cursors():
|
|
||||||
remove_child(c)
|
|
||||||
c.free()
|
|
||||||
for i in v:
|
|
||||||
add_cursor(i.pos*(rect_size.x-GradientCursor.WIDTH), Color(i.r, i.g, i.b))
|
|
||||||
|
@ -26,10 +26,8 @@ anchor_left = 0.0
|
|||||||
anchor_top = 0.0
|
anchor_top = 0.0
|
||||||
anchor_right = 0.0
|
anchor_right = 0.0
|
||||||
anchor_bottom = 0.0
|
anchor_bottom = 0.0
|
||||||
margin_left = 24.0
|
margin_right = 120.0
|
||||||
margin_top = 14.0
|
margin_bottom = 30.0
|
||||||
margin_right = 144.0
|
|
||||||
margin_bottom = 44.0
|
|
||||||
rect_min_size = Vector2( 120, 30 )
|
rect_min_size = Vector2( 120, 30 )
|
||||||
rect_pivot_offset = Vector2( 0, 0 )
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
rect_clip_content = false
|
rect_clip_content = false
|
||||||
@ -57,7 +55,7 @@ mouse_default_cursor_shape = 0
|
|||||||
size_flags_horizontal = 1
|
size_flags_horizontal = 1
|
||||||
size_flags_vertical = 1
|
size_flags_vertical = 1
|
||||||
color = Color( 1, 1, 1, 1 )
|
color = Color( 1, 1, 1, 1 )
|
||||||
_sections_unfolded = [ "Material" ]
|
_sections_unfolded = [ "Material", "Rect" ]
|
||||||
|
|
||||||
[node name="Popup" type="Popup" parent="Gradient" index="0"]
|
[node name="Popup" type="Popup" parent="Gradient" index="0"]
|
||||||
|
|
||||||
|
@ -6,6 +6,8 @@ var configurations = {}
|
|||||||
var current = null
|
var current = null
|
||||||
onready var button = null
|
onready var button = null
|
||||||
|
|
||||||
|
const Types = preload("res://addons/material_maker/types/types.gd")
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
update_options()
|
update_options()
|
||||||
|
|
||||||
@ -41,10 +43,16 @@ func update_options():
|
|||||||
func add_linked(node, widget):
|
func add_linked(node, widget):
|
||||||
linked_widgets.append({ node=node, widget=widget })
|
linked_widgets.append({ node=node, widget=widget })
|
||||||
|
|
||||||
|
func duplicate_value(value):
|
||||||
|
if typeof(value) == TYPE_OBJECT and value.has_method("duplicate"):
|
||||||
|
value = value.duplicate()
|
||||||
|
return value
|
||||||
|
|
||||||
func apply_configuration(c):
|
func apply_configuration(c):
|
||||||
for w in configurations[c]:
|
for w in configurations[c]:
|
||||||
w.widget.set(WIDGETS[get_widget_type(w.widget)].value_attr , w.value)
|
var value = duplicate_value(w.value)
|
||||||
w.node.set(w.widget.name, w.value)
|
w.widget.set(WIDGETS[get_widget_type(w.widget)].value_attr, value)
|
||||||
|
w.node.set(w.widget.name, value)
|
||||||
var graph_node = get_parent()
|
var graph_node = get_parent()
|
||||||
while !(graph_node is GraphNode):
|
while !(graph_node is GraphNode):
|
||||||
graph_node = graph_node.get_parent()
|
graph_node = graph_node.get_parent()
|
||||||
@ -53,7 +61,7 @@ func apply_configuration(c):
|
|||||||
func do_update_configuration(name):
|
func do_update_configuration(name):
|
||||||
var configuration = []
|
var configuration = []
|
||||||
for w in linked_widgets:
|
for w in linked_widgets:
|
||||||
configuration.append({ node=w.node, widget=w.widget, value=w.node.get(w.widget.name) })
|
configuration.append({ node=w.node, widget=w.widget, value=duplicate_value(w.node.get(w.widget.name)) })
|
||||||
configurations[name] = configuration
|
configurations[name] = configuration
|
||||||
current = name
|
current = name
|
||||||
update_options()
|
update_options()
|
||||||
@ -90,7 +98,7 @@ func serialize():
|
|||||||
var c = configurations[k]
|
var c = configurations[k]
|
||||||
var data_configuration = []
|
var data_configuration = []
|
||||||
for e in c:
|
for e in c:
|
||||||
data_configuration.append({ node=e.node.name, widget=e.widget.name, value=e.value })
|
data_configuration.append({ node=e.node.name, widget=e.widget.name, value=Types.serialize_value(e.value) })
|
||||||
data_configurations[k] = data_configuration
|
data_configurations[k] = data_configuration
|
||||||
data.configurations = data_configurations
|
data.configurations = data_configurations
|
||||||
return data
|
return data
|
||||||
@ -113,7 +121,7 @@ func deserialize(data):
|
|||||||
if w.name == e.widget:
|
if w.name == e.widget:
|
||||||
widget = w
|
widget = w
|
||||||
break
|
break
|
||||||
configuration.append({ node=node, widget=widget, value=e.value })
|
configuration.append({ node=node, widget=widget, value=Types.deserialize_value(e.value) })
|
||||||
configurations[k] = configuration
|
configurations[k] = configuration
|
||||||
update_options()
|
update_options()
|
||||||
|
|
||||||
|
@ -11,6 +11,9 @@ func add_linked(node, widget):
|
|||||||
elif widget is ColorPickerButton:
|
elif widget is ColorPickerButton:
|
||||||
new_widget = ColorPickerButton.new()
|
new_widget = ColorPickerButton.new()
|
||||||
type = "ColorPickerButton"
|
type = "ColorPickerButton"
|
||||||
|
elif widget is Control && widget.filename == "res://addons/material_maker/widgets/gradient_editor.tscn":
|
||||||
|
new_widget = preload("res://addons/material_maker/widgets/gradient_editor.tscn").instance()
|
||||||
|
type = "GradientEditor"
|
||||||
elif widget is HSlider:
|
elif widget is HSlider:
|
||||||
new_widget = HSlider.new()
|
new_widget = HSlider.new()
|
||||||
type = "HSlider"
|
type = "HSlider"
|
||||||
@ -46,6 +49,11 @@ func _on_item_selected(i):
|
|||||||
l.widget.selected = i
|
l.widget.selected = i
|
||||||
l.node.set(l.widget.name, i)
|
l.node.set(l.widget.name, i)
|
||||||
|
|
||||||
|
func _on_gradient_updated(i):
|
||||||
|
for l in linked_widgets:
|
||||||
|
l.widget.value = i
|
||||||
|
l.node.set(l.widget.name, i)
|
||||||
|
|
||||||
func serialize():
|
func serialize():
|
||||||
var data = .serialize()
|
var data = .serialize()
|
||||||
data.type = "linked_control"
|
data.type = "linked_control"
|
||||||
|
@ -13,7 +13,8 @@ const WIDGETS = {
|
|||||||
SpinBox={ attrs=[ "min_value", "max_value", "step", "value" ], value_attr="value", sig="value_changed", sig_handler="_on_value_changed" },
|
SpinBox={ attrs=[ "min_value", "max_value", "step", "value" ], value_attr="value", sig="value_changed", sig_handler="_on_value_changed" },
|
||||||
HSlider={ attrs=[ "min_value", "max_value", "step", "value" ], value_attr="value", sig="value_changed", sig_handler="_on_value_changed" },
|
HSlider={ attrs=[ "min_value", "max_value", "step", "value" ], value_attr="value", sig="value_changed", sig_handler="_on_value_changed" },
|
||||||
ColorPickerButton={ attrs=[ "edit_alpha", "color" ], value_attr="color", sig="color_changed", sig_handler="_on_color_changed" },
|
ColorPickerButton={ attrs=[ "edit_alpha", "color" ], value_attr="color", sig="color_changed", sig_handler="_on_color_changed" },
|
||||||
OptionButton={ attrs=[ "selected" ], value_attr="selected", sig="item_selected", sig_handler="_on_item_selected" }
|
OptionButton={ attrs=[ "selected" ], value_attr="selected", sig="item_selected", sig_handler="_on_item_selected" },
|
||||||
|
GradientEditor={ attrs=[ "value" ], value_attr="value", sig="updated", sig_handler="_on_gradient_updated" }
|
||||||
}
|
}
|
||||||
|
|
||||||
func get_widget_type(widget):
|
func get_widget_type(widget):
|
||||||
@ -21,6 +22,10 @@ func get_widget_type(widget):
|
|||||||
return "SpinBox"
|
return "SpinBox"
|
||||||
elif widget is ColorPickerButton:
|
elif widget is ColorPickerButton:
|
||||||
return "ColorPickerButton"
|
return "ColorPickerButton"
|
||||||
|
elif widget is Control && widget.filename == "res://addons/material_maker/widgets/gradient_editor.tscn":
|
||||||
|
return "GradientEditor"
|
||||||
|
elif widget is HSlider:
|
||||||
|
return "HSlider"
|
||||||
elif widget is OptionButton:
|
elif widget is OptionButton:
|
||||||
return "OptionButton"
|
return "OptionButton"
|
||||||
else:
|
else:
|
||||||
|
Loading…
Reference in New Issue
Block a user