window: Use GSignalGroup to watch zoom levels
This allows us to git rid of more expression code.
This commit is contained in:
parent
aab50af31a
commit
3d445f25fe
2 changed files with 58 additions and 42 deletions
|
|
@ -433,6 +433,13 @@ impl LpImageView {
|
|||
self.imp().sliding_view.current_page().map(|x| x.image())
|
||||
}
|
||||
|
||||
pub fn current_image_signals(&self) -> &glib::SignalGroup {
|
||||
self.imp()
|
||||
.current_image_signals
|
||||
.get()
|
||||
.expect("Signal group should be set up during construction")
|
||||
}
|
||||
|
||||
pub fn current_page(&self) -> Option<LpImagePage> {
|
||||
self.imp().sliding_view.current_page()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ use std::path::{Path, PathBuf};
|
|||
|
||||
use crate::config;
|
||||
use crate::util::{self, Direction, Position};
|
||||
use crate::widgets::{LpImage, LpImagePage, LpImageView, LpPropertiesView};
|
||||
use crate::widgets::{LpImage, LpImageView, LpPropertiesView};
|
||||
|
||||
mod imp {
|
||||
use super::*;
|
||||
|
|
@ -227,50 +227,39 @@ mod imp {
|
|||
gtk::WindowGroup::new().add_window(&*obj);
|
||||
|
||||
obj.set_actions_enabled(false);
|
||||
self.image_view
|
||||
.property_expression("current-page")
|
||||
.chain_property::<LpImagePage>("image")
|
||||
.chain_property::<LpImage>("best-fit")
|
||||
.watch(
|
||||
glib::Object::NONE,
|
||||
// clone! is a macro from glib-rs that allows
|
||||
// you to easily handle references in callbacks
|
||||
// without refcycles or leaks.
|
||||
//
|
||||
// When you don't want the callback to keep the
|
||||
// Object alive, pass as @weak. Otherwise, pass
|
||||
// as @strong. Most of the time you will want
|
||||
// to use @weak.
|
||||
glib::clone!(@weak obj => move || {
|
||||
let enabled = obj
|
||||
.imp()
|
||||
.image_view
|
||||
.current_page()
|
||||
.map(|page| !page.image().is_best_fit())
|
||||
.unwrap_or_default();
|
||||
|
||||
obj.action_set_enabled("win.zoom-out", enabled);
|
||||
}),
|
||||
);
|
||||
let signal_group = self.image_view.current_image_signals();
|
||||
// clone! is a macro from glib-rs that allows
|
||||
// you to easily handle references in callbacks
|
||||
// without refcycles or leaks.
|
||||
//
|
||||
// When you don't want the callback to keep the
|
||||
// Object alive, pass as @weak. Otherwise, pass
|
||||
// as @strong. Most of the time you will want
|
||||
// to use @weak.
|
||||
signal_group.connect_bind_local(glib::clone!(@weak obj => move |_, _| {
|
||||
obj.on_zoom_status_changed()
|
||||
}));
|
||||
|
||||
// disable zoom-in if at maximum zoom level
|
||||
self.image_view
|
||||
.property_expression("current-page")
|
||||
.chain_property::<LpImagePage>("image")
|
||||
.chain_property::<LpImage>("is-max-zoom")
|
||||
.watch(
|
||||
glib::Object::NONE,
|
||||
glib::clone!(@weak obj => move || {
|
||||
let enabled = obj
|
||||
.imp()
|
||||
.image_view
|
||||
.current_page()
|
||||
.map(|page| !page.image().is_max_zoom())
|
||||
.unwrap_or_default();
|
||||
let win = &*obj;
|
||||
signal_group.connect_closure(
|
||||
"notify::best-fit",
|
||||
false,
|
||||
// `closure_local!` is similar to `clone`, but you use `@watch` instead of clone.
|
||||
// `@watch` means that this signal will be disconnected when the watched object
|
||||
// is dropped.
|
||||
glib::closure_local!(@watch win => move |_: &LpImage, _: &glib::ParamSpec| {
|
||||
win.on_zoom_status_changed();
|
||||
}),
|
||||
);
|
||||
|
||||
obj.action_set_enabled("win.zoom-in", enabled);
|
||||
}),
|
||||
);
|
||||
signal_group.connect_closure(
|
||||
"notify::is-max-zoom",
|
||||
false,
|
||||
glib::closure_local!(@watch win => move |_: &LpImage, _: &glib::ParamSpec| {
|
||||
win.on_zoom_status_changed();
|
||||
}),
|
||||
);
|
||||
|
||||
self.image_view.connect_notify_local(
|
||||
Some("current-page"),
|
||||
|
|
@ -360,6 +349,10 @@ mod imp {
|
|||
}),
|
||||
);
|
||||
}
|
||||
|
||||
fn dispose(&self) {
|
||||
self.obj().disconnect_present_watches();
|
||||
}
|
||||
}
|
||||
|
||||
impl WidgetImpl for LpWindow {}
|
||||
|
|
@ -657,6 +650,22 @@ impl LpWindow {
|
|||
}
|
||||
}
|
||||
|
||||
fn on_zoom_status_changed(&self) {
|
||||
let can_zoom_out = self
|
||||
.image_view()
|
||||
.current_image()
|
||||
.map(|image| !image.is_best_fit())
|
||||
.unwrap_or_default();
|
||||
let can_zoom_in = self
|
||||
.image_view()
|
||||
.current_image()
|
||||
.map(|image| !image.is_max_zoom())
|
||||
.unwrap_or_default();
|
||||
|
||||
self.action_set_enabled("win.zoom-out", can_zoom_out);
|
||||
self.action_set_enabled("win.zoom-in", can_zoom_in);
|
||||
}
|
||||
|
||||
// In the LpWindow UI file we define a `gtk::Expression`s
|
||||
// that is a closure. This closure takes the current `gio::File`
|
||||
// and processes it to return a window title.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue