mirror of
https://github.com/an-anime-team/an-anime-game-launcher.git
synced 2025-04-05 16:25:52 +03:00
feat(ui): reworked game sessions selection
This commit is contained in:
parent
4b40901141
commit
636ccffebf
1 changed files with 50 additions and 68 deletions
|
@ -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 = >k::Button {
|
add_suffix = >k::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)]
|
||||||
|
@ -123,39 +130,25 @@ impl SimpleAsyncComponent for GamePage {
|
||||||
adw::PreferencesPage {
|
adw::PreferencesPage {
|
||||||
set_title: &tr("game"),
|
set_title: &tr("game"),
|
||||||
set_icon_name: Some("applications-games-symbolic"),
|
set_icon_name: Some("applications-games-symbolic"),
|
||||||
|
|
||||||
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"),
|
||||||
|
|
||||||
add_suffix = >k::Button {
|
add_suffix = >k::Button {
|
||||||
set_icon_name: "list-add-symbolic",
|
set_icon_name: "list-add-symbolic",
|
||||||
add_css_class: "flat",
|
add_css_class: "flat",
|
||||||
|
|
||||||
set_valign: gtk::Align::Center,
|
set_valign: gtk::Align::Center,
|
||||||
|
|
||||||
connect_clicked => GamePageMsg::AddSession
|
connect_clicked => GamePageMsg::AddSession
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
#[local_ref]
|
#[local_ref]
|
||||||
add = sessions -> adw::PreferencesGroup {},
|
add = sessions -> adw::PreferencesGroup {},
|
||||||
}
|
}
|
||||||
|
@ -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(>k::StringList::new(&self.sessions_names.iter().map(|name: &String| name.as_str()).collect::<Vec<&str>>())));
|
|
||||||
self.sessions_combo.set_selected(selected);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue