Commit 181247c0 authored by Bilal Elmoussaoui's avatar Bilal Elmoussaoui

Port to latest gtk-rs crates

parent 95892ed1
...@@ -6,9 +6,9 @@ edition = "2021" ...@@ -6,9 +6,9 @@ edition = "2021"
[dependencies] [dependencies]
gtk = { package = "gtk4", version = "0.4", features= ["v4_2"]} gtk = { package = "gtk4", version = "0.5", features= ["v4_2"]}
log = "0.4" log = "0.4"
gettext-rs = { version = "0.7", features = ["gettext-system"] } gettext-rs = { version = "0.7", features = ["gettext-system"] }
adw = {package = "libadwaita", version = "0.1"} adw = {package = "libadwaita", version = "0.2"}
pretty_env_logger = "0.4" pretty_env_logger = "0.4"
regex = "1.5" regex = "1.5"
use crate::config; use crate::config;
use crate::utils;
use crate::widgets::Window; use crate::widgets::Window;
use adw::prelude::*; use adw::prelude::*;
use gtk::{ use gtk::{gio, glib, subclass::prelude::*};
gio,
glib::{self, clone},
subclass::prelude::*,
};
use log::info;
mod imp { mod imp {
use super::*; use super::*;
...@@ -28,66 +22,55 @@ mod imp { ...@@ -28,66 +22,55 @@ mod imp {
impl ObjectImpl for Application {} impl ObjectImpl for Application {}
impl ApplicationImpl for Application { impl ApplicationImpl for Application {
fn activate(&self, application: &Self::Type) { fn activate(&self) {
let window = Window::new(application); self.parent_activate();
let application = self.instance();
let window = Window::new(&application);
application.add_window(&window); application.add_window(&window);
window.present(); window.present();
self.window.set(window.downgrade()).unwrap(); self.window.set(window.downgrade()).unwrap();
self.parent_activate(application);
} }
fn startup(&self, application: &Self::Type) { fn startup(&self) {
self.parent_startup();
let application = self.instance();
// Quit // Quit
utils::action( let quit = gio::ActionEntry::builder("quit")
application, .activate(move |app: &Self::Type, _, _| app.quit())
"quit", .build();
clone!(@weak application => move |_, _| {
application.quit();
}),
);
// Start Tour // Start Tour
utils::action( let start_tour = gio::ActionEntry::builder("start-tour")
application, .activate(move |app: &Self::Type, _, _| app.window().start_tour())
"start-tour", .build();
clone!(@weak application => move |_, _| {
application.window().start_tour();
}),
);
// Skip Tour // Skip Tour
utils::action( let skip_tour = gio::ActionEntry::builder("skip-tour")
application, .activate(move |app: &Self::Type, _, _| app.quit())
"skip-tour", .build();
clone!(@weak application => move |_, _| { // Next page
application.quit(); let next_page = gio::ActionEntry::builder("next-page")
}), .activate(move |app: &Self::Type, _, _| {
); let window = app.window();
utils::action(
application,
"next-page",
clone!(@weak application => move |_, _| {
let window = application.window();
if window.paginator().try_next().is_none() { if window.paginator().try_next().is_none() {
window.close(); window.close();
} }
}), })
); .build();
// Previous page
utils::action( let previous_page = gio::ActionEntry::builder("previous-page")
application, .activate(move |app: &Self::Type, _, _| {
"previous-page", let window = app.window();
clone!(@weak application => move |_, _| {
let window = application.window();
if window.paginator().try_previous().is_none() { if window.paginator().try_previous().is_none() {
window.reset_tour(); window.reset_tour();
} }
}), })
); .build();
application
.add_action_entries([quit, start_tour, skip_tour, next_page, previous_page])
.unwrap();
application.set_accels_for_action("app.quit", &["<Control>q"]); application.set_accels_for_action("app.quit", &["<Control>q"]);
application.set_accels_for_action("app.skip-tour", &["Escape"]); application.set_accels_for_action("app.skip-tour", &["Escape"]);
self.parent_startup(application);
} }
} }
impl GtkApplicationImpl for Application {} impl GtkApplicationImpl for Application {}
...@@ -107,7 +90,6 @@ impl Application { ...@@ -107,7 +90,6 @@ impl Application {
("application-id", &config::APP_ID), ("application-id", &config::APP_ID),
("resource-base-path", &Some("/org/gnome/Tour")), ("resource-base-path", &Some("/org/gnome/Tour")),
]) ])
.unwrap()
} }
fn window(&self) -> Window { fn window(&self) -> Window {
...@@ -115,9 +97,9 @@ impl Application { ...@@ -115,9 +97,9 @@ impl Application {
} }
pub fn run() { pub fn run() {
info!("GNOME Tour ({})", config::APP_ID); log::info!("GNOME Tour ({})", config::APP_ID);
info!("Version: {} ({})", config::VERSION, config::PROFILE); log::info!("Version: {} ({})", config::VERSION, config::PROFILE);
info!("Datadir: {}", config::PKGDATADIR); log::info!("Datadir: {}", config::PKGDATADIR);
let app = Self::new(); let app = Self::new();
gtk::prelude::ApplicationExtManual::run(&app); gtk::prelude::ApplicationExtManual::run(&app);
} }
......
// based on https://gitlab.gnome.org/World/podcasts/-/blob/master/podcasts-gtk/src/i18n|utils.rs // based on https://gitlab.gnome.org/World/podcasts/-/blob/master/podcasts-gtk/src/i18n|utils.rs
use gettextrs::gettext; use gettextrs::gettext;
use gtk::{gio, glib};
use regex::{Captures, Regex}; use regex::{Captures, Regex};
pub fn action<T, F>(thing: &T, name: &str, action: F)
where
T: gio::traits::ActionMapExt,
for<'r, 's> F: Fn(&'r gio::SimpleAction, Option<&glib::Variant>) + 'static,
{
// Create a stateless, parameterless action
let act = gio::SimpleAction::new(name, None);
// Connect the handler
act.connect_activate(action);
// Add it to the map
thing.add_action(&act);
}
pub fn i18n_f(format: &str, kwargs: &[(&str, &str)]) -> String { pub fn i18n_f(format: &str, kwargs: &[(&str, &str)]) -> String {
let mut s = gettext(format); let mut s = gettext(format);
for (k, v) in kwargs { for (k, v) in kwargs {
......
...@@ -5,7 +5,7 @@ use gtk::subclass::prelude::*; ...@@ -5,7 +5,7 @@ use gtk::subclass::prelude::*;
mod imp { mod imp {
use super::*; use super::*;
use glib::once_cell::sync::Lazy; use glib::once_cell::sync::Lazy;
use glib::{ParamFlags, ParamSpec, ParamSpecString, Value}; use glib::{ParamSpec, ParamSpecString, Value};
use gtk::glib::once_cell::sync::OnceCell; use gtk::glib::once_cell::sync::OnceCell;
use std::cell::RefCell; use std::cell::RefCell;
...@@ -25,7 +25,9 @@ mod imp { ...@@ -25,7 +25,9 @@ mod imp {
} }
impl ObjectImpl for ImagePageWidget { impl ObjectImpl for ImagePageWidget {
fn constructed(&self, obj: &Self::Type) { fn constructed(&self) {
self.parent_constructed();
let obj = self.instance();
let layout_manager = obj let layout_manager = obj
.layout_manager() .layout_manager()
.map(|l| l.downcast::<gtk::BoxLayout>().unwrap()) .map(|l| l.downcast::<gtk::BoxLayout>().unwrap())
...@@ -81,27 +83,22 @@ mod imp { ...@@ -81,27 +83,22 @@ mod imp {
container.append(&body_label); container.append(&body_label);
obj.append(&clamp); obj.append(&clamp);
self.parent_constructed(obj);
} }
fn properties() -> &'static [ParamSpec] { fn properties() -> &'static [ParamSpec] {
static PROPERTIES: Lazy<Vec<ParamSpec>> = Lazy::new(|| { static PROPERTIES: Lazy<Vec<ParamSpec>> = Lazy::new(|| {
vec![ vec![
ParamSpecString::builder("resource-uri") ParamSpecString::builder("resource-uri")
.flags(ParamFlags::READWRITE | ParamFlags::CONSTRUCT_ONLY) .construct_only()
.build(),
ParamSpecString::builder("head")
.flags(ParamFlags::READWRITE | ParamFlags::CONSTRUCT_ONLY)
.build(),
ParamSpecString::builder("body")
.flags(ParamFlags::READWRITE | ParamFlags::CONSTRUCT)
.build(), .build(),
ParamSpecString::builder("head").construct_only().build(),
ParamSpecString::builder("body").construct().build(),
] ]
}); });
PROPERTIES.as_ref() PROPERTIES.as_ref()
} }
fn set_property(&self, _obj: &Self::Type, _id: usize, value: &Value, pspec: &ParamSpec) { fn set_property(&self, _id: usize, value: &Value, pspec: &ParamSpec) {
match pspec.name() { match pspec.name() {
"resource-uri" => { "resource-uri" => {
let resource_uri: String = value.get().unwrap(); let resource_uri: String = value.get().unwrap();
...@@ -121,7 +118,7 @@ mod imp { ...@@ -121,7 +118,7 @@ mod imp {
} }
} }
fn property(&self, _obj: &Self::Type, _id: usize, pspec: &ParamSpec) -> Value { fn property(&self, _id: usize, pspec: &ParamSpec) -> Value {
match pspec.name() { match pspec.name() {
"resource-uri" => self.resource_uri.get().to_value(), "resource-uri" => self.resource_uri.get().to_value(),
"head" => self.head.get().to_value(), "head" => self.head.get().to_value(),
...@@ -146,7 +143,6 @@ impl ImagePageWidget { ...@@ -146,7 +143,6 @@ impl ImagePageWidget {
("head", &head), ("head", &head),
("body", &body), ("body", &body),
]) ])
.unwrap()
} }
pub fn set_body(&self, body: &str) { pub fn set_body(&self, body: &str) {
......
...@@ -42,7 +42,9 @@ mod imp { ...@@ -42,7 +42,9 @@ mod imp {
} }
impl ObjectImpl for PaginatorWidget { impl ObjectImpl for PaginatorWidget {
fn constructed(&self, obj: &Self::Type) { fn constructed(&self) {
self.parent_constructed();
let obj = self.instance();
let layout_manager = obj let layout_manager = obj
.layout_manager() .layout_manager()
.map(|l| l.downcast::<gtk::BoxLayout>().unwrap()) .map(|l| l.downcast::<gtk::BoxLayout>().unwrap())
...@@ -66,24 +68,17 @@ mod imp { ...@@ -66,24 +68,17 @@ mod imp {
})); }));
obj.add_controller(&controller); obj.add_controller(&controller);
self.parent_constructed(obj);
} }
} }
impl WidgetImpl for PaginatorWidget {} impl WidgetImpl for PaginatorWidget {}
impl BoxImpl for PaginatorWidget {} impl BoxImpl for PaginatorWidget {}
impl BuildableImpl for PaginatorWidget { impl BuildableImpl for PaginatorWidget {
fn add_child( fn add_child(&self, builder: &gtk::Builder, child: &glib::Object, type_: Option<&str>) {
&self,
buildable: &Self::Type,
builder: &gtk::Builder,
child: &glib::Object,
type_: Option<&str>,
) {
if !self.carousel.is_bound() { if !self.carousel.is_bound() {
self.parent_add_child(buildable, builder, child, type_); self.parent_add_child(builder, child, type_);
} else { } else {
buildable.add_page(child.clone().downcast::<gtk::Widget>().unwrap()); self.instance()
.add_page(child.clone().downcast::<gtk::Widget>().unwrap());
} }
} }
} }
...@@ -97,7 +92,7 @@ glib::wrapper! { ...@@ -97,7 +92,7 @@ glib::wrapper! {
impl PaginatorWidget { impl PaginatorWidget {
pub fn new() -> Self { pub fn new() -> Self {
glib::Object::new(&[]).unwrap() glib::Object::new(&[])
} }
pub fn try_next(&self) -> Option<()> { pub fn try_next(&self) -> Option<()> {
......
...@@ -37,7 +37,9 @@ mod imp { ...@@ -37,7 +37,9 @@ mod imp {
} }
impl ObjectImpl for Window { impl ObjectImpl for Window {
fn constructed(&self, widget: &Self::Type) { fn constructed(&self) {
self.parent_constructed();
let widget = self.instance();
widget.set_icon_name(Some(config::APP_ID)); widget.set_icon_name(Some(config::APP_ID));
// Devel Profile // Devel Profile
...@@ -53,7 +55,6 @@ mod imp { ...@@ -53,7 +55,6 @@ mod imp {
&[("name", &name), ("version", &version)], &[("name", &name), ("version", &version)],
); );
self.welcome_page.set_body(&body); self.welcome_page.set_body(&body);
self.parent_constructed(widget);
} }
} }
impl WidgetImpl for Window {} impl WidgetImpl for Window {}
...@@ -70,7 +71,7 @@ glib::wrapper! { ...@@ -70,7 +71,7 @@ glib::wrapper! {
impl Window { impl Window {
pub fn new(app: &Application) -> Self { pub fn new(app: &Application) -> Self {
glib::Object::new(&[("application", app)]).unwrap() glib::Object::new(&[("application", app)])
} }
pub fn paginator(&self) -> PaginatorWidget { pub fn paginator(&self) -> PaginatorWidget {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment