From 50dd8f5e18beb55628c6f0fd43c8713dc08fde63 Mon Sep 17 00:00:00 2001 From: Tine Jozelj Date: Wed, 20 Dec 2023 18:32:50 +0100 Subject: [PATCH] feat: refactoring etc. trying to implement settings store --- Cargo.lock | 86 ++++++++++++ Cargo.toml | 3 +- meson.build | 18 +++ meson_options.txt | 10 ++ src/application.rs | 25 ++-- src/components/mod.rs | 2 + .../mods_list.blp} | 14 +- .../welcome.rs => components/mods_list.rs} | 42 +++--- src/config.rs.in | 1 + src/dev.mnts.ModManager.gschema.xml.in | 9 ++ src/gtk/help-overlay.blp | 24 ---- src/main.rs | 8 +- src/meson.build | 30 ++++- src/mod-manager.gresource.xml | 10 +- src/pages/main.blp | 123 ------------------ src/pages/mod.rs | 2 - src/pages/welcome.blp | 26 ---- src/settings.rs | 18 +++ src/window.blp | 57 -------- src/windows/add_new_game/add_new_game.blp | 46 +++++++ src/windows/add_new_game/add_new_game.rs | 99 ++++++++++++++ src/windows/add_new_game/mod.rs | 2 + src/windows/main/main.blp | 25 ++++ src/{window.rs => windows/main/main.rs} | 41 +++--- src/windows/main/mod.rs | 5 + src/windows/main/pages/games_and_mods.blp | 45 +++++++ src/windows/main/pages/games_and_mods.rs | 62 +++++++++ src/windows/main/pages/mod.rs | 5 + src/windows/main/pages/welcome.blp | 28 ++++ src/windows/main/pages/welcome.rs | 76 +++++++++++ src/windows/mod.rs | 5 + 31 files changed, 636 insertions(+), 311 deletions(-) create mode 100644 meson_options.txt create mode 100644 src/components/mod.rs rename src/{pages/chose-game-location.blp => components/mods_list.blp} (90%) rename src/{pages/welcome.rs => components/mods_list.rs} (58%) create mode 100644 src/dev.mnts.ModManager.gschema.xml.in delete mode 100644 src/gtk/help-overlay.blp delete mode 100644 src/pages/main.blp delete mode 100644 src/pages/mod.rs delete mode 100644 src/pages/welcome.blp create mode 100644 src/settings.rs delete mode 100644 src/window.blp create mode 100644 src/windows/add_new_game/add_new_game.blp create mode 100644 src/windows/add_new_game/add_new_game.rs create mode 100644 src/windows/add_new_game/mod.rs create mode 100644 src/windows/main/main.blp rename src/{window.rs => windows/main/main.rs} (58%) create mode 100644 src/windows/main/mod.rs create mode 100644 src/windows/main/pages/games_and_mods.blp create mode 100644 src/windows/main/pages/games_and_mods.rs create mode 100644 src/windows/main/pages/mod.rs create mode 100644 src/windows/main/pages/welcome.blp create mode 100644 src/windows/main/pages/welcome.rs create mode 100644 src/windows/mod.rs diff --git a/Cargo.lock b/Cargo.lock index dfd64f8..46d17d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,6 +32,12 @@ version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "autocfg" version = "1.1.0" @@ -155,6 +161,47 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "deluxe" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed332aaf752b459088acf3dd4eca323e3ef4b83c70a84ca48fb0ec5305f1488" +dependencies = [ + "deluxe-core", + "deluxe-macros", + "once_cell", + "proc-macro2", + "syn 2.0.41", +] + +[[package]] +name = "deluxe-core" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddada51c8576df9d6a8450c351ff63042b092c9458b8ac7d20f89cbd0ffd313" +dependencies = [ + "arrayvec", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.41", +] + +[[package]] +name = "deluxe-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87546d9c837f0b7557e47b8bd6eae52c3c223141b76aa233c345c9ab41d9117" +dependencies = [ + "deluxe-core", + "heck", + "if_chain", + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 2.0.41", +] + [[package]] name = "encoding_rs" version = "0.8.33" @@ -494,6 +541,22 @@ dependencies = [ "system-deps", ] +[[package]] +name = "gsettings-macro" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5582953d3e15ef858ec22b6e5312c540dbbf9e3a653f3d4cf51afc444bf0b5d" +dependencies = [ + "deluxe", + "heck", + "proc-macro-error", + "proc-macro2", + "quick-xml", + "quote", + "serde", + "syn 2.0.41", +] + [[package]] name = "gsk4" version = "0.7.3" @@ -697,6 +760,12 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "if_chain" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" + [[package]] name = "indexmap" version = "2.1.0" @@ -852,6 +921,7 @@ name = "mod-manager" version = "0.1.0" dependencies = [ "gettext-rs", + "gsettings-macro", "gtk4", "libadwaita", "reqwest", @@ -1076,6 +1146,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "quick-xml" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "quote" version = "1.0.33" @@ -1310,6 +1390,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "syn" version = "1.0.109" diff --git a/Cargo.toml b/Cargo.toml index dce1538..63d556c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,8 @@ edition = "2021" [dependencies] gettext-rs = { version = "0.7", features = ["gettext-system"] } -gtk = { version = "0.7", package = "gtk4" } +gsettings-macro = "0.1.20" +gtk = { version = "0.7", package = "gtk4", features = ["v4_10"] } reqwest = { version = "0.11", features = ["json", "blocking"] } serde = { version = "1.0", features = ["derive"] } diff --git a/meson.build b/meson.build index 4eee23b..f9ddc38 100644 --- a/meson.build +++ b/meson.build @@ -8,6 +8,24 @@ i18n = import('i18n') gnome = import('gnome') +base_id = 'dev.mnts.ModManager' +gettext_package = meson.project_name() + +if get_option('profile') == 'development' + profile = 'Devel' + vcs_tag = run_command('git', 'rev-parse', '--short', 'HEAD').stdout().strip() + if vcs_tag == '' + version_suffix = '-devel' + else + version_suffix = '-@0@'.format(vcs_tag) + endif + application_id = '@0@.@1@'.format(base_id, profile) +else + profile = '' + version_suffix = '' + application_id = base_id +endif + subdir('data') subdir('src') diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 0000000..64a6b69 --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,10 @@ +option( + 'profile', + type: 'combo', + choices: [ + 'default', + 'development' + ], + value: 'default', + description: 'The build profile for ModManager. One of "default" or "development".' +) \ No newline at end of file diff --git a/src/application.rs b/src/application.rs index 0d8966c..94b8d87 100644 --- a/src/application.rs +++ b/src/application.rs @@ -23,10 +23,13 @@ use gtk::prelude::*; use gtk::{gio, glib}; use crate::config::VERSION; -use crate::ModManagerWindow; -use crate::pages::welcome::ModManagerWelcome; +use crate::config::APP_ID; +use crate::windows::main::Welcome; +use crate::windows::main::ModManagerWindowMain; +use crate::settings::ModManagerSettings; mod imp { + use super::*; #[derive(Debug, Default)] @@ -59,14 +62,14 @@ mod imp { let window = if let Some(window) = application.active_window() { window } else { - let window = ModManagerWindow::new(&*application); + let settings = ModManagerSettings::default(); - let welcome = ModManagerWelcome::new(); - - // TODO: Somehow we should handle this at some other point? - welcome.setup_dropdown(); - window.set_page(&welcome.upcast::()); + let games = settings.games(); + println!("Games: {:?}", games); + // TODO: Figure our if show welcome or games_and_mods. + let welcome = Welcome::new(); + let window = ModManagerWindowMain::new(&*application, &welcome.upcast()); window.upcast() }; @@ -86,9 +89,9 @@ glib::wrapper! { } impl ModManagerApplication { - pub fn new(application_id: &str, flags: &gio::ApplicationFlags) -> Self { + pub fn new( flags: &gio::ApplicationFlags) -> Self { glib::Object::builder() - .property("application-id", application_id) + .property("application-id", APP_ID) .property("flags", flags) .build() } @@ -108,7 +111,7 @@ impl ModManagerApplication { let about = adw::AboutWindow::builder() .transient_for(&window) .application_name("mod-manager") - .application_icon("dev.mnts.ModManager") + .application_icon(APP_ID) .developer_name("Tine Jozelj") .version(VERSION) .developers(vec!["Tine Jozelj "]) diff --git a/src/components/mod.rs b/src/components/mod.rs new file mode 100644 index 0000000..325197d --- /dev/null +++ b/src/components/mod.rs @@ -0,0 +1,2 @@ +pub mod mods_list; +pub use mods_list::*; \ No newline at end of file diff --git a/src/pages/chose-game-location.blp b/src/components/mods_list.blp similarity index 90% rename from src/pages/chose-game-location.blp rename to src/components/mods_list.blp index f97b733..01a2988 100644 --- a/src/pages/chose-game-location.blp +++ b/src/components/mods_list.blp @@ -1,6 +1,16 @@ using Gtk 4.0; +using Adw 1; -Box welcome { +template $ModsList : Adw.NavigationPage { + title: _("Main"); + + Adw.ToolbarView { + [top] + Adw.HeaderBar header_bar { + show-back-button: true; + } + + content: Box { orientation: vertical; valign: center; halign: center; @@ -120,4 +130,6 @@ Box welcome { } } } +}; +} } \ No newline at end of file diff --git a/src/pages/welcome.rs b/src/components/mods_list.rs similarity index 58% rename from src/pages/welcome.rs rename to src/components/mods_list.rs index 540ec9c..e8f6f08 100644 --- a/src/pages/welcome.rs +++ b/src/components/mods_list.rs @@ -18,26 +18,22 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ -use gtk::prelude::*; use adw::subclass::prelude::*; use gtk::{gio, glib}; - -use crate::api::*; +use gtk::{glib::clone, prelude::*}; mod imp { use super::*; #[derive(Debug, Default, gtk::CompositeTemplate)] - #[template(resource = "/dev/mnts/ModManager/pages/welcome.ui")] - pub struct ModManagerWelcome { - #[template_child] - pub games_dropdown: TemplateChild + #[template(resource = "/dev/mnts/ModManager/components/mods_list.ui")] + pub struct ModsList { } #[glib::object_subclass] - impl ObjectSubclass for ModManagerWelcome { - const NAME: &'static str = "ModManagerWelcome"; - type Type = super::ModManagerWelcome; + impl ObjectSubclass for ModsList { + const NAME: &'static str = "ModsList"; + type Type = super::ModsList; type ParentType = adw::NavigationPage; fn class_init(klass: &mut Self::Class) { @@ -49,30 +45,22 @@ mod imp { } } - impl ObjectImpl for ModManagerWelcome {} - impl WidgetImpl for ModManagerWelcome {} - impl NavigationPageImpl for ModManagerWelcome {} - + impl ObjectImpl for ModsList { + fn constructed(&self) { + } + } + impl WidgetImpl for ModsList {} + impl NavigationPageImpl for ModsList {} } glib::wrapper! { - pub struct ModManagerWelcome(ObjectSubclass) + pub struct ModsList(ObjectSubclass) @extends gtk::Widget, gtk::Buildable, adw::NavigationPage, @implements gio::ActionGroup, gio::ActionMap; } -impl ModManagerWelcome { +impl ModsList { pub fn new() -> Self { - glib::Object::builder() - .build() - } - - pub fn setup_dropdown(&self) { - let games = games::get_games(); - let games_strs: Vec<&str> = games.iter().map(|s| s.as_str()).collect(); - let games_list = >k::StringList::new(&games_strs); - - imp::ModManagerWelcome::from_obj(self).games_dropdown.set_property("model", games_list) + glib::Object::builder().build() } } - diff --git a/src/config.rs.in b/src/config.rs.in index 0558aa7..27bcb2f 100644 --- a/src/config.rs.in +++ b/src/config.rs.in @@ -1,3 +1,4 @@ +pub static APP_ID: &str = @APP_ID@; pub static VERSION: &str = @VERSION@; pub static GETTEXT_PACKAGE: &str = @GETTEXT_PACKAGE@; pub static LOCALEDIR: &str = @LOCALEDIR@; diff --git a/src/dev.mnts.ModManager.gschema.xml.in b/src/dev.mnts.ModManager.gschema.xml.in new file mode 100644 index 0000000..9c4e250 --- /dev/null +++ b/src/dev.mnts.ModManager.gschema.xml.in @@ -0,0 +1,9 @@ + + + + + {} + Dictionary of games being managed. First string is game name second is path to mods folder. + + + \ No newline at end of file diff --git a/src/gtk/help-overlay.blp b/src/gtk/help-overlay.blp deleted file mode 100644 index 90ee78f..0000000 --- a/src/gtk/help-overlay.blp +++ /dev/null @@ -1,24 +0,0 @@ -using Gtk 4.0; - -ShortcutsWindow help_overlay { - modal: true; - - ShortcutsSection { - section-name: "shortcuts"; - max-height: 10; - - ShortcutsGroup { - title: C_("shortcut window", "General"); - - ShortcutsShortcut { - title: C_("shortcut window", "Show Shortcuts"); - action-name: "win.show-help-overlay"; - } - - ShortcutsShortcut { - title: C_("shortcut window", "Quit"); - action-name: "app.quit"; - } - } - } -} diff --git a/src/main.rs b/src/main.rs index 4741f6c..87c08d4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,12 +17,12 @@ mod application; mod config; -mod window; -mod pages; +mod windows; +mod components; mod api; +mod settings; use self::application::ModManagerApplication; -use self::window::ModManagerWindow; use config::{GETTEXT_PACKAGE, LOCALEDIR, PKGDATADIR}; use gettextrs::{bind_textdomain_codeset, bindtextdomain, textdomain}; @@ -44,7 +44,7 @@ fn main() -> glib::ExitCode { // Create a new GtkApplication. The application manages our main loop, // application windows, integration with the window manager/compositor, and // desktop features such as file opening and single-instance applications. - let app = ModManagerApplication::new("dev.mnts.ModManager", &gio::ApplicationFlags::empty()); + let app = ModManagerApplication::new( &gio::ApplicationFlags::empty()); // Run the application. This function will block until the application // exits. Upon return, we have our exit code to return to the shell. (This diff --git a/src/meson.build b/src/meson.build index 674ce5e..34d7c14 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,13 +1,14 @@ -pkgdatadir = get_option('prefix') / get_option('datadir') / meson.project_name() +datadir = get_option('prefix') / get_option('datadir') +pkgdatadir = datadir / meson.project_name() gnome = import('gnome') blueprints = custom_target('blueprints', input: files( - 'window.blp', - 'gtk/help-overlay.blp', - 'pages/chose-game-location.blp', - 'pages/main.blp', - 'pages/welcome.blp', + 'windows/main/main.blp', + 'windows/main/pages/welcome.blp', + 'windows/main/pages/games_and_mods.blp', + 'windows/add_new_game/add_new_game.blp', + 'components/mods_list.blp', ), output: '.', command: [find_program('blueprint-compiler'), 'batch-compile', '@OUTPUT@', '@CURRENT_SOURCE_DIR@', '@INPUT@'], @@ -21,9 +22,24 @@ gnome.compile_resources('mod-manager', install_dir: pkgdatadir, ) +# GSchema +gschema_conf = configuration_data() +gschema_conf.set('APP_ID', application_id) +gschema_conf.set('GETTEXT_PACKAGE', gettext_package) +gschema = configure_file( + input: '@0@.gschema.xml.in'.format(base_id), + output: '@0@.gschema.xml'.format(application_id), + configuration: gschema_conf, + install: true, + install_dir: pkgdatadir / 'glib-2.0' / 'schemas' +) +gnome.compile_schemas(depend_files: gschema) + +# Configuration conf = configuration_data() +conf.set_quoted('APP_ID', application_id) conf.set_quoted('VERSION', meson.project_version()) -conf.set_quoted('GETTEXT_PACKAGE', 'mod-manager') +conf.set_quoted('GETTEXT_PACKAGE', gettext_package) conf.set_quoted('LOCALEDIR', get_option('prefix') / get_option('localedir')) conf.set_quoted('PKGDATADIR', pkgdatadir) conf.set_quoted('API_KEY', '$2a$10$AtaQ/fkWxMoVHVhO.6PMoOHQq7ERdSdpmegqJ09.2Mgj5iTQP3r.2') diff --git a/src/mod-manager.gresource.xml b/src/mod-manager.gresource.xml index 0e9b2d2..b6db1de 100644 --- a/src/mod-manager.gresource.xml +++ b/src/mod-manager.gresource.xml @@ -1,11 +1,11 @@ - pages/welcome.ui - pages/main.ui - pages/chose-game-location.blp - gtk/help-overlay.ui - window.ui + windows/main/main.ui + windows/main/pages/welcome.ui + windows/main/pages/games_and_mods.ui + windows/add_new_game/add_new_game.ui + components/mods_list.ui diff --git a/src/pages/main.blp b/src/pages/main.blp deleted file mode 100644 index f97b733..0000000 --- a/src/pages/main.blp +++ /dev/null @@ -1,123 +0,0 @@ -using Gtk 4.0; - -Box welcome { - orientation: vertical; - valign: center; - halign: center; - - Image { - name: "logo"; - icon-name: "re.sonny.Workbench"; - pixel-size: 196; - margin-bottom: 30; - - styles [ - "icon-dropshadow" - ] - } - - Label { - label: _("Welcome to Mod Manager"); - margin-bottom: 30; - - styles [ - "title-1" - ] - } - - Box subtitle { - orientation: vertical; - halign: center; - margin-bottom: 30; - - Label { - label: "Learn and prototype with\nGNOME technologies"; - justify: center; - } - } - - Box { - orientation: vertical; - homogeneous: true; - halign: center; - - Box { - margin-bottom: 6; - - Image { - icon-name: "update-symbolic"; - margin-end: 12; - icon-size: normal; - } - - Label { - label: _("Edit Style or UI to update the Preview"); - } - } - - Box { - margin-bottom: 6; - - Image { - icon-name: "media-playback-start-symbolic"; - margin-end: 12; - icon-size: normal; - } - - Label { - label: _("Hit"); - } - - ShortcutsShortcut { - accelerator: "Return"; - margin-start: 12; - } - - Label { - label: _("to format and run Code"); - } - } - - Box { - margin-bottom: 6; - - Image { - icon-name: "media-floppy-symbolic"; - margin-end: 12; - icon-size: normal; - } - - Label { - label: _("Changes are automatically saved and restored"); - } - } - - Box { - margin-bottom: 6; - - Image { - icon-name: "library-symbolic"; - margin-end: 12; - icon-size: normal; - } - - Label { - label: _("Browse the Library for demos and examples"); - } - } - - Box { - margin-bottom: 6; - - Image { - icon-name: "user-bookmarks-symbolic"; - margin-end: 12; - icon-size: normal; - } - - Label { - label: _("Checkout the Bookmarks menu to learn and get help"); - } - } - } -} \ No newline at end of file diff --git a/src/pages/mod.rs b/src/pages/mod.rs deleted file mode 100644 index dc04f27..0000000 --- a/src/pages/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod welcome; -pub use welcome::*; \ No newline at end of file diff --git a/src/pages/welcome.blp b/src/pages/welcome.blp deleted file mode 100644 index 5d1e51c..0000000 --- a/src/pages/welcome.blp +++ /dev/null @@ -1,26 +0,0 @@ -using Gtk 4.0; -using Adw 1; - -template $ModManagerWelcome : Adw.NavigationPage { - - Box { - orientation: vertical; - halign: center; - valign: center; - - Label { - label: _("Welcome to Mod Manager"); - margin-bottom: 30; - justify: center; - styles ["title-1"] - } - - Label { - label: _("Start with picking the game you want to manage mods for"); - margin-bottom: 30; - justify: center; - } - - DropDown games_dropdown {} - } -} \ No newline at end of file diff --git a/src/settings.rs b/src/settings.rs new file mode 100644 index 0000000..3a5808b --- /dev/null +++ b/src/settings.rs @@ -0,0 +1,18 @@ +use gsettings_macro::gen_settings; +use gtk::gio; +use gio::glib; +use std::collections::HashMap; + +use crate::config::APP_ID; + +#[gen_settings( + file = "./src/dev.mnts.ModManager.gschema.xml.in", +)] +#[gen_settings_define(key_name = "games", arg_type = "HashMap", ret_type = "HashMap")] +pub struct ModManagerSettings; + +impl Default for ModManagerSettings { + fn default() -> Self { + Self::new(APP_ID) + } +} \ No newline at end of file diff --git a/src/window.blp b/src/window.blp deleted file mode 100644 index a977cdf..0000000 --- a/src/window.blp +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright (c) 2023 Tine Jozelj - - 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 . - */ - -using Gtk 4.0; -using Adw 1; - -template $ModManagerWindow : Adw.ApplicationWindow { - default-width: 600; - default-height: 300; - - content: Adw.ToolbarView { - [top] - Adw.HeaderBar header_bar { - [end] - MenuButton { - primary: true; - icon-name: "open-menu-symbolic"; - tooltip-text: _("Menu"); - menu-model: primary_menu; - } - } - content: Adw.NavigationView navigation_view {}; - }; -} - -menu primary_menu { - section { - item { - label: _("_Preferences"); - action: "app.preferences"; - } - - item { - label: _("_Keyboard Shortcuts"); - action: "win.show-help-overlay"; - } - - item { - label: _("_About Mod-manager"); - action: "app.about"; - } - } -} diff --git a/src/windows/add_new_game/add_new_game.blp b/src/windows/add_new_game/add_new_game.blp new file mode 100644 index 0000000..9a1172a --- /dev/null +++ b/src/windows/add_new_game/add_new_game.blp @@ -0,0 +1,46 @@ +using Gtk 4.0; +using Adw 1; + +template $ModManagerWindowAddNewGame : Adw.ApplicationWindow { + default-width: 600; + default-height: 400; + title: _("Add a new game"); + + content: Adw.ToolbarView { + [top] + Adw.HeaderBar header_bar { + show-back-button: true; + } + + content: Box { + orientation: vertical; + halign: center; + valign: center; + + Label { + label: _("Chose a game to manage mods for"); + margin-bottom: 30; + justify: center; + wrap: true; + styles ["title-1"] + } + + DropDown games_dropdown { + margin-bottom: 30; + } + + FileDialog mods_folder { + title: _("Chose a location where to install the mods"); + } + + Button chose_button { + label: _("Chose the location"); + margin-bottom: 30; + } + + Button complete_button { + label: _("Add game"); + } + }; + }; +} \ No newline at end of file diff --git a/src/windows/add_new_game/add_new_game.rs b/src/windows/add_new_game/add_new_game.rs new file mode 100644 index 0000000..c0856b0 --- /dev/null +++ b/src/windows/add_new_game/add_new_game.rs @@ -0,0 +1,99 @@ +/* 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 . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +use gtk::prelude::*; +use adw::subclass::prelude::*; +use gtk::{gio, glib}; +use glib::clone; + +use crate::api::*; + +mod imp { + use super::*; + + #[derive(Debug, Default, gtk::CompositeTemplate)] + #[template(resource = "/dev/mnts/ModManager/windows/add_new_game/add_new_game.ui")] + pub struct ModManagerWindowAddNewGame { + #[template_child] + pub complete_button: TemplateChild, + + #[template_child] + pub games_dropdown: TemplateChild + } + + #[glib::object_subclass] + impl ObjectSubclass for ModManagerWindowAddNewGame { + const NAME: &'static str = "ModManagerWindowAddNewGame"; + type Type = super::ModManagerWindowAddNewGame; + type ParentType = adw::ApplicationWindow; + + fn class_init(klass: &mut Self::Class) { + klass.bind_template(); + } + + fn instance_init(obj: &glib::subclass::InitializingObject) { + obj.init_template(); + } + } + + impl ObjectImpl for ModManagerWindowAddNewGame {} + impl WidgetImpl for ModManagerWindowAddNewGame {} + impl WindowImpl for ModManagerWindowAddNewGame {} + impl ApplicationWindowImpl for ModManagerWindowAddNewGame {} + impl AdwApplicationWindowImpl for ModManagerWindowAddNewGame {} + +} + +glib::wrapper! { + pub struct ModManagerWindowAddNewGame(ObjectSubclass) + @extends gtk::Widget, gtk::Window, gtk::ApplicationWindow, adw::ApplicationWindow, + @implements gio::ActionGroup, gio::ActionMap; +} + +impl ModManagerWindowAddNewGame { + pub fn new() -> Self { + glib::Object::builder() + .build() + } + + pub fn setup(&self) { + let games = games::get_games(); + let games_strs: Vec<&str> = games.iter().map(|s| s.as_str()).collect(); + let games_list = >k::StringList::new(&games_strs); + + let complete_button = &imp::ModManagerWindowAddNewGame::from_obj(self).complete_button; + let games_dropdown = &imp::ModManagerWindowAddNewGame::from_obj(self).games_dropdown; + + games_dropdown.set_property("model", games_list); + + let instance = self; + + complete_button.connect_clicked(clone!(@strong instance => move |_| { + //let selected_game = games_dropdown.selected_item(); + + println!("complete button clicked"); + + //if let Some(selected_game) = selected_game { + instance.hide() + //} + })); + } +} + diff --git a/src/windows/add_new_game/mod.rs b/src/windows/add_new_game/mod.rs new file mode 100644 index 0000000..395d67d --- /dev/null +++ b/src/windows/add_new_game/mod.rs @@ -0,0 +1,2 @@ +pub mod add_new_game; +pub use add_new_game::*; \ No newline at end of file diff --git a/src/windows/main/main.blp b/src/windows/main/main.blp new file mode 100644 index 0000000..0a677b9 --- /dev/null +++ b/src/windows/main/main.blp @@ -0,0 +1,25 @@ +/* + Copyright (c) 2023 Tine Jozelj + + 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 . + */ + +using Gtk 4.0; +using Adw 1; + +template $ModManagerWindowMain : Adw.ApplicationWindow { + default-width: 1000; + default-height: 800; + title: _("Mod Manager"); +} \ No newline at end of file diff --git a/src/window.rs b/src/windows/main/main.rs similarity index 58% rename from src/window.rs rename to src/windows/main/main.rs index b6961f8..5ab65cd 100644 --- a/src/window.rs +++ b/src/windows/main/main.rs @@ -23,19 +23,14 @@ mod imp { use super::*; #[derive(Debug, Default, gtk::CompositeTemplate)] - #[template(resource = "/dev/mnts/ModManager/window.ui")] - pub struct ModManagerWindow { - // Template widgets - #[template_child] - pub header_bar: TemplateChild, - #[template_child] - pub navigation_view: TemplateChild, + #[template(resource = "/dev/mnts/ModManager/windows/main/main.ui")] + pub struct ModManagerWindowMain { } #[glib::object_subclass] - impl ObjectSubclass for ModManagerWindow { - const NAME: &'static str = "ModManagerWindow"; - type Type = super::ModManagerWindow; + impl ObjectSubclass for ModManagerWindowMain { + const NAME: &'static str = "ModManagerWindowMain"; + type Type = super::ModManagerWindowMain; type ParentType = adw::ApplicationWindow; fn class_init(klass: &mut Self::Class) { @@ -47,28 +42,28 @@ mod imp { } } - impl ObjectImpl for ModManagerWindow {} - impl WidgetImpl for ModManagerWindow {} - impl WindowImpl for ModManagerWindow {} - impl ApplicationWindowImpl for ModManagerWindow {} - impl AdwApplicationWindowImpl for ModManagerWindow {} + impl ObjectImpl for ModManagerWindowMain { + fn constructed(&self) { + self.parent_constructed(); + } + } + impl WidgetImpl for ModManagerWindowMain {} + impl WindowImpl for ModManagerWindowMain {} + impl ApplicationWindowImpl for ModManagerWindowMain {} + impl AdwApplicationWindowImpl for ModManagerWindowMain {} } glib::wrapper! { - pub struct ModManagerWindow(ObjectSubclass) + pub struct ModManagerWindowMain(ObjectSubclass) @extends gtk::Widget, gtk::Window, gtk::ApplicationWindow, adw::ApplicationWindow, @implements gio::ActionGroup, gio::ActionMap; } -impl ModManagerWindow { - pub fn new>(application: &P) -> Self { +impl ModManagerWindowMain { + pub fn new>(application: &P, content: >k::Widget) -> Self { glib::Object::builder() .property("application", application) + .property("content", content) .build() } - - pub fn set_page(&self, page: &adw::NavigationPage) { - imp::ModManagerWindow::from_obj(self) - .navigation_view.push(page); - } } diff --git a/src/windows/main/mod.rs b/src/windows/main/mod.rs new file mode 100644 index 0000000..77a274a --- /dev/null +++ b/src/windows/main/mod.rs @@ -0,0 +1,5 @@ +pub mod main; +pub use main::*; + +pub mod pages; +pub use pages::*; \ No newline at end of file diff --git a/src/windows/main/pages/games_and_mods.blp b/src/windows/main/pages/games_and_mods.blp new file mode 100644 index 0000000..496fe8a --- /dev/null +++ b/src/windows/main/pages/games_and_mods.blp @@ -0,0 +1,45 @@ +using Gtk 4.0; +using Adw 1; + +template $GamesAndMods: Adw.Bin { + Adw.NavigationSplitView { + sidebar: Adw.NavigationPage { + title: "Games"; + tag: "sidebar"; + + Adw.ToolbarView { + [top] + Adw.HeaderBar { + } + + content: Box { + Label { + label: "The Sims 4"; + } + Label { + label: "The Sims 3"; + } + Label { + label: "The Sims 2"; + } + }; + } + }; + content: Adw.NavigationPage{ + title: "Mods"; + tag: "content"; + + Adw.ToolbarView { + [top] + Adw.HeaderBar { + } + + content: Box { + Label { + label: "Mods"; + } + }; + } + }; + } +} \ No newline at end of file diff --git a/src/windows/main/pages/games_and_mods.rs b/src/windows/main/pages/games_and_mods.rs new file mode 100644 index 0000000..6722ff6 --- /dev/null +++ b/src/windows/main/pages/games_and_mods.rs @@ -0,0 +1,62 @@ +/* + Copyright (c) 2023 Tine Jozelj + + 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 . + */ + +use gtk::prelude::*; +use adw::subclass::prelude::*; +use gtk::{gio, glib}; + +mod imp { + + use super::*; + + #[derive(Debug, Default, gtk::CompositeTemplate)] + #[template(resource = "/dev/mnts/ModManager/windows/main/pages/games_and_mods.ui")] + pub struct GamesAndMods { + } + + #[glib::object_subclass] + impl ObjectSubclass for GamesAndMods { + const NAME: &'static str = "GamesAndMods"; + type Type = super::GamesAndMods; + type ParentType = adw::Bin; + + fn class_init(klass: &mut Self::Class) { + klass.bind_template(); + } + + fn instance_init(obj: &glib::subclass::InitializingObject) { + obj.init_template(); + } + } + + impl ObjectImpl for GamesAndMods {} + impl WidgetImpl for GamesAndMods {} + impl BinImpl for GamesAndMods {} +} + +glib::wrapper! { + pub struct GamesAndMods(ObjectSubclass) + @extends gtk::Widget, adw::NavigationSplitView, + @implements gio::ActionGroup, gio::ActionMap; +} + +impl GamesAndMods { + pub fn new() -> Self { + glib::Object::builder() + .build() + } +} diff --git a/src/windows/main/pages/mod.rs b/src/windows/main/pages/mod.rs new file mode 100644 index 0000000..964caf8 --- /dev/null +++ b/src/windows/main/pages/mod.rs @@ -0,0 +1,5 @@ +pub mod games_and_mods; +pub use games_and_mods::*; + +pub mod welcome; +pub use welcome::*; \ No newline at end of file diff --git a/src/windows/main/pages/welcome.blp b/src/windows/main/pages/welcome.blp new file mode 100644 index 0000000..77e9305 --- /dev/null +++ b/src/windows/main/pages/welcome.blp @@ -0,0 +1,28 @@ +using Gtk 4.0; +using Adw 1; + +template $Welcome: Adw.Bin { + Adw.ToolbarView { + [top] + Adw.HeaderBar { + } + + content: Box { + orientation: vertical; + halign: center; + valign: center; + + Label { + label: "No games added yet!"; + justify: center; + wrap: true; + styles ["title-1"] + margin-bottom: 30; + } + Button add_new_game { + label: "Add new game"; + styles ["suggested-action", "pill"] + } + }; + } +} \ No newline at end of file diff --git a/src/windows/main/pages/welcome.rs b/src/windows/main/pages/welcome.rs new file mode 100644 index 0000000..9ddfd49 --- /dev/null +++ b/src/windows/main/pages/welcome.rs @@ -0,0 +1,76 @@ +/* +Copyright (c) 2023 Tine Jozelj + +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 . +*/ + +use adw::subclass::prelude::*; +use gtk::prelude::*; +use gtk::{gio, glib}; + +use crate::windows::ModManagerWindowAddNewGame; + +mod imp { + + use super::*; + + #[derive(Debug, Default, gtk::CompositeTemplate)] + #[template(resource = "/dev/mnts/ModManager/windows/main/pages/welcome.ui")] + pub struct Welcome { + #[template_child] + pub add_new_game: gtk::TemplateChild, + } + + #[glib::object_subclass] + impl ObjectSubclass for Welcome { + const NAME: &'static str = "Welcome"; + type Type = super::Welcome; + type ParentType = adw::Bin; + + fn class_init(klass: &mut Self::Class) { + klass.bind_template(); + } + + fn instance_init(obj: &glib::subclass::InitializingObject) { + obj.init_template(); + } + } + + impl ObjectImpl for Welcome { + fn constructed(&self) { + self.parent_constructed(); + + self.add_new_game.connect_clicked(|_| { + let welcome = ModManagerWindowAddNewGame::new(); + welcome.setup(); + welcome.set_modal(true); + welcome.present(); + }); + } + } + impl WidgetImpl for Welcome {} + impl BinImpl for Welcome {} +} + +glib::wrapper! { + pub struct Welcome(ObjectSubclass) + @extends gtk::Widget, adw::ToolbarView, + @implements gio::ActionGroup, gio::ActionMap; +} + +impl Welcome { + pub fn new() -> Self { + glib::Object::builder().build() + } +} diff --git a/src/windows/mod.rs b/src/windows/mod.rs new file mode 100644 index 0000000..be8c4ba --- /dev/null +++ b/src/windows/mod.rs @@ -0,0 +1,5 @@ +pub mod main; +pub use main::*; + +pub mod add_new_game; +pub use add_new_game::*;