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"
|
||||
|
||||
[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"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
toml = "0.9.2"
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ impl Default for Multiplier {
|
|||
impl From<i64> for Multiplier {
|
||||
fn from(value: i64) -> Self { Multiplier(value) }
|
||||
}
|
||||
impl Into<f64> for Multiplier {
|
||||
fn into(self) -> f64 { self.0 as f64 }
|
||||
}
|
||||
|
||||
// flow scale
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
|
|
@ -19,6 +22,9 @@ impl Default for FlowScale {
|
|||
impl From<f64> for FlowScale {
|
||||
fn from(value: f64) -> Self { FlowScale(value) }
|
||||
}
|
||||
impl Into<f64> for FlowScale {
|
||||
fn into(self) -> f64 { self.0 }
|
||||
}
|
||||
|
||||
// present mode
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
|
|
@ -41,7 +47,7 @@ pub struct TomlGlobal {
|
|||
}
|
||||
|
||||
/// Game-specific configuration
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
#[derive(Debug, Default, Clone, Deserialize, Serialize)]
|
||||
pub struct TomlGame {
|
||||
pub exe: String,
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ fn main() {
|
|||
|
||||
// prepare the application state
|
||||
STATE.set(Arc::new(RwLock::new(State {
|
||||
selected_game: Some(0)
|
||||
selected_game: None
|
||||
}))).expect("Failed to set application state");
|
||||
|
||||
// start the application
|
||||
|
|
@ -37,6 +37,39 @@ fn main() {
|
|||
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) {
|
||||
// create the main window
|
||||
let window = wrapper::Window::new(app);
|
||||
|
|
@ -50,9 +83,63 @@ fn build_ui(app: &adw::Application) {
|
|||
for game in config.game.iter() {
|
||||
let entry = wrapper::entry::Entry::new();
|
||||
entry.set_exe(game.exe.clone());
|
||||
|
||||
helper_add_deletion_signal(entry.clone(), sidebar.profiles.clone());
|
||||
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
|
||||
let main = window.imp().main.imp();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue