feat(ui): reworked game sessions selection

This commit is contained in:
Observer KRypt0n_ 2023-06-08 15:10:21 +02:00
parent 4b40901141
commit 636ccffebf
No known key found for this signature in database
GPG key ID: 844DA47BA25FE1E2

View file

@ -15,7 +15,8 @@ use crate::*;
#[derive(Debug)] #[derive(Debug)]
struct GameSession { struct GameSession {
name: String, name: String,
description: Option<String> description: Option<String>,
check_button: gtk::CheckButton
} }
#[relm4::factory(async)] #[relm4::factory(async)]
@ -36,6 +37,9 @@ impl AsyncFactoryComponent for GameSession {
None => "" None => ""
}, },
// Looks weird but yes
add_prefix = &self.check_button.clone(),
add_suffix = &gtk::Button { add_suffix = &gtk::Button {
set_icon_name: "view-refresh-symbolic", set_icon_name: "view-refresh-symbolic",
add_css_class: "flat", add_css_class: "flat",
@ -60,6 +64,12 @@ impl AsyncFactoryComponent for GameSession {
connect_clicked[sender, index] => move |_| { connect_clicked[sender, index] => move |_| {
sender.output(GamePageMsg::RemoveSession(index.clone())); sender.output(GamePageMsg::RemoveSession(index.clone()));
} }
},
set_activatable: true,
connect_activated[sender, index] => move |_| {
sender.output(GamePageMsg::SetCurrent(index.clone()));
} }
} }
} }
@ -80,9 +90,7 @@ impl AsyncFactoryComponent for GameSession {
pub struct GamePage { pub struct GamePage {
sessions: AsyncFactoryVecDeque<GameSession>, sessions: AsyncFactoryVecDeque<GameSession>,
sessions_names: Vec<String>, sessions_root_widget: gtk::CheckButton,
sessions_combo: adw::ComboRow,
session_name_entry: adw::EntryRow session_name_entry: adw::EntryRow
} }
@ -91,8 +99,7 @@ pub enum GamePageMsg {
AddSession, AddSession,
UpdateSession(DynamicIndex), UpdateSession(DynamicIndex),
RemoveSession(DynamicIndex), RemoveSession(DynamicIndex),
SetCurrent(u32), SetCurrent(DynamicIndex)
UpdateCombo
} }
#[relm4::component(async, pub)] #[relm4::component(async, pub)]
@ -127,20 +134,6 @@ impl SimpleAsyncComponent for GamePage {
add = &adw::PreferencesGroup { add = &adw::PreferencesGroup {
set_title: &tr("game-sessions"), set_title: &tr("game-sessions"),
#[local_ref]
sessions_combo -> adw::ComboRow {
set_title: &tr("active-sessions"),
set_subtitle: &tr("active-session-description"),
connect_selected_notify[sender] => move |row| {
if is_ready() {
sender.input(GamePageMsg::SetCurrent(row.selected()));
}
}
}
},
add = &adw::PreferencesGroup {
#[local_ref] #[local_ref]
session_name_entry -> adw::EntryRow { session_name_entry -> adw::EntryRow {
set_title: &tr("name"), set_title: &tr("name"),
@ -172,28 +165,34 @@ impl SimpleAsyncComponent for GamePage {
let mut model = Self { let mut model = Self {
sessions: AsyncFactoryVecDeque::new(adw::PreferencesGroup::new(), sender.input_sender()), sessions: AsyncFactoryVecDeque::new(adw::PreferencesGroup::new(), sender.input_sender()),
sessions_names: Vec::new(), sessions_root_widget: gtk::CheckButton::new(),
sessions_combo: adw::ComboRow::new(),
session_name_entry: adw::EntryRow::new() session_name_entry: adw::EntryRow::new()
}; };
let current = Sessions::get_current().unwrap_or_default();
for (name, _) in Sessions::list().unwrap_or_default() { for (name, _) in Sessions::list().unwrap_or_default() {
let check_button = gtk::CheckButton::new();
check_button.set_group(Some(&model.sessions_root_widget));
if Some(&name) == current.as_ref() {
check_button.set_active(true);
}
model.sessions.guard().push_back(GameSession { model.sessions.guard().push_back(GameSession {
name: name.clone(), name,
description: None description: None,
check_button
}); });
} }
let sessions = model.sessions.widget(); let sessions = model.sessions.widget();
let sessions_combo = &model.sessions_combo;
let session_name_entry = &model.session_name_entry; let session_name_entry = &model.session_name_entry;
let widgets = view_output!(); let widgets = view_output!();
sender.input(GamePageMsg::UpdateCombo);
AsyncComponentParts { model, widgets } AsyncComponentParts { model, widgets }
} }
@ -210,10 +209,9 @@ impl SimpleAsyncComponent for GamePage {
Ok(()) => { Ok(()) => {
self.sessions.guard().push_back(GameSession { self.sessions.guard().push_back(GameSession {
name, name,
description: None description: None,
check_button: gtk::CheckButton::new()
}); });
sender.input(GamePageMsg::UpdateCombo);
} }
Err(err) => { Err(err) => {
@ -242,27 +240,23 @@ impl SimpleAsyncComponent for GamePage {
GamePageMsg::RemoveSession(index) => { GamePageMsg::RemoveSession(index) => {
if let Some(session) = self.sessions.guard().get(index.current_index()) { if let Some(session) = self.sessions.guard().get(index.current_index()) {
match Sessions::remove(&session.name) { if let Err(err) = Sessions::remove(&session.name) {
Ok(()) => sender.input(GamePageMsg::UpdateCombo), sender.output(EnhancementsAppMsg::Toast {
title: tr("game-session-remove-failed"),
description: Some(err.to_string())
}).unwrap();
Err(err) => { return;
sender.output(EnhancementsAppMsg::Toast {
title: tr("game-session-remove-failed"),
description: Some(err.to_string())
}).unwrap();
return;
}
} }
} }
self.sessions.guard().remove(index.current_index()); self.sessions.guard().remove(index.current_index());
} }
GamePageMsg::SetCurrent(id) => { GamePageMsg::SetCurrent(index) => {
if let Some(name) = self.sessions_names.get(id as usize) { if let Some(session) = self.sessions.guard().get(index.current_index()) {
if let Ok(config) = Config::get() { if let Ok(config) = Config::get() {
if let Err(err) = Sessions::set_current(name.to_owned()) { if let Err(err) = Sessions::set_current(session.name.clone()) {
sender.output(EnhancementsAppMsg::Toast { sender.output(EnhancementsAppMsg::Toast {
title: tr("game-session-set-current-failed"), title: tr("game-session-set-current-failed"),
description: Some(err.to_string()) description: Some(err.to_string())
@ -272,32 +266,20 @@ impl SimpleAsyncComponent for GamePage {
return; return;
} }
if let Err(err) = Sessions::apply(name.to_owned(), config.get_wine_prefix_path()) { if let Err(err) = Sessions::apply(session.name.clone(), config.get_wine_prefix_path()) {
sender.output(EnhancementsAppMsg::Toast { sender.output(EnhancementsAppMsg::Toast {
title: tr("game-session-apply-failed"), title: tr("game-session-apply-failed"),
description: Some(err.to_string()) description: Some(err.to_string())
}).unwrap(); }).unwrap();
// Prevent session activation
return;
} }
session.check_button.set_active(true);
} }
} }
} }
GamePageMsg::UpdateCombo => {
let sessions = Sessions::get_sessions().unwrap_or_default();
self.sessions_names = sessions.sessions.into_keys().collect::<Vec<String>>();
let mut selected = 0;
for (i, name) in self.sessions_names.iter().enumerate() {
if sessions.current.as_ref() == Some(name) {
selected = i as u32;
}
}
self.sessions_combo.set_model(Some(&gtk::StringList::new(&self.sessions_names.iter().map(|name: &String| name.as_str()).collect::<Vec<&str>>())));
self.sessions_combo.set_selected(selected);
}
} }
} }
} }