feat: progress on settings
Some checks failed
CI / Rustfmt (push) Failing after 59s
CI / Flatpak (push) Failing after 4m40s

This commit is contained in:
Tine Jozelj 2023-12-21 19:24:38 +01:00
parent 0be80bdaac
commit 807f4b668c
Signed by: mentos1386
SSH key fingerprint: SHA256:MNtTsLbihYaWF8j1fkOHfkKNlnN1JQfxEU/rBU8nCGw
11 changed files with 134 additions and 116 deletions

View file

@ -9,7 +9,7 @@ lto = true
[dependencies] [dependencies]
gettext-rs = { version = "0.7", features = ["gettext-system"] } gettext-rs = { version = "0.7", features = ["gettext-system"] }
gtk = { version = "0.7", package = "gtk4", features = ["v4_10"] } gtk = { version = "0.7", package = "gtk4", features = ["v4_12"] }
tracing = "0.1.37" tracing = "0.1.37"
tracing-subscriber = "0.3" tracing-subscriber = "0.3"
reqwest = { version = "0.11", features = ["json", "blocking"] } reqwest = { version = "0.11", features = ["json", "blocking"] }

View file

@ -13,10 +13,9 @@
<default>false</default> <default>false</default>
<summary>Window maximized state</summary> <summary>Window maximized state</summary>
</key> </key>
<key name="games" type="{ss}"> <key name="games" type="as">
<default>{}</default> <default>[]</default>
<summary>Dictionary of games being managed. First string is game name second is path to mods <summary>Games</summary>
folder.</summary>
</key> </key>
</schema> </schema>
</schemalist> </schemalist>

View file

@ -10,18 +10,14 @@ template $GamesAndMods: Adw.Bin {
Adw.ToolbarView { Adw.ToolbarView {
[top] [top]
Adw.HeaderBar { Adw.HeaderBar {
[end]
Button add_new_game {
label: "Add game";
}
} }
content: Box { content: ListBox games_list {
Label { styles ["navigation-sidebar"]
label: "The Sims 4";
}
Label {
label: "The Sims 3";
}
Label {
label: "The Sims 2";
}
}; };
} }
}; };
@ -32,12 +28,18 @@ template $GamesAndMods: Adw.Bin {
Adw.ToolbarView { Adw.ToolbarView {
[top] [top]
Adw.HeaderBar { Adw.HeaderBar {
[title]
SearchEntry search {
}
} }
content: Box { content: Box {
Label { Label {
label: "Mods"; label: "Mods";
} }
Button remove_all_games {
label: "Remove all games";
}
}; };
} }
}; };

View file

@ -25,11 +25,16 @@ use tracing::{debug, info};
use crate::config::VERSION; use crate::config::VERSION;
use crate::config::{APP_ID, PKGDATADIR, PROFILE}; use crate::config::{APP_ID, PKGDATADIR, PROFILE};
use crate::settings::ModManagerSettings;
use crate::windows::main::ModManagerWindowMain; use crate::windows::main::ModManagerWindowMain;
use crate::windows::main::Welcome; use crate::windows::main::Welcome;
mod imp { mod imp {
use games_and_mods::GamesAndMods;
use crate::windows::games_and_mods;
use super::*; use super::*;
#[derive(Debug, Default)] #[derive(Debug, Default)]
@ -47,14 +52,6 @@ mod imp {
self.parent_constructed(); self.parent_constructed();
let obj = self.obj(); let obj = self.obj();
obj.set_accels_for_action("app.quit", &["<primary>q"]); obj.set_accels_for_action("app.quit", &["<primary>q"]);
//let settings = ModManagerSettings::default();
// let games = settings.games();
//let settings = gio::Settings::new(APP_ID);
//let games = settings.string("games");
//println!("Games: {:?}", games);
} }
} }
@ -70,9 +67,7 @@ mod imp {
let window = if let Some(window) = application.active_window() { let window = if let Some(window) = application.active_window() {
window window
} else { } else {
// TODO: Figure our if show welcome or games_and_mods. let window = ModManagerWindowMain::new(&*application);
let welcome = Welcome::new();
let window = ModManagerWindowMain::new(&*application, &welcome.upcast());
window.upcast() window.upcast()
}; };

View file

@ -19,13 +19,13 @@ mod api;
mod application; mod application;
mod components; mod components;
mod config; mod config;
mod settings;
mod windows; mod windows;
use self::application::ModManagerApplication; use self::application::ModManagerApplication;
use config::{GETTEXT_PACKAGE, LOCALEDIR, RESOURCES_FILE}; use config::{GETTEXT_PACKAGE, LOCALEDIR, RESOURCES_FILE};
use gettextrs::{gettext, LocaleCategory}; use gettextrs::{gettext, LocaleCategory};
use gtk::prelude::*;
use gtk::{gio, glib}; use gtk::{gio, glib};
fn main() -> glib::ExitCode { fn main() -> glib::ExitCode {

View file

@ -1,66 +0,0 @@
/* welcome.rs
*
* Copyright 2023 Tine
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
use adw::subclass::prelude::*;
use gtk::{gio, glib};
use gtk::{glib::clone, prelude::*};
mod imp {
use super::*;
#[derive(Debug, Default, gtk::CompositeTemplate)]
#[template(resource = "/dev/mnts/ModManager/components/mods_list.ui")]
pub struct ModsList {
}
#[glib::object_subclass]
impl ObjectSubclass for ModsList {
const NAME: &'static str = "ModsList";
type Type = super::ModsList;
type ParentType = adw::NavigationPage;
fn class_init(klass: &mut Self::Class) {
klass.bind_template();
}
fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
obj.init_template();
}
}
impl ObjectImpl for ModsList {
fn constructed(&self) {
}
}
impl WidgetImpl for ModsList {}
impl NavigationPageImpl for ModsList {}
}
glib::wrapper! {
pub struct ModsList(ObjectSubclass<imp::ModsList>)
@extends gtk::Widget, gtk::Buildable, adw::NavigationPage,
@implements gio::ActionGroup, gio::ActionMap;
}
impl ModsList {
pub fn new() -> Self {
glib::Object::builder().build()
}
}

View file

@ -6,11 +6,6 @@ use std::collections::HashMap;
use crate::config::APP_ID; use crate::config::APP_ID;
#[gen_settings(file = "./data/dev.mnts.ModManager.gschema.xml.in")] #[gen_settings(file = "./data/dev.mnts.ModManager.gschema.xml.in")]
#[gen_settings_define(
key_name = "games",
arg_type = "HashMap<String, String>",
ret_type = "HashMap<String, String>"
)]
pub struct ModManagerSettings; pub struct ModManagerSettings;
impl Default for ModManagerSettings { impl Default for ModManagerSettings {

View file

@ -20,10 +20,12 @@
use adw::subclass::prelude::*; use adw::subclass::prelude::*;
use glib::clone; use glib::clone;
use gtk::glib::subclass::types::FromObject;
use gtk::prelude::*; use gtk::prelude::*;
use gtk::{gio, glib}; use gtk::{gio, glib};
use crate::api::*; use crate::api::*;
use crate::settings::ModManagerSettings;
mod imp { mod imp {
use super::*; use super::*;
@ -71,22 +73,39 @@ impl ModManagerWindowAddNewGame {
glib::Object::builder().build() glib::Object::builder().build()
} }
pub fn show() -> Self {
let welcome = ModManagerWindowAddNewGame::new();
welcome.setup();
welcome.set_modal(true);
welcome.present();
return welcome;
}
pub fn setup(&self) { pub fn setup(&self) {
let games = games::get_games(); let games = games::get_games();
let games_strs: Vec<&str> = games.iter().map(|s| s.as_str()).collect(); let games_strs: Vec<&str> = games.iter().map(|s| s.as_str()).collect();
let games_list = &gtk::StringList::new(&games_strs); let games_list = &gtk::StringList::new(&games_strs);
let complete_button = &imp::ModManagerWindowAddNewGame::from_obj(self).complete_button; let obj = self.imp();
let games_dropdown = &imp::ModManagerWindowAddNewGame::from_obj(self).games_dropdown;
games_dropdown.set_property("model", games_list); obj.games_dropdown.set_property("model", games_list);
let instance = self; let instance = self;
complete_button.connect_clicked(clone!(@strong instance => move |_| { obj.complete_button
.connect_clicked(clone!(@strong instance, @strong games_list => move |_| {
//let selected_game = games_dropdown.selected_item(); //let selected_game = games_dropdown.selected_item();
println!("complete button clicked"); let settings = ModManagerSettings::default();
let game_selected = games_list.string(instance.imp().games_dropdown.selected()).unwrap().to_string();
println!("complete button clicked, selected game: {:?}", &game_selected);
let mut selected = settings.games().to_vec();
selected.push(game_selected);
settings.set_strv("games", selected);
//if let Some(selected_game) = selected_game { //if let Some(selected_game) = selected_game {
instance.hide() instance.hide()

View file

@ -18,11 +18,18 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
use adw::subclass::prelude::*; use adw::subclass::prelude::*;
use gtk::prelude::*; use gtk::prelude::*;
use gtk::{gio, glib}; use gtk::{gio, glib};
use tracing::{debug, info};
use crate::config::PROFILE; use crate::config::PROFILE;
use crate::settings::ModManagerSettings;
use crate::windows::GamesAndMods;
use super::Welcome;
mod imp { mod imp {
use gtk::glib::clone;
use super::*; use super::*;
#[derive(Debug, Default, gtk::CompositeTemplate)] #[derive(Debug, Default, gtk::CompositeTemplate)]
@ -53,6 +60,27 @@ mod imp {
if PROFILE == "Devel" { if PROFILE == "Devel" {
obj.add_css_class("devel"); obj.add_css_class("devel");
} }
let settings = ModManagerSettings::default();
settings.connect_games_changed(clone!(@strong obj, @strong settings => move |_| {
info!("Games changed, deciding on initial page.");
let page: gtk::Widget = if settings.games().len() > 0 {
GamesAndMods::new().upcast()
} else {
Welcome::new().upcast()
};
obj.set_property("content", page);
}));
let page: gtk::Widget = if settings.games().len() > 0 {
GamesAndMods::new().upcast()
} else {
Welcome::new().upcast()
};
obj.set_property("content", page)
} }
} }
@ -69,10 +97,9 @@ glib::wrapper! {
} }
impl ModManagerWindowMain { impl ModManagerWindowMain {
pub fn new<P: glib::IsA<gtk::Application>>(application: &P, content: &gtk::Widget) -> Self { pub fn new<P: glib::IsA<gtk::Application>>(application: &P) -> Self {
glib::Object::builder() glib::Object::builder()
.property("application", application) .property("application", application)
.property("content", content)
.build() .build()
} }
} }

View file

@ -21,11 +21,26 @@ use gtk::{gio, glib};
mod imp { mod imp {
use adw::prelude::PreferencesRowExt;
use gtk::glib::clone;
use tracing::info;
use crate::{api::games, settings::ModManagerSettings, windows::ModManagerWindowAddNewGame};
use super::*; use super::*;
#[derive(Debug, Default, gtk::CompositeTemplate)] #[derive(Debug, Default, gtk::CompositeTemplate)]
#[template(resource = "/dev/mnts/ModManager/ui/windows/main/pages/games_and_mods.ui")] #[template(resource = "/dev/mnts/ModManager/ui/windows/main/pages/games_and_mods.ui")]
pub struct GamesAndMods {} pub struct GamesAndMods {
#[template_child]
pub add_new_game: TemplateChild<gtk::Button>,
#[template_child]
pub remove_all_games: TemplateChild<gtk::Button>,
#[template_child]
pub games_list: TemplateChild<gtk::ListBox>,
}
#[glib::object_subclass] #[glib::object_subclass]
impl ObjectSubclass for GamesAndMods { impl ObjectSubclass for GamesAndMods {
@ -42,7 +57,42 @@ mod imp {
} }
} }
impl ObjectImpl for GamesAndMods {} impl ObjectImpl for GamesAndMods {
fn constructed(&self) {
self.parent_constructed();
let obj = self.obj();
self.remove_all_games.connect_clicked(|_| {
let settings = ModManagerSettings::default();
settings.set_games(&[]);
println!("Remove all games button clicked");
});
self.add_new_game.connect_clicked(|_| {
ModManagerWindowAddNewGame::show();
});
let settings = ModManagerSettings::default();
for game in settings.games() {
info!("Adding game {} to list", game);
let row = adw::ActionRow::new();
row.set_title(&game);
obj.imp().games_list.append(&row);
}
settings.connect_games_changed(clone!(@weak obj, @strong settings => move |_| {
info!("Games changed, modifying list");
obj.imp().games_list.remove_all();
for game in settings.games() {
info!("Adding game {} to list", game);
let row = adw::ActionRow::new();
row.set_title(&game);
obj.imp().games_list.append(&row);
}
}));
}
}
impl WidgetImpl for GamesAndMods {} impl WidgetImpl for GamesAndMods {}
impl BinImpl for GamesAndMods {} impl BinImpl for GamesAndMods {}
} }

View file

@ -52,10 +52,7 @@ mod imp {
self.parent_constructed(); self.parent_constructed();
self.add_new_game.connect_clicked(|_| { self.add_new_game.connect_clicked(|_| {
let welcome = ModManagerWindowAddNewGame::new(); ModManagerWindowAddNewGame::show();
welcome.setup();
welcome.set_modal(true);
welcome.present();
}); });
} }
} }