Added the curve editor and polygon editor from Material Maker. I only fixed compile so far.

This commit is contained in:
Relintai 2021-10-20 11:54:54 +02:00
parent df1a1c59a2
commit c082ee9a60
23 changed files with 968 additions and 0 deletions

View File

@ -0,0 +1,98 @@
tool
extends MMNode
class Point:
var p : Vector2
var ls : float
var rs : float
func _init(x : float, y : float, nls : float, nrs : float) -> void:
p = Vector2(x, y)
ls = nls
rs = nrs
var points = [ Point.new(0.0, 0.0, 0.0, 1.0), Point.new(1.0, 1.0, 1.0, 0.0) ]
func to_string() -> String:
var rv = PoolStringArray()
for p in points:
rv.append("("+str(p.x)+","+str(p.y)+","+str(p.ls)+","+str(p.rs)+")")
return rv.join(",")
func clear() -> void:
points.clear()
func add_point(x : float, y : float, ls : float = INF, rs : float = INF) -> void:
for i in points.size():
if x < points[i].p.x:
if ls == INF:
ls == 0
if rs == INF:
rs == 0
points.insert(i, Point.new(x, y, ls, rs))
return
points.append(Point.new(x, y, ls, rs))
func remove_point(index : int) -> bool:
if index <= 0 or index >= points.size() - 1:
return false
else:
points.remove(index)
return true
func get_point_count() -> int:
return points.size()
func set_point(i : int, v : Point) -> void:
points[i] = v
func get_shader_params(name) -> Dictionary:
var rv = {}
for i in range(points.size()):
rv["p_"+name+"_"+str(i)+"_x"] = points[i].p.x
rv["p_"+name+"_"+str(i)+"_y"] = points[i].p.y
rv["p_"+name+"_"+str(i)+"_ls"] = points[i].ls
rv["p_"+name+"_"+str(i)+"_rs"] = points[i].rs
return rv
func get_shader(name) -> String:
var shader
shader = "float "+name+"_curve_fct(float x) {\n"
for i in range(points.size()-1):
if i < points.size()-2:
shader += "if (x <= p_"+name+"_"+str(i+1)+"_x) "
shader += "{\n"
shader += "float dx = x - p_"+name+"_"+str(i)+"_x;\n"
shader += "float d = p_"+name+"_"+str(i+1)+"_x - p_"+name+"_"+str(i)+"_x;\n"
shader += "float t = dx/d;\n"
shader += "float omt = (1.0 - t);\n"
shader += "float omt2 = omt * omt;\n"
shader += "float omt3 = omt2 * omt;\n"
shader += "float t2 = t * t;\n"
shader += "float t3 = t2 * t;\n"
shader += "d /= 3.0;\n"
shader += "float y1 = p_"+name+"_"+str(i)+"_y;\n"
shader += "float yac = p_"+name+"_"+str(i)+"_y + d*p_"+name+"_"+str(i)+"_rs;\n"
shader += "float ybc = p_"+name+"_"+str(i+1)+"_y - d*p_"+name+"_"+str(i+1)+"_ls;\n"
shader += "float y2 = p_"+name+"_"+str(i+1)+"_y;\n"
shader += "return y1*omt3 + yac*omt2*t*3.0 + ybc*omt*t2*3.0 + y2*t3;\n"
shader += "}\n"
shader += "}\n"
return shader
func serialize() -> Dictionary:
var rv = []
for p in points:
rv.append({ x=p.p.x, y=p.p.y, ls=p.ls, rs=p.rs })
return { type="Curve", points=rv }
func deserialize(v) -> void:
clear()
if typeof(v) == TYPE_DICTIONARY and v.has("type") and v.type == "Curve":
for p in v.points:
add_point(p.x, p.y, p.ls, p.rs)
elif typeof(v) == TYPE_OBJECT and v.get_script() == get_script():
clear()
for p in v.points:
add_point(p.p.x, p.p.y, p.ls, p.rs)
else:
print("Cannot deserialize curve")

View File

