Skip to content

Commit ea8b64c

Browse files
committed
Enable drag-and-drop to arrange remote/ios params
1 parent 3b18267 commit ea8b64c

File tree

8 files changed

+274
-69
lines changed

8 files changed

+274
-69
lines changed

material_maker/nodes/ios/ios.gd

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,6 @@ func on_parameter_changed(p, _v) -> void:
1313
if p == "__update_all__":
1414
update_node.call_deferred()
1515

16-
func update_up_down_buttons() -> void:
17-
for c in get_children():
18-
if ! (c is Button):
19-
c.update_up_down_button()
20-
2116
func update_node() -> void:
2217
for c in get_children():
2318
remove_child(c)
@@ -42,7 +37,6 @@ func update_node() -> void:
4237
add_child(add_button)
4338
add_button.connect("pressed", Callable(generator, "add_port"))
4439
set_slot(get_child_count()-1, false, 0, color, false, 0, color)
45-
update_up_down_buttons()
4640

4741
func command(command_name : String, command_parameters : Array, update_node : bool = false):
4842
var parent_generator = generator.get_parent().get_parent()

material_maker/nodes/ios/ios.tscn

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[gd_scene load_steps=2 format=3 uid="uid://d1j47uuqrti7e"]
22

3-
[ext_resource type="Script" path="res://material_maker/nodes/ios/ios.gd" id="1"]
3+
[ext_resource type="Script" uid="uid://da5v0wx0fxv65" path="res://material_maker/nodes/ios/ios.gd" id="1"]
44

55
[node name="IOs" type="GraphNode"]
66
offset_right = 32.0

material_maker/nodes/ios/port.gd

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ func _ready() -> void:
55
for tn in mm_io_types.type_names:
66
var t = mm_io_types.types[tn]
77
$Type.add_item(t.label)
8+
$Drag.icon = get_theme_icon("arrow_updown", "MM_Icons")
9+
$Drag.set_drag_forwarding(_row_drag_data, _row_can_drop_data, _row_drop_data)
810

911
func set_model_data(data, remaining_group_size = 0) -> int:
1012
$Name.set_text(data.name if data.has("name") else "")
@@ -21,13 +23,6 @@ func set_model_data(data, remaining_group_size = 0) -> int:
2123
$PortGroupButton.set_state(1)
2224
return int(max(remaining_group_size-1, 0))
2325

24-
func update_up_down_button() -> void:
25-
var parent = get_parent()
26-
if parent == null:
27-
return
28-
$Up.disabled = (get_index() == 0)
29-
$Down.disabled = (get_index() == get_parent().get_child_count()-2)
30-
3126
func _on_Name_label_changed(new_label) -> void:
3227
get_parent().command("set_port_name", [get_index(), new_label])
3328

@@ -43,10 +38,52 @@ func _on_Description_descriptions_changed(short_description, long_description):
4338
func _on_Delete_pressed() -> void:
4439
get_parent().command("delete_port", [get_index()])
4540

46-
func _on_Up_pressed() -> void:
47-
get_parent().command("swap_ports", [get_index(), get_index()-1])
41+
func _row_drag_data(_at_position: Vector2) -> Variant:
42+
var bg_panel := PanelContainer.new()
43+
bg_panel.theme_type_variation = "MM_PanelBackground"
44+
45+
var panel_stylebox := get_theme_stylebox("panel", "GraphNode").duplicate()
46+
panel_stylebox.set_corner_radius_all(5)
47+
panel_stylebox.set_border_width_all(0)
48+
panel_stylebox.set_expand_margin_all(0)
49+
panel_stylebox.set_content_margin_all(4.0)
50+
panel_stylebox.bg_color.a = 0.8
51+
bg_panel.add_theme_stylebox_override("panel", panel_stylebox)
52+
53+
var row : HBoxContainer = HBoxContainer.new()
54+
for control in get_children():
55+
var dupe := control.duplicate()
56+
dupe.custom_minimum_size.x = control.size.x
57+
if dupe.name == "Drag":
58+
dupe.toggle_mode = true
59+
dupe.button_pressed = true
60+
row.add_child(dupe)
61+
self.modulate = Color.TRANSPARENT
62+
63+
bg_panel.add_child(row)
64+
bg_panel.position -= Vector2(16, 16)
65+
66+
var preview_root := Control.new()
67+
preview_root.add_child(bg_panel)
68+
69+
# match control scale to graph edit zoom
70+
preview_root.scale = Vector2.ONE * get_parent().get_parent().zoom
71+
set_drag_preview(preview_root)
72+
73+
return { "index": get_index(), "parent_node": get_parent().name }
74+
75+
76+
func _row_can_drop_data(_at_position: Vector2, data: Variant) -> bool:
77+
return data.index != get_index() and data.parent_node == get_parent().name
78+
4879

