mirror of
https://github.com/Relintai/material-maker.git
synced 2025-04-17 14:26:33 +02:00
Added support for cut/copy/paste in Material Maker
This commit is contained in:
parent
27f6de16e9
commit
0d0f862a99
@ -8,6 +8,7 @@ signal save_path_changed
|
|||||||
signal graph_changed
|
signal graph_changed
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
|
$SaveViewport/ColorRect.material = $SaveViewport/ColorRect.material.duplicate(true)
|
||||||
OS.low_processor_usage_mode = true
|
OS.low_processor_usage_mode = true
|
||||||
|
|
||||||
func get_source(node, port):
|
func get_source(node, port):
|
||||||
@ -23,6 +24,7 @@ func add_node(node, global_position = null):
|
|||||||
|
|
||||||
func connect_node(from, from_slot, to, to_slot):
|
func connect_node(from, from_slot, to, to_slot):
|
||||||
var source_list = [ from ]
|
var source_list = [ from ]
|
||||||
|
# Check if the new connection creates a cycle in the graph
|
||||||
while !source_list.empty():
|
while !source_list.empty():
|
||||||
var source = source_list.pop_front()
|
var source = source_list.pop_front()
|
||||||
if source == to:
|
if source == to:
|
||||||
@ -50,7 +52,6 @@ func remove_node(node):
|
|||||||
send_changed_signal()
|
send_changed_signal()
|
||||||
node.queue_free()
|
node.queue_free()
|
||||||
|
|
||||||
|
|
||||||
# Global operations on graph
|
# Global operations on graph
|
||||||
|
|
||||||
func update_tab_title():
|
func update_tab_title():
|
||||||
@ -89,6 +90,14 @@ func new_material():
|
|||||||
create_node({name="Material", type="material"})
|
create_node({name="Material", type="material"})
|
||||||
set_save_path(null)
|
set_save_path(null)
|
||||||
|
|
||||||
|
func get_free_name(type):
|
||||||
|
var i = 0
|
||||||
|
while true:
|
||||||
|
var node_name = type+"_"+str(i)
|
||||||
|
if !has_node(node_name):
|
||||||
|
return node_name
|
||||||
|
i += 1
|
||||||
|
|
||||||
func create_node(data, global_position = null):
|
func create_node(data, global_position = null):
|
||||||
if !data.has("type"):
|
if !data.has("type"):
|
||||||
return null
|
return null
|
||||||
@ -98,16 +107,11 @@ func create_node(data, global_position = null):
|
|||||||
if data.has("name") && !has_node(data.name):
|
if data.has("name") && !has_node(data.name):
|
||||||
node.name = data.name
|
node.name = data.name
|
||||||
else:
|
else:
|
||||||
var i = 0
|
node.name = get_free_name(data.type)
|
||||||
while true:
|
|
||||||
var node_name = data.type+"_"+str(i)
|
|
||||||
if !has_node(node_name):
|
|
||||||
node.name = node_name
|
|
||||||
break
|
|
||||||
i += 1
|
|
||||||
add_node(node, global_position)
|
add_node(node, global_position)
|
||||||
node.deserialize(data)
|
node.deserialize(data)
|
||||||
send_changed_signal()
|
send_changed_signal()
|
||||||
|
return node
|
||||||
|
|
||||||
func load_file():
|
func load_file():
|
||||||
var dialog = FileDialog.new()
|
var dialog = FileDialog.new()
|
||||||
@ -176,6 +180,44 @@ func send_changed_signal():
|
|||||||
func do_send_changed_signal():
|
func do_send_changed_signal():
|
||||||
emit_signal("graph_changed")
|
emit_signal("graph_changed")
|
||||||
|
|
||||||
|
func cut():
|
||||||
|
copy()
|
||||||
|
for c in get_children():
|
||||||
|
if c is GraphNode and c.selected:
|
||||||
|
remove_node(c)
|
||||||
|
|
||||||
|
func copy():
|
||||||
|
var data = { nodes = [], connections = [] }
|
||||||
|
for c in get_children():
|
||||||
|
if c is GraphNode and c.selected:
|
||||||
|
data.nodes.append(c.serialize())
|
||||||
|
for c in get_connection_list():
|
||||||
|
var from = get_node(c.from)
|
||||||
|
var to = get_node(c.to)
|
||||||
|
if from != null and from.selected and to != null and to.selected:
|
||||||
|
data.connections.append(c)
|
||||||
|
OS.clipboard = to_json(data)
|
||||||
|
|
||||||
|
func paste():
|
||||||
|
for c in get_children():
|
||||||
|
if c is GraphNode:
|
||||||
|
c.selected = false
|
||||||
|
var data = parse_json(OS.clipboard)
|
||||||
|
if data == null or typeof(data) != TYPE_DICTIONARY:
|
||||||
|
return
|
||||||
|
if !data.has("nodes") or !data.has("connections"):
|
||||||
|
return
|
||||||
|
if typeof(data.nodes) != TYPE_ARRAY or typeof(data.connections) != TYPE_ARRAY:
|
||||||
|
return
|
||||||
|
var names = {}
|
||||||
|
for c in data.nodes:
|
||||||
|
var node = create_node(c)
|
||||||
|
if node != null:
|
||||||
|
names[c.name] = node.name
|
||||||
|
node.selected = true
|
||||||
|
for c in data.connections:
|
||||||
|
connect_node(names[c.from], c.from_port, names[c.to], c.to_port)
|
||||||
|
|
||||||
# Drag and drop
|
# Drag and drop
|
||||||
|
|
||||||
func can_drop_data(position, data):
|
func can_drop_data(position, data):
|
||||||
@ -211,7 +253,6 @@ func render_shader_to_viewport(shader, textures, size, method, args):
|
|||||||
$SaveViewport.update_worlds()
|
$SaveViewport.update_worlds()
|
||||||
yield(get_tree(), "idle_frame")
|
yield(get_tree(), "idle_frame")
|
||||||
yield(get_tree(), "idle_frame")
|
yield(get_tree(), "idle_frame")
|
||||||
yield(get_tree(), "idle_frame")
|
|
||||||
callv(job.method, job.args)
|
callv(job.method, job.args)
|
||||||
render_queue.pop_front()
|
render_queue.pop_front()
|
||||||
|
|
||||||
|
@ -10,231 +10,8 @@
|
|||||||
|
|
||||||
code = "shader_type canvas_item;
|
code = "shader_type canvas_item;
|
||||||
|
|
||||||
float rand(vec2 x) {
|
|
||||||
return fract(sin(dot(x, vec2(13.9898, 8.141))) * 43758.5453);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 rand2(vec2 x) {
|
|
||||||
return fract(sin(vec2(dot(x, vec2(13.9898, 8.141)),
|
|
||||||
dot(x, vec2(3.4562, 17.398)))) * 43758.5453);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 rand3(vec2 x) {
|
|
||||||
return fract(sin(vec3(dot(x, vec2(13.9898, 8.141)),
|
|
||||||
dot(x, vec2(3.4562, 17.398)),
|
|
||||||
dot(x, vec2(13.254, 5.867)))) * 43758.5453);
|
|
||||||
}
|
|
||||||
|
|
||||||
float wave_sin(float x) {
|
|
||||||
return 0.5-0.5*cos(3.1415928*2.0*x);
|
|
||||||
}
|
|
||||||
|
|
||||||
float wave_saw(float x) {
|
|
||||||
x = fract(x);
|
|
||||||
return min(2.0*x, 2.0-2.0*x);
|
|
||||||
}
|
|
||||||
|
|
||||||
float wave_square(float x) {
|
|
||||||
return (fract(x) < 0.5) ? 0.0 : 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
float mix_multiply(float x, float y) {
|
|
||||||
return x*y;
|
|
||||||
}
|
|
||||||
|
|
||||||
float mix_add(float x, float y) {
|
|
||||||
return min(x+y, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float mix_max(float x, float y) {
|
|
||||||
return max(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
float mix_min(float x, float y) {
|
|
||||||
return min(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
float mix_min(float x, float y) {
|
|
||||||
return min(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
float mix_xor(float x, float y) {
|
|
||||||
return min(x+y, 2.0-x-y);
|
|
||||||
}
|
|
||||||
|
|
||||||
float mix_pow(float x, float y) {
|
|
||||||
return pow(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 blend_normal(vec2 uv, vec3 c1, vec3 c2, float opacity) {
|
|
||||||
return opacity*c1 + (1.0-opacity)*c2;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 blend_dissolve(vec2 uv, vec3 c1, vec3 c2, float opacity) {
|
|
||||||
if (rand(uv) < opacity) {
|
|
||||||
return c1;
|
|
||||||
} else {
|
|
||||||
return c2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 blend_multiply(vec2 uv, vec3 c1, vec3 c2, float opacity) {
|
|
||||||
return opacity*c1*c2 + (1.0-opacity)*c2;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 blend_screen(vec2 uv, vec3 c1, vec3 c2, float opacity) {
|
|
||||||
return opacity*(1.0-(1.0-c1)*(1.0-c2)) + (1.0-opacity)*c2;
|
|
||||||
}
|
|
||||||
|
|
||||||
float blend_overlay_f(float c1, float c2) {
|
|
||||||
return (c1 < 0.5) ? (2.0*c1*c2) : (1.0-2.0*(1.0-c1)*(1.0-c2));
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 blend_overlay(vec2 uv, vec3 c1, vec3 c2, float opacity) {
|
|
||||||
return opacity*vec3(blend_overlay_f(c1.x, c2.x), blend_overlay_f(c1.y, c2.y), blend_overlay_f(c1.z, c2.z)) + (1.0-opacity)*c2;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 blend_hard_light(vec2 uv, vec3 c1, vec3 c2, float opacity) {
|
|
||||||
return opacity*0.5*(c1*c2+blend_overlay(uv, c1, c2, 1.0)) + (1.0-opacity)*c2;
|
|
||||||
}
|
|
||||||
|
|
||||||
float blend_soft_light_f(float c1, float c2) {
|
|
||||||
return (c2 < 0.5) ? (2.0*c1*c2+c1*c1*(1.0-2.0*c2)) : 2.0*c1*(1.0-c2)+sqrt(c1)*(2.0*c2-1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 blend_soft_light(vec2 uv, vec3 c1, vec3 c2, float opacity) {
|
|
||||||
return opacity*vec3(blend_soft_light_f(c1.x, c2.x), blend_soft_light_f(c1.y, c2.y), blend_soft_light_f(c1.z, c2.z)) + (1.0-opacity)*c2;
|
|
||||||
}
|
|
||||||
|
|
||||||
float blend_burn_f(float c1, float c2) {
|
|
||||||
return (c1==0.0)?c1:max((1.0-((1.0-c2)/c1)),0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 blend_burn(vec2 uv, vec3 c1, vec3 c2, float opacity) {
|
|
||||||
return opacity*vec3(blend_burn_f(c1.x, c2.x), blend_burn_f(c1.y, c2.y), blend_burn_f(c1.z, c2.z)) + (1.0-opacity)*c2;
|
|
||||||
}
|
|
||||||
|
|
||||||
float blend_dodge_f(float c1, float c2) {
|
|
||||||
return (c1==1.0)?c1:min(c2/(1.0-c1),1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 blend_dodge(vec2 uv, vec3 c1, vec3 c2, float opacity) {
|
|
||||||
return opacity*vec3(blend_dodge_f(c1.x, c2.x), blend_dodge_f(c1.y, c2.y), blend_dodge_f(c1.z, c2.z)) + (1.0-opacity)*c2;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 blend_lighten(vec2 uv, vec3 c1, vec3 c2, float opacity) {
|
|
||||||
return opacity*max(c1, c2) + (1.0-opacity)*c2;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 blend_darken(vec2 uv, vec3 c1, vec3 c2, float opacity) {
|
|
||||||
return opacity*min(c1, c2) + (1.0-opacity)*c2;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 transform(vec2 uv, vec2 translate, float rotate, float scale) {
|
|
||||||
vec2 rv;
|
|
||||||
uv -= vec2(0.5);
|
|
||||||
rv.x = cos(rotate)*uv.x + sin(rotate)*uv.y;
|
|
||||||
rv.y = -sin(rotate)*uv.x + cos(rotate)*uv.y;
|
|
||||||
rv /= scale;
|
|
||||||
rv += vec2(0.5);
|
|
||||||
rv -= translate;
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
float bricks(vec2 uv, vec2 count, float offset, float mortar, float bevel) {
|
|
||||||
mortar /= max(count.x, count.y);
|
|
||||||
bevel /= max(count.x, count.y);
|
|
||||||
float fract_x = fract(uv.x*count.x+offset*step(0.5, fract(uv.y*count.y*0.5)));
|
|
||||||
float slope_x = 1.0/(bevel*count.x);
|
|
||||||
float off = 0.5*mortar/bevel;
|
|
||||||
float f1 = fract_x*slope_x-off;
|
|
||||||
float f2 = (1.0-fract_x)*slope_x-off;
|
|
||||||
float fract_y = fract(uv.y*count.y);
|
|
||||||
float slope_y = 1.0/(bevel*count.y);
|
|
||||||
float f3 = fract_y*slope_y-off;
|
|
||||||
float f4 = (1.0-fract_y)*slope_y-off;
|
|
||||||
return max(0.0, min(1.0, min(min(f1, f2), min(f3, f4))));
|
|
||||||
}
|
|
||||||
|
|
||||||
float colored_bricks(vec2 uv, vec2 count, float offset) {
|
|
||||||
float x = floor(uv.x*count.x+offset*step(0.5, fract(uv.y*count.y*0.5)));
|
|
||||||
float y = floor(uv.y*count.y);
|
|
||||||
return fract(x/3.0+y/7.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float perlin(vec2 uv, vec2 size, int iterations, float persistence, int seed) {
|
|
||||||
uv += vec2(float(seed)*0.1234567);
|
|
||||||
float rv = 0.0;
|
|
||||||
float coef = 1.0;
|
|
||||||
float acc = 0.0;
|
|
||||||
for (int i = 0; i < iterations; ++i) {
|
|
||||||
vec2 step = vec2(1.0)/size;
|
|
||||||
float f0 = rand(floor(fract(uv)*size));
|
|
||||||
float f1 = rand(floor(fract(uv+vec2(step.x, 0.0))*size));
|
|
||||||
float f2 = rand(floor(fract(uv+vec2(0.0, step.y))*size));
|
|
||||||
float f3 = rand(floor(fract(uv+vec2(step.x, step.y))*size));
|
|
||||||
vec2 mixval = fract(uv*size);
|
|
||||||
mixval = 0.5*(1.0-cos(3.1415928*mixval));
|
|
||||||
rv += coef * mix(mix(f0, f1, mixval.x), mix(f2, f3, mixval.x), mixval.y);
|
|
||||||
acc += coef;
|
|
||||||
size *= 2.0;
|
|
||||||
coef *= persistence;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv / acc;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 voronoi(vec2 uv, vec2 size, float intensity, int seed) {
|
|
||||||
uv += vec2(float(seed)*0.1234567);
|
|
||||||
uv *= size;
|
|
||||||
float best_distance0 = 1.0;
|
|
||||||
float best_distance1 = 1.0;
|
|
||||||
vec2 point0;
|
|
||||||
vec2 point1;
|
|
||||||
vec2 p0 = floor(uv);
|
|
||||||
for (int dx = -1; dx < 2; ++dx) {
|
|
||||||
for (int dy = -1; dy < 2; ++dy) {
|
|
||||||
vec2 d = vec2(float(dx), float(dy));
|
|
||||||
vec2 p = p0+d;
|
|
||||||
p += rand2(mod(p, size));
|
|
||||||
float distance = length((uv - p) / size);
|
|
||||||
if (best_distance0 > distance) {
|
|
||||||
best_distance1 = best_distance0;
|
|
||||||
best_distance0 = distance;
|
|
||||||
point1 = point0;
|
|
||||||
point0 = p;
|
|
||||||
} else if (best_distance1 > distance) {
|
|
||||||
best_distance1 = distance;
|
|
||||||
point1 = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
float edge_distance = dot(uv - 0.5*(point0+point1), normalize(point0-point1));
|
|
||||||
|
|
||||||
return vec4(point0, best_distance0*length(size)*intensity, edge_distance);
|
|
||||||
}
|
|
||||||
|
|
||||||
float Perlin_f(vec2 uv) { return perlin(uv, vec2(4.000000, 4.000000), 6, 0.500000000, 2375); }
|
|
||||||
float Bricks_f(vec2 uv) { return bricks(uv, vec2(3, 6), 0.5, 0.05, 0.2); }
|
|
||||||
vec3 colorize_3_gradient(float x) {
|
|
||||||
if (x < 0.000000000) {
|
|
||||||
return vec3(0.273438007,0.273438007,0.273438007);
|
|
||||||
} else if (x < 1.000000000) {
|
|
||||||
return vec3(0.273438007,0.273438007,0.273438007)+x*vec3(-0.273438007,-0.273438007,-0.273438007);
|
|
||||||
}
|
|
||||||
return vec3(0.000000000,0.000000000,0.000000000);
|
|
||||||
}
|
|
||||||
void fragment() {
|
void fragment() {
|
||||||
float Perlin_0_f = Perlin_f(UV+vec2(0.01, 0.0));
|
COLOR = vec4(1.0);
|
||||||
float Perlin_1_f = Perlin_f(UV-vec2(0.01, 0.0));
|
|
||||||
float Perlin_2_f = Perlin_f(UV+vec2(0.0, 0.01));
|
|
||||||
float Perlin_3_f = Perlin_f(UV-vec2(0.0, 0.01));
|
|
||||||
vec2 Warp_0_uv = UV+0.100000001*vec2((Perlin_0_f)-(Perlin_1_f), (Perlin_2_f)-(Perlin_3_f));
|
|
||||||
float Bricks_0_f = Bricks_f(Warp_0_uv);
|
|
||||||
vec3 Warp_0_rgb = vec3(Bricks_0_f);
|
|
||||||
float Warp_0_f = dot(vec3(Bricks_0_f), vec3(1.0))/3.0;
|
|
||||||
vec3 colorize_3_0_rgb = colorize_3_gradient(Warp_0_f);
|
|
||||||
COLOR = vec4(colorize_3_0_rgb, 1.0);
|
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
|
|
||||||
@ -268,7 +45,7 @@ _sections_unfolded = [ "Material", "Mouse", "Visibility" ]
|
|||||||
[node name="Material" parent="." index="0" instance=ExtResource( 2 )]
|
[node name="Material" parent="." index="0" instance=ExtResource( 2 )]
|
||||||
|
|
||||||
theme = SubResource( 1 )
|
theme = SubResource( 1 )
|
||||||
_sections_unfolded = [ "Anchor", "Margin", "Mouse", "Theme", "slot", "slot/2", "slot/3", "slot/4", "slot/5" ]
|
_sections_unfolded = [ "Anchor", "Margin", "Mouse", "Theme", "slot/2", "slot/3", "slot/4", "slot/5" ]
|
||||||
|
|
||||||
[node name="Timer" type="Timer" parent="." index="1"]
|
[node name="Timer" type="Timer" parent="." index="1"]
|
||||||
|
|
||||||
|
@ -15,6 +15,9 @@ const MENU = [
|
|||||||
{ menu="File" },
|
{ menu="File" },
|
||||||
{ menu="File", command="close_material", description="Close material" },
|
{ menu="File", command="close_material", description="Close material" },
|
||||||
{ menu="File", command="quit", shortcut="Control+Q", description="Quit" },
|
{ menu="File", command="quit", shortcut="Control+Q", description="Quit" },
|
||||||
|
{ menu="Edit", command="edit_cut", shortcut="Control+X", description="Cut" },
|
||||||
|
{ menu="Edit", command="edit_copy", shortcut="Control+C", description="Copy" },
|
||||||
|
{ menu="Edit", command="edit_paste", shortcut="Control+V", description="Paste" },
|
||||||
{ menu="Tools", command="add_to_user_library", description="Add selected node to user library" },
|
{ menu="Tools", command="add_to_user_library", description="Add selected node to user library" },
|
||||||
{ menu="Tools", command="save_user_library", description="Save user library" },
|
{ menu="Tools", command="save_user_library", description="Save user library" },
|
||||||
{ menu="Help", command="bug_report", description="Report a bug" },
|
{ menu="Help", command="bug_report", description="Report a bug" },
|
||||||
@ -118,6 +121,21 @@ func quit():
|
|||||||
else:
|
else:
|
||||||
get_tree().quit()
|
get_tree().quit()
|
||||||
|
|
||||||
|
func edit_cut():
|
||||||
|
var graph_edit = $VBoxContainer/HBoxContainer/Projects.get_current_tab_control()
|
||||||
|
if graph_edit != null:
|
||||||
|
graph_edit.cut()
|
||||||
|
|
||||||
|
func edit_copy():
|
||||||
|
var graph_edit = $VBoxContainer/HBoxContainer/Projects.get_current_tab_control()
|
||||||
|
if graph_edit != null:
|
||||||
|
graph_edit.copy()
|
||||||
|
|
||||||
|
func edit_paste():
|
||||||
|
var graph_edit = $VBoxContainer/HBoxContainer/Projects.get_current_tab_control()
|
||||||
|
if graph_edit != null:
|
||||||
|
graph_edit.paste()
|
||||||
|
|
||||||
func add_to_user_library():
|
func add_to_user_library():
|
||||||
var graph_edit = $VBoxContainer/HBoxContainer/Projects.get_current_tab_control()
|
var graph_edit = $VBoxContainer/HBoxContainer/Projects.get_current_tab_control()
|
||||||
if graph_edit != null and graph_edit is GraphEdit:
|
if graph_edit != null and graph_edit is GraphEdit:
|
||||||
|
@ -97,7 +97,7 @@ group = null
|
|||||||
text = "Edit"
|
text = "Edit"
|
||||||
flat = true
|
flat = true
|
||||||
align = 1
|
align = 1
|
||||||
items = [ ]
|
items = [ "Cut", null, 0, false, false, 11, 268435544, null, "", false, "Copy", null, 0, false, false, 12, 268435523, null, "", false, "Paste", null, 0, false, false, 13, 268435542, null, "", false ]
|
||||||
|
|
||||||
[node name="Tools" type="MenuButton" parent="VBoxContainer/Menu" index="2"]
|
[node name="Tools" type="MenuButton" parent="VBoxContainer/Menu" index="2"]
|
||||||
|
|
||||||
@ -122,7 +122,7 @@ group = null
|
|||||||
text = "Tools"
|
text = "Tools"
|
||||||
flat = true
|
flat = true
|
||||||
align = 1
|
align = 1
|
||||||
items = [ "Add selected node to user library", null, 0, false, false, 11, 0, null, "", false, "Save user library", null, 0, false, false, 12, 0, null, "", false ]
|
items = [ "Add selected node to user library", null, 0, false, false, 14, 0, null, "", false, "Save user library", null, 0, false, false, 15, 0, null, "", false ]
|
||||||
|
|
||||||
[node name="Help" type="MenuButton" parent="VBoxContainer/Menu" index="3"]
|
[node name="Help" type="MenuButton" parent="VBoxContainer/Menu" index="3"]
|
||||||
|
|
||||||
@ -147,7 +147,7 @@ group = null
|
|||||||
text = "Help"
|
text = "Help"
|
||||||
flat = true
|
flat = true
|
||||||
align = 1
|
align = 1
|
||||||
items = [ "Report a bug", null, 0, false, false, 13, 0, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "About", null, 0, false, false, 15, 0, null, "", false ]
|
items = [ "Report a bug", null, 0, false, false, 16, 0, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "About", null, 0, false, false, 18, 0, null, "", false ]
|
||||||
|
|
||||||
[node name="HBoxContainer" type="HSplitContainer" parent="VBoxContainer" index="1"]
|
[node name="HBoxContainer" type="HSplitContainer" parent="VBoxContainer" index="1"]
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
; param=value ; assign values to parameters
|
; param=value ; assign values to parameters
|
||||||
|
|
||||||
config_version=3
|
config_version=3
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|
||||||
config/name="Material Maker"
|
config/name="Material Maker"
|
||||||
|
Loading…
Reference in New Issue
Block a user