@ -0,0 +1,71 @@
tool
extends MMNode
var points : Array = [Vector2(0.2, 0.2), Vector2(0.7, 0.4), Vector2(0.4, 0.7)]
func to_string() -> String:
var rv = PoolStringArray()
for p in points:
rv.append("("+str(p.x)+","+str(p.y)+")")
return rv.join(",")
func clear() -> void:
points.clear()
func add_point(x : float, y : float, closed : bool = true) -> void:
var p : Vector2 = Vector2(x, y)
var points_count = points.size()
if points_count < 3:
points.append(p)
return
var min_length : float = (p-Geometry.get_closest_point_to_segment_2d(p, points[0], points[points_count-1])).length()
var insert_point = 0
for i in points_count-1:
var length = (p-Geometry.get_closest_point_to_segment_2d(p, points[i], points[i+1])).length()
if length < min_length:
min_length = length
insert_point = i+1
if !closed and insert_point == 0 and (points[0]-p).length() > (points[points_count-1]-p).length():
insert_point = points_count
points.insert(insert_point, p)
func remove_point(index : int) -> bool:
var s = points.size()
if s < 4 or index < 0 or index >= s:
return false
else:
points.remove(index)
return true
func get_point_count() -> int:
return points.size()
func get_point(i : int) -> Vector2:
return points[i]
func set_point(i : int, v : Vector2) -> void:
points[i] = v
func get_shader() -> String:
var elements : PoolStringArray = PoolStringArray()
for p in points:
elements.append("vec2(%.9f, %.9f)" % [p.x, p.y])
return "{"+elements.join(", ")+"}"
func serialize() -> Dictionary:
var rv = []
for p in points:
rv.append({ x=p.x, y=p.y })
return { type="Polygon", points=rv }
func deserialize(v) -> void:
clear()
if typeof(v) == TYPE_DICTIONARY and v.has("type") and v.type == "Polygon":
for p in v.points:
points.push_back(Vector2(p.x, p.y))
elif typeof(v) == TYPE_OBJECT and v.get_script() == get_script():
clear()
for p in v.points:
points.push_back(Vector2(p.x, p.y))
else:
print("Cannot deserialize polygon")

View File

@ -0,0 +1,66 @@
extends Control
var MMCurve = preload("res://addons/mat_maker_gd/nodes/bases/curve_base.gd")
var moving : bool = false
var min_x : float
var max_x : float
var min_y : float
var max_y : float
const OFFSET : Vector2 = Vector2(3, 3)
signal moved(index)
signal removed(index)
func _ready():
pass # Replace with function body.
func _draw():
var current_theme : Theme = get_node("/root/MainWindow").theme
var color : Color = current_theme.get_color("font_color", "Label")
for c in get_children():
if c.visible:
draw_line(OFFSET, c.rect_position+OFFSET, color)
draw_rect(Rect2(0, 0, 7, 7), color)
#p : MMCurve.Point
func initialize(p) -> void:
rect_position = get_parent().transform_point(p.p)-OFFSET
if p.ls != INF:
$LeftSlope.rect_position = $LeftSlope.distance*(get_parent().rect_size*Vector2(1.0, -p.ls)).normalized()
if p.rs != INF:
$RightSlope.rect_position = $RightSlope.distance*(get_parent().rect_size*Vector2(1.0, -p.rs)).normalized()
func set_constraint(x : float, X : float, y : float, Y : float) -> void:
min_x = x
max_x = X
min_y = y
max_y = Y
func _on_ControlPoint_gui_input(event):
if event is InputEventMouseButton:
if event.button_index == BUTTON_LEFT:
if event.pressed:
moving = true
else:
moving = false
get_parent().update_controls()
elif event.button_index == BUTTON_RIGHT and event.pressed:
emit_signal("removed", get_index())
elif moving and event is InputEventMouseMotion:
rect_position += event.relative
if rect_position.x < min_x:
rect_position.x = min_x
elif rect_position.x > max_x:
rect_position.x = max_x
if rect_position.y < min_y:
rect_position.y = min_y
elif rect_position.y > max_y:
rect_position.y = max_y
emit_signal("moved", get_index())
func update_tangents() -> void:
update()
emit_signal("moved", get_index())

View File

@ -0,0 +1,39 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://material_maker/widgets/curve_edit/slope_point.gd" type="Script" id=1]
[ext_resource path="res://material_maker/widgets/curve_edit/control_point.gd" type="Script" id=2]
[node name="ControlPoint" type="Control"]
margin_left = 56.9864
margin_top = 33.8615
margin_right = 63.9864
margin_bottom = 40.8615
rect_min_size = Vector2( 7, 7 )
script = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="LeftSlope" type="Control" parent="."]
margin_left = -18.5235
margin_right = -11.5235
margin_bottom = 7.0
rect_min_size = Vector2( 7, 7 )
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
distance = -30.0
[node name="RightSlope" type="Control" parent="."]
margin_left = 15.6919
margin_right = 22.6919
margin_bottom = 7.0
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
distance = 30.0
[connection signal="gui_input" from="." to="." method="_on_ControlPoint_gui_input"]
[connection signal="gui_input" from="LeftSlope" to="LeftSlope" method="_on_ControlPoint_gui_input"]
[connection signal="gui_input" from="RightSlope" to="RightSlope" method="_on_ControlPoint_gui_input"]

View File

@ -0,0 +1,32 @@
extends WindowDialog
var MMCurve = preload("res://addons/mat_maker_gd/nodes/bases/curve_base.gd")
var previous_value
signal curve_changed(curve)
signal return_curve(curve)
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
func _on_CurveDialog_popup_hide():
emit_signal("return_curve", null)
func _on_OK_pressed():
emit_signal("return_curve", $VBoxContainer/EditorContainer/CurveEditor.curve)
func _on_Cancel_pressed():
emit_signal("return_curve", previous_value)
func edit_curve(curve) -> Array:
previous_value = curve.duplicate()
$VBoxContainer/EditorContainer/CurveEditor.set_curve(curve)
popup_centered()
var result = yield(self, "return_curve")
queue_free()
return result
func _on_CurveEditor_value_changed(value):
emit_signal("curve_changed", value)

View File

@ -0,0 +1,81 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://material_maker/widgets/curve_edit/curve_editor.tscn" type="PackedScene" id=1]
[ext_resource path="res://material_maker/widgets/curve_edit/curve_dialog.gd" type="Script" id=2]
[node name="CurveDialog" type="WindowDialog"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 307.0
margin_top = 151.0
margin_right = -347.0
margin_bottom = -174.0
window_title = "Edit curve"
script = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="VBoxContainer" type="VBoxContainer" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 5.0
margin_top = 5.0
margin_right = -5.0
margin_bottom = -5.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="EditorContainer" type="MarginContainer" parent="VBoxContainer"]
margin_right = 616.0
margin_bottom = 353.0
rect_clip_content = true
size_flags_horizontal = 3
size_flags_vertical = 3
custom_constants/margin_right = 4
custom_constants/margin_top = 4
custom_constants/margin_left = 4
custom_constants/margin_bottom = 4
[node name="CurveEditor" parent="VBoxContainer/EditorContainer" instance=ExtResource( 1 )]
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 4.0
margin_top = 4.0
margin_right = 612.0
margin_bottom = 349.0
size_flags_vertical = 3
[node name="HSeparator" type="HSeparator" parent="VBoxContainer"]
margin_top = 357.0
margin_right = 616.0
margin_bottom = 361.0
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"]
margin_top = 365.0
margin_right = 616.0
margin_bottom = 385.0
[node name="Control" type="Control" parent="VBoxContainer/HBoxContainer"]
margin_right = 488.0
margin_bottom = 20.0
size_flags_horizontal = 3
[node name="OK" type="Button" parent="VBoxContainer/HBoxContainer"]
margin_left = 492.0
margin_right = 552.0
margin_bottom = 20.0
rect_min_size = Vector2( 60, 0 )
text = "OK"
[node name="Cancel" type="Button" parent="VBoxContainer/HBoxContainer"]
margin_left = 556.0
margin_right = 616.0
margin_bottom = 20.0
rect_min_size = Vector2( 60, 0 )
text = "Cancel"
[connection signal="popup_hide" from="." to="." method="_on_CurveDialog_popup_hide"]
[connection signal="value_changed" from="VBoxContainer/EditorContainer/CurveEditor" to="." method="_on_CurveEditor_value_changed"]
[connection signal="pressed" from="VBoxContainer/HBoxContainer/OK" to="." method="_on_OK_pressed"]
[connection signal="pressed" from="VBoxContainer/HBoxContainer/Cancel" to="." method="_on_Cancel_pressed"]

View File

@ -0,0 +1,32 @@
extends Control
var MMCurve = preload("res://addons/mat_maker_gd/nodes/bases/curve_base.gd")
var value = null setget set_value
signal updated(curve)
func _ready():
set_value(MMCurve.new())
func set_value(v) -> void:
value = v.duplicate()
$CurveView.curve = value
$CurveView.update()
func _on_CurveEdit_pressed():
var dialog = preload("res://addons/mat_maker_gd/widgets/curve_edit/curve_dialog.tscn").instance()
add_child(dialog)
dialog.connect("curve_changed", self, "on_value_changed")
var new_curve = dialog.edit_curve(value)
while new_curve is GDScriptFunctionState:
new_curve = yield(new_curve, "completed")
if new_curve != null:
set_value(new_curve)
emit_signal("updated", new_curve.duplicate())
func on_value_changed(v) -> void:
set_value(v)
emit_signal("updated", v.duplicate())

View File

@ -0,0 +1,21 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://material_maker/widgets/curve_edit/curve_edit.gd" type="Script" id=1]
[ext_resource path="res://material_maker/widgets/curve_edit/curve_view.tscn" type="PackedScene" id=2]
[node name="CurveEdit" type="Button"]
anchor_left = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -1280.0
margin_right = -1220.0
margin_bottom = -700.0
rect_min_size = Vector2( 60, 20 )
focus_mode = 1
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="CurveView" parent="." instance=ExtResource( 2 )]
[connection signal="pressed" from="." to="." method="_on_CurveEdit_pressed"]

View File

@ -0,0 +1,64 @@
extends "res://addons/mat_maker_gd/widgets/curve_edit/curve_view.gd"
signal value_changed(value)
func _ready():
update_controls()
func set_curve(c) -> void:
curve = c
update()
update_controls()
func update_controls() -> void:
for c in get_children():
c.queue_free()
for i in curve.points.size():
var p = curve.points[i]
var control_point = preload("res://addons/mat_maker_gd/widgets/curve_edit/control_point.tscn").instance()
add_child(control_point)
control_point.initialize(p)
control_point.rect_position = transform_point(p.p)-control_point.OFFSET
if i == 0 or i == curve.points.size()-1:
control_point.set_constraint(control_point.rect_position.x, control_point.rect_position.x, -control_point.OFFSET.y, rect_size.y-control_point.OFFSET.y)
if i == 0:
control_point.get_child(0).visible = false
else:
control_point.get_child(1).visible = false
else:
var min_x = transform_point(curve.points[i-1].p).x+1
var max_x = transform_point(curve.points[i+1].p).x-1
control_point.set_constraint(min_x, max_x, -control_point.OFFSET.y, rect_size.y-control_point.OFFSET.y)
control_point.connect("moved", self, "_on_ControlPoint_moved")
control_point.connect("removed", self, "_on_ControlPoint_removed")
emit_signal("value_changed", curve)
func _on_ControlPoint_moved(index):
var control_point = get_child(index)
curve.points[index].p = reverse_transform_point(control_point.rect_position+control_point.OFFSET)
if control_point.has_node("LeftSlope"):
var slope_vector = control_point.get_node("LeftSlope").rect_position/rect_size
if slope_vector.x != 0:
curve.points[index].ls = -slope_vector.y / slope_vector.x
if control_point.has_node("RightSlope"):
var slope_vector = control_point.get_node("RightSlope").rect_position/rect_size
if slope_vector.x != 0:
curve.points[index].rs = -slope_vector.y / slope_vector.x
update()
emit_signal("value_changed", curve)
func _on_ControlPoint_removed(index):
if curve.remove_point(index):
update()
update_controls()
func _on_CurveEditor_gui_input(event):
if event is InputEventMouseButton:
if event.button_index == BUTTON_LEFT and event.doubleclick:
var new_point_position = reverse_transform_point(get_local_mouse_position())
curve.add_point(new_point_position.x, new_point_position.y, 0.0, 0.0)
update_controls()
func _on_resize() -> void:
._on_resize()
update_controls()

View File

@ -0,0 +1,13 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://material_maker/widgets/curve_edit/curve_view.tscn" type="PackedScene" id=1]
[ext_resource path="res://material_maker/widgets/curve_edit/curve_editor.gd" type="Script" id=2]
[node name="CurveEditor" instance=ExtResource( 1 )]
margin_left = 10.0
margin_top = 10.0
margin_right = -10.0
margin_bottom = -10.0
mouse_filter = 0
script = ExtResource( 2 )
[connection signal="gui_input" from="." to="." method="_on_CurveEditor_gui_input"]

View File

@ -0,0 +1,53 @@
tool
extends Control
var MMCurve = preload("res://addons/mat_maker_gd/nodes/bases/curve_base.gd")
export var show_axes : bool = false
var curve #: MMCurve
func _ready() -> void:
curve = MMCurve.new()
connect("resized", self, "_on_resize")
update()
func transform_point(p : Vector2) -> Vector2:
return (Vector2(0.0, 1.0)+Vector2(1.0, -1.0)*p)*rect_size
func reverse_transform_point(p : Vector2) -> Vector2:
return Vector2(0.0, 1.0)+Vector2(1.0, -1.0)*p/rect_size
func _draw():
var current_theme : Theme = get_node("/root/MainWindow").theme
var bg = current_theme.get_stylebox("panel", "Panel").bg_color
var fg = current_theme.get_color("font_color", "Label")
var axes_color : Color = bg.linear_interpolate(fg, 0.25)
var curve_color : Color = bg.linear_interpolate(fg, 0.75)
if show_axes:
for i in range(5):
var p = transform_point(0.25*Vector2(i, i))
draw_line(Vector2(p.x, 0), Vector2(p.x, rect_size.y-1), axes_color)
draw_line(Vector2(0, p.y), Vector2(rect_size.x-1, p.y), axes_color)
for i in range(curve.points.size()-1):
var p1 = curve.points[i].p
var p2 = curve.points[i+1].p
var d = (p2.x-p1.x)/3.0
var yac = p1.y+d*curve.points[i].rs
var ybc = p2.y-d*curve.points[i+1].ls
var p = transform_point(p1)
var count : int = max(1, int((transform_point(p2).x-p.x/5.0)))
for tt in range(count):
var t = (tt+1.0)/count
var omt = (1.0 - t)
var omt2 = omt * omt
var omt3 = omt2 * omt
var t2 = t * t
var t3 = t2 * t
var x = p1.x+(p2.x-p1.x)*t
var np = transform_point(Vector2(x, p1.y*omt3 + yac*omt2*t*3.0 + ybc*omt*t2*3.0 + p2.y*t3))
draw_line(p, np, curve_color)
p = np
func _on_resize() -> void:
update()

View File

@ -0,0 +1,16 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://material_maker/widgets/curve_edit/curve_view.gd" type="Script" id=1]
[node name="CurveView" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 4.0
margin_top = 4.0
margin_right = -4.0
margin_bottom = -4.0
mouse_filter = 2
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}

View File

@ -0,0 +1,44 @@
extends Control
export var distance : float
var moving = false
const OFFSET = -Vector2(0, 0)
func _ready():
pass # Replace with function body.
func _draw():
var current_theme : Theme = get_node("/root/MainWindow").theme
var color : Color = current_theme.get_color("font_color", "Label")
draw_circle(Vector2(3.0, 3.0), 3.0, color)
func _on_ControlPoint_gui_input(event):
if event is InputEventMouseButton:
if event.button_index == BUTTON_LEFT:
if event.pressed:
if event.doubleclick:
var parent = get_parent()
var vector : Vector2
if get_index() == 0:
vector = parent.rect_position-parent.get_parent().get_child(parent.get_index()-1).rect_position
else:
vector = parent.get_parent().get_child(parent.get_index()+1).rect_position-parent.rect_position
vector = distance*vector.normalized()
rect_position = vector-OFFSET
if event.control:
get_parent().get_child(1-get_index()).rect_position = -vector-OFFSET
get_parent().update_tangents()
else:
moving = true
else:
moving = false
elif moving and event is InputEventMouseMotion:
var vector = get_global_mouse_position()-get_parent().get_global_rect().position+OFFSET
vector *= sign(vector.x)
vector = distance*vector.normalized()
rect_position = vector-OFFSET
if event.control:
get_parent().get_child(1-get_index()).rect_position = -vector-OFFSET
get_parent().update_tangents()

View File

@ -0,0 +1,30 @@
extends Control
var moving : bool = false
const OFFSET : Vector2 = Vector2(3, 3)
signal moved(index)
signal removed(index)
func _draw():
var current_theme : Theme = get_node("/root/MainWindow").theme
var color : Color = current_theme.get_color("font_color", "Label")
draw_rect(Rect2(0, 0, 7, 7), color)
func initialize(p : Vector2) -> void:
rect_position = get_parent().transform_point(p)-OFFSET
func _on_ControlPoint_gui_input(event):
if event is InputEventMouseButton:
if event.button_index == BUTTON_LEFT:
if event.pressed:
moving = true
else:
moving = false
get_parent().update_controls()
elif event.button_index == BUTTON_RIGHT and event.pressed:
emit_signal("removed", get_index())
elif moving and event is InputEventMouseMotion:
rect_position += event.relative
emit_signal("moved", get_index())

View File

@ -0,0 +1,15 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://material_maker/widgets/polygon_edit/control_point.gd" type="Script" id=1]
[node name="ControlPoint" type="Control"]
margin_left = 56.9864
margin_top = 33.8615
margin_right = 63.9864
margin_bottom = 40.8615
rect_min_size = Vector2( 7, 7 )
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[connection signal="gui_input" from="." to="." method="_on_ControlPoint_gui_input"]

View File

@ -0,0 +1,32 @@
extends WindowDialog
export var closed : bool = true setget set_closed
var previous_value
signal polygon_changed(polygon)
signal return_polygon(polygon)
func set_closed(c : bool = true):
closed = c
window_title = "Edit polygon" if closed else "Edit polyline"
$VBoxContainer/EditorContainer/PolygonEditor.set_closed(closed)
func _on_CurveDialog_popup_hide():
emit_signal("return_polygon", null)
func _on_OK_pressed():
emit_signal("return_polygon", $VBoxContainer/EditorContainer/PolygonEditor.polygon)
func _on_Cancel_pressed():
emit_signal("return_polygon", previous_value)
func edit_polygon(polygon) -> Array:
previous_value = polygon.duplicate()
$VBoxContainer/EditorContainer/PolygonEditor.set_polygon(polygon)
popup_centered()
var result = yield(self, "return_polygon")
queue_free()
return result
func _on_PolygonEditor_value_changed(value):
emit_signal("polygon_changed", value)

View File

@ -0,0 +1,81 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://material_maker/widgets/polygon_edit/polygon_editor.tscn" type="PackedScene" id=1]
[ext_resource path="res://material_maker/widgets/polygon_edit/polygon_dialog.gd" type="Script" id=2]
[node name="PolygonDialog" type="WindowDialog"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 307.0
margin_top = 151.0
margin_right = -508.0
margin_bottom = -70.0
window_title = "Edit polygon"
script = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="VBoxContainer" type="VBoxContainer" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 5.0
margin_top = 5.0
margin_right = -5.0
margin_bottom = -5.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="EditorContainer" type="MarginContainer" parent="VBoxContainer"]
margin_right = 455.0
margin_bottom = 457.0
rect_clip_content = true
size_flags_horizontal = 3
size_flags_vertical = 3
custom_constants/margin_right = 4
custom_constants/margin_top = 4
custom_constants/margin_left = 4
custom_constants/margin_bottom = 4
[node name="PolygonEditor" parent="VBoxContainer/EditorContainer" instance=ExtResource( 1 )]
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 4.0
margin_top = 4.0
margin_right = 451.0
margin_bottom = 453.0
[node name="HSeparator" type="HSeparator" parent="VBoxContainer"]
margin_top = 461.0
margin_right = 455.0
margin_bottom = 465.0
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"]
margin_top = 469.0
margin_right = 455.0
margin_bottom = 489.0
[node name="Control" type="Control" parent="VBoxContainer/HBoxContainer"]
margin_right = 327.0
margin_bottom = 20.0
size_flags_horizontal = 3
[node name="OK" type="Button" parent="VBoxContainer/HBoxContainer"]
margin_left = 331.0
margin_right = 391.0
margin_bottom = 20.0
rect_min_size = Vector2( 60, 0 )
text = "OK"
[node name="Cancel" type="Button" parent="VBoxContainer/HBoxContainer"]
margin_left = 395.0
margin_right = 455.0
margin_bottom = 20.0
rect_min_size = Vector2( 60, 0 )
text = "Cancel"
[connection signal="popup_hide" from="." to="." method="_on_CurveDialog_popup_hide"]
[connection signal="value_changed" from="VBoxContainer/EditorContainer/PolygonEditor" to="." method="_on_PolygonEditor_value_changed"]
[connection signal="pressed" from="VBoxContainer/HBoxContainer/OK" to="." method="_on_OK_pressed"]
[connection signal="pressed" from="VBoxContainer/HBoxContainer/Cancel" to="." method="_on_Cancel_pressed"]

View File

@ -0,0 +1,38 @@
extends Control
var MMPolygon = preload("res://addons/mat_maker_gd/nodes/bases/polygon_base.gd")
export var closed : bool = true setget set_closed
var value = null setget set_value
signal updated(polygon)
func set_closed(c : bool = true):
closed = c
$PolygonView.set_closed(c)
func _ready():
set_value(MMPolygon.new())
func set_value(v) -> void:
value = v.duplicate()
$PolygonView.polygon = value
$PolygonView.update()
func _on_PolygonEdit_pressed():
var dialog = preload("res://addons/mat_maker_gd/widgets/polygon_edit/polygon_dialog.tscn").instance()
dialog.set_closed(closed)
add_child(dialog)
dialog.connect("polygon_changed", self, "on_value_changed")
var new_polygon = dialog.edit_polygon(value)
while new_polygon is GDScriptFunctionState:
new_polygon = yield(new_polygon, "completed")
if new_polygon != null:
set_value(new_polygon)
emit_signal("updated", new_polygon.duplicate())
func on_value_changed(v) -> void:
set_value(v)
emit_signal("updated", v.duplicate())

View File

@ -0,0 +1,26 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://material_maker/widgets/polygon_edit/polygon_edit.gd" type="Script" id=1]
[ext_resource path="res://material_maker/widgets/polygon_edit/polygon_view.tscn" type="PackedScene" id=2]
[node name="PolygonEdit" type="Button"]
anchor_left = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = -1280.0
margin_right = -1248.0
margin_bottom = -688.0
rect_min_size = Vector2( 32, 32 )
focus_mode = 1
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="PolygonView" parent="." instance=ExtResource( 2 )]
anchor_right = 1.0
anchor_bottom = 1.0
margin_right = 0.0
margin_bottom = 0.0
[connection signal="pressed" from="." to="." method="_on_PolygonEdit_pressed"]

View File

@ -0,0 +1,46 @@
extends "res://addons/mat_maker_gd/widgets/polygon_edit/polygon_view.gd"
signal value_changed(value)
func _ready():
update_controls()
func set_polygon(p) -> void:
polygon = p
update()
update_controls()
func update_controls() -> void:
for c in get_children():
c.queue_free()
for i in polygon.points.size():
var p = polygon.points[i]
var control_point = preload("res://addons/mat_maker_gd/widgets/polygon_edit/control_point.tscn").instance()
add_child(control_point)
control_point.initialize(p)
control_point.rect_position = transform_point(p)-control_point.OFFSET
control_point.connect("moved", self, "_on_ControlPoint_moved")
control_point.connect("removed", self, "_on_ControlPoint_removed")
emit_signal("value_changed", polygon)
func _on_ControlPoint_moved(index):
var control_point = get_child(index)
polygon.points[index] = reverse_transform_point(control_point.rect_position+control_point.OFFSET)
update()
emit_signal("value_changed", polygon)
func _on_ControlPoint_removed(index):
if polygon.remove_point(index):
update()
update_controls()
func _on_PolygonEditor_gui_input(event):
if event is InputEventMouseButton:
if event.button_index == BUTTON_LEFT and event.doubleclick:
var new_point_position = reverse_transform_point(get_local_mouse_position())
polygon.add_point(new_point_position.x, new_point_position.y, closed)
update_controls()
func _on_resize() -> void:
._on_resize()
update_controls()

View File

@ -0,0 +1,14 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://material_maker/widgets/curve_edit/curve_view.tscn" type="PackedScene" id=1]
[ext_resource path="res://material_maker/widgets/polygon_edit/polygon_editor.gd" type="Script" id=2]
[node name="PolygonEditor" instance=ExtResource( 1 )]
margin_left = 10.0
margin_top = 10.0
margin_right = -10.0
margin_bottom = -10.0
mouse_filter = 0
script = ExtResource( 2 )
[connection signal="gui_input" from="." to="." method="_on_PolygonEditor_gui_input"]

View File

@ -0,0 +1,44 @@
tool
extends Control
var MMPolygon = preload("res://addons/mat_maker_gd/nodes/bases/polygon_base.gd")
var polygon #: MMPolygon
var draw_size : Vector2 = Vector2(1, 1)
var draw_offset : Vector2 = Vector2(0, 0)
var closed : bool = true
func set_closed(c : bool = true):
closed = c
update()
func _ready() -> void:
polygon = MMPolygon.new()
connect("resized", self, "_on_resize")
_on_resize()
func transform_point(p : Vector2) -> Vector2:
return draw_offset+p*draw_size
func reverse_transform_point(p : Vector2) -> Vector2:
return (p-draw_offset)/draw_size
func _draw():
var current_theme : Theme = get_node("/root/MainWindow").theme
var bg = current_theme.get_stylebox("panel", "Panel").bg_color
var fg = current_theme.get_color("font_color", "Label")
var axes_color : Color = bg.linear_interpolate(fg, 0.25)
var curve_color : Color = bg.linear_interpolate(fg, 0.75)
draw_rect(Rect2(draw_offset, draw_size), axes_color, false)
var tp : Vector2 = transform_point(polygon.points[polygon.points.size()-1 if closed else 0])
for p in polygon.points:
var tnp = transform_point(p)
draw_line(tp, tnp, curve_color)
tp = tnp
func _on_resize() -> void:
var ds : float = min(rect_size.x, rect_size.y)
draw_size = Vector2(ds, ds)
draw_offset = 0.5*(rect_size-draw_size)
update()

View File

@ -0,0 +1,12 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://material_maker/widgets/polygon_edit/polygon_view.gd" type="Script" id=1]
[node name="PolygonView" type="Control"]
margin_right = 64.0
margin_bottom = 64.0
mouse_filter = 2
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}