49-
func _on_Down_pressed() -> void:
50-
get_parent().command("swap_ports", [get_index(), get_index()+1])
80+
func _row_drop_data(_at_position: Vector2, data: Variant) -> void:
81+
get_parent().command("swap_ports", [get_index(), data.index])
82+
get_parent().get_child(data.index).modulate = Color.WHITE
5183

5284

85+
func _notification(what: int) -> void:
86+
match what:
87+
NOTIFICATION_DRAG_END:
88+
for c in get_parent().get_children():
89+
c.modulate = Color.WHITE

material_maker/nodes/ios/port.tscn

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,31 @@
1-
[gd_scene load_steps=9 format=3 uid="uid://24n1vcw48pi"]
1+
[gd_scene load_steps=8 format=3 uid="uid://24n1vcw48pi"]
22

3-
[ext_resource type="Script" path="res://material_maker/nodes/ios/port.gd" id="1"]
3+
[ext_resource type="Script" uid="uid://74k1155djatm" path="res://material_maker/nodes/ios/port.gd" id="1"]
44
[ext_resource type="Texture2D" uid="uid://c0j4px4n72di5" path="res://material_maker/icons/icons.tres" id="2"]
55
[ext_resource type="PackedScene" uid="uid://dvp8gd7whg6h7" path="res://material_maker/widgets/linked_widgets/editable_label.tscn" id="3"]
66
[ext_resource type="PackedScene" uid="uid://bi88rsdxt0ld7" path="res://material_maker/widgets/port_group_button/port_group_button.tscn" id="4"]
77
[ext_resource type="PackedScene" uid="uid://buj231c2gxm4o" path="res://material_maker/widgets/desc_button/desc_button.tscn" id="5"]
88

9+
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_beq70"]
10+
911
[sub_resource type="AtlasTexture" id="1"]
1012
atlas = ExtResource("2")
1113
region = Rect2(2, 17, 12, 14)
1214

13-
[sub_resource type="AtlasTexture" id="2"]
14-
atlas = ExtResource("2")
15-
region = Rect2(18, 49, 12, 14)
16-
17-
[sub_resource type="AtlasTexture" id="3"]
18-
atlas = ExtResource("2")
19-
region = Rect2(34, 49, 12, 14)
20-
2115
[node name="Port" type="HBoxContainer"]
2216
anchors_preset = 10
2317
anchor_right = 1.0
2418
offset_bottom = 20.0
2519
script = ExtResource("1")
2620

27-
[node name="Delete" type="Button" parent="."]
21+
[node name="Drag" type="Button" parent="."]
2822
layout_mode = 2
29-
icon = SubResource("1")
30-
31-
[node name="Up" type="Button" parent="."]
32-
layout_mode = 2
33-
icon = SubResource("2")
23+
theme_override_styles/focus = SubResource("StyleBoxEmpty_beq70")
24+
flat = true
3425

35-
[node name="Down" type="Button" parent="."]
26+
[node name="Delete" type="Button" parent="."]
3627
layout_mode = 2
37-
icon = SubResource("3")
28+
icon = SubResource("1")
3829

3930
[node name="Name" parent="." instance=ExtResource("3")]
4031
custom_minimum_size = Vector2(30, 0)
@@ -53,8 +44,6 @@ tooltip_text = "Port type"
5344
layout_mode = 2
5445

5546
[connection signal="pressed" from="Delete" to="." method="_on_Delete_pressed"]
56-
[connection signal="pressed" from="Up" to="." method="_on_Up_pressed"]
57-
[connection signal="pressed" from="Down" to="." method="_on_Down_pressed"]
5847
[connection signal="label_changed" from="Name" to="." method="_on_Name_label_changed"]
5948
[connection signal="descriptions_changed" from="Description" to="." method="_on_Description_descriptions_changed"]
6049
[connection signal="item_selected" from="Type" to="." method="_on_Type_item_selected"]

material_maker/nodes/remote/remote.gd

Lines changed: 86 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,32 @@ var links = {}
1313
func _ready():
1414
super._ready()
1515

16-
func add_control(text : String, control : Control, is_named_param : bool, short_description : String = "", long_description : String = "", is_first : bool = false, is_last : bool = false) -> void:
16+
17+
func add_control(text : String, control : Control, is_named_param : bool, short_description : String = "", long_description : String = "") -> void:
18+
var drag_button := Button.new()
19+
drag_button.flat = true
20+
drag_button.add_theme_stylebox_override("focus", StyleBoxEmpty.new())
21+
drag_button.icon = get_theme_icon("arrow_updown", "MM_Icons")
22+
drag_button.mouse_filter = Control.MOUSE_FILTER_STOP
23+
grid.add_child(drag_button)
24+
drag_button.set_drag_forwarding(
25+
row_get_data.bind(drag_button.get_index(), control.name),
26+
row_can_drop.bind(drag_button.get_index()),
27+
row_drop_data.bind(drag_button.get_index()))
28+
1729
var line_edit : LineEdit = LineEdit.new()
1830
line_edit.set_text(control.name)
1931
line_edit.custom_minimum_size.x = 80
2032
grid.add_child(line_edit)
2133
line_edit.connect("text_changed", Callable(self, "on_param_name_changed").bind(control.name, line_edit))
2234
line_edit.connect("text_submitted", Callable(self, "on_param_name_entered").bind(control.name, line_edit))
2335
line_edit.connect("focus_exited", Callable(self, "on_param_name_entered2").bind(control.name, line_edit))
36+
2437
var label = preload("res://material_maker/widgets/linked_widgets/editable_label.tscn").instantiate()
2538
label.set_text(text)
2639
label.connect("label_changed", Callable(self, "on_label_changed").bind(control.name))
2740
grid.add_child(label)
41+
2842
var description = preload("res://material_maker/widgets/desc_button/desc_button.tscn").instantiate()
2943
description.short_description = short_description
3044
description.long_description = long_description
@@ -34,6 +48,7 @@ func add_control(text : String, control : Control, is_named_param : bool, short_
3448
control.connect("mouse_entered", Callable(self, "on_enter_widget").bind(control))
3549
control.connect("mouse_exited", Callable(self, "on_exit_widget").bind(control))
3650
control.tooltip_text = ""
51+
3752
var button = Button.new()
3853
if is_named_param:
3954
button.icon = preload("res://material_maker/icons/edit.tres")
@@ -50,22 +65,6 @@ func add_control(text : String, control : Control, is_named_param : bool, short_
5065
button.tooltip_text = "Remove parameter"
5166
grid.add_child(button)
5267
button.connect("pressed", Callable(self, "remove_parameter").bind(control.name))
53-
button = Button.new()
54-
button.icon = preload("res://material_maker/icons/up.tres")
55-
button.tooltip_text = "Move parameter up"
56-
grid.add_child(button)
57-
if is_first:
58-
button.disabled = true
59-
else:
60-
button.connect("pressed", Callable(self, "move_parameter").bind(control.name, -1))
61-
button = Button.new()
62-
button.icon = preload("res://material_maker/icons/down.tres")
63-
button.tooltip_text = "Move parameter down"
64-
grid.add_child(button)
65-
if is_last:
66-
button.disabled = true
67-
else:
68-
button.connect("pressed", Callable(self, "move_parameter").bind(control.name, 1))
6968

7069
func update_node() -> void:
7170
await get_tree().process_frame
@@ -88,7 +87,7 @@ func update_node() -> void:
8887
var shortdesc : String = widget.shortdesc if widget.has("shortdesc") else ""
8988
var longdesc : String = widget.longdesc if widget.has("longdesc") else ""
9089
var is_named_param : bool = ( p.widget_type == "named_parameter" )
91-
add_control(generator.get_widget(p.name).label, control, is_named_param, shortdesc, longdesc, i == 0, i == parameter_count-1)
90+
add_control(generator.get_widget(p.name).label, control, is_named_param, shortdesc, longdesc)
9291
if generator.widgets[i].type == "config_control" and control is OptionButton:
9392
var current = null
9493
if control.get_item_count() > 0 and generator.parameters.has(p.name):
@@ -269,3 +268,72 @@ func on_exit_widget(widget) -> void:
269268
for l in links[widget]:
270269
l.queue_free()
271270
links.erase(widget)
271+
272+
273+
func modulate_row_controls(row_index: int, color: Color):
274+
for i in range(grid.columns * row_index, grid.columns * row_index + grid.columns):
275+
grid.get_child(i).modulate = color
276+
277+
278+
func row_get_data(_at_pos: Vector2, index: int, widget_name: String) -> Dictionary:
279+
var preview_root := Control.new()
280+
281+
var bg_panel := PanelContainer.new()
282+
bg_panel.theme_type_variation = "MM_PanelBackground"
283+
284+
var panel_stylebox := get_theme_stylebox("panel", "GraphNode").duplicate()
285+
panel_stylebox.set_corner_radius_all(5)
286+
panel_stylebox.set_border_width_all(0)
287+
panel_stylebox.set_expand_margin_all(0)
288+
panel_stylebox.set_content_margin_all(4.0)
289+
panel_stylebox.bg_color.a = 0.8
290+
bg_panel.add_theme_stylebox_override("panel", panel_stylebox)
291+
292+
var grid_container := GridContainer.new()
293+
bg_panel.add_child(grid_container)
294+
grid_container.columns = grid.columns
295+
for c in range(index, index + grid.columns):
296+
var src := grid.get_child(c)
297+
var dupe := src.duplicate(true)
298+
299+
if c == index and dupe is Button:
300+
dupe.toggle_mode = true
301+
dupe.button_pressed = true
302+
303+
dupe.custom_minimum_size.x = src.size.x
304+
grid_container.add_child(dupe)
305+
306+
bg_panel.position = -Vector2(16, 16)
307+
preview_root.add_child(bg_panel)
308+
309+
# match control scale to graph edit zoom
310+
preview_root.scale = Vector2.ONE * get_parent().zoom
311+
312+
var row_index : int = floor(index / grid.columns)
313+
modulate_row_controls(row_index, Color.TRANSPARENT)
314+
set_drag_preview(preview_root)
315+
316+
return { "row_index": row_index, "widget_name": widget_name, "node_name": name }
317+
318+
319+
func row_can_drop(_at_pos: Vector2, data: Dictionary, index: int) -> bool:
320+
return data.row_index != floor(index / grid.columns) and data.node_name == name
321+
322+
323+
func row_drop_data(_at_pos: Vector2, data: Dictionary, index: int) -> void:
324+
move_parameter(data.widget_name, floor(index / grid.columns) - data.row_index)
325+
326+
# workaround FloatEdit' focused state when dropping row towards top
327+
await get_tree().process_frame
328+
for float_edit in grid.get_children():
329+
if float_edit is PanelContainer:
330+
float_edit.get_child(0).add_theme_stylebox_override(
331+
"fill", get_theme_stylebox("fill_normal", "MM_NodeFloatEdit"))
332+
float_edit.get_child(0).add_theme_stylebox_override(
333+
"background", get_theme_stylebox("normal","MM_NodeFloatEdit"))
334+
335+
336+
func _notification(what: int) -> void:
337+
match what:
338+
NOTIFICATION_DRAG_END:
339+
grid.get_children().map(func(c): c.modulate = Color.WHITE)

material_maker/nodes/remote/remote.tscn

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[gd_scene load_steps=6 format=3 uid="uid://bg8ghn24uo0cr"]
22

3-
[ext_resource type="Script" path="res://material_maker/nodes/remote/remote.gd" id="1"]
3+
[ext_resource type="Script" uid="uid://b2ail0itjyaba" path="res://material_maker/nodes/remote/remote.gd" id="1"]
44
[ext_resource type="Texture2D" uid="uid://c0j4px4n72di5" path="res://material_maker/icons/icons.tres" id="2"]
55

66
[sub_resource type="Theme" id="1"]
@@ -19,7 +19,6 @@ offset_bottom = 52.0
1919
mouse_filter = 1
2020
theme = SubResource("1")
2121
title = "Remote"
22-
show_close = true
2322
slot/0/left_enabled = false
2423
slot/0/left_type = 0
2524
slot/0/left_color = Color(0.5, 0.5, 1, 1)
@@ -42,7 +41,7 @@ script = ExtResource("1")
4241

4342
[node name="Controls" type="GridContainer" parent="."]
4443
layout_mode = 2
45-
columns = 8
44+
columns = 7
4645

4746
[node name="HBoxContainer" type="HBoxContainer" parent="."]
4847
layout_mode = 2

material_maker/theme/default.tres

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[gd_resource type="Theme" load_steps=143 format=3 uid="uid://b628lwfk6ig2c"]
1+
[gd_resource type="Theme" load_steps=144 format=3 uid="uid://b628lwfk6ig2c"]
22

33
[ext_resource type="FontFile" uid="uid://lro0qdrhfytt" path="res://material_maker/theme/font_rubik/Rubik-Light.ttf" id="1_5tfb1"]
44
[ext_resource type="Texture2D" uid="uid://1s0c37uoj4rf" path="res://material_maker/theme/default_theme_icons.svg" id="1_s43fy"]
@@ -372,6 +372,10 @@ region = Rect2(32, 48, 16, 16)
372372
atlas = ExtResource("1_s43fy")
373373
region = Rect2(48, 48, 16, 16)
374374

375+
[sub_resource type="AtlasTexture" id="AtlasTexture_rqjp3"]
376+
atlas = ExtResource("1_s43fy")
377+
region = Rect2(112, 176, 16, 16)
378+
375379
[sub_resource type="AtlasTexture" id="AtlasTexture_j13i3"]
376380
atlas = ExtResource("1_s43fy")
377381
region = Rect2(64, 160, 16, 16)
@@ -1095,6 +1099,7 @@ MM_Icons/icons/add_image = SubResource("AtlasTexture_86qok")
10951099
MM_Icons/icons/arrange_nodes = SubResource("AtlasTexture_60g77")
10961100
MM_Icons/icons/arrow_left = SubResource("AtlasTexture_q32qs")
10971101
MM_Icons/icons/arrow_right = SubResource("AtlasTexture_r3xak")
1102+
MM_Icons/icons/arrow_updown = SubResource("AtlasTexture_rqjp3")
10981103
MM_Icons/icons/color_picker = SubResource("AtlasTexture_j13i3")
10991104
MM_Icons/icons/connection_bezier = SubResource("AtlasTexture_ovvp6")
11001105
MM_Icons/icons/connection_diagonal = SubResource("AtlasTexture_8tn7x")

0 commit comments

Comments
 (0)