feat: progress on settings
This commit is contained in:
parent
0be80bdaac
commit
807f4b668c
11 changed files with 134 additions and 116 deletions
|
@ -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"] }
|
||||||
|
|
|
@ -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>
|
|
@ -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";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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,26 +73,43 @@ 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 = >k::StringList::new(&games_strs);
|
let games_list = >k::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
|
||||||
//let selected_game = games_dropdown.selected_item();
|
.connect_clicked(clone!(@strong instance, @strong games_list => move |_| {
|
||||||
|
//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);
|
||||||
|
|
||||||
//if let Some(selected_game) = selected_game {
|
let mut selected = settings.games().to_vec();
|
||||||
instance.hide()
|
selected.push(game_selected);
|
||||||
//}
|
|
||||||
}));
|
settings.set_strv("games", selected);
|
||||||
|
|
||||||
|
|
||||||
|
//if let Some(selected_game) = selected_game {
|
||||||
|
instance.hide()
|
||||||
|
//}
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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: >k::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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue