This repository has been archived on 2024-04-19. You can view files and clone it, but cannot push or open issues or pull requests.
Jessist/addons/godot-immediate-gui/GUI.gd

285 lines
7.4 KiB
GDScript3
Raw Permalink Normal View History

2022-06-18 13:05:48 +02:00
extends Control
var boxes = [];
var used = [];
var notused = [];
var layout := true;
var _layout := VBoxContainer.new();
var _last_control;
var _default = {
Control:{
"size_flags_horizontal":0,
"size_flags_vertical":0,
},
BaseButton:{
"action_mode":BaseButton.ACTION_MODE_BUTTON_PRESS,
"mouse_default_cursor_shape":CURSOR_POINTING_HAND,
},
ColorPickerButton:{
"rect_min_size":Vector2(20, 20),
},
};
var property = {};
func clear_default():
_default.clear();
# warning-ignore:shadowed_variable
func add_default(type, property, value):
var props = _default.get(type);
if props == null:
props = {};
_default[type] = props;
props[property] = value;
# warning-ignore:shadowed_variable
func remove_default(type, property=null):
var props = _default.get(type);
assert(props != null, str("There is no default values for type \"", type, "\""));
if property == null:
_default.erase(type);
return;
var has_property = props.has(property);
assert(has_property, str("Can't remove property \"", property, "\" from type \"", type, "\", property not set"));
if has_property:
props.erase(property);
func _init():
mouse_filter = MOUSE_FILTER_IGNORE;
_layout.mouse_filter = MOUSE_FILTER_IGNORE;
func _ready():
add_child(_layout);
set_anchors_and_margins_preset(PRESET_WIDE);
_layout.set_anchors_and_margins_preset(PRESET_WIDE);
func _process(delta):
get_parent().propagate_call("_gui", [delta]);
raise();
layout = true;
assert(boxes.size() == 0, "Not all containers are closed. Use GUI.end() to close containers.");
boxes.clear();
for c in notused:
c.queue_free();
notused.clear();
var t = notused;
notused = used;
used = t;
func printvar(node, v):
label(str(node.name, " ", "[", node.get_instance_id(), "] ", v, ": ", node.get(v)));
func _get_control(type, text=null):
var _c;
for c in notused:
if c is type:
_c = c;
c.base.revert();
notused.erase(c);
break;
if _c == null:
_c = type.new();
used.append(_c);
# warning-ignore:incompatible_ternary
# warning-ignore:incompatible_ternary
reparent(_c, (_layout if layout else self) if boxes.size() == 0 else boxes[-1]);
if text != null:
_c.text = str(text);
_c.rect_size = Vector2();
for type in _default.keys():
if _c is type:
var defs = _default[type];
for p in defs.keys():
_c.base.set_property(p, defs[p]);
for p in property.keys():
_c.base.set_property(p, property[p]);
property.clear();
_last_control = _c;
return _c;
func reparent(node:Node, new_parent:Node):
var p = node.get_parent();
if p == new_parent:
node.raise();
return;
if p != null:
p.remove_child(node);
if new_parent != null:
new_parent.add_child(node);
func _toggle(type, text, state):
var b = _get_control(type, text);
b.pressed = !state if b.base.get_changed() else state;
return b.pressed;
func label(text):
_get_control(GUILabel, text);
func button(text):
return _get_control(GUIButton, text).base.get_changed();
func buttonpress(text):
var b = _get_control(GUIButton, text);
b.base.get_changed();
return b.pressed;
func toggle(text, state:bool):
return _toggle(GUIToggle, text, state);
func checkbox(text, state:bool):
return _toggle(GUICheckBox, text, state);
func checkbutton(text, state:bool):
return _toggle(GUICheckButton, text, state);
func options(selected:int, options:Array):
var b = _get_control(GUIOptions);
b.set_options(options);
if !b.base.get_changed():
b.selected = selected;
return b.selected;
func pickcolor(color:Color, edit_alpha:bool=true):
var c = _get_control(GUIPickColor);
c.edit_alpha = edit_alpha;
c.get_popup().rect_global_position = c.rect_global_position + Vector2(0, c.rect_size.y);
if !c.base.get_changed():
c.color = color;
return c.color;
func progress(value:float, percent_visible:bool=true):
var c = _get_control(GUIProgress);
c.percent_visible = percent_visible;
c.min_value = 0;
c.max_value = 100;
c.value = value*100;
func spin(value, min_value, max_value, step=null):
var c = _get_control(GUISpin);
c.min_value = min_value;
c.max_value = max_value;
c.step = (1.0 if value is int else 0.001) if step == null else step;
if !c.base.get_changed() && c.value != value:
c.value = value;
return c.value;
func line(text:String):
var l = _get_control(GUILine);
if !l.base.get_changed() && l.text != text:
l.text = text;
return l.text;
func _get_box(type):
var box = _get_control(type);
boxes.append(box);
return box;
func control():
_get_box(GUIControl);
return true;
func hbox(separation=null):
var box = _get_box(GUIHBox);
box.set("custom_constants/separation", separation);
return true;
func vbox(separation=null):
var box = _get_box(GUIVBox);
box.set("custom_constants/separation", separation);
return true;
func grid(columns:int, vseparation=null, hseparation=null):
var box = _get_box(GUIGrid);
box.columns = columns;
box.set("custom_constants/vseparation", vseparation);
box.set("custom_constants/hseparation", hseparation);
return true;
func panel():
_get_box(GUIPanel);
return true;
func margin(left:int=0, top:int=0, right:int=0, bottom:int=0):
var box = _get_box(GUIMargin);
box.set("custom_constants/margin_left", left);
box.set("custom_constants/margin_top", top);
box.set("custom_constants/margin_right", right);
box.set("custom_constants/margin_bottom", bottom);
return true;
func center():
_get_box(GUICenter);
return true;
func scroll():
_get_box(GUIScroll);
return true;
func end():
boxes.pop_back();
class GUIControl extends Control:
var base = GUIBase.new(self);
class GUIVBox extends VBoxContainer:
var base = GUIBase.new(self);
class GUIHBox extends HBoxContainer:
var base = GUIBase.new(self);
class GUIGrid extends GridContainer:
var base = GUIBase.new(self);
class GUIPanel extends PanelContainer:
var base = GUIBase.new(self);
class GUIMargin extends MarginContainer:
var base = GUIBase.new(self);
class GUICenter extends CenterContainer:
var base = GUIBase.new(self);
class GUIScroll extends ScrollContainer:
var base = GUIBase.new(self);
class GUILabel extends Label:
var base = GUIBase.new(self);
class GUIBaseButton extends Button:
var base = GUIBase.new(self, "pressed");
class GUIButton extends GUIBaseButton:
pass
class GUIToggle extends GUIBaseButton:
func _init():
toggle_mode = true;
class GUICheckBox extends CheckBox:
var base = GUIBase.new(self, "pressed");
class GUICheckButton extends CheckButton:
var base = GUIBase.new(self, "pressed");
class GUIOptions extends OptionButton:
var base = GUIBase.new(self, "item_selected");
var options = [];
func set_options(_options):
if options != _options:
options = _options;
clear();
for text in options:
add_item(str(text));
class GUILine extends LineEdit:
var base = GUIBase.new(self, "text_changed");
class GUIPickColor extends ColorPickerButton:
var base = GUIBase.new(self, "color_changed");
class GUIProgress extends ProgressBar:
var base = GUIBase.new(self);
class GUISpin extends SpinBox:
var base = GUIBase.new(self, "value_changed");
class GUIBase:
var node;
var changed:bool;
func _changed(_v=null):
changed = true;
func get_changed():
if changed:
changed = false;
return true;
return false;
var defs = {};
var edited = [];
func _init(_node, _signal=null):
node = _node;
if _signal != null:
node.connect(_signal, self, "_changed");
func set_property(p, v):
if !defs.has(p):
defs[p] = node.get(p);
edited.append(p);
node.set(p, v);
func revert():
for p in edited:
var def = defs.get(p);
if node.get(p) != def:
node.set(p, def);
edited.clear();