mirror of
https://github.com/PancakeTAS/lsfg-vk.git
synced 2025-10-30 07:01:10 +00:00
ui: hook up sidepanel
This commit is contained in:
parent
d91f38c80e
commit
f4f18a6e6d
3 changed files with 96 additions and 3 deletions
|
|
@ -4,7 +4,7 @@ version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
gtk = { version = "0.10.0", package = "gtk4" }
|
gtk = { version = "0.10.0", package = "gtk4", features = ["v4_10"] }
|
||||||
adw = { version = "0.8.0", package = "libadwaita", features = ["v1_4"] }
|
adw = { version = "0.8.0", package = "libadwaita", features = ["v1_4"] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
toml = "0.9.2"
|
toml = "0.9.2"
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@ impl Default for Multiplier {
|
||||||
impl From<i64> for Multiplier {
|
impl From<i64> for Multiplier {
|
||||||
fn from(value: i64) -> Self { Multiplier(value) }
|
fn from(value: i64) -> Self { Multiplier(value) }
|
||||||
}
|
}
|
||||||
|
impl Into<f64> for Multiplier {
|
||||||
|
fn into(self) -> f64 { self.0 as f64 }
|
||||||
|
}
|
||||||
|
|
||||||
// flow scale
|
// flow scale
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
|
|
@ -19,6 +22,9 @@ impl Default for FlowScale {
|
||||||
impl From<f64> for FlowScale {
|
impl From<f64> for FlowScale {
|
||||||
fn from(value: f64) -> Self { FlowScale(value) }
|
fn from(value: f64) -> Self { FlowScale(value) }
|
||||||
}
|
}
|
||||||
|
impl Into<f64> for FlowScale {
|
||||||
|
fn into(self) -> f64 { self.0 }
|
||||||
|
}
|
||||||
|
|
||||||
// present mode
|
// present mode
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
|
|
@ -41,7 +47,7 @@ pub struct TomlGlobal {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Game-specific configuration
|
/// Game-specific configuration
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
#[derive(Debug, Default, Clone, Deserialize, Serialize)]
|
||||||
pub struct TomlGame {
|
pub struct TomlGame {
|
||||||
pub exe: String,
|
pub exe: String,
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ fn main() {
|
||||||
|
|
||||||
// prepare the application state
|
// prepare the application state
|
||||||
STATE.set(Arc::new(RwLock::new(State {
|
STATE.set(Arc::new(RwLock::new(State {
|
||||||
selected_game: Some(0)
|
selected_game: None
|
||||||
}))).expect("Failed to set application state");
|
}))).expect("Failed to set application state");
|
||||||
|
|
||||||
// start the application
|
// start the application
|
||||||
|
|
@ -37,6 +37,39 @@ fn main() {
|
||||||
app.run();
|
app.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn helper_add_deletion_signal(
|
||||||
|
entry: wrapper::entry::Entry,
|
||||||
|
profiles: gtk::ListBox) {
|
||||||
|
let entry_clone = entry.clone();
|
||||||
|
entry.imp().delete.connect_clicked(move |btn| {
|
||||||
|
let dialog = gtk::AlertDialog::builder()
|
||||||
|
.message("Delete Profile")
|
||||||
|
.detail("Are you sure you want to delete this profile?")
|
||||||
|
.buttons(vec!["Cancel".to_string(), "Delete".to_string()])
|
||||||
|
.cancel_button(0)
|
||||||
|
.default_button(1)
|
||||||
|
.modal(true)
|
||||||
|
.build();
|
||||||
|
let window = btn.root()
|
||||||
|
.and_downcast::<gtk::Window>()
|
||||||
|
.expect("Button root is not a Window");
|
||||||
|
|
||||||
|
let profiles = profiles.clone();
|
||||||
|
let entry_clone = entry_clone.clone();
|
||||||
|
dialog.choose(Some(&window), None::<&gio::Cancellable>, move |result| {
|
||||||
|
match result {
|
||||||
|
Ok(idx) if idx == 1 => {
|
||||||
|
let _ = config::edit_config(|config| {
|
||||||
|
config.game.retain(|g| g.exe != entry_clone.exe());
|
||||||
|
});
|
||||||
|
profiles.remove(&entry_clone);
|
||||||
|
},
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn build_ui(app: &adw::Application) {
|
fn build_ui(app: &adw::Application) {
|
||||||
// create the main window
|
// create the main window
|
||||||
let window = wrapper::Window::new(app);
|
let window = wrapper::Window::new(app);
|
||||||
|
|
@ -50,9 +83,63 @@ fn build_ui(app: &adw::Application) {
|
||||||
for game in config.game.iter() {
|
for game in config.game.iter() {
|
||||||
let entry = wrapper::entry::Entry::new();
|
let entry = wrapper::entry::Entry::new();
|
||||||
entry.set_exe(game.exe.clone());
|
entry.set_exe(game.exe.clone());
|
||||||
|
|
||||||
|
helper_add_deletion_signal(entry.clone(), sidebar.profiles.clone());
|
||||||
sidebar.profiles.append(&entry);
|
sidebar.profiles.append(&entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// register side pane signals
|
||||||
|
let profiles = sidebar.profiles.clone();
|
||||||
|
let main = window.imp().main.clone();
|
||||||
|
sidebar.create.connect_clicked(move |_| {
|
||||||
|
let mut conf_entry = config::TomlGame::default();
|
||||||
|
conf_entry.exe = "new profile".to_string();
|
||||||
|
let _ = config::edit_config(|config| {
|
||||||
|
config.game.push(conf_entry.clone());
|
||||||
|
});
|
||||||
|
|
||||||
|
let entry = wrapper::entry::Entry::new();
|
||||||
|
entry.set_exe(conf_entry.exe);
|
||||||
|
|
||||||
|
helper_add_deletion_signal(entry.clone(), profiles.clone());
|
||||||
|
profiles.append(&entry);
|
||||||
|
entry.activate();
|
||||||
|
});
|
||||||
|
|
||||||
|
let state = STATE.get().unwrap().clone();
|
||||||
|
sidebar.profiles.connect_row_activated(move |_, entry| {
|
||||||
|
// find config entry
|
||||||
|
let index = entry.index() as usize;
|
||||||
|
let config = config::get_config()
|
||||||
|
.expect("Failed to get configuration");
|
||||||
|
let conf = config.game[index].clone();
|
||||||
|
|
||||||
|
// update state
|
||||||
|
{
|
||||||
|
let mut state = state.write()
|
||||||
|
.expect("Failed to acquire write lock on state");
|
||||||
|
state.selected_game = Some(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// update main pane
|
||||||
|
let main = main.imp();
|
||||||
|
let pref_multiplier = main.pref_multiplier.imp();
|
||||||
|
pref_multiplier.number.set_value(conf.multiplier.into());
|
||||||
|
let pref_flow_scale = main.pref_flow_scale.imp();
|
||||||
|
pref_flow_scale.slider.set_value(Into::<f64>::into(conf.flow_scale) * 100.0);
|
||||||
|
let pref_performance_mode = main.pref_performance_mode.imp();
|
||||||
|
pref_performance_mode.switch.set_state(conf.performance_mode);
|
||||||
|
let pref_hdr_mode = main.pref_hdr_mode.imp();
|
||||||
|
pref_hdr_mode.switch.set_state(conf.hdr_mode);
|
||||||
|
let pref_experimental_present_mode = main.pref_experimental_present_mode.imp();
|
||||||
|
let mode = match conf.experimental_present_mode {
|
||||||
|
PresentMode::Vsync => 0,
|
||||||
|
PresentMode::Mailbox => 1,
|
||||||
|
PresentMode::Immediate => 2,
|
||||||
|
};
|
||||||
|
pref_experimental_present_mode.dropdown.set_selected(mode);
|
||||||
|
});
|
||||||
|
|
||||||
// register main pane signals
|
// register main pane signals
|
||||||
let main = window.imp().main.imp();
|
let main = window.imp().main.imp();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue