mirror of
https://github.com/Relintai/material-maker.git
synced 2025-01-09 05:39:38 +01:00
Merge branch 'master' into dev-generic
This commit is contained in:
commit
6b183aa7a0
15
README.md
15
README.md
@ -7,9 +7,20 @@ be used to create textures procedurally. It can also be used as a Godot addon
|
||||
Its user interface is based on Godot's GraphEdit node: textures are described
|
||||
as interconnected texture generators and operators.
|
||||
|
||||
## Download
|
||||
|
||||
- **[Download on itch.io](https://rodzilla.itch.io/material-maker)**
|
||||
|
||||
On Windows, you can also install Material Maker using [Scoop](https://scoop.sh):
|
||||
|
||||
```text
|
||||
scoop bucket add extras
|
||||
scoop install material-maker
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
- **[User manual](https://rodzill4.github.io/godot-procedural-textures/doc/)**
|
||||
- **[User manual](https://rodzill4.github.io/material-maker/doc/)**
|
||||
|
||||
## Screenshot
|
||||
|
||||
@ -17,7 +28,7 @@ as interconnected texture generators and operators.
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) 2018-2020 Rodz Labs and contributors
|
||||
Copyright (c) 2018-2020 Rodolphe Suescun and contributors
|
||||
|
||||
Unless otherwise specified, files in this repository are licensed under the
|
||||
MIT license. See [LICENSE.md](LICENSE.md) for more information.
|
||||
|
@ -8,6 +8,8 @@ Comments to put in the graph
|
||||
|
||||
var text : String = "Double-click to write a comment"
|
||||
var size : Vector2 = Vector2(0, 0)
|
||||
var title : String = "Comment"
|
||||
var color : Color = Color(1.0, 0.5, 0.0)
|
||||
|
||||
func _ready() -> void:
|
||||
if !parameters.has("size"):
|
||||
@ -30,6 +32,8 @@ func get_output_defs() -> Array:
|
||||
|
||||
func _serialize(data: Dictionary) -> Dictionary:
|
||||
data.type = "comment"
|
||||
data.title = title
|
||||
data.color = MMType.serialize_value(color)
|
||||
data.text = text
|
||||
data.size = { x=size.x, y=size.y }
|
||||
return data
|
||||
@ -39,3 +43,7 @@ func _deserialize(data : Dictionary) -> void:
|
||||
text = data.text
|
||||
if data.has("size"):
|
||||
size = Vector2(data.size.x, data.size.y)
|
||||
if data.has("title"):
|
||||
title = data.title
|
||||
if data.has("color"):
|
||||
color = MMType.deserialize_value(data.color)
|
||||
|
File diff suppressed because one or more lines are too long
@ -12,6 +12,8 @@ var generator = null
|
||||
|
||||
var last_selected = null
|
||||
|
||||
onready var node_popup = $"../AddNodePopup"
|
||||
|
||||
onready var timer : Timer = $Timer
|
||||
|
||||
onready var subgraph_ui : HBoxContainer = $GraphUI/SubGraphUI
|
||||
@ -34,7 +36,6 @@ func _gui_input(event) -> void:
|
||||
remove_selection()
|
||||
|
||||
# Misc. useful functions
|
||||
|
||||
func get_source(node, port) -> Dictionary:
|
||||
for c in get_connection_list():
|
||||
if c.to == node and c.to_port == port:
|
||||
@ -165,6 +166,7 @@ func update_graph(generators, connections) -> Array:
|
||||
rv.push_back(node)
|
||||
for c in connections:
|
||||
.connect_node("node_"+c.from, c.from_port, "node_"+c.to, c.to_port)
|
||||
|
||||
return rv
|
||||
|
||||
func new_material() -> void:
|
||||
@ -371,10 +373,20 @@ func set_last_selected(node) -> void:
|
||||
last_selected = null
|
||||
|
||||
func _on_GraphEdit_gui_input(event) -> void:
|
||||
if event.is_action_pressed("ui_library_popup") && get_rect().has_point(get_local_mouse_position()):
|
||||
node_popup.rect_global_position = get_global_mouse_position()
|
||||
node_popup.show()
|
||||
if event is InputEventMouseButton:
|
||||
call_deferred("check_last_selected")
|
||||
|
||||
func request_popup(from, from_slot, release_position) -> void:
|
||||
node_popup.rect_global_position = get_global_mouse_position()
|
||||
node_popup.show()
|
||||
node_popup.set_quick_connect(from, from_slot)
|
||||
|
||||
func check_last_selected() -> void:
|
||||
if last_selected != null and !(is_instance_valid(last_selected) and last_selected.selected):
|
||||
last_selected = null
|
||||
emit_signal("node_selected", null)
|
||||
|
||||
|
||||
|
@ -79,6 +79,7 @@ margin_bottom = 24.0
|
||||
hint_tooltip = "Show hierarchy"
|
||||
icon = SubResource( 4 )
|
||||
[connection signal="connection_request" from="." to="." method="connect_node"]
|
||||
[connection signal="connection_to_empty" from="." to="." method="request_popup"]
|
||||
[connection signal="disconnection_request" from="." to="." method="disconnect_node"]
|
||||
[connection signal="duplicate_nodes_request" from="." to="." method="duplicate_selected"]
|
||||
[connection signal="gui_input" from="." to="." method="_on_GraphEdit_gui_input"]
|
||||
|
8
material_maker/icons/edit.tres
Normal file
8
material_maker/icons/edit.tres
Normal file
@ -0,0 +1,8 @@
|
||||
[gd_resource type="AtlasTexture" load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://material_maker/icons/icons.svg" type="Texture" id=1]
|
||||
|
||||
[resource]
|
||||
flags = 4
|
||||
atlas = ExtResource( 1 )
|
||||
region = Rect2( 16, 16, 16, 16 )
|
@ -18,6 +18,8 @@ onready var preview_3d = $VBoxContainer/HBoxContainer/VBoxContainer/Preview/Prev
|
||||
|
||||
const RECENT_FILES_COUNT = 15
|
||||
|
||||
const THEMES = [ "Dark", "Default", "Light" ]
|
||||
|
||||
const MENU = [
|
||||
{ menu="File", command="new_material", description="New material" },
|
||||
{ menu="File", command="load_material", shortcut="Control+O", description="Load material" },
|
||||
@ -36,6 +38,8 @@ const MENU = [
|
||||
{ menu="Edit", command="edit_copy", shortcut="Control+C", description="Copy" },
|
||||
{ menu="Edit", command="edit_paste", shortcut="Control+V", description="Paste" },
|
||||
{ menu="Edit", command="edit_duplicate", shortcut="Control+D", description="Duplicate" },
|
||||
{ menu="Edit" },
|
||||
{ menu="Edit", submenu="set_theme", description="Set theme" },
|
||||
|
||||
{ menu="View", command="view_center", shortcut="C", description="Center view" },
|
||||
{ menu="View", command="view_reset_zoom", shortcut="Control+0", description="Reset zoom" },
|
||||
@ -61,19 +65,22 @@ var is_mac = false
|
||||
func _ready() -> void:
|
||||
# Restore the window position/size if values are present in the configuration cache
|
||||
config_cache.load("user://cache.ini")
|
||||
if Engine.editor_hint:
|
||||
set_process_input(false)
|
||||
else:
|
||||
if config_cache.has_section_key("window", "screen"):
|
||||
OS.current_screen = config_cache.get_value("window", "screen")
|
||||
if config_cache.has_section_key("window", "maximized"):
|
||||
OS.window_maximized = config_cache.get_value("window", "maximized")
|
||||
if config_cache.has_section_key("window", "screen"):
|
||||
OS.current_screen = config_cache.get_value("window", "screen")
|
||||
if config_cache.has_section_key("window", "maximized"):
|
||||
OS.window_maximized = config_cache.get_value("window", "maximized")
|
||||
|
||||
if !OS.window_maximized:
|
||||
if config_cache.has_section_key("window", "position"):
|
||||
OS.window_position = config_cache.get_value("window", "position")
|
||||
if config_cache.has_section_key("window", "size"):
|
||||
OS.window_size = config_cache.get_value("window", "size")
|
||||
|
||||
if !OS.window_maximized:
|
||||
if config_cache.has_section_key("window", "position"):
|
||||
OS.window_position = config_cache.get_value("window", "position")
|
||||
if config_cache.has_section_key("window", "size"):
|
||||
OS.window_size = config_cache.get_value("window", "size")
|
||||
# Restore the theme
|
||||
var theme_name : String = "default"
|
||||
if config_cache.has_section_key("window", "theme"):
|
||||
theme_name = config_cache.get_value("window", "theme")
|
||||
set_theme(theme_name)
|
||||
|
||||
if OS.get_name() == "OSX":
|
||||
is_mac = true
|
||||
@ -103,8 +110,7 @@ func _ready() -> void:
|
||||
# This property is only available in 3.2alpha or later, so use `set()` to fail gracefully if it doesn't exist.
|
||||
OS.set("min_window_size", Vector2(1024, 600))
|
||||
|
||||
if !Engine.editor_hint:
|
||||
OS.set_window_title(ProjectSettings.get_setting("application/config/name")+" v"+ProjectSettings.get_setting("application/config/release"))
|
||||
OS.set_window_title(ProjectSettings.get_setting("application/config/name")+" v"+ProjectSettings.get_setting("application/config/release"))
|
||||
load_recents()
|
||||
for m in $VBoxContainer/Menu.get_children():
|
||||
var menu = m.get_popup()
|
||||
@ -194,6 +200,21 @@ func add_recent(path) -> void:
|
||||
f.store_string(to_json(recent_files))
|
||||
f.close()
|
||||
|
||||
func create_menu_set_theme(menu) -> void:
|
||||
menu.clear()
|
||||
for t in THEMES:
|
||||
menu.add_item(t)
|
||||
if !menu.is_connected("id_pressed", self, "_on_SetTheme_id_pressed"):
|
||||
menu.connect("id_pressed", self, "_on_SetTheme_id_pressed")
|
||||
|
||||
func set_theme(theme_name) -> void:
|
||||
theme = load("res://material_maker/theme/"+theme_name+".tres")
|
||||
|
||||
func _on_SetTheme_id_pressed(id) -> void:
|
||||
var theme_name : String = THEMES[id].to_lower()
|
||||
set_theme(theme_name)
|
||||
config_cache.set_value("window", "theme", theme_name)
|
||||
|
||||
func create_menu_create(menu) -> void:
|
||||
var gens = mm_loader.get_generator_list()
|
||||
menu.clear()
|
||||
@ -295,11 +316,8 @@ func export_material_is_disabled() -> bool:
|
||||
return graph_edit == null or graph_edit.save_path == null
|
||||
|
||||
func quit() -> void:
|
||||
if Engine.editor_hint:
|
||||
emit_signal("quit")
|
||||
else:
|
||||
dim_window()
|
||||
get_tree().quit()
|
||||
dim_window()
|
||||
get_tree().quit()
|
||||
|
||||
func edit_cut() -> void:
|
||||
var graph_edit : MMGraphEdit = get_current_graph_edit()
|
||||
@ -521,17 +539,15 @@ func _on_Projects_tab_changed(tab) -> void:
|
||||
|
||||
func _exit_tree() -> void:
|
||||
# Save the window position and size to remember it when restarting the application
|
||||
if !Engine.editor_hint:
|
||||
config_cache.set_value("window", "screen", OS.current_screen)
|
||||
config_cache.set_value("window", "maximized", OS.window_maximized || OS.window_fullscreen)
|
||||
config_cache.set_value("window", "position", OS.window_position)
|
||||
config_cache.set_value("window", "size", OS.window_size)
|
||||
config_cache.save("user://cache.ini")
|
||||
config_cache.set_value("window", "screen", OS.current_screen)
|
||||
config_cache.set_value("window", "maximized", OS.window_maximized || OS.window_fullscreen)
|
||||
config_cache.set_value("window", "position", OS.window_position)
|
||||
config_cache.set_value("window", "size", OS.window_size)
|
||||
config_cache.save("user://cache.ini")
|
||||
|
||||
func _notification(what : int) -> void:
|
||||
if !Engine.editor_hint:
|
||||
if what == MainLoop.NOTIFICATION_WM_QUIT_REQUEST:
|
||||
dim_window()
|
||||
if what == MainLoop.NOTIFICATION_WM_QUIT_REQUEST:
|
||||
dim_window()
|
||||
|
||||
func dim_window() -> void:
|
||||
# Darken the UI to denote that the application is currently exiting
|
||||
|
@ -1,4 +1,4 @@
|
||||
[gd_scene load_steps=11 format=2]
|
||||
[gd_scene load_steps=13 format=2]
|
||||
|
||||
[ext_resource path="res://material_maker/main_window.gd" type="Script" id=1]
|
||||
[ext_resource path="res://material_maker/library.tscn" type="PackedScene" id=2]
|
||||
@ -6,17 +6,19 @@
|
||||
[ext_resource path="res://material_maker/preview/preview_3d.tscn" type="PackedScene" id=4]
|
||||
[ext_resource path="res://material_maker/preview/preview_3d_ui.tscn" type="PackedScene" id=5]
|
||||
[ext_resource path="res://material_maker/widgets/tabs.gd" type="Script" id=6]
|
||||
[ext_resource path="res://material_maker/icons/icons.svg" type="Texture" id=7]
|
||||
[ext_resource path="res://material_maker/node_factory.gd" type="Script" id=8]
|
||||
[ext_resource path="res://material_maker/widgets/add_node_popup.tscn" type="PackedScene" id=7]
|
||||
[ext_resource path="res://material_maker/icons/icons.svg" type="Texture" id=8]
|
||||
[ext_resource path="res://material_maker/node_factory.gd" type="Script" id=9]
|
||||
[ext_resource path="res://material_maker/theme/default.tres" type="Theme" id=10]
|
||||
|
||||
[sub_resource type="AtlasTexture" id=1]
|
||||
flags = 4
|
||||
atlas = ExtResource( 7 )
|
||||
atlas = ExtResource( 8 )
|
||||
region = Rect2( 96, 32, 32, 32 )
|
||||
|
||||
[sub_resource type="AtlasTexture" id=2]
|
||||
flags = 4
|
||||
atlas = ExtResource( 7 )
|
||||
atlas = ExtResource( 8 )
|
||||
region = Rect2( 96, 64, 32, 32 )
|
||||
|
||||
[node name="MainWindow" type="Panel"]
|
||||
@ -24,6 +26,7 @@ anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
theme = ExtResource( 10 )
|
||||
script = ExtResource( 1 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
@ -38,14 +41,17 @@ margin_right = -6.0
|
||||
margin_bottom = -6.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="Menu" type="HBoxContainer" parent="VBoxContainer"]
|
||||
margin_right = 1268.0
|
||||
margin_bottom = 20.0
|
||||
margin_bottom = 22.0
|
||||
|
||||
[node name="File" type="MenuButton" parent="VBoxContainer/Menu"]
|
||||
margin_right = 35.0
|
||||
margin_bottom = 20.0
|
||||
margin_bottom = 22.0
|
||||
text = "File"
|
||||
items = [ "New material", null, 0, false, false, 0, 0, null, "", false, "Load material", null, 0, false, false, 1, 268435535, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "Save material", null, 0, false, false, 4, 268435539, null, "", false, "Save material as...", null, 0, false, false, 5, 301989971, null, "", false, "Save all materials...", null, 0, false, false, 6, 0, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "Export material", null, 0, false, false, 8, 268435525, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "Close material", null, 0, false, false, 10, 0, null, "", false, "Quit", null, 0, false, false, 11, 268435537, null, "", false ]
|
||||
switch_on_hover = true
|
||||
@ -53,7 +59,7 @@ switch_on_hover = true
|
||||
[node name="Edit" type="MenuButton" parent="VBoxContainer/Menu"]
|
||||
margin_left = 39.0
|
||||
margin_right = 75.0
|
||||
margin_bottom = 20.0
|
||||
margin_bottom = 22.0
|
||||
text = "Edit"
|
||||
items = [ "Cut", null, 0, false, false, 12, 268435544, null, "", false, "Copy", null, 0, false, false, 13, 268435523, null, "", false, "Paste", null, 0, false, false, 14, 268435542, null, "", false, "Duplicate", null, 0, false, false, 15, 268435524, null, "", false ]
|
||||
switch_on_hover = true
|
||||
@ -61,7 +67,7 @@ switch_on_hover = true
|
||||
[node name="View" type="MenuButton" parent="VBoxContainer/Menu"]
|
||||
margin_left = 79.0
|
||||
margin_right = 121.0
|
||||
margin_bottom = 20.0
|
||||
margin_bottom = 22.0
|
||||
text = "View"
|
||||
items = [ "Center view", null, 0, false, false, 16, 67, null, "", false, "Reset zoom", null, 0, false, false, 17, 268435504, null, "", false ]
|
||||
switch_on_hover = true
|
||||
@ -69,7 +75,7 @@ switch_on_hover = true
|
||||
[node name="Tools" type="MenuButton" parent="VBoxContainer/Menu"]
|
||||
margin_left = 125.0
|
||||
margin_right = 171.0
|
||||
margin_bottom = 20.0
|
||||
margin_bottom = 22.0
|
||||
text = "Tools"
|
||||
items = [ "Create", null, 0, false, false, 0, 0, null, "PopupMenu", false, "Create group", null, 0, false, false, 19, 268435527, null, "", false, "Make selected nodes editable", null, 0, false, false, 20, 268435543, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "Add selected node to user library", null, 0, false, false, 22, 0, null, "", false, "Export the nodes library", null, 0, false, false, 23, 0, null, "", false ]
|
||||
switch_on_hover = true
|
||||
@ -77,51 +83,55 @@ switch_on_hover = true
|
||||
[node name="Help" type="MenuButton" parent="VBoxContainer/Menu"]
|
||||
margin_left = 175.0
|
||||
margin_right = 217.0
|
||||
margin_bottom = 20.0
|
||||
margin_bottom = 22.0
|
||||
text = "Help"
|
||||
items = [ "User manual", null, 0, false, false, 24, 16777244, null, "", false, "Show selected library item documentation", null, 0, false, false, 25, 285212700, null, "", false, "Report a bug", null, 0, false, false, 26, 0, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "About", null, 0, false, false, 28, 0, null, "", false ]
|
||||
switch_on_hover = true
|
||||
|
||||
[node name="HBoxContainer" type="HSplitContainer" parent="VBoxContainer"]
|
||||
margin_top = 24.0
|
||||
margin_top = 26.0
|
||||
margin_right = 1268.0
|
||||
margin_bottom = 708.0
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="VBoxContainer" type="VSplitContainer" parent="VBoxContainer/HBoxContainer"]
|
||||
margin_right = 311.0
|
||||
margin_bottom = 684.0
|
||||
margin_right = 313.0
|
||||
margin_bottom = 682.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="Library" parent="VBoxContainer/HBoxContainer/VBoxContainer" instance=ExtResource( 2 )]
|
||||
margin_right = 311.0
|
||||
margin_bottom = 386.0
|
||||
margin_right = 313.0
|
||||
margin_bottom = 390.0
|
||||
size_flags_vertical = 3
|
||||
size_flags_stretch_ratio = 1.5
|
||||
|
||||
[node name="Preview" type="TabContainer" parent="VBoxContainer/HBoxContainer/VBoxContainer"]
|
||||
margin_top = 398.0
|
||||
margin_right = 311.0
|
||||
margin_bottom = 684.0
|
||||
margin_right = 313.0
|
||||
margin_bottom = 682.0
|
||||
tab_align = 0
|
||||
|
||||
[node name="Preview2D" parent="VBoxContainer/HBoxContainer/VBoxContainer/Preview" instance=ExtResource( 3 )]
|
||||
margin_left = 4.0
|
||||
margin_top = 32.0
|
||||
margin_right = -4.0
|
||||
margin_bottom = -4.0
|
||||
margin_left = 5.0
|
||||
margin_top = 29.0
|
||||
margin_right = -5.0
|
||||
margin_bottom = -5.0
|
||||
rect_min_size = Vector2( 250, 250 )
|
||||
|
||||
[node name="Preview3D" parent="VBoxContainer/HBoxContainer/VBoxContainer/Preview" instance=ExtResource( 4 )]
|
||||
margin_left = 5.0
|
||||
margin_top = 29.0
|
||||
margin_right = -5.0
|
||||
margin_bottom = -5.0
|
||||
rect_min_size = Vector2( 250, 250 )
|
||||
|
||||
[node name="Preview3DUI" parent="VBoxContainer/HBoxContainer/VBoxContainer/Preview/Preview3D" instance=ExtResource( 5 )]
|
||||
|
||||
[node name="ProjectsPane" type="Control" parent="VBoxContainer/HBoxContainer"]
|
||||
margin_left = 323.0
|
||||
margin_left = 321.0
|
||||
margin_right = 1268.0
|
||||
margin_bottom = 684.0
|
||||
margin_bottom = 682.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
size_flags_stretch_ratio = 3.0
|
||||
@ -152,6 +162,8 @@ margin_bottom = 24.0
|
||||
tab_align = 0
|
||||
tab_close_display_policy = 1
|
||||
|
||||
[node name="AddNodePopup" parent="VBoxContainer/HBoxContainer/ProjectsPane/Projects" instance=ExtResource( 7 )]
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/HBoxContainer/ProjectsPane"]
|
||||
anchor_top = 1.0
|
||||
anchor_bottom = 1.0
|
||||
@ -163,7 +175,7 @@ custom_constants/separation = 7
|
||||
|
||||
[node name="Button" type="Button" parent="VBoxContainer/HBoxContainer/ProjectsPane/HBoxContainer"]
|
||||
margin_right = 44.0
|
||||
margin_bottom = 38.0
|
||||
margin_bottom = 40.0
|
||||
hint_tooltip = "Show 3D preview"
|
||||
toggle_mode = true
|
||||
icon = SubResource( 1 )
|
||||
@ -191,7 +203,7 @@ margin_bottom = 30.0
|
||||
size_flags_vertical = 4
|
||||
|
||||
[node name="NodeFactory" type="Node" parent="."]
|
||||
script = ExtResource( 8 )
|
||||
script = ExtResource( 9 )
|
||||
[connection signal="need_update" from="VBoxContainer/HBoxContainer/VBoxContainer/Preview/Preview3D" to="." method="update_preview_3d"]
|
||||
[connection signal="environment_selected" from="VBoxContainer/HBoxContainer/VBoxContainer/Preview/Preview3D/Preview3DUI" to="VBoxContainer/HBoxContainer/VBoxContainer/Preview/Preview3D" method="_on_Environment_item_selected"]
|
||||
[connection signal="model_selected" from="VBoxContainer/HBoxContainer/VBoxContainer/Preview/Preview3D/Preview3DUI" to="VBoxContainer/HBoxContainer/VBoxContainer/Preview/Preview3D" method="_on_Model_item_selected"]
|
||||
|
@ -1,4 +1,3 @@
|
||||
tool
|
||||
extends GraphNode
|
||||
class_name MMGraphNodeBase
|
||||
|
||||
@ -30,3 +29,4 @@ func _on_gui_input(event) -> void:
|
||||
if event is InputEventMouseButton and event.pressed and event.button_index == BUTTON_LEFT and Rect2(rect_size.x-48, 4, 16, 16).has_point(event.position):
|
||||
generator.toggle_lock_seed()
|
||||
update()
|
||||
get_parent().send_changed_signal()
|
||||
|
@ -1,13 +1,21 @@
|
||||
tool
|
||||
extends MMGraphNodeBase
|
||||
|
||||
onready var label = $VBox/Label
|
||||
onready var editor = $VBox/TextEdit
|
||||
|
||||
func _draw() -> void:
|
||||
var icon = preload("res://material_maker/icons/edit.tres")
|
||||
draw_texture_rect(icon, Rect2(rect_size.x-68, 4, 16, 16), false)
|
||||
draw_rect(Rect2(rect_size.x-48, 4, 16, 16), generator.color)
|
||||
if !is_connected("gui_input", self, "_on_gui_input"):
|
||||
connect("gui_input", self, "_on_gui_input")
|
||||
|
||||
func set_generator(g) -> void:
|
||||
generator = g
|
||||
label.text = generator.text
|
||||
rect_size = generator.size
|
||||
title = generator.title
|
||||
set_color(generator.color)
|
||||
|
||||
func _on_resize_request(new_size) -> void:
|
||||
rect_size = new_size
|
||||
@ -27,3 +35,32 @@ func _on_TextEdit_focus_exited() -> void:
|
||||
generator.text = editor.text
|
||||
label.visible = true
|
||||
editor.visible = false
|
||||
|
||||
func _on_gui_input(event) -> void:
|
||||
if event is InputEventMouseButton and event.pressed and event.button_index == BUTTON_LEFT:
|
||||
if Rect2(rect_size.x-48, 4, 16, 16).has_point(event.position):
|
||||
$Popup/ColorPicker.color = generator.color
|
||||
$Popup/ColorPicker.connect("color_changed", self, "set_color")
|
||||
$Popup.rect_position = event.global_position
|
||||
$Popup.popup()
|
||||
accept_event()
|
||||
elif Rect2(rect_size.x-68, 4, 16, 16).has_point(event.position):
|
||||
var dialog = preload("res://material_maker/widgets/line_dialog.tscn").instance()
|
||||
dialog.set_value(generator.title)
|
||||
dialog.set_texts("Comment", "Enter the comment node title")
|
||||
add_child(dialog)
|
||||
dialog.connect("ok", self, "set_title")
|
||||
dialog.popup_centered()
|
||||
accept_event()
|
||||
|
||||
func set_color(c):
|
||||
generator.color = c
|
||||
var color = c
|
||||
color.a = 0.3
|
||||
get_stylebox("comment").bg_color = color
|
||||
get_parent().send_changed_signal()
|
||||
|
||||
func set_title(t):
|
||||
title = t
|
||||
generator.title = t
|
||||
get_parent().send_changed_signal()
|
||||
|
@ -1,18 +1,32 @@
|
||||
[gd_scene load_steps=3 format=2]
|
||||
[gd_scene load_steps=4 format=2]
|
||||
|
||||
[ext_resource path="res://material_maker/nodes/comment.gd" type="Script" id=1]
|
||||
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id=1]
|
||||
resource_local_to_scene = true
|
||||
content_margin_left = 28.0
|
||||
content_margin_right = 28.0
|
||||
content_margin_top = 24.0
|
||||
content_margin_bottom = 5.0
|
||||
bg_color = Color( 0, 0, 0, 0.3 )
|
||||
border_width_left = 1
|
||||
border_width_top = 1
|
||||
border_width_right = 1
|
||||
border_width_bottom = 1
|
||||
border_color = Color( 1, 1, 1, 0.9 )
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id=2]
|
||||
bg_color = Color( 1, 1, 1, 0.0627451 )
|
||||
|
||||
[node name="GraphNode" type="GraphNode"]
|
||||
margin_left = 1.0
|
||||
margin_top = 1.0
|
||||
margin_right = 250.0
|
||||
margin_bottom = 44.0
|
||||
margin_right = 256.0
|
||||
margin_bottom = 82.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
custom_styles/commentfocus = SubResource( 1 )
|
||||
custom_styles/comment = SubResource( 1 )
|
||||
title = "Comment"
|
||||
show_close = true
|
||||
resizable = true
|
||||
@ -23,16 +37,25 @@ slot/0/left_color = Color( 1, 1, 1, 1 )
|
||||
slot/0/right_enabled = false
|
||||
slot/0/right_type = 0
|
||||
slot/0/right_color = Color( 1, 1, 1, 1 )
|
||||
slot/1/left_enabled = false
|
||||
slot/1/left_type = 0
|
||||
slot/1/left_color = Color( 1, 1, 1, 1 )
|
||||
slot/1/right_enabled = false
|
||||
slot/1/right_type = 0
|
||||
slot/1/right_color = Color( 1, 1, 1, 1 )
|
||||
script = ExtResource( 1 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="VBox" type="VBoxContainer" parent="."]
|
||||
margin_left = 16.0
|
||||
margin_top = 24.0
|
||||
margin_right = 233.0
|
||||
margin_right = 239.0
|
||||
margin_bottom = 38.0
|
||||
|
||||
[node name="Label" type="Label" parent="VBox"]
|
||||
margin_right = 217.0
|
||||
margin_right = 223.0
|
||||
margin_bottom = 14.0
|
||||
mouse_filter = 0
|
||||
text = "Double-click to write a comment"
|
||||
@ -43,9 +66,22 @@ visible = false
|
||||
margin_top = 18.0
|
||||
margin_right = 221.0
|
||||
margin_bottom = 18.0
|
||||
custom_styles/focus = SubResource( 1 )
|
||||
custom_styles/normal = SubResource( 1 )
|
||||
custom_styles/focus = SubResource( 2 )
|
||||
custom_styles/normal = SubResource( 2 )
|
||||
wrap_enabled = true
|
||||
|
||||
[node name="Popup" type="Popup" parent="."]
|
||||
margin_left = 16.0
|
||||
margin_top = 39.0
|
||||
margin_right = 239.0
|
||||
margin_bottom = 39.0
|
||||
|
||||
[node name="ColorPicker" type="ColorPicker" parent="Popup"]
|
||||
margin_left = 4.0
|
||||
margin_top = 4.0
|
||||
margin_right = 4.0
|
||||
margin_bottom = 4.0
|
||||
rect_scale = Vector2( 0.75, 0.75 )
|
||||
[connection signal="resize_request" from="." to="." method="_on_resize_request"]
|
||||
[connection signal="gui_input" from="VBox/Label" to="." method="_on_Label_gui_input"]
|
||||
[connection signal="focus_exited" from="VBox/TextEdit" to="." method="_on_TextEdit_focus_exited"]
|
||||
|
12358
material_maker/theme/dark.tres
Normal file
12358
material_maker/theme/dark.tres
Normal file
File diff suppressed because one or more lines are too long
12225
material_maker/theme/default.tres
Normal file
12225
material_maker/theme/default.tres
Normal file
File diff suppressed because one or more lines are too long
12366
material_maker/theme/light.tres
Normal file
12366
material_maker/theme/light.tres
Normal file
File diff suppressed because one or more lines are too long
146
material_maker/widgets/add_node_popup.gd
Normal file
146
material_maker/widgets/add_node_popup.gd
Normal file
@ -0,0 +1,146 @@
|
||||
extends Popup
|
||||
|
||||
var libraries = []
|
||||
var data = []
|
||||
onready var itemlist : ItemList = $PanelContainer/VBoxContainer/ItemList
|
||||
onready var filter_line_edit : LineEdit = $PanelContainer/VBoxContainer/Filter
|
||||
var insert_position : Vector2
|
||||
|
||||
func get_current_graph():
|
||||
return get_parent().get_current_tab_control()
|
||||
|
||||
func _ready() -> void:
|
||||
var lib_path = OS.get_executable_path().get_base_dir()+"/library/base.json"
|
||||
if !add_library(lib_path):
|
||||
add_library("res://material_maker/library/base.json")
|
||||
add_library("user://library/user.json")
|
||||
filter_line_edit.connect("text_changed" ,self,"update_list")
|
||||
filter_line_edit.connect("text_entered",self,"filter_entered")
|
||||
itemlist.connect("item_selected",self,"item_selected")
|
||||
itemlist.connect("item_activated",self,"item_selected")
|
||||
update_list()
|
||||
|
||||
func filter_entered(filter) -> void:
|
||||
item_selected(0)
|
||||
|
||||
func add_node(data) -> void:
|
||||
var node : GraphNode = get_current_graph().create_nodes(data, get_current_graph().offset_from_global_position(insert_position))[0]
|
||||
# if this node created by dragging to an empty space
|
||||
if quick_connect_node != null:
|
||||
var type = quick_connect_node.get_connection_output_type(quick_connect_slot)
|
||||
for new_slot in node.get_connection_input_count():
|
||||
if type == node.get_connection_input_type(new_slot):
|
||||
#connect the first two slots with the same type
|
||||
get_current_graph().connect_node(quick_connect_node.name, quick_connect_slot, node.name, new_slot)
|
||||
break
|
||||
quick_connect_node = null
|
||||
hide()
|
||||
|
||||
func item_selected(index) -> void:
|
||||
# checks if mouse left | enter pressed. it prevents
|
||||
# adding nodes just by using arrow keys as it selects the item
|
||||
if Input.is_mouse_button_pressed(BUTTON_LEFT) || Input.is_key_pressed(KEY_ENTER):
|
||||
if (index>=itemlist.get_item_count()):
|
||||
return
|
||||
if (itemlist.is_item_selectable(index) == false):
|
||||
item_selected(index+1)
|
||||
return
|
||||
add_node(data[index])
|
||||
hide()
|
||||
|
||||
func hide() -> void:
|
||||
.hide()
|
||||
|
||||
# clearing the quick connect data after hiding to prevent unintended autoconnection
|
||||
quick_connect_node = null
|
||||
|
||||
# grabbing the focus for the graph again as creating popup removes the focus.
|
||||
get_current_graph().grab_focus()
|
||||
|
||||
clear()
|
||||
|
||||
func show() -> void:
|
||||
.show()
|
||||
update_list()
|
||||
filter_line_edit.grab_focus()
|
||||
var parent_rect = get_parent().get_parent().get_global_rect()
|
||||
var clipped = parent_rect.clip(get_global_rect())
|
||||
var offset = (get_rect().size-clipped.size)
|
||||
insert_position = rect_position
|
||||
rect_position = rect_position - offset
|
||||
|
||||
func update_list(filter : String = "") -> void:
|
||||
clear_list()
|
||||
data.clear()
|
||||
for library in libraries:
|
||||
for obj in library:
|
||||
if !obj.has("type"):
|
||||
continue
|
||||
var show : bool = true
|
||||
for f in filter.to_lower().split(" ", false):
|
||||
if f != "" && obj.tree_item.to_lower().find(f) == -1:
|
||||
show = false
|
||||
break
|
||||
if show:
|
||||
data.append(obj)
|
||||
itemlist.add_item(obj.tree_item, get_preview_texture(obj))
|
||||
|
||||
func get_preview_texture(data : Dictionary) -> ImageTexture:
|
||||
if data.has("icon") and data.has("library"):
|
||||
var image_path = data.library.left(data.library.rfind("."))+"/"+data.icon+".png"
|
||||
var t : ImageTexture
|
||||
if image_path.left(6) == "res://":
|
||||
image_path = ProjectSettings.globalize_path(image_path)
|
||||
t = ImageTexture.new()
|
||||
var image : Image = Image.new()
|
||||
if image.load(image_path) == OK:
|
||||
image.resize(16, 16)
|
||||
t.create_from_image(image)
|
||||
else:
|
||||
print("Cannot load image "+image_path)
|
||||
return t
|
||||
return null
|
||||
|
||||
func clear_list() -> void:
|
||||
itemlist.clear()
|
||||
|
||||
func add_library(file_name : String, filter : String = "") -> bool:
|
||||
var file = File.new()
|
||||
if file.open(file_name, File.READ) != OK:
|
||||
return false
|
||||
var lib = parse_json(file.get_as_text())
|
||||
file.close()
|
||||
if lib != null and lib.has("lib"):
|
||||
for m in lib.lib:
|
||||
m.library = file_name
|
||||
libraries.push_back(lib.lib)
|
||||
return true
|
||||
return false
|
||||
|
||||
# Quickly connecting when tried to connect to empty
|
||||
var quick_connect_node : GraphNode
|
||||
var quick_connect_slot = 0
|
||||
|
||||
func set_quick_connect(from, from_slot) -> void:
|
||||
quick_connect_node = get_current_graph().get_node(from)
|
||||
quick_connect_slot = from_slot
|
||||
|
||||
func _input(event) -> void:
|
||||
if event is InputEventMouseButton and event.is_pressed() and event.button_index == BUTTON_LEFT:
|
||||
if !get_rect().has_point(event.position):
|
||||
clear()
|
||||
hide()
|
||||
|
||||
func _unhandled_input(event) -> void:
|
||||
if event is InputEventKey and event.scancode == KEY_ESCAPE:
|
||||
clear()
|
||||
hide()
|
||||
|
||||
func clear() -> void:
|
||||
filter_line_edit.text = ""
|
||||
|
||||
func _on_itemlist_focus_entered() -> void:
|
||||
# if itemlist received focus and no item is yet selected
|
||||
# select the first item
|
||||
if itemlist.get_selected_items().size() == 0:
|
||||
itemlist.select(0)
|
34
material_maker/widgets/add_node_popup.tscn
Normal file
34
material_maker/widgets/add_node_popup.tscn
Normal file
@ -0,0 +1,34 @@
|
||||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://material_maker/widgets/add_node_popup.gd" type="Script" id=1]
|
||||
|
||||
[node name="AddNodePopup" type="Popup"]
|
||||
margin_right = 228.0
|
||||
margin_bottom = 319.0
|
||||
mouse_filter = 1
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="."]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer"]
|
||||
margin_left = 7.0
|
||||
margin_top = 7.0
|
||||
margin_right = 221.0
|
||||
margin_bottom = 312.0
|
||||
|
||||
[node name="Filter" type="LineEdit" parent="PanelContainer/VBoxContainer"]
|
||||
margin_right = 214.0
|
||||
margin_bottom = 24.0
|
||||
rect_min_size = Vector2( 0, 20 )
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="ItemList" type="ItemList" parent="PanelContainer/VBoxContainer"]
|
||||
margin_top = 28.0
|
||||
margin_right = 214.0
|
||||
margin_bottom = 305.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
allow_reselect = true
|
||||
[connection signal="focus_entered" from="PanelContainer/VBoxContainer/ItemList" to="." method="_on_itemlist_focus_entered"]
|
@ -216,6 +216,11 @@ toggle_fullscreen={
|
||||
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":true,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777221,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
ui_library_popup={
|
||||
"deadzone": 0.5,
|
||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"unicode":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
|
||||
[logging]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user