161 lines
5.1 KiB
Rust
161 lines
5.1 KiB
Rust
use std::collections::HashMap;
|
|
|
|
use godot::{
|
|
classes::{Control, GridContainer, IPanel, Label, LineEdit, Panel, control::SizeFlags},
|
|
prelude::*,
|
|
};
|
|
|
|
use crate::{game_settings::GameSettingsManager, ui::slider::SliderContainer};
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Hash)]
|
|
pub enum Setting {
|
|
FoV,
|
|
DefaultName,
|
|
}
|
|
|
|
impl ToString for Setting {
|
|
fn to_string(&self) -> String {
|
|
match self {
|
|
Setting::FoV => "Field of View",
|
|
Setting::DefaultName => "Default Name",
|
|
}
|
|
.to_string()
|
|
}
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub enum SettingValue {
|
|
SliderNumber(SliderValue),
|
|
String(String),
|
|
}
|
|
|
|
#[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,
|
|
}),
|
|
);
|
|
self.settings.insert(
|
|
Setting::DefaultName,
|
|
SettingValue::String(settings.default_name.clone()),
|
|
);
|
|
|
|
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>()
|
|
}
|
|
SettingValue::String(value) => {
|
|
let mut text_edit = LineEdit::new_alloc();
|
|
text_edit.set_custom_minimum_size(Vector2::new(100., -1.));
|
|
text_edit.set_text(value);
|
|
|
|
let setting_clone = setting.clone();
|
|
text_edit
|
|
.signals()
|
|
.text_changed()
|
|
.connect_other(self, move |s, v| {
|
|
s.on_change(setting_clone, SettingValue::String(v.to_string()));
|
|
});
|
|
|
|
text_edit.upcast()
|
|
}
|
|
};
|
|
|
|
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;
|
|
}
|
|
(Setting::DefaultName, SettingValue::String(value)) => {
|
|
new_settings.default_name = value.clone()
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
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);
|
|
}
|
|
}
|