Add welcome page and improve generated code

This commit is contained in:
Elias Projahn 2023-09-13 14:58:31 +02:00
parent 379923e4ca
commit f61482c329
11 changed files with 175 additions and 92 deletions

View file

@ -3,6 +3,7 @@ gnome = import('gnome')
blueprints = custom_target('blueprints', blueprints = custom_target('blueprints',
input: files( input: files(
'welcome_page.blp',
'window.blp' 'window.blp'
), ),
output: '.', output: '.',

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<gresources> <gresources>
<gresource prefix="/de/johrpan/musicus"> <gresource prefix="/de/johrpan/musicus">
<file preprocess="xml-stripblanks">welcome_page.ui</file>
<file preprocess="xml-stripblanks">window.ui</file> <file preprocess="xml-stripblanks">window.ui</file>
</gresource> </gresource>
</gresources> </gresources>

39
data/res/welcome_page.blp Normal file
View file

@ -0,0 +1,39 @@
using Gtk 4.0;
using Adw 1;
template $MusicusWelcomePage : Adw.NavigationPage {
title: _("Welcome to Musicus");
Adw.ToolbarView {
[top]
Adw.HeaderBar header_bar {
[end]
MenuButton {
icon-name: "open-menu-symbolic";
menu-model: primary_menu;
}
}
Adw.StatusPage {
icon-name: "de.johrpan.musicus";
title: _("Welcome to Musicus");
description: _("Get started by choosing where to store your music library. Is this your first time using Musicus? If so, create a new empty folder for your library. Musicus will use this location to manage your recordings. You can also select a folder that already contains a music library created by Musicus.");
child: Gtk.Button choose_library_button {
styles ["suggested-action", "pill"]
halign: center;
label: _("Choose library folder");
};
}
}
}
menu primary_menu {
item {
label: _("_Preferences");
action: "app.preferences";
}
item {
label: _("_About Musicus");
action: "app.about";
}
}

View file

@ -2,35 +2,9 @@ using Gtk 4.0;
using Adw 1; using Adw 1;
template $MusicusWindow : Adw.ApplicationWindow { template $MusicusWindow : Adw.ApplicationWindow {
default-width: 600; title: _("Musicus");
default-height: 300; default-width: 800;
default-height: 600;
Box { Adw.NavigationView navigation_view {}
orientation: vertical;
HeaderBar header_bar {
[end]
MenuButton {
icon-name: "open-menu-symbolic";
menu-model: primary_menu;
}
}
Label label {
label: _("Hello, World!");
vexpand: true;
styles ["title-1"]
}
}
}
menu primary_menu {
item {
label: _("_Preferences");
action: "app.preferences";
}
item {
label: _("_About Musicus");
action: "app.about";
}
} }

View file

@ -1,4 +1,6 @@
data/res/welcome_page.blp
data/res/window.blp
data/de.johrpan.musicus.desktop.in data/de.johrpan.musicus.desktop.in
data/de.johrpan.musicus.appdata.xml.in data/de.johrpan.musicus.appdata.xml.in
data/de.johrpan.musicus.gschema.xml data/de.johrpan.musicus.gschema.xml
src/window.blp src/application.rs

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-07-06 14:30+0200\n" "POT-Creation-Date: 2023-09-13 14:57+0200\n"
"PO-Revision-Date: 2023-06-28 14:58+0200\n" "PO-Revision-Date: 2023-06-28 14:58+0200\n"
"Last-Translator: <elias@johrpan.de>\n" "Last-Translator: <elias@johrpan.de>\n"
"Language-Team: German <translation-team-de@lists.sourceforge.net>\n" "Language-Team: German <translation-team-de@lists.sourceforge.net>\n"
@ -18,7 +18,32 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: data/de.johrpan.musicus.desktop.in:3 #: data/res/welcome_page.blp:5 data/res/welcome_page.blp:19
msgid "Welcome to Musicus"
msgstr ""
#: data/res/welcome_page.blp:20
msgid ""
"Get started by choosing where to store your music library. Is this your "
"first time using Musicus? If so, create a new empty folder for your library. "
"Musicus will use this location to manage your recordings. You can also "
"select a folder that already contains a music library created by Musicus."
msgstr ""
#: data/res/welcome_page.blp:24
msgid "Choose library folder"
msgstr ""
#: data/res/welcome_page.blp:32
msgid "_Preferences"
msgstr "_Einstellungen"
#: data/res/welcome_page.blp:36
msgid "_About Musicus"
msgstr "_Über Musicus"
#: data/res/window.blp:5 data/de.johrpan.musicus.desktop.in:3
#: src/application.rs:79
msgid "Musicus" msgid "Musicus"
msgstr "Musicus" msgstr "Musicus"
@ -26,14 +51,5 @@ msgstr "Musicus"
msgid "No description" msgid "No description"
msgstr "Keine Beschreibung" msgstr "Keine Beschreibung"
#: src/window.blp:20 #~ msgid "Hello, World!"
msgid "Hello, World!" #~ msgstr "Hallo, Welt!"
msgstr "Hallo, Welt!"
#: src/window.blp:29
msgid "_Preferences"
msgstr "_Einstellungen"
#: src/window.blp:33
msgid "_About Musicus"
msgstr "_Über Musicus"

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-07-06 14:30+0200\n" "POT-Creation-Date: 2023-09-13 14:57+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,22 +17,35 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n" "Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: data/de.johrpan.musicus.desktop.in:3 #: data/res/welcome_page.blp:5 data/res/welcome_page.blp:19
msgid "Welcome to Musicus"
msgstr ""
#: data/res/welcome_page.blp:20
msgid ""
"Get started by choosing where to store your music library. Is this your "
"first time using Musicus? If so, create a new empty folder for your library. "
"Musicus will use this location to manage your recordings. You can also "
"select a folder that already contains a music library created by Musicus."
msgstr ""
#: data/res/welcome_page.blp:24
msgid "Choose library folder"
msgstr ""
#: data/res/welcome_page.blp:32
msgid "_Preferences"
msgstr ""
#: data/res/welcome_page.blp:36
msgid "_About Musicus"
msgstr ""
#: data/res/window.blp:5 data/de.johrpan.musicus.desktop.in:3
#: src/application.rs:79
msgid "Musicus" msgid "Musicus"
msgstr "" msgstr ""
#: data/de.johrpan.musicus.appdata.xml.in:7 #: data/de.johrpan.musicus.appdata.xml.in:7
msgid "No description" msgid "No description"
msgstr "" msgstr ""
#: src/window.blp:20
msgid "Hello, World!"
msgstr ""
#: src/window.blp:29
msgid "_Preferences"
msgstr ""
#: src/window.blp:33
msgid "_About Musicus"
msgstr ""

View file

@ -1,6 +1,6 @@
use gtk::prelude::*;
use adw::subclass::prelude::*; use adw::subclass::prelude::*;
use gtk::{gio, glib}; use gettextrs::gettext;
use gtk::{gio, glib, prelude::*};
use crate::config::VERSION; use crate::config::VERSION;
use crate::MusicusWindow; use crate::MusicusWindow;
@ -28,13 +28,9 @@ mod imp {
} }
impl ApplicationImpl for MusicusApplication { impl ApplicationImpl for MusicusApplication {
// We connect to the activate callback to create a window when the application
// has been launched. Additionally, this callback notifies us when the user
// tries to launch a "second instance" of the application. When they try
// to do that, we'll just present any existing window.
fn activate(&self) { fn activate(&self) {
let application = self.obj(); let application = self.obj();
// Get the current window or create one if necessary
let window = if let Some(window) = application.active_window() { let window = if let Some(window) = application.active_window() {
window window
} else { } else {
@ -42,7 +38,6 @@ mod imp {
window.upcast() window.upcast()
}; };
// Ask the window manager/compositor to present the window
window.present(); window.present();
} }
} }
@ -69,9 +64,11 @@ impl MusicusApplication {
let quit_action = gio::ActionEntry::builder("quit") let quit_action = gio::ActionEntry::builder("quit")
.activate(move |app: &Self, _, _| app.quit()) .activate(move |app: &Self, _, _| app.quit())
.build(); .build();
let about_action = gio::ActionEntry::builder("about") let about_action = gio::ActionEntry::builder("about")
.activate(move |app: &Self, _, _| app.show_about()) .activate(move |app: &Self, _, _| app.show_about())
.build(); .build();
self.add_action_entries([quit_action, about_action]); self.add_action_entries([quit_action, about_action]);
} }
@ -79,12 +76,14 @@ impl MusicusApplication {
let window = self.active_window().unwrap(); let window = self.active_window().unwrap();
let about = adw::AboutWindow::builder() let about = adw::AboutWindow::builder()
.transient_for(&window) .transient_for(&window)
.application_name("musicus") .application_name(gettext("Musicus"))
.application_icon("de.johrpan.musicus") .application_icon("de.johrpan.musicus")
.developer_name("Unknown") .developer_name("Elias Projahn")
.version(VERSION) .version(VERSION)
.developers(vec!["Unknown"]) .website("https://code.johrpan.de/johrpan/musicus")
.copyright("© 2023 Unknown") .developers(vec!["Elias Projahn <elias@johrpan.de>"])
.copyright("© 2023 Elias Projahn")
.license_type(gtk::License::Gpl30)
.build(); .build();
about.present(); about.present();

View file

@ -1,35 +1,23 @@
mod application; mod application;
mod config; mod config;
mod welcome_page;
mod window; mod window;
use self::application::MusicusApplication; use self::{application::MusicusApplication, window::MusicusWindow};
use self::window::MusicusWindow;
use config::{GETTEXT_PACKAGE, LOCALEDIR, PKGDATADIR}; use config::{GETTEXT_PACKAGE, LOCALEDIR, PKGDATADIR};
use gettextrs::{bind_textdomain_codeset, bindtextdomain, textdomain}; use gettextrs::{bind_textdomain_codeset, bindtextdomain, textdomain};
use gtk::{gio, glib}; use gtk::{gio, glib, prelude::*};
use gtk::prelude::*;
fn main() -> glib::ExitCode { fn main() -> glib::ExitCode {
// Set up gettext translations
bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR).expect("Unable to bind the text domain"); bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR).expect("Unable to bind the text domain");
bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8") bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8")
.expect("Unable to set the text domain encoding"); .expect("Unable to set the text domain encoding");
textdomain(GETTEXT_PACKAGE).expect("Unable to switch to the text domain"); textdomain(GETTEXT_PACKAGE).expect("Unable to switch to the text domain");
// Load resources
let resources = gio::Resource::load(PKGDATADIR.to_owned() + "/musicus.gresource") let resources = gio::Resource::load(PKGDATADIR.to_owned() + "/musicus.gresource")
.expect("Could not load resources"); .expect("Could not load resources");
gio::resources_register(&resources); gio::resources_register(&resources);
// Create a new GtkApplication. The application manages our main loop, MusicusApplication::new("de.johrpan.musicus", &gio::ApplicationFlags::empty()).run()
// application windows, integration with the window manager/compositor, and
// desktop features such as file opening and single-instance applications.
let app = MusicusApplication::new("de.johrpan.musicus", &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
// is the code you see when you do `echo $?` after running a command in a
// terminal.
app.run()
} }

