Skip to content

Commit

Permalink
INDEV - Gui nodes CollapsableVBox and LabelledHSlider
Browse files Browse the repository at this point in the history
  • Loading branch information
QueenOfSquiggles committed Mar 20, 2024
1 parent fcb95f9 commit 8335d25
Show file tree
Hide file tree
Showing 8 changed files with 294 additions and 0 deletions.
4 changes: 4 additions & 0 deletions scenes/prefabs/sqore_options_menu/gameplay.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
extends CollapsingVBoxContainer

func _ready() -> void:
pass
12 changes: 12 additions & 0 deletions scenes/prefabs/sqore_options_menu/sqore_options_menu.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
extends VBoxContainer
"""
Relatively system agnostic menu for use of quickly bootstrapping an options menu for your game. If you want to create a custom menu this may serve as a template and example of how to interface with Sqore's various system settings
"""

## When entering the tree, forces Sqore global settings to be loaded from disk (in cast that hasn't happened yet)
func _enter_tree() -> void:
Sqore.reload_globals()

## When exiting the tree, force Sqore to save to disk any changes that have been made. This helps to prevent any dissonance between runtime globals and disk.
func _exit_tree() -> void:
Sqore.save_globals()
100 changes: 100 additions & 0 deletions scenes/prefabs/sqore_options_menu/sqore_options_menu.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
[gd_scene load_steps=3 format=3 uid="uid://dnbbxlomwl1pr"]

[ext_resource type="Script" path="res://addons/sqore/scenes/prefabs/sqore_options_menu/sqore_options_menu.gd" id="1_6met4"]
[ext_resource type="Script" path="res://addons/sqore/scenes/prefabs/sqore_options_menu/gameplay.gd" id="2_n73id"]

[node name="SqoreOptionsMenu" type="VBoxContainer"]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_6met4")

[node name="Gameplay" type="CollapsingVBoxContainer" parent="."]
heading_text = "Gameplay"
layout_mode = 2
script = ExtResource("2_n73id")

[node name="HFlowContainer" type="HFlowContainer" parent="Gameplay"]
visible = false
layout_mode = 2

[node name="CheckSSAO" type="CheckButton" parent="Gameplay/HFlowContainer"]
layout_mode = 2
text = "Use SSAO"

[node name="CheckBloom" type="CheckButton" parent="Gameplay/HFlowContainer"]
layout_mode = 2

[node name="CheckSDFGI" type="CheckButton" parent="Gameplay/HFlowContainer"]
layout_mode = 2

[node name="CheckSSIL" type="CheckButton" parent="Gameplay/HFlowContainer"]
layout_mode = 2

[node name="CheckSSR" type="CheckButton" parent="Gameplay/HFlowContainer"]
layout_mode = 2

[node name="Graphics" type="CollapsingVBoxContainer" parent="."]
heading_text = "Graphics"
layout_mode = 2

[node name="Controls" type="CollapsingVBoxContainer" parent="."]
heading_text = "Controls"
layout_mode = 2

[node name="Audio" type="CollapsingVBoxContainer" parent="."]
heading_text = "Audio"
layout_mode = 2

[node name="HSlider" type="HSlider" parent="."]
custom_minimum_size = Vector2(0, 64)
layout_mode = 2

[node name="Title" type="Label" parent="HSlider"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
text = "asdasdasd"

[node name="Min" type="Label" parent="HSlider"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
text = "0"
vertical_alignment = 2

[node name="Max" type="Label" parent="HSlider"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
text = "1"
horizontal_alignment = 2
vertical_alignment = 2

[node name="Current" type="Label" parent="HSlider"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
text = "0.55556"
horizontal_alignment = 1
vertical_alignment = 2

[node name="LabelledHSlider" type="LabelledHSlider" parent="."]
text = "This is a cool slider"
custom_minimum_size = Vector2(0, 64)
layout_mode = 2
max_value = 89.46
2 changes: 2 additions & 0 deletions sqore.gdextension
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
[configuration]
entry_symbol = "gdext_rust_init"
compatibility_minimum = 4.2

;; set to false for better performance. Set to true for development
reloadable = false


Expand Down
73 changes: 73 additions & 0 deletions src/scene/gui/collapsable_container.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use godot::engine::Button;
use godot::engine::Control;
use godot::engine::IVBoxContainer;
use godot::engine::VBoxContainer;
use godot::prelude::*;

#[derive(GodotClass)]
#[class(tool, init, base=VBoxContainer)]
pub struct CollapsingVBoxContainer {
#[export]
#[var(get,set = set_heading_text)]
heading_text: GString,

#[export]
default_visibility: bool,

heading: Option<Gd<Button>>,
base: Base<VBoxContainer>,
}

#[godot_api]
impl IVBoxContainer for CollapsingVBoxContainer {
fn enter_tree(&mut self) {
let mut heading_button = Button::new_alloc();
self.heading = Some(heading_button.clone());
heading_button.set_text(self.heading_text.clone());
heading_button.set_toggle_mode(true);
heading_button.set_pressed(self.default_visibility);
self.base_mut().add_child(heading_button.clone().upcast());
self.base_mut()
.move_child(heading_button.clone().upcast(), 0);
heading_button.connect(
StringName::from("toggled"),
Callable::from_object_method(&self.to_gd(), "on_heading_toggle"),
);
self.on_heading_toggle(self.default_visibility);
}

fn ready(&mut self) {
// is anything needed here??
}
}

#[godot_api]
impl CollapsingVBoxContainer {
#[func]
fn on_heading_toggle(&mut self, is_toggled: bool) {
let mut children: Vec<Gd<Node>> = self.base_mut().get_children().iter_shared().collect();
if let Some(btn) = &self.heading {
let btn_base = &btn.clone().upcast::<Node>();
children = children.into_iter().filter(|p| p != btn_base).collect();

Check failure on line 51 in src/scene/gui/collapsable_container.rs

View workflow job for this annotation

GitHub Actions / Clippy

this expression can be written more simply using `.retain()`
}
for child in children {
if let Ok(control) = &mut child.clone().try_cast::<Control>() {
control.set_visible(is_toggled);
}
if let Ok(node2d) = &mut child.clone().try_cast::<Node2D>() {
node2d.set_visible(is_toggled);
}
if let Ok(node3d) = &mut child.clone().try_cast::<Node3D>() {
node3d.set_visible(is_toggled);
}
}
}

#[func]
fn set_heading_text(&mut self, n_text: GString) {
self.heading_text = n_text;
if let Some(btn) = &mut self.heading {
btn.set_text(self.heading_text.clone());
}
}
}
100 changes: 100 additions & 0 deletions src/scene/gui/labelled_hslider.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
use godot::{
engine::{
control::LayoutPreset,
global::{HorizontalAlignment, VerticalAlignment},
HSlider, IHSlider, Label,
},
obj::WithBaseField,
prelude::*,
};

#[derive(GodotClass)]
#[class(tool, init, base=HSlider)]
pub struct LabelledHSlider {
#[export]
#[var(get, set=set_text)]
text: GString,

label_title: Option<Gd<Label>>,
label_min: Option<Gd<Label>>,
label_max: Option<Gd<Label>>,
label_current: Option<Gd<Label>>,

base: Base<HSlider>,
}

#[godot_api]
impl IHSlider for LabelledHSlider {
fn enter_tree(&mut self) {
//pass
let mut l_title = Label::new_alloc();
let mut l_min = Label::new_alloc();
let mut l_max = Label::new_alloc();
let mut l_cur = Label::new_alloc();
l_title.set_text(self.text.clone());
l_min.set_text(Self::as_text(self.base().get_min()));
l_max.set_text(Self::as_text(self.base().get_max()));
l_cur.set_text(Self::as_text(self.base().get_value()));

let call_range = Callable::from_object_method(&self.to_gd(), "update_range");
let call_value = Callable::from_object_method(&self.to_gd(), "update_value");
self.base_mut().add_child(l_title.clone().upcast());
self.base_mut().add_child(l_min.clone().upcast());
self.base_mut().add_child(l_max.clone().upcast());
self.base_mut().add_child(l_cur.clone().upcast());
self.base_mut()
.connect(StringName::from("changed"), call_range);
self.base_mut()
.connect(StringName::from("value_changed"), call_value);

l_title.set_anchors_and_offsets_preset(LayoutPreset::FULL_RECT);
l_title.set_vertical_alignment(VerticalAlignment::TOP);
l_title.set_horizontal_alignment(HorizontalAlignment::LEFT);

l_min.set_anchors_and_offsets_preset(LayoutPreset::FULL_RECT);
l_min.set_vertical_alignment(VerticalAlignment::BOTTOM);
l_min.set_horizontal_alignment(HorizontalAlignment::LEFT);

l_max.set_anchors_and_offsets_preset(LayoutPreset::FULL_RECT);
l_max.set_vertical_alignment(VerticalAlignment::BOTTOM);
l_max.set_horizontal_alignment(HorizontalAlignment::RIGHT);

l_cur.set_anchors_and_offsets_preset(LayoutPreset::FULL_RECT);
l_cur.set_vertical_alignment(VerticalAlignment::BOTTOM);
l_cur.set_horizontal_alignment(HorizontalAlignment::CENTER);
}
}

#[godot_api]
impl LabelledHSlider {
#[func]
fn set_text(&mut self, n_text: GString) {
self.text = n_text.clone();
if let Some(label) = &mut self.label_title {
label.set_text(n_text);
}
}
#[func]
fn update_range(&mut self) {
let min = self.base().get_min();
let max = self.base().get_max();
if let Some(l_min) = &mut self.label_min {
l_min.set_text(Self::as_text(min));
}
if let Some(l_max) = &mut self.label_max {
l_max.set_text(Self::as_text(max));
}
}

#[func]
fn update_value(&mut self, value: f64) {
let Some(label) = &mut self.label_current else {
return;
};
label.set_text(Self::as_text(value));
}

fn as_text(num: f64) -> GString {
format!("{}", num).to_godot()
}
}
2 changes: 2 additions & 0 deletions src/scene/gui/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod collapsable_container;
pub mod labelled_hslider;
1 change: 1 addition & 0 deletions src/scene/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub mod signals;
pub mod state_machine;
pub mod utility_nodes;
pub mod vfx_stack;
pub mod gui;

pub fn register_singletons() {
game_globals::register_singleton();
Expand Down

0 comments on commit 8335d25

Please sign in to comment.