image_view: Expose file as a property instead of filename
The GFile is more useful for other data. The window can use expressions to calculate an appropriate title, so we no longer need to call `set_title()` or connect to a signal manually. This commit also adjusts the `uri()` and `print()` functions to use `active_file()`
This commit is contained in:
parent
fa513596b2
commit
1e95dd4cbb
3 changed files with 46 additions and 36 deletions
|
|
@ -83,6 +83,7 @@ mod imp {
|
|||
// bind_template() is a function generated by the
|
||||
// CompositeTemplate macro to bind all children at once.
|
||||
Self::bind_template(klass);
|
||||
Self::Type::bind_template_callbacks(klass);
|
||||
|
||||
// Set up actions
|
||||
klass.install_action("win.toggle-fullscreen", None, move |win, _, _| {
|
||||
|
|
@ -139,20 +140,12 @@ mod imp {
|
|||
let help_overlay = builder.object("help_overlay").unwrap();
|
||||
obj.set_help_overlay(Some(&help_overlay));
|
||||
|
||||
self.drop_target.set_types(&[gdk::FileList::static_type()]);
|
||||
|
||||
// For callbacks, you will want to reference the GTK docs on
|
||||
// the relevant signal to see which parameters you need.
|
||||
// In this case, we need one to react to the signal,
|
||||
// so we name it `iv` then use `_` for the other spots.
|
||||
self.image_view.connect_notify_local(
|
||||
Some("filename"),
|
||||
clone!(@weak obj => move |iv, _| {
|
||||
if let Some(filename) = iv.filename() {
|
||||
obj.set_title(Some(&filename));
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
self.drop_target.set_types(&[gdk::FileList::static_type()]);
|
||||
// In this case, we need only need the GValue,
|
||||
// so we name it `value` then use `_` for the other spots.
|
||||
self.drop_target.connect_drop(
|
||||
clone!(@weak obj => @default-return false, move |_, value, _, _| {
|
||||
// Here we use a GValue, which is a dynamic object that can hold different types,
|
||||
|
|
@ -206,6 +199,7 @@ glib::wrapper! {
|
|||
@implements gio::ActionMap, gio::ActionGroup, gtk::Native;
|
||||
}
|
||||
|
||||
#[gtk::template_callbacks]
|
||||
impl LpWindow {
|
||||
pub fn new<A: IsA<gtk::Application>>(app: &A) -> Self {
|
||||
glib::Object::new(&[("application", app)]).expect("Failed to create LpWindow")
|
||||
|
|
@ -261,8 +255,7 @@ impl LpWindow {
|
|||
|
||||
if let Some(file) = imp
|
||||
.image_view
|
||||
.current_page()
|
||||
.and_then(|p| p.file())
|
||||
.active_file()
|
||||
.and_then(|f| f.peek_path())
|
||||
.and_then(|p| std::fs::File::open(p).ok())
|
||||
{
|
||||
|
|
@ -375,4 +368,18 @@ impl LpWindow {
|
|||
self.set_default_size(final_width, final_height);
|
||||
log::debug!("Window resized to {} x {}", final_width, final_height);
|
||||
}
|
||||
|
||||
// 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.
|
||||
//
|
||||
// In this function we chain `Option`s with `and_then()` in order
|
||||
// to handle optional results with a fallback, without needing to
|
||||
// have multiple `match` or `if let` branches, and without needing
|
||||
// to unwrap.
|
||||
#[template_callback]
|
||||
fn window_title(&self, file: Option<gio::File>) -> String {
|
||||
file.and_then(|f| util::get_file_display_name(&f)) // If the file exists, get display name
|
||||
.unwrap_or_else(|| String::from("Image Viewer")) // Return that or the default if there's nothing
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue