feat: refactoring etc. trying to implement settings store

This commit is contained in:
Tine Jozelj 2023-12-20 18:32:50 +01:00
parent 303b95e32f
commit 50dd8f5e18
Signed by: mentos1386
SSH key fingerprint: SHA256:MNtTsLbihYaWF8j1fkOHfkKNlnN1JQfxEU/rBU8nCGw
31 changed files with 636 additions and 311 deletions

86
Cargo.lock generated
View file

@ -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"

View file

@ -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"] }

View file

@ -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')

10
meson_options.txt Normal file
View file

@ -0,0 +1,10 @@
option(
'profile',
type: 'combo',
choices: [
'default',
'development'
],
value: 'default',
description: 'The build profile for ModManager. One of "default" or "development".'
)

View file

@ -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::<adw::NavigationPage>());
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 <tine@tjo.space>"])

2
src/components/mod.rs Normal file
View file

@ -0,0 +1,2 @@
pub mod mods_list;
pub use mods_list::*;

View file

@ -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 {
}
}
}
};
}
}

View file

@ -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<gtk::DropDown>
#[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<imp::ModManagerWelcome>)
pub struct ModsList(ObjectSubclass<imp::ModsList>)
@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 = &gtk::StringList::new(&games_strs);
imp::ModManagerWelcome::from_obj(self).games_dropdown.set_property("model", games_list)
glib::Object::builder().build()
}
}

View file

@ -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@;

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<schemalist>
<schema id="@APP_ID@" gettext-domain="@GETTEXT_PACKAGE@" path="/dev/mnts/ModManager/">
<key name="games" type="{ss}">
<default>{}</default>
<summary>Dictionary of games being managed. First string is game name second is path to mods folder.</summary>
</key>
</schema>
</schemalist>

View file

@ -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";
}
}
}
}

View file

@ -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

View file

@ -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')

View file

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/dev/mnts/ModManager">
<file>pages/welcome.ui</file>
<file>pages/main.ui</file>
<file>pages/chose-game-location.blp</file>
<file>gtk/help-overlay.ui</file>
<file>window.ui</file>
<file>windows/main/main.ui</file>
<file>windows/main/pages/welcome.ui</file>
<file>windows/main/pages/games_and_mods.ui</file>
<file>windows/add_new_game/add_new_game.ui</file>
<file>components/mods_list.ui</file>
</gresource>
</gresources>

View file

@ -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: "<Control>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");
}
}
}
}

View file

@ -1,2 +0,0 @@
pub mod welcome;
pub use welcome::*;

View file

@ -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 {}
}
}

18
src/settings.rs Normal file
View file

@ -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<String, String>", ret_type = "HashMap<String, String>")]
pub struct ModManagerSettings;
impl Default for ModManagerSettings {
fn default() -> Self {
Self::new(APP_ID)
}
}

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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";
}
}
}

View file

@ -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");
}
};
};
}

View file

@ -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 <http://www.gnu.org/licenses/>.
*
* 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<gtk::Button>,
#[template_child]
pub games_dropdown: TemplateChild<gtk::DropDown>
}
#[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<Self>) {
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<imp::ModManagerWindowAddNewGame>)
@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 = &gtk::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()
//}
}));
}
}

View file

@ -0,0 +1,2 @@
pub mod add_new_game;
pub use add_new_game::*;

25
src/windows/main/main.blp Normal file
View file

@ -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 <https://www.gnu.org/licenses/>.
*/
using Gtk 4.0;
using Adw 1;
template $ModManagerWindowMain : Adw.ApplicationWindow {
default-width: 1000;
default-height: 800;
title: _("Mod Manager");
}

View file

@ -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<adw::HeaderBar>,
#[template_child]
pub navigation_view: TemplateChild<adw::NavigationView>,
#[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<imp::ModManagerWindow>)
pub struct ModManagerWindowMain(ObjectSubclass<imp::ModManagerWindowMain>)
@extends gtk::Widget, gtk::Window, gtk::ApplicationWindow, adw::ApplicationWindow,
@implements gio::ActionGroup, gio::ActionMap;
}
impl ModManagerWindow {
pub fn new<P: glib::IsA<gtk::Application>>(application: &P) -> Self {
impl ModManagerWindowMain {
pub fn new<P: glib::IsA<gtk::Application>>(application: &P, content: &gtk::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);
}
}

5
src/windows/main/mod.rs Normal file
View file

@ -0,0 +1,5 @@
pub mod main;
pub use main::*;
pub mod pages;
pub use pages::*;

View file

@ -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";
}
};
}
};
}
}

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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<Self>) {
obj.init_template();
}
}
impl ObjectImpl for GamesAndMods {}
impl WidgetImpl for GamesAndMods {}
impl BinImpl for GamesAndMods {}
}
glib::wrapper! {
pub struct GamesAndMods(ObjectSubclass<imp::GamesAndMods>)
@extends gtk::Widget, adw::NavigationSplitView,
@implements gio::ActionGroup, gio::ActionMap;
}
impl GamesAndMods {
pub fn new() -> Self {
glib::Object::builder()
.build()
}
}

View file

@ -0,0 +1,5 @@
pub mod games_and_mods;
pub use games_and_mods::*;
pub mod welcome;
pub use welcome::*;

View file

@ -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"]
}
};
}
}

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
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<gtk::Button>,
}
#[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<Self>) {
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<imp::Welcome>)
@extends gtk::Widget, adw::ToolbarView,
@implements gio::ActionGroup, gio::ActionMap;
}
impl Welcome {
pub fn new() -> Self {
glib::Object::builder().build()
}
}

5
src/windows/mod.rs Normal file
View file

@ -0,0 +1,5 @@
pub mod main;
pub use main::*;
pub mod add_new_game;
pub use add_new_game::*;