Add settings that persist
This commit is contained in:
parent
60c0c6e71e
commit
798dcbc1bd
77
Cargo.lock
generated
77
Cargo.lock
generated
@ -41,6 +41,12 @@ version = "0.2.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
|
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "equivalent"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gdextension-api"
|
name = "gdextension-api"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
@ -138,12 +144,28 @@ dependencies = [
|
|||||||
"zerocopy",
|
"zerocopy",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.17.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "2.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
|
||||||
|
dependencies = [
|
||||||
|
"equivalent",
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.186"
|
version = "0.2.186"
|
||||||
@ -181,6 +203,7 @@ dependencies = [
|
|||||||
"godot",
|
"godot",
|
||||||
"serde",
|
"serde",
|
||||||
"teanet",
|
"teanet",
|
||||||
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -222,6 +245,15 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_spanned"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26"
|
||||||
|
dependencies = [
|
||||||
|
"serde_core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.119"
|
version = "2.0.119"
|
||||||
@ -262,6 +294,45 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "1.1.3+spec-1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53c96ecdfa941c8fc4fcaed14f99ada8ebed502eef533015095a07e3301d4c3c"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"serde_core",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"toml_parser",
|
||||||
|
"toml_writer",
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_datetime"
|
||||||
|
version = "1.1.1+spec-1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7"
|
||||||
|
dependencies = [
|
||||||
|
"serde_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_parser"
|
||||||
|
version = "1.1.2+spec-1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526"
|
||||||
|
dependencies = [
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_writer"
|
||||||
|
version = "1.1.2+spec-1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.24"
|
version = "1.0.24"
|
||||||
@ -278,6 +349,12 @@ dependencies = [
|
|||||||
"quote",
|
"quote",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
version = "0.8.54"
|
version = "0.8.54"
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
[gd_scene format=3 uid="uid://lahirbqfppvw"]
|
[gd_scene format=3 uid="uid://lahirbqfppvw"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://bbmc2gmy7g8ag" path="res://scenes/misc/menu_player.tscn" id="1_o5qli"]
|
[ext_resource type="PackedScene" uid="uid://bbmc2gmy7g8ag" path="res://scenes/misc/menu_player.tscn" id="1_o5qli"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://n3u0jr4wiib1" path="res://scenes/ui/settings.tscn" id="2_0wfyh"]
|
||||||
|
|
||||||
[node name="menu" type="MainMenu" unique_id=2036763876 node_paths=PackedStringArray("camera", "main_position", "host_position", "main_panel", "host_panel", "join_panel", "host_port", "join_addr", "popup_panel", "popup_title", "popup_text", "popup_button")]
|
[node name="menu" type="MainMenu" unique_id=2036763876 node_paths=PackedStringArray("camera", "main_position", "host_position", "main_panel", "host_panel", "join_panel", "host_port", "join_addr", "popup_panel", "popup_title", "popup_text", "popup_button")]
|
||||||
camera = NodePath("camera_3d")
|
camera = NodePath("camera_3d")
|
||||||
@ -175,6 +176,9 @@ text = "Join"
|
|||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "Back"
|
text = "Back"
|
||||||
|
|
||||||
|
[node name="settings" parent="." unique_id=999912383 instance=ExtResource("2_0wfyh")]
|
||||||
|
visible = false
|
||||||
|
|
||||||
[node name="main_pos" type="Node3D" parent="." unique_id=98241074]
|
[node name="main_pos" type="Node3D" parent="." unique_id=98241074]
|
||||||
transform = Transform3D(0.98629165, -0.031186387, 0.16203767, -1.4054484e-08, 0.981978, 0.1889952, -0.16501155, -0.18640435, 0.9685167, 1.0974054, 1.7166122, 1.4909104)
|
transform = Transform3D(0.98629165, -0.031186387, 0.16203767, -1.4054484e-08, 0.981978, 0.1889952, -0.16501155, -0.18640435, 0.9685167, 1.0974054, 1.7166122, 1.4909104)
|
||||||
|
|
||||||
@ -232,6 +236,7 @@ text = "Ok"
|
|||||||
|
|
||||||
[connection signal="pressed" from="main_panel/v_box_container/host" to="." method="go_to_host_game"]
|
[connection signal="pressed" from="main_panel/v_box_container/host" to="." method="go_to_host_game"]
|
||||||
[connection signal="pressed" from="main_panel/v_box_container/join" to="." method="go_to_join_game"]
|
[connection signal="pressed" from="main_panel/v_box_container/join" to="." method="go_to_join_game"]
|
||||||
|
[connection signal="pressed" from="main_panel/v_box_container/settings" to="settings" method="open"]
|
||||||
[connection signal="pressed" from="main_panel/v_box_container/quit" to="." method="quit_game"]
|
[connection signal="pressed" from="main_panel/v_box_container/quit" to="." method="quit_game"]
|
||||||
[connection signal="pressed" from="host_panel/v_box_container/host" to="." method="host_game"]
|
[connection signal="pressed" from="host_panel/v_box_container/host" to="." method="host_game"]
|
||||||
[connection signal="pressed" from="host_panel/v_box_container/back" to="." method="go_to_main_menu"]
|
[connection signal="pressed" from="host_panel/v_box_container/back" to="." method="go_to_main_menu"]
|
||||||
|
|||||||
54
godot/scenes/ui/settings.tscn
Normal file
54
godot/scenes/ui/settings.tscn
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
[gd_scene format=3 uid="uid://n3u0jr4wiib1"]
|
||||||
|
|
||||||
|
[ext_resource type="PackedScene" uid="uid://cqiwdajl71ujv" path="res://scenes/ui/slider.tscn" id="1_8wfqe"]
|
||||||
|
|
||||||
|
[node name="settings" type="SettingsPanel" unique_id=999912383 node_paths=PackedStringArray("settings_grid")]
|
||||||
|
settings_grid = NodePath("grid")
|
||||||
|
slider_scene = ExtResource("1_8wfqe")
|
||||||
|
anchors_preset = 8
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_left = -207.0
|
||||||
|
offset_top = -112.0
|
||||||
|
offset_right = 207.0
|
||||||
|
offset_bottom = 112.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
|
[node name="label" type="Label" parent="." unique_id=2036746921]
|
||||||
|
layout_mode = 0
|
||||||
|
offset_left = 57.0
|
||||||
|
offset_right = 357.0
|
||||||
|
offset_bottom = 23.0
|
||||||
|
text = "Settings"
|
||||||
|
horizontal_alignment = 1
|
||||||
|
|
||||||
|
[node name="grid" type="GridContainer" parent="." unique_id=833231169]
|
||||||
|
custom_minimum_size = Vector2(400, 0)
|
||||||
|
custom_maximum_size = Vector2(400, -1)
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 8
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_left = -145.0
|
||||||
|
offset_top = -74.0
|
||||||
|
offset_right = 155.0
|
||||||
|
offset_bottom = 67.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
columns = 2
|
||||||
|
|
||||||
|
[node name="button" type="Button" parent="." unique_id=1301469030]
|
||||||
|
layout_mode = 0
|
||||||
|
offset_left = 182.0
|
||||||
|
offset_top = 192.0
|
||||||
|
offset_right = 232.0
|
||||||
|
offset_bottom = 223.0
|
||||||
|
size_flags_horizontal = 4
|
||||||
|
text = "Close"
|
||||||
|
|
||||||
|
[connection signal="pressed" from="button" to="." method="close"]
|
||||||
19
godot/scenes/ui/slider.tscn
Normal file
19
godot/scenes/ui/slider.tscn
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
[gd_scene format=3 uid="uid://cqiwdajl71ujv"]
|
||||||
|
|
||||||
|
[node name="slider" type="SliderContainer" unique_id=2000698366 node_paths=PackedStringArray("label", "slider")]
|
||||||
|
label = NodePath("label")
|
||||||
|
slider = NodePath("h_slider")
|
||||||
|
value = 50.0
|
||||||
|
max = 100.0
|
||||||
|
offset_right = 214.0
|
||||||
|
offset_bottom = 23.0
|
||||||
|
|
||||||
|
[node name="label" type="Label" parent="." unique_id=2059967949]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "50"
|
||||||
|
|
||||||
|
[node name="h_slider" type="HSlider" parent="." unique_id=1564648919]
|
||||||
|
custom_minimum_size = Vector2(200, 0)
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_vertical = 4
|
||||||
|
value = 50.0
|
||||||
@ -10,3 +10,4 @@ crate-type = ["cdylib"] # Compile this crate to a dynamic C library.
|
|||||||
godot = "0.5.4"
|
godot = "0.5.4"
|
||||||
serde = "1.0.228"
|
serde = "1.0.228"
|
||||||
teanet = { path = "../teanet-rust" }
|
teanet = { path = "../teanet-rust" }
|
||||||
|
toml = "1.1.3"
|
||||||
|
|||||||
47
rust/src/game_settings.rs
Normal file
47
rust/src/game_settings.rs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
use godot::{
|
||||||
|
classes::{FileAccess, file_access::ModeFlags},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct GameSettings {
|
||||||
|
pub fov: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for GameSettings {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { fov: 90. }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(GodotClass)]
|
||||||
|
#[class(base=Node, singleton)]
|
||||||
|
pub struct GameSettingsManager {
|
||||||
|
pub settings: GameSettings,
|
||||||
|
base: Base<Node>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[godot_api]
|
||||||
|
impl INode for GameSettingsManager {
|
||||||
|
fn init(base: Base<Node>) -> GameSettingsManager {
|
||||||
|
let mut settings = GameSettings::default();
|
||||||
|
if let Some(file) = FileAccess::open("user://config.toml", ModeFlags::READ) {
|
||||||
|
if let Ok(deserialized) = toml::from_str(&file.get_as_text().to_string()) {
|
||||||
|
settings = deserialized;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GameSettingsManager { settings, base }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GameSettingsManager {
|
||||||
|
pub fn update_settings(&mut self, settings: GameSettings) {
|
||||||
|
self.settings = settings;
|
||||||
|
if let Some(mut file) = FileAccess::open("user://config.toml", ModeFlags::WRITE) {
|
||||||
|
if let Ok(serialized) = toml::to_string(&self.settings) {
|
||||||
|
file.store_string(&serialized);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,6 +3,7 @@ use godot::prelude::*;
|
|||||||
pub mod ball;
|
pub mod ball;
|
||||||
pub mod cli_parser;
|
pub mod cli_parser;
|
||||||
pub mod game_manager;
|
pub mod game_manager;
|
||||||
|
pub mod game_settings;
|
||||||
pub mod goal;
|
pub mod goal;
|
||||||
pub mod killbox;
|
pub mod killbox;
|
||||||
pub mod map;
|
pub mod map;
|
||||||
|
|||||||
@ -6,4 +6,6 @@ pub mod main_menu;
|
|||||||
pub mod menu_player;
|
pub mod menu_player;
|
||||||
pub mod net_stats;
|
pub mod net_stats;
|
||||||
pub mod player_listing;
|
pub mod player_listing;
|
||||||
|
pub mod settings;
|
||||||
pub mod simple_score_view;
|
pub mod simple_score_view;
|
||||||
|
pub mod slider;
|
||||||
|
|||||||
137
rust/src/ui/settings.rs
Normal file
137
rust/src/ui/settings.rs
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use godot::{
|
||||||
|
classes::{Control, GridContainer, IPanel, Label, Panel, control::SizeFlags},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
game_settings::{GameSettings, GameSettingsManager},
|
||||||
|
ui::slider::SliderContainer,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Hash)]
|
||||||
|
pub enum Setting {
|
||||||
|
FoV,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for Setting {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
match self {
|
||||||
|
Setting::FoV => "Field of View",
|
||||||
|
}
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub enum SettingValue {
|
||||||
|
SliderNumber(SliderValue),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct SliderValue {
|
||||||
|
min: f64,
|
||||||
|
max: f64,
|
||||||
|
value: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(GodotClass)]
|
||||||
|
#[class(base=Panel, init)]
|
||||||
|
pub struct SettingsPanel {
|
||||||
|
#[export]
|
||||||
|
settings_grid: Option<Gd<GridContainer>>,
|
||||||
|
#[export]
|
||||||
|
slider_scene: Option<Gd<PackedScene>>,
|
||||||
|
|
||||||
|
settings: HashMap<Setting, SettingValue>,
|
||||||
|
|
||||||
|
base: Base<Panel>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[godot_api]
|
||||||
|
impl IPanel for SettingsPanel {
|
||||||
|
fn ready(&mut self) {
|
||||||
|
let singleton = GameSettingsManager::singleton();
|
||||||
|
let settings = &singleton.bind().settings;
|
||||||
|
self.settings.insert(
|
||||||
|
Setting::FoV,
|
||||||
|
SettingValue::SliderNumber(SliderValue {
|
||||||
|
min: 60.,
|
||||||
|
max: 120.,
|
||||||
|
value: settings.fov,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(mut grid) = self.settings_grid.clone() {
|
||||||
|
for (setting, value) in &self.settings {
|
||||||
|
let mut label = Label::new_alloc();
|
||||||
|
label.set_text(&setting.to_string());
|
||||||
|
label.set_h_size_flags(SizeFlags::EXPAND | SizeFlags::SHRINK_BEGIN);
|
||||||
|
grid.add_child(&label);
|
||||||
|
|
||||||
|
if let Some(scene) = self.slider_scene.clone() {
|
||||||
|
let node = match value {
|
||||||
|
SettingValue::SliderNumber(slider_value) => {
|
||||||
|
let mut slider = scene.instantiate_as::<SliderContainer>();
|
||||||
|
|
||||||
|
slider.bind_mut().min = slider_value.min;
|
||||||
|
slider.bind_mut().max = slider_value.max;
|
||||||
|
slider.bind_mut().value = slider_value.value;
|
||||||
|
|
||||||
|
let setting_clone = setting.clone();
|
||||||
|
let value_clone = slider_value.clone();
|
||||||
|
slider.bind_mut().signals().on_change().connect_other(
|
||||||
|
self,
|
||||||
|
move |s, new_value| {
|
||||||
|
s.run_deferred(move |s| {
|
||||||
|
s.on_change(
|
||||||
|
setting_clone,
|
||||||
|
SettingValue::SliderNumber(SliderValue {
|
||||||
|
value: new_value,
|
||||||
|
..value_clone
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
slider.upcast::<Control>()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
grid.add_child(&node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[godot_api]
|
||||||
|
impl SettingsPanel {
|
||||||
|
pub fn on_change(&mut self, setting: Setting, new_value: SettingValue) {
|
||||||
|
self.settings.insert(setting, new_value);
|
||||||
|
|
||||||
|
let mut new_settings = GameSettingsManager::singleton().bind().settings.clone();
|
||||||
|
for (setting, value) in &self.settings {
|
||||||
|
match (setting, value) {
|
||||||
|
(Setting::FoV, SettingValue::SliderNumber(value)) => {
|
||||||
|
new_settings.fov = value.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GameSettingsManager::singleton()
|
||||||
|
.bind_mut()
|
||||||
|
.update_settings(new_settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[func]
|
||||||
|
pub fn open(&mut self) {
|
||||||
|
self.base_mut().set_visible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[func]
|
||||||
|
pub fn close(&mut self) {
|
||||||
|
self.base_mut().set_visible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
56
rust/src/ui/slider.rs
Normal file
56
rust/src/ui/slider.rs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
use godot::{
|
||||||
|
classes::{HBoxContainer, IHBoxContainer, Label, Slider},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(GodotClass)]
|
||||||
|
#[class(base=HBoxContainer, init, tool)]
|
||||||
|
pub struct SliderContainer {
|
||||||
|
#[export]
|
||||||
|
label: Option<Gd<Label>>,
|
||||||
|
#[export]
|
||||||
|
slider: Option<Gd<Slider>>,
|
||||||
|
#[export]
|
||||||
|
pub value: f64,
|
||||||
|
#[export]
|
||||||
|
pub min: f64,
|
||||||
|
#[export]
|
||||||
|
pub max: f64,
|
||||||
|
|
||||||
|
last_value: f64,
|
||||||
|
|
||||||
|
base: Base<HBoxContainer>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[godot_api]
|
||||||
|
impl IHBoxContainer for SliderContainer {
|
||||||
|
fn ready(&mut self) {}
|
||||||
|
|
||||||
|
fn process(&mut self, _delta: f64) {
|
||||||
|
if let Some(slider) = &mut self.slider {
|
||||||
|
slider.set_min(self.min);
|
||||||
|
slider.set_max(self.max);
|
||||||
|
if self.last_value != self.value {
|
||||||
|
slider.set_value(self.value);
|
||||||
|
}
|
||||||
|
self.value = slider.get_value();
|
||||||
|
if self.last_value != self.value {
|
||||||
|
let value = self.value;
|
||||||
|
self.signals().on_change().emit(value);
|
||||||
|
}
|
||||||
|
self.last_value = self.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(label) = &mut self.label
|
||||||
|
&& let Some(slider) = &self.slider
|
||||||
|
{
|
||||||
|
label.set_text(&format!("{}", slider.get_value()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[godot_api]
|
||||||
|
impl SliderContainer {
|
||||||
|
#[signal]
|
||||||
|
pub fn on_change(value: f64);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user