43
src/welcome_page.rs Normal file
View file

@ -0,0 +1,43 @@
use adw::subclass::{navigation_page::NavigationPageImpl, prelude::*};
use gtk::glib;
mod imp {
use super::*;
#[derive(Debug, Default, gtk::CompositeTemplate)]
#[template(resource = "/de/johrpan/musicus/welcome_page.ui")]
pub struct MusicusWelcomePage {
#[template_child]
pub choose_library_button: TemplateChild<gtk::Button>,
}
#[glib::object_subclass]
impl ObjectSubclass for MusicusWelcomePage {
const NAME: &'static str = "MusicusWelcomePage";
type Type = super::MusicusWelcomePage;
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 MusicusWelcomePage {}
impl WidgetImpl for MusicusWelcomePage {}
impl NavigationPageImpl for MusicusWelcomePage {}
}
glib::wrapper! {
pub struct MusicusWelcomePage(ObjectSubclass<imp::MusicusWelcomePage>)
@extends gtk::Widget, adw::NavigationPage;
}
impl MusicusWelcomePage {
pub fn new() -> Self {
glib::Object::new()
}
}

View file

@ -1,3 +1,5 @@
use crate::welcome_page::MusicusWelcomePage;
use adw::subclass::prelude::*; use adw::subclass::prelude::*;
use gtk::{gio, glib}; use gtk::{gio, glib};
@ -7,11 +9,8 @@ mod imp {
#[derive(Debug, Default, gtk::CompositeTemplate)] #[derive(Debug, Default, gtk::CompositeTemplate)]
#[template(resource = "/de/johrpan/musicus/window.ui")] #[template(resource = "/de/johrpan/musicus/window.ui")]
pub struct MusicusWindow { pub struct MusicusWindow {
// Template widgets
#[template_child] #[template_child]
pub header_bar: TemplateChild<gtk::HeaderBar>, pub navigation_view: TemplateChild<adw::NavigationView>,
#[template_child]
pub label: TemplateChild<gtk::Label>,
} }
#[glib::object_subclass] #[glib::object_subclass]
@ -29,7 +28,14 @@ mod imp {
} }
} }
impl ObjectImpl for MusicusWindow {} impl ObjectImpl for MusicusWindow {
fn constructed(&self) {
self.parent_constructed();
self.navigation_view.add(&MusicusWelcomePage::new());
}
}
impl WidgetImpl for MusicusWindow {} impl WidgetImpl for MusicusWindow {}
impl WindowImpl for MusicusWindow {} impl WindowImpl for MusicusWindow {}
impl ApplicationWindowImpl for MusicusWindow {} impl ApplicationWindowImpl for MusicusWindow {}
@ -38,7 +44,8 @@ mod imp {
glib::wrapper! { glib::wrapper! {
pub struct MusicusWindow(ObjectSubclass<imp::MusicusWindow>) pub struct MusicusWindow(ObjectSubclass<imp::MusicusWindow>)
@extends gtk::Widget, gtk::Window, gtk::ApplicationWindow, adw::ApplicationWindow, @implements gio::ActionGroup, gio::ActionMap; @extends gtk::Widget, gtk::Window, gtk::ApplicationWindow, adw::ApplicationWindow,
@implements gio::ActionGroup, gio::ActionMap;
} }
impl MusicusWindow { impl MusicusWindow {