Merge branch 'switch-clone' into 'master'
Switch to glib::clone macro and fix some typos See merge request World/podcasts!138
This commit is contained in:
commit
3e5ddb2aff
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#![allow(clippy::new_without_default)]
|
#![allow(clippy::new_without_default)]
|
||||||
|
|
||||||
|
use glib::clone;
|
||||||
use glib::subclass::prelude::*;
|
use glib::subclass::prelude::*;
|
||||||
use glib::subclass::simple::{ClassStruct, InstanceStruct};
|
use glib::subclass::simple::{ClassStruct, InstanceStruct};
|
||||||
use glib::translate::*;
|
use glib::translate::*;
|
||||||
@ -94,7 +95,10 @@ impl gio::subclass::prelude::ApplicationImpl for PdApplicationPrivate {
|
|||||||
window.present();
|
window.present();
|
||||||
self.window.replace(Some(window));
|
self.window.replace(Some(window));
|
||||||
// Setup the Action channel
|
// Setup the Action channel
|
||||||
gtk::timeout_add(25, clone!(app => move || app.setup_action_channel()));
|
gtk::timeout_add(
|
||||||
|
25,
|
||||||
|
clone!(@strong app => move || app.setup_action_channel()),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn startup(&self, app: &gio::Application) {
|
fn startup(&self, app: &gio::Application) {
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
use gio;
|
use gio;
|
||||||
|
use glib::clone;
|
||||||
use gtk;
|
use gtk;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use libhandy;
|
use libhandy;
|
||||||
@ -83,7 +84,7 @@ impl AddPopover {
|
|||||||
url.to_owned()
|
url.to_owned()
|
||||||
};
|
};
|
||||||
|
|
||||||
rayon::spawn(clone!(sender => move || {
|
rayon::spawn(clone!(@strong sender => move || {
|
||||||
if let Ok(source) = Source::from_url(&url) {
|
if let Ok(source) = Source::from_url(&url) {
|
||||||
schedule_refresh(Some(vec![source]), sender.clone());
|
schedule_refresh(Some(vec![source]), sender.clone());
|
||||||
} else {
|
} else {
|
||||||
@ -227,41 +228,38 @@ impl Header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn init(s: &Rc<Self>, content: &Content, sender: &Sender<Action>) {
|
pub(crate) fn init(s: &Rc<Self>, content: &Content, sender: &Sender<Action>) {
|
||||||
let weak = Rc::downgrade(s);
|
|
||||||
|
|
||||||
s.bottom_switcher.set_stack(Some(&content.get_stack()));
|
s.bottom_switcher.set_stack(Some(&content.get_stack()));
|
||||||
s.switch.set_stack(Some(&content.get_stack()));
|
s.switch.set_stack(Some(&content.get_stack()));
|
||||||
|
|
||||||
s.add.entry.connect_changed(clone!(weak => move |_| {
|
s.add.entry.connect_changed(clone!(@weak s => move |_| {
|
||||||
weak.upgrade().map(|h| {
|
s.add.on_entry_changed()
|
||||||
h.add.on_entry_changed()
|
.map_err(|err| error!("Error: {}", err))
|
||||||
.map_err(|err| error!("Error: {}", err))
|
.ok();
|
||||||
.ok();
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
s.add.add.connect_clicked(clone!(weak, sender => move |_| {
|
|
||||||
weak.upgrade().map(|h| h.add.on_add_clicked(&sender));
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
s.add
|
s.add
|
||||||
.entry
|
.add
|
||||||
.connect_activate(clone!(weak, sender => move |_| {
|
.connect_clicked(clone!(@weak s, @strong sender => move |_| {
|
||||||
weak.upgrade().map(|h| {
|
s.add.on_add_clicked(&sender).unwrap();
|
||||||
if h.add.add.get_sensitive() {
|
|
||||||
h.add.on_add_clicked(&sender).unwrap();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
s.back.connect_clicked(clone!(weak, sender => move |_| {
|
s.add
|
||||||
weak.upgrade().map(|h| h.switch_to_normal());
|
.entry
|
||||||
sender.send(Action::ShowShowsAnimated).expect("Action channel blew up somehow");
|
.connect_activate(clone!(@weak s, @strong sender => move |_| {
|
||||||
}));
|
if s.add.add.get_sensitive() {
|
||||||
|
s.add.on_add_clicked(&sender).unwrap();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
s.back
|
||||||
|
.connect_clicked(clone!(@weak s, @strong sender => move |_| {
|
||||||
|
s.switch_to_normal();
|
||||||
|
sender.send(Action::ShowShowsAnimated).expect("Action channel blew up somehow");
|
||||||
|
}));
|
||||||
|
|
||||||
s.switch_squeezer
|
s.switch_squeezer
|
||||||
.connect_property_visible_child_notify(clone!(weak => move |_| {
|
.connect_property_visible_child_notify(clone!(@weak s => move |_| {
|
||||||
weak.upgrade().map(|h| h.update_bottom_switcher());
|
s.update_bottom_switcher();
|
||||||
}));
|
}));
|
||||||
s.update_bottom_switcher();
|
s.update_bottom_switcher();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,25 +60,6 @@ use log::Level;
|
|||||||
|
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
|
|
||||||
// https://gtk-rs.org/docs-src/tutorial/closures
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! clone {
|
|
||||||
(@param _) => ( _ );
|
|
||||||
(@param $x:ident) => ( $x );
|
|
||||||
($($n:ident),+ => move || $body:expr) => (
|
|
||||||
{
|
|
||||||
$( let $n = $n.clone(); )+
|
|
||||||
move || $body
|
|
||||||
}
|
|
||||||
);
|
|
||||||
($($n:ident),+ => move |$($p:tt),+| $body:expr) => (
|
|
||||||
{
|
|
||||||
$( let $n = $n.clone(); )+
|
|
||||||
move |$(clone!(@param $p),)+| $body
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
mod stacks;
|
mod stacks;
|
||||||
mod widgets;
|
mod widgets;
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
#![allow(clippy::type_complexity)]
|
#![allow(clippy::type_complexity)]
|
||||||
|
|
||||||
use gdk_pixbuf::Pixbuf;
|
use gdk_pixbuf::Pixbuf;
|
||||||
|
use glib::clone;
|
||||||
use glib::{self, object::WeakRef};
|
use glib::{self, object::WeakRef};
|
||||||
use glib::{IsA, Object};
|
use glib::{IsA, Object};
|
||||||
use gtk;
|
use gtk;
|
||||||
@ -183,7 +184,7 @@ pub(crate) fn ignore_show(id: i32) -> Result<bool, Error> {
|
|||||||
.map_err(|err| format_err!("{}", err))
|
.map_err(|err| format_err!("{}", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn uningore_show(id: i32) -> Result<bool, Error> {
|
pub(crate) fn unignore_show(id: i32) -> Result<bool, Error> {
|
||||||
IGNORESHOWS
|
IGNORESHOWS
|
||||||
.lock()
|
.lock()
|
||||||
.map(|mut guard| guard.remove(&id))
|
.map(|mut guard| guard.remove(&id))
|
||||||
@ -300,7 +301,7 @@ pub(crate) fn set_image_from_path(
|
|||||||
// If it fails another download will be scheduled.
|
// If it fails another download will be scheduled.
|
||||||
if let Ok(guard) = COVER_DL_REGISTRY.read() {
|
if let Ok(guard) = COVER_DL_REGISTRY.read() {
|
||||||
if guard.contains(&show_id) {
|
if guard.contains(&show_id) {
|
||||||
let callback = clone!(image => move || {
|
let callback = clone!(@weak image => @default-return glib::Continue(false), move || {
|
||||||
let _ = set_image_from_path(&image, show_id, size);
|
let _ = set_image_from_path(&image, show_id, size);
|
||||||
glib::Continue(false)
|
glib::Continue(false)
|
||||||
});
|
});
|
||||||
@ -417,7 +418,7 @@ pub(crate) fn on_import_clicked(window: >k::ApplicationWindow, sender: &Sender
|
|||||||
if let Some(filename) = dialog.get_filename() {
|
if let Some(filename) = dialog.get_filename() {
|
||||||
debug!("File selected: {:?}", filename);
|
debug!("File selected: {:?}", filename);
|
||||||
|
|
||||||
rayon::spawn(clone!(sender => move || {
|
rayon::spawn(clone!(@strong sender => move || {
|
||||||
// Parse the file and import the feeds
|
// Parse the file and import the feeds
|
||||||
if let Ok(sources) = opml::import_from_file(filename) {
|
if let Ok(sources) = opml::import_from_file(filename) {
|
||||||
// Refresh the successfully parsed feeds to index them
|
// Refresh the successfully parsed feeds to index them
|
||||||
@ -464,7 +465,7 @@ pub(crate) fn on_export_clicked(window: >k::ApplicationWindow, sender: &Sender
|
|||||||
if let Some(filename) = dialog.get_filename() {
|
if let Some(filename) = dialog.get_filename() {
|
||||||
debug!("File selected: {:?}", filename);
|
debug!("File selected: {:?}", filename);
|
||||||
|
|
||||||
rayon::spawn(clone!(sender => move || {
|
rayon::spawn(clone!(@strong sender => move || {
|
||||||
if opml::export_from_db(filename, i18n("GNOME Podcasts Subscriptions").as_str()).is_err() {
|
if opml::export_from_db(filename, i18n("GNOME Podcasts Subscriptions").as_str()).is_err() {
|
||||||
let text = i18n("Failed to export podcasts");
|
let text = i18n("Failed to export podcasts");
|
||||||
sender.send(Action::ErrorNotification(text)).expect("Action channel blew up somehow");
|
sender.send(Action::ErrorNotification(text)).expect("Action channel blew up somehow");
|
||||||
|
|||||||
@ -67,7 +67,7 @@ impl BaseView {
|
|||||||
self.scrolled_window.add(widget);
|
self.scrolled_window.add(widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_adjutments<'a, 'b>(
|
pub(crate) fn set_adjustments<'a, 'b>(
|
||||||
&self,
|
&self,
|
||||||
hadjustment: Option<&'a Adjustment>,
|
hadjustment: Option<&'a Adjustment>,
|
||||||
vadjustment: Option<&'b Adjustment>,
|
vadjustment: Option<&'b Adjustment>,
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
use glib;
|
use glib;
|
||||||
|
use glib::clone;
|
||||||
use gtk;
|
use gtk;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
|
|
||||||
@ -235,16 +236,18 @@ impl EpisodeWidget {
|
|||||||
let widget = Rc::new(Self::default());
|
let widget = Rc::new(Self::default());
|
||||||
let episode = RefCell::new(Some(episode));
|
let episode = RefCell::new(Some(episode));
|
||||||
let weak = Rc::downgrade(&widget);
|
let weak = Rc::downgrade(&widget);
|
||||||
widget.container.connect_draw(clone!(sender => move |_, _| {
|
widget
|
||||||
episode.borrow_mut().take().map(|ep| {
|
.container
|
||||||
weak.upgrade().map(|w| w.info.init(&ep));
|
.connect_draw(clone!(@strong sender => move |_, _| {
|
||||||
Self::determine_buttons_state(&weak, &ep, &sender)
|
episode.borrow_mut().take().map(|ep| {
|
||||||
.map_err(|err| error!("Error: {}", err))
|
weak.upgrade().map(|w| w.info.init(&ep));
|
||||||
.ok();
|
Self::determine_buttons_state(&weak, &ep, &sender)
|
||||||
});
|
.map_err(|err| error!("Error: {}", err))
|
||||||
|
.ok();
|
||||||
|
});
|
||||||
|
|
||||||
gtk::Inhibit(false)
|
gtk::Inhibit(false)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// When the widget is attached to a parent,
|
// When the widget is attached to a parent,
|
||||||
// since it's a rust struct and not a widget the
|
// since it's a rust struct and not a widget the
|
||||||
@ -372,7 +375,7 @@ impl EpisodeWidget {
|
|||||||
// State: InProgress
|
// State: InProgress
|
||||||
if let Some(prog) = active_dl()? {
|
if let Some(prog) = active_dl()? {
|
||||||
// set a callback that will update the state when the download finishes
|
// set a callback that will update the state when the download finishes
|
||||||
let callback = clone!(weak, sender => move || {
|
let callback = clone!(@strong weak, @strong sender => move || {
|
||||||
if let Ok(guard) = manager::ACTIVE_DOWNLOADS.read() {
|
if let Ok(guard) = manager::ACTIVE_DOWNLOADS.read() {
|
||||||
if !guard.contains_key(&id) {
|
if !guard.contains_key(&id) {
|
||||||
if let Ok(ep) = dbqueries::get_episode_widget_from_rowid(id) {
|
if let Ok(ep) = dbqueries::get_episode_widget_from_rowid(id) {
|
||||||
@ -393,14 +396,14 @@ impl EpisodeWidget {
|
|||||||
widget
|
widget
|
||||||
.buttons
|
.buttons
|
||||||
.cancel
|
.cancel
|
||||||
.connect_clicked(clone!(prog, weak, sender => move |_| {
|
.connect_clicked(clone!(@strong prog, @strong weak, @strong sender => move |_| {
|
||||||
// Cancel the download
|
// Cancel the download
|
||||||
if let Ok(mut m) = prog.lock() {
|
if let Ok(mut m) = prog.lock() {
|
||||||
m.cancel();
|
m.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cancel is not instant so we have to wait a bit
|
// Cancel is not instant so we have to wait a bit
|
||||||
timeout_add(50, clone!(weak, sender => move || {
|
timeout_add(50, clone!(@strong weak, @strong sender => move || {
|
||||||
if let Ok(thing) = active_dl() {
|
if let Ok(thing) = active_dl() {
|
||||||
if thing.is_none() {
|
if thing.is_none() {
|
||||||
// Recalculate the widget state
|
// Recalculate the widget state
|
||||||
@ -441,7 +444,7 @@ impl EpisodeWidget {
|
|||||||
widget
|
widget
|
||||||
.buttons
|
.buttons
|
||||||
.play
|
.play
|
||||||
.connect_clicked(clone!(weak, sender => move |_| {
|
.connect_clicked(clone!(@strong weak, @strong sender => move |_| {
|
||||||
if let Ok(mut ep) = dbqueries::get_episode_widget_from_rowid(id) {
|
if let Ok(mut ep) = dbqueries::get_episode_widget_from_rowid(id) {
|
||||||
on_play_bttn_clicked(&weak, &mut ep, &sender)
|
on_play_bttn_clicked(&weak, &mut ep, &sender)
|
||||||
.map_err(|err| error!("Error: {}", err))
|
.map_err(|err| error!("Error: {}", err))
|
||||||
@ -457,7 +460,7 @@ impl EpisodeWidget {
|
|||||||
widget
|
widget
|
||||||
.buttons
|
.buttons
|
||||||
.download
|
.download
|
||||||
.connect_clicked(clone!(weak, sender => move |dl| {
|
.connect_clicked(clone!(@strong weak, @strong sender => move |dl| {
|
||||||
// Make the button insensitive so it won't be pressed twice
|
// Make the button insensitive so it won't be pressed twice
|
||||||
dl.set_sensitive(false);
|
dl.set_sensitive(false);
|
||||||
if let Ok(ep) = dbqueries::get_episode_widget_from_rowid(id) {
|
if let Ok(ep) = dbqueries::get_episode_widget_from_rowid(id) {
|
||||||
@ -528,7 +531,7 @@ fn update_progressbar_callback(
|
|||||||
prog: &Arc<Mutex<manager::Progress>>,
|
prog: &Arc<Mutex<manager::Progress>>,
|
||||||
episode_rowid: i32,
|
episode_rowid: i32,
|
||||||
) {
|
) {
|
||||||
let callback = clone!(widget, prog => move || {
|
let callback = clone!(@strong widget,@strong prog => move || {
|
||||||
progress_bar_helper(&widget, &prog, episode_rowid)
|
progress_bar_helper(&widget, &prog, episode_rowid)
|
||||||
.unwrap_or(glib::Continue(false))
|
.unwrap_or(glib::Continue(false))
|
||||||
});
|
});
|
||||||
@ -602,7 +605,7 @@ fn progress_bar_helper(
|
|||||||
// relying to the RSS feed.
|
// relying to the RSS feed.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn update_total_size_callback(widget: &Weak<EpisodeWidget>, prog: &Arc<Mutex<manager::Progress>>) {
|
fn update_total_size_callback(widget: &Weak<EpisodeWidget>, prog: &Arc<Mutex<manager::Progress>>) {
|
||||||
let callback = clone!(prog, widget => move || {
|
let callback = clone!(@strong prog, @strong widget => move || {
|
||||||
total_size_helper(&widget, &prog).unwrap_or(glib::Continue(true))
|
total_size_helper(&widget, &prog).unwrap_or(glib::Continue(true))
|
||||||
});
|
});
|
||||||
timeout_add(100, callback);
|
timeout_add(100, callback);
|
||||||
|
|||||||
@ -143,7 +143,7 @@ impl HomeView {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(ref v) = vadj {
|
if let Some(ref v) = vadj {
|
||||||
home.view.set_adjutments(None, Some(v))
|
home.view.set_adjustments(None, Some(v))
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -26,6 +26,7 @@ use libhandy as hdy;
|
|||||||
use libhandy::prelude::*;
|
use libhandy::prelude::*;
|
||||||
|
|
||||||
use gio::{File, FileExt};
|
use gio::{File, FileExt};
|
||||||
|
use glib::clone;
|
||||||
use glib::{SignalHandlerId, WeakRef};
|
use glib::{SignalHandlerId, WeakRef};
|
||||||
|
|
||||||
use chrono::{prelude::*, NaiveTime};
|
use chrono::{prelude::*, NaiveTime};
|
||||||
@ -241,17 +242,18 @@ impl PlayerRate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn connect_signals(&self, widget: &Rc<PlayerWidget>) {
|
fn connect_signals(&self, widget: &Rc<PlayerWidget>) {
|
||||||
let weak = Rc::downgrade(widget);
|
self.radio_normal
|
||||||
|
.connect_toggled(clone!(@weak widget => move |_| {
|
||||||
self.radio_normal.connect_toggled(clone!(weak => move |_| {
|
widget.on_rate_changed(1.00);
|
||||||
weak.upgrade().map(|w| w.on_rate_changed(1.00));
|
}));
|
||||||
}));
|
self.radio125
|
||||||
self.radio125.connect_toggled(clone!(weak => move |_| {
|
.connect_toggled(clone!(@weak widget => move |_| {
|
||||||
weak.upgrade().map(|w| w.on_rate_changed(1.25));
|
widget.on_rate_changed(1.25);
|
||||||
}));
|
}));
|
||||||
self.radio150.connect_toggled(clone!(weak => move |_| {
|
self.radio150
|
||||||
weak.upgrade().map(|w| w.on_rate_changed(1.50));
|
.connect_toggled(clone!(@weak widget => move |_| {
|
||||||
}));
|
widget.on_rate_changed(1.50);
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -680,21 +682,18 @@ impl PlayerWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn connect_dialog(&self) {
|
fn connect_dialog(&self) {
|
||||||
let weak = Rc::downgrade(self);
|
let this = self.deref();
|
||||||
|
|
||||||
self.squeezer
|
self.squeezer
|
||||||
.connect_property_visible_child_notify(clone!(weak => move |_| {
|
.connect_property_visible_child_notify(clone!(@weak this => move |_| {
|
||||||
weak.upgrade().map(|w| {
|
if let Some(child) = this.squeezer.get_visible_child() {
|
||||||
if let Some(child) = w.squeezer.get_visible_child() {
|
let full = child == this.full;
|
||||||
let full = child == w.full;
|
this.timer.progress_bar.set_visible(!full);
|
||||||
w.timer.progress_bar.set_visible(!full);
|
|
||||||
if full {
|
if full {
|
||||||
w.action_bar.get_style_context().remove_class("player-small");
|
this.action_bar.get_style_context().remove_class("player-small");
|
||||||
} else {
|
} else {
|
||||||
w.action_bar.get_style_context().add_class("player-small");
|
this.action_bar.get_style_context().add_class("player-small");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
self.timer
|
self.timer
|
||||||
@ -711,103 +710,110 @@ impl PlayerWrapper {
|
|||||||
.slider
|
.slider
|
||||||
.set_adjustment(&self.timer.slider.get_adjustment());
|
.set_adjustment(&self.timer.slider.get_adjustment());
|
||||||
|
|
||||||
self.evbox
|
self.evbox.connect_button_press_event(
|
||||||
.connect_button_press_event(clone!(weak => move |_, event| {
|
clone!(@weak this => @default-return Inhibit(false), move |_, event| {
|
||||||
if event.get_button() != 1 {
|
if event.get_button() != 1 {
|
||||||
return Inhibit(false);
|
return Inhibit(false);
|
||||||
}
|
}
|
||||||
|
// only open the dialog when the small toolbar is visible
|
||||||
if let Some(w) = weak.upgrade() {
|
if let Some(child) = this.squeezer.get_visible_child() {
|
||||||
// only open the dialog when the small toolbar is visible
|
if child == this.full {
|
||||||
if let Some(child) = w.squeezer.get_visible_child() {
|
return Inhibit(false);
|
||||||
if child == w.full {
|
|
||||||
return Inhibit(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let parent = w.container.get_toplevel().and_then(|toplevel| {
|
|
||||||
toplevel
|
|
||||||
.downcast::<gtk::Window>()
|
|
||||||
.ok()
|
|
||||||
}).unwrap();
|
|
||||||
|
|
||||||
info!("showing dialog");
|
|
||||||
w.dialog.dialog.set_transient_for(Some(&parent));
|
|
||||||
w.dialog.dialog.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Inhibit(false)
|
let parent = this.container.get_toplevel().and_then(|toplevel| {
|
||||||
}));
|
toplevel
|
||||||
|
.downcast::<gtk::Window>()
|
||||||
|
.ok()
|
||||||
|
}).unwrap();
|
||||||
|
|
||||||
self.dialog.close.connect_clicked(clone!(weak => move |_| {
|
info!("showing dialog");
|
||||||
weak.upgrade().map(|w| w.dialog.dialog.hide());
|
this.dialog.dialog.set_transient_for(Some(&parent));
|
||||||
}));
|
this.dialog.dialog.show();
|
||||||
|
|
||||||
|
Inhibit(false)
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.dialog
|
||||||
|
.close
|
||||||
|
.connect_clicked(clone!(@weak this => move |_| {
|
||||||
|
this.dialog.dialog.hide();
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Connect the `PlayerControls` buttons to the `PlayerExt` methods.
|
/// Connect the `PlayerControls` buttons to the `PlayerExt` methods.
|
||||||
fn connect_control_buttons(&self) {
|
fn connect_control_buttons(&self) {
|
||||||
let weak = Rc::downgrade(self);
|
let this = self.deref();
|
||||||
|
|
||||||
// Connect the play button to the gst Player.
|
// Connect the play button to the gst Player.
|
||||||
self.controls.play.connect_clicked(clone!(weak => move |_| {
|
self.controls
|
||||||
weak.upgrade().map(|p| p.play());
|
.play
|
||||||
}));
|
.connect_clicked(clone!(@weak this => move |_| {
|
||||||
|
this.play();
|
||||||
|
}));
|
||||||
|
|
||||||
// Connect the pause button to the gst Player.
|
// Connect the pause button to the gst Player.
|
||||||
self.controls
|
self.controls
|
||||||
.pause
|
.pause
|
||||||
.connect_clicked(clone!(weak => move |_| {
|
.connect_clicked(clone!(@weak this => move |_| {
|
||||||
weak.upgrade().map(|p| p.pause());
|
this.pause();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Connect the play button to the gst Player.
|
// Connect the play button to the gst Player.
|
||||||
self.controls
|
self.controls
|
||||||
.play_small
|
.play_small
|
||||||
.connect_clicked(clone!(weak => move |_| {
|
.connect_clicked(clone!(@weak this => move |_| {
|
||||||
weak.upgrade().map(|p| p.play());
|
this.play();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Connect the pause button to the gst Player.
|
// Connect the pause button to the gst Player.
|
||||||
self.controls
|
self.controls
|
||||||
.pause_small
|
.pause_small
|
||||||
.connect_clicked(clone!(weak => move |_| {
|
.connect_clicked(clone!(@weak this => move |_| {
|
||||||
weak.upgrade().map(|p| p.pause());
|
this.pause();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Connect the rewind button to the gst Player.
|
// Connect the rewind button to the gst Player.
|
||||||
self.controls
|
self.controls
|
||||||
.rewind
|
.rewind
|
||||||
.connect_clicked(clone!(weak => move |_| {
|
.connect_clicked(clone!(@weak this => move |_| {
|
||||||
weak.upgrade().map(|p| p.rewind());
|
this.rewind();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Connect the fast-forward button to the gst Player.
|
// Connect the fast-forward button to the gst Player.
|
||||||
self.controls
|
self.controls
|
||||||
.forward
|
.forward
|
||||||
.connect_clicked(clone!(weak => move |_| {
|
.connect_clicked(clone!(@weak this => move |_| {
|
||||||
weak.upgrade().map(|p| p.fast_forward());
|
this.fast_forward();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Connect the play button to the gst Player.
|
// Connect the play button to the gst Player.
|
||||||
self.dialog.play.connect_clicked(clone!(weak => move |_| {
|
self.dialog
|
||||||
weak.upgrade().map(|p| p.play());
|
.play
|
||||||
}));
|
.connect_clicked(clone!(@weak this => move |_| {
|
||||||
|
this.play();
|
||||||
|
}));
|
||||||
|
|
||||||
// Connect the pause button to the gst Player.
|
// Connect the pause button to the gst Player.
|
||||||
self.dialog.pause.connect_clicked(clone!(weak => move |_| {
|
self.dialog
|
||||||
weak.upgrade().map(|p| p.pause());
|
.pause
|
||||||
}));
|
.connect_clicked(clone!(@weak this => move |_| {
|
||||||
|
this.pause();
|
||||||
|
}));
|
||||||
|
|
||||||
// Connect the rewind button to the gst Player.
|
// Connect the rewind button to the gst Player.
|
||||||
self.dialog.rewind.connect_clicked(clone!(weak => move |_| {
|
self.dialog
|
||||||
weak.upgrade().map(|p| p.rewind());
|
.rewind
|
||||||
}));
|
.connect_clicked(clone!(@weak this => move |_| {
|
||||||
|
this.rewind();
|
||||||
|
}));
|
||||||
|
|
||||||
// Connect the fast-forward button to the gst Player.
|
// Connect the fast-forward button to the gst Player.
|
||||||
self.dialog
|
self.dialog
|
||||||
.forward
|
.forward
|
||||||
.connect_clicked(clone!(weak => move |_| {
|
.connect_clicked(clone!(@weak this => move |_| {
|
||||||
weak.upgrade().map(|p| p.fast_forward());
|
this.fast_forward();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -817,7 +823,7 @@ impl PlayerWrapper {
|
|||||||
self.player.connect_warning(move |_, warn| warn!("gst warning: {}", warn));
|
self.player.connect_warning(move |_, warn| warn!("gst warning: {}", warn));
|
||||||
|
|
||||||
// Log gst errors.
|
// Log gst errors.
|
||||||
self.player.connect_error(clone!(sender => move |_, _error| {
|
self.player.connect_error(clone!(@strong sender => move |_, _error| {
|
||||||
// sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
|
// sender.send(Action::ErrorNotification(format!("Player Error: {}", error)));
|
||||||
let s = i18n("The media player was unable to execute an action.");
|
let s = i18n("The media player was unable to execute an action.");
|
||||||
sender.send(Action::ErrorNotification(s)).expect("Action channel blew up somehow");
|
sender.send(Action::ErrorNotification(s)).expect("Action channel blew up somehow");
|
||||||
@ -827,21 +833,21 @@ impl PlayerWrapper {
|
|||||||
let weak = Fragile::new(Rc::downgrade(self));
|
let weak = Fragile::new(Rc::downgrade(self));
|
||||||
|
|
||||||
// Update the duration label and the slider
|
// Update the duration label and the slider
|
||||||
self.player.connect_duration_changed(clone!(weak => move |_, clock| {
|
self.player.connect_duration_changed(clone!(@strong weak => move |_, clock| {
|
||||||
weak.get()
|
weak.get()
|
||||||
.upgrade()
|
.upgrade()
|
||||||
.map(|p| p.timer.on_duration_changed(Duration(clock)));
|
.map(|p| p.timer.on_duration_changed(Duration(clock)));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Update the position label and the slider
|
// Update the position label and the slider
|
||||||
self.player.connect_position_updated(clone!(weak => move |_, clock| {
|
self.player.connect_position_updated(clone!(@strong weak => move |_, clock| {
|
||||||
weak.get()
|
weak.get()
|
||||||
.upgrade()
|
.upgrade()
|
||||||
.map(|p| p.timer.on_position_updated(Position(clock)));
|
.map(|p| p.timer.on_position_updated(Position(clock)));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Reset the slider to 0 and show a play button
|
// Reset the slider to 0 and show a play button
|
||||||
self.player.connect_end_of_stream(clone!(weak => move |_| {
|
self.player.connect_end_of_stream(clone!(@strong weak => move |_| {
|
||||||
weak.get()
|
weak.get()
|
||||||
.upgrade()
|
.upgrade()
|
||||||
.map(|p| p.stop());
|
.map(|p| p.stop());
|
||||||
@ -859,49 +865,60 @@ impl PlayerWrapper {
|
|||||||
|
|
||||||
// FIXME: Reference cycle with mpris
|
// FIXME: Reference cycle with mpris
|
||||||
let mpris = self.info.mpris.clone();
|
let mpris = self.info.mpris.clone();
|
||||||
self.info.mpris.connect_play_pause(clone!(weak => move || {
|
self.info
|
||||||
let player = match weak.upgrade() {
|
.mpris
|
||||||
Some(s) => s,
|
.connect_play_pause(clone!(@strong weak => move || {
|
||||||
None => return
|
let player = match weak.upgrade() {
|
||||||
};
|
Some(s) => s,
|
||||||
|
None => return
|
||||||
if let Ok(status) = mpris.get_playback_status() {
|
|
||||||
match status.as_ref() {
|
|
||||||
"Paused" => player.play(),
|
|
||||||
"Stopped" => player.play(),
|
|
||||||
_ => player.pause(),
|
|
||||||
};
|
};
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
self.info.mpris.connect_play(clone!(weak => move || {
|
if let Ok(status) = mpris.get_playback_status() {
|
||||||
let player = match weak.upgrade() {
|
match status.as_ref() {
|
||||||
Some(s) => s,
|
"Paused" => player.play(),
|
||||||
None => return
|
"Stopped" => player.play(),
|
||||||
};
|
_ => player.pause(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
self.info
|
||||||
|
.mpris
|
||||||
|
.connect_play(clone!(@strong weak => move || {
|
||||||
|
let player = match weak.upgrade() {
|
||||||
|
Some(s) => s,
|
||||||
|
None => return
|
||||||
|
};
|
||||||
|
|
||||||
player.play();
|
player.play();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
self.info.mpris.connect_pause(clone!(weak => move || {
|
self.info
|
||||||
let player = match weak.upgrade() {
|
.mpris
|
||||||
Some(s) => s,
|
.connect_pause(clone!(@strong weak => move || {
|
||||||
None => return
|
let player = match weak.upgrade() {
|
||||||
};
|
Some(s) => s,
|
||||||
|
None => return
|
||||||
|
};
|
||||||
|
|
||||||
player.pause();
|
player.pause();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
self.info.mpris.connect_next(clone!(weak => move || {
|
self.info
|
||||||
weak.upgrade().map(|p| p.fast_forward());
|
.mpris
|
||||||
}));
|
.connect_next(clone!(@strong weak => move || {
|
||||||
|
weak.upgrade().map(|p| p.fast_forward());
|
||||||
|
}));
|
||||||
|
|
||||||
self.info.mpris.connect_previous(clone!(weak => move || {
|
self.info
|
||||||
weak.upgrade().map(|p| p.rewind());
|
.mpris
|
||||||
}));
|
.connect_previous(clone!(@strong weak => move || {
|
||||||
|
weak.upgrade().map(|p| p.rewind());
|
||||||
|
}));
|
||||||
|
|
||||||
self.info.mpris.connect_raise(clone!(sender => move || {
|
self.info
|
||||||
sender.send(Action::RaiseWindow).expect("Action channel blew up somehow");
|
.mpris
|
||||||
}));
|
.connect_raise(clone!(@strong sender => move || {
|
||||||
|
sender.send(Action::RaiseWindow).expect("Action channel blew up somehow");
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
use glib;
|
use glib;
|
||||||
|
use glib::clone;
|
||||||
use gtk::{self, prelude::*, Adjustment};
|
use gtk::{self, prelude::*, Adjustment};
|
||||||
|
|
||||||
use crossbeam_channel::{bounded, Sender};
|
use crossbeam_channel::{bounded, Sender};
|
||||||
@ -108,16 +109,14 @@ impl ShowWidget {
|
|||||||
let res = populate_listbox(&pdw, pd.clone(), sender, vadj);
|
let res = populate_listbox(&pdw, pd.clone(), sender, vadj);
|
||||||
debug_assert!(res.is_ok());
|
debug_assert!(res.is_ok());
|
||||||
|
|
||||||
let weak = Rc::downgrade(&pdw);
|
|
||||||
pdw.description_short
|
pdw.description_short
|
||||||
.connect_size_allocate(clone!(weak => move |_, _2| {
|
.connect_size_allocate(clone!(@weak pdw => move |_, _2| {
|
||||||
weak.upgrade().map(|w| w.update_read_more());
|
pdw.update_read_more();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
pdw.description_button
|
pdw.description_button
|
||||||
.connect_clicked(clone!(weak => move |_| {
|
.connect_clicked(clone!(@weak pdw => move |_| {
|
||||||
weak.upgrade()
|
pdw.description_stack.set_visible_child_name("full");
|
||||||
.map(|w| w.description_stack.set_visible_child_name("full"));
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
pdw
|
pdw
|
||||||
@ -180,7 +179,7 @@ fn populate_listbox(
|
|||||||
let count = dbqueries::get_pd_episodes_count(&pd)?;
|
let count = dbqueries::get_pd_episodes_count(&pd)?;
|
||||||
|
|
||||||
let (sender_, receiver) = bounded(1);
|
let (sender_, receiver) = bounded(1);
|
||||||
rayon::spawn(clone!(pd => move || {
|
rayon::spawn(clone!(@strong pd => move || {
|
||||||
if let Ok(episodes) = dbqueries::get_pd_episodeswidgets(&pd) {
|
if let Ok(episodes) = dbqueries::get_pd_episodeswidgets(&pd) {
|
||||||
// The receiver can be dropped if there's an early return
|
// The receiver can be dropped if there's an early return
|
||||||
// like on show without episodes for example.
|
// like on show without episodes for example.
|
||||||
@ -205,13 +204,13 @@ fn populate_listbox(
|
|||||||
|
|
||||||
debug_assert!(episodes.len() as i64 == count);
|
debug_assert!(episodes.len() as i64 == count);
|
||||||
|
|
||||||
let constructor = clone!(sender => move |ep| {
|
let constructor = clone!(@strong sender => move |ep| {
|
||||||
EpisodeWidget::new(ep, &sender).container.clone()
|
EpisodeWidget::new(ep, &sender).container.clone()
|
||||||
});
|
});
|
||||||
|
|
||||||
let callback = clone!(show_weak, vadj => move || {
|
let callback = clone!(@strong show_weak, @strong vadj => move || {
|
||||||
match (show_weak.upgrade(), &vadj) {
|
match (show_weak.upgrade(), &vadj) {
|
||||||
(Some(ref shows), Some(ref v)) => shows.view.set_adjutments(None, Some(v)),
|
(Some(ref shows), Some(ref v)) => shows.view.set_adjustments(None, Some(v)),
|
||||||
_ => (),
|
_ => (),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
use glib;
|
use glib;
|
||||||
|
use glib::clone;
|
||||||
use gtk;
|
use gtk;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
|
|
||||||
@ -78,7 +79,7 @@ impl ShowMenu {
|
|||||||
|
|
||||||
fn connect_website(&self, pd: &Arc<Show>) {
|
fn connect_website(&self, pd: &Arc<Show>) {
|
||||||
self.website.set_tooltip_text(Some(pd.link()));
|
self.website.set_tooltip_text(Some(pd.link()));
|
||||||
self.website.connect_clicked(clone!(pd => move |_| {
|
self.website.connect_clicked(clone!(@strong pd => move |_| {
|
||||||
let link = pd.link();
|
let link = pd.link();
|
||||||
info!("Opening link: {}", link);
|
info!("Opening link: {}", link);
|
||||||
let res = open::that(link);
|
let res = open::that(link);
|
||||||
@ -87,13 +88,7 @@ impl ShowMenu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn connect_played(&self, pd: &Arc<Show>, episodes: >k::ListBox, sender: &Sender<Action>) {
|
fn connect_played(&self, pd: &Arc<Show>, episodes: >k::ListBox, sender: &Sender<Action>) {
|
||||||
let episodes_weak = episodes.downgrade();
|
self.played.connect_clicked(clone!(@strong pd, @strong sender, @weak episodes => move |_| {
|
||||||
self.played.connect_clicked(clone!(pd, sender => move |_| {
|
|
||||||
let episodes = match episodes_weak.upgrade() {
|
|
||||||
Some(e) => e,
|
|
||||||
None => return,
|
|
||||||
};
|
|
||||||
|
|
||||||
let res = dim_titles(&episodes);
|
let res = dim_titles(&episodes);
|
||||||
debug_assert!(res.is_some());
|
debug_assert!(res.is_some());
|
||||||
|
|
||||||
@ -103,7 +98,7 @@ impl ShowMenu {
|
|||||||
|
|
||||||
fn connect_unsub(&self, pd: &Arc<Show>, sender: &Sender<Action>) {
|
fn connect_unsub(&self, pd: &Arc<Show>, sender: &Sender<Action>) {
|
||||||
self.unsub
|
self.unsub
|
||||||
.connect_clicked(clone!(pd, sender => move |unsub| {
|
.connect_clicked(clone!(@strong pd, @strong sender => move |unsub| {
|
||||||
// hack to get away without properly checking for none.
|
// hack to get away without properly checking for none.
|
||||||
// if pressed twice would panic.
|
// if pressed twice would panic.
|
||||||
unsub.set_sensitive(false);
|
unsub.set_sensitive(false);
|
||||||
@ -173,7 +168,7 @@ pub(crate) fn mark_all_notif(pd: Arc<Show>, sender: &Sender<Action>) -> InAppNot
|
|||||||
glib::Continue(false)
|
glib::Continue(false)
|
||||||
};
|
};
|
||||||
|
|
||||||
let undo_callback = clone!(sender => move || {
|
let undo_callback = clone!(@strong sender => move || {
|
||||||
sender.send(Action::RefreshWidgetIfSame(id)).expect("Action channel blew up somehow")
|
sender.send(Action::RefreshWidgetIfSame(id)).expect("Action channel blew up somehow")
|
||||||
});
|
});
|
||||||
let text = i18n("Marked all episodes as listened");
|
let text = i18n("Marked all episodes as listened");
|
||||||
@ -189,11 +184,11 @@ pub(crate) fn remove_show_notif(pd: Arc<Show>, sender: Sender<Action>) -> InAppN
|
|||||||
let sender_ = sender.clone();
|
let sender_ = sender.clone();
|
||||||
let pd_ = pd.clone();
|
let pd_ = pd.clone();
|
||||||
let callback = move |revealer: gtk::Revealer| {
|
let callback = move |revealer: gtk::Revealer| {
|
||||||
let res = utils::uningore_show(pd_.id());
|
let res = utils::unignore_show(pd_.id());
|
||||||
debug_assert!(res.is_ok());
|
debug_assert!(res.is_ok());
|
||||||
|
|
||||||
// Spawn a thread so it won't block the ui.
|
// Spawn a thread so it won't block the ui.
|
||||||
rayon::spawn(clone!(pd_, sender_ => move || {
|
rayon::spawn(clone!(@strong pd_, @strong sender_ => move || {
|
||||||
delete_show(&pd_)
|
delete_show(&pd_)
|
||||||
.map_err(|err| error!("Error: {}", err))
|
.map_err(|err| error!("Error: {}", err))
|
||||||
.map_err(|_| error!("Failed to delete {}", pd_.title()))
|
.map_err(|_| error!("Failed to delete {}", pd_.title()))
|
||||||
@ -207,7 +202,7 @@ pub(crate) fn remove_show_notif(pd: Arc<Show>, sender: Sender<Action>) -> InAppN
|
|||||||
};
|
};
|
||||||
|
|
||||||
let undo_callback = move || {
|
let undo_callback = move || {
|
||||||
let res = utils::uningore_show(pd.id());
|
let res = utils::unignore_show(pd.id());
|
||||||
debug_assert!(res.is_ok());
|
debug_assert!(res.is_ok());
|
||||||
sender
|
sender
|
||||||
.send(Action::RefreshShowsView)
|
.send(Action::RefreshShowsView)
|
||||||
|
|||||||
@ -89,7 +89,7 @@ fn populate_flowbox(shows: &Rc<ShowsView>, vadj: Option<Adjustment>) -> Result<(
|
|||||||
let constructor = move |parent| ShowsChild::new(&parent).child;
|
let constructor = move |parent| ShowsChild::new(&parent).child;
|
||||||
let callback = move || {
|
let callback = move || {
|
||||||
match (show_weak.upgrade(), &vadj) {
|
match (show_weak.upgrade(), &vadj) {
|
||||||
(Some(ref shows), Some(ref v)) => shows.view.set_adjutments(None, Some(v)),
|
(Some(ref shows), Some(ref v)) => shows.view.set_adjustments(None, Some(v)),
|
||||||
_ => (),
|
_ => (),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
use glib;
|
use glib;
|
||||||
|
use glib::clone;
|
||||||
use glib::Variant;
|
use glib::Variant;
|
||||||
|
|
||||||
use gio::{self, prelude::*, ActionMapExt, SettingsExt};
|
use gio::{self, prelude::*, ActionMapExt, SettingsExt};
|
||||||
@ -172,13 +173,11 @@ impl MainWindow {
|
|||||||
#[cfg_attr(rustfmt, rustfmt_skip)]
|
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||||
pub fn setup_gactions(&self) {
|
pub fn setup_gactions(&self) {
|
||||||
let sender = &self.sender;
|
let sender = &self.sender;
|
||||||
let weak_win = self.window.downgrade();
|
|
||||||
|
|
||||||
// Create the `refresh` action.
|
// Create the `refresh` action.
|
||||||
//
|
//
|
||||||
// This will trigger a refresh of all the shows in the database.
|
// This will trigger a refresh of all the shows in the database.
|
||||||
action(&self.window, "refresh", clone!(sender => move |_, _| {
|
action(&self.window, "refresh", clone!(@strong sender => move |_, _| {
|
||||||
gtk::idle_add(clone!(sender => move || {
|
gtk::idle_add(clone!(@strong sender => move || {
|
||||||
let s: Option<Vec<_>> = None;
|
let s: Option<Vec<_>> = None;
|
||||||
utils::schedule_refresh(s, sender.clone());
|
utils::schedule_refresh(s, sender.clone());
|
||||||
glib::Continue(false)
|
glib::Continue(false)
|
||||||
@ -187,17 +186,17 @@ impl MainWindow {
|
|||||||
self.app.set_accels_for_action("win.refresh", &["<primary>r"]);
|
self.app.set_accels_for_action("win.refresh", &["<primary>r"]);
|
||||||
|
|
||||||
// Create the `OPML` import action
|
// Create the `OPML` import action
|
||||||
action(&self.window, "import", clone!(sender, weak_win => move |_, _| {
|
action(&self.window, "import", clone!(@strong sender, @weak self.window as win => move |_, _| {
|
||||||
weak_win.upgrade().map(|win| utils::on_import_clicked(&win, &sender));
|
utils::on_import_clicked(&win, &sender);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
action(&self.window, "export", clone!(sender, weak_win => move |_, _| {
|
action(&self.window, "export", clone!(@strong sender, @weak self.window as win => move |_, _| {
|
||||||
weak_win.upgrade().map(|win| utils::on_export_clicked(&win, &sender));
|
utils::on_export_clicked(&win, &sender);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Create the action that shows a `gtk::AboutDialog`
|
// Create the action that shows a `gtk::AboutDialog`
|
||||||
action(&self.window, "about", clone!(weak_win => move |_, _| {
|
action(&self.window, "about", clone!(@weak self.window as win => move |_, _| {
|
||||||
weak_win.upgrade().map(|win| about_dialog(&win));
|
about_dialog(&win);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Create the quit action
|
// Create the quit action
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user