metadata: Centralize many loose ends

This commit is contained in:
Sophie Herold 2024-01-01 22:41:56 +01:00
parent b6d578cc0a
commit fe43bc3a4c
21 changed files with 179 additions and 195 deletions

View file

@ -1,4 +1,4 @@
// Copyright (c) 2023 Sophie Herold
// Copyright (c) 2023-2024 Sophie Herold
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -62,11 +62,7 @@ impl imp::LpImage {
}
// Shortcut for formats that don't support transparency
if !obj
.metadata()
.format()
.map_or(true, |x| x.is_potentially_transparent())
{
if !obj.metadata().is_potentially_transparent() {
log::debug!("This format does not support transparency");
return Some(Self::default_background_color());
}

View file

@ -1,4 +1,4 @@
// Copyright (c) 2023 Sophie Herold
// Copyright (c) 2023-2024 Sophie Herold
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -45,41 +45,48 @@ impl imp::LpImage {
gtk::EventControllerScroll::new(gtk::EventControllerScrollFlags::VERTICAL);
scroll_controller.connect_scroll(glib::clone!(@weak obj => @default-return glib::Propagation::Proceed, move |event, _, y| {
// use Ctrl key as modifier for vertical scrolling
if event.current_event_state().contains(gdk::ModifierType::CONTROL_MASK)
|| event.current_event_state().contains(gdk::ModifierType::SHIFT_MASK)
{
// propagate event to scrolled window
return glib::Propagation::Proceed;
}
let state = event.current_event_state();
// touchpads do zoom via gestures only
if event.current_event_device().map(|x| x.source())
== Some(gdk::InputSource::Touchpad)
if event.current_event_device().map(|x| x.source()) == Some(gdk::InputSource::Touchpad)
{
// propagate event to scrolled window
return glib::Propagation::Proceed;
// Touchpads do zoom via gestures, expect when Ctrl key is pressed
if !state.contains(gdk::ModifierType::CONTROL_MASK) {
// propagate event to scrolled window
return glib::Propagation::Proceed;
}
} else {
// use Ctrl key as modifier for vertical scrolling
if state.contains(gdk::ModifierType::CONTROL_MASK)
|| state.contains(gdk::ModifierType::SHIFT_MASK)
{
// propagate event to scrolled window
return glib::Propagation::Proceed;
}
}
// Use exponential scaling since zoom is always multiplicative with the existing value
// This is the right thing since `exp(n/2)^2 == exp(n)` (two small steps are the same as one larger step)
let (zoom_factor, animated) = match event.unit() {
gdk::ScrollUnit::Wheel => (f64::exp( - y * f64::ln(ZOOM_FACTOR_SCROLL_WHEEL)), y.abs() >= 1.),
gdk::ScrollUnit::Surface => (f64::exp( - y * f64::ln(ZOOM_FACTOR_SCROLL_SURFACE)), false),
gdk::ScrollUnit::Wheel => (
f64::exp(-y * f64::ln(ZOOM_FACTOR_SCROLL_WHEEL)),
y.abs() >= 1.,
),
gdk::ScrollUnit::Surface => {
(f64::exp(-y * f64::ln(ZOOM_FACTOR_SCROLL_SURFACE)), false)
}
unknown_unit => {
log::warn!("Ignoring unknown scroll unit: {unknown_unit}");
(1., false)
}
};
let zoom =
obj.imp().zoom_target.get() * zoom_factor;
let zoom = obj.imp().zoom_target.get() * zoom_factor;
if animated {
obj.zoom_to(zoom);
} else {
obj.imp().zoom_to_full(zoom, false, false);
}
if animated {
obj.zoom_to(zoom);
} else {
obj.imp().zoom_to_full(zoom, false, false);
}
// do not propagate event to scrolled window
glib::Propagation::Stop

View file

@ -1,4 +1,4 @@
// Copyright (c) 2023 Sophie Herold
// Copyright (c) 2023-2024 Sophie Herold
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -68,14 +68,13 @@ impl imp::LpImage {
match update {
DecoderUpdate::Metadata(metadata) => {
log::debug!("Received metadata");
self.metadata.borrow_mut().merge(metadata);
self.metadata.borrow_mut().merge(*metadata);
self.emmit_metadata_changed();
obj.reset_rotation();
}
DecoderUpdate::Dimensions(dimension_details) => {
DecoderUpdate::Dimensions => {
log::debug!("Received dimensions: {:?}", self.original_dimensions());
self.dimension_details.replace(dimension_details);
obj.notify_image_size_available();
self.configure_best_fit();
self.request_tiles();
@ -105,10 +104,6 @@ impl imp::LpImage {
DecoderUpdate::Error(err) => {
self.set_error(Some(err));
}
DecoderUpdate::Format(format) => {
self.metadata.borrow_mut().set_format(format);
self.emmit_metadata_changed();
}
DecoderUpdate::Animated => {
if self.still.get() {
// Just load the first frame

View file

@ -83,10 +83,6 @@ impl imp::LpImage {
}
impl LpImage {
pub fn dimension_details(&self) -> decoder::ImageDimensionDetails {
self.imp().dimension_details.borrow().clone()
}
pub fn file(&self) -> Option<gio::File> {
self.imp().file.borrow().clone()
}

View file

@ -1,4 +1,4 @@
// Copyright (c) 2023 Sophie Herold
// Copyright (c) 2023-2024 Sophie Herold
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -65,7 +65,7 @@ impl WidgetImpl for imp::LpImage {
let applicable_zoom = self.applicable_zoom();
let scaling_filter = if obj.metadata().format().map_or(false, |x| x.is_svg()) {
let scaling_filter = if obj.metadata().is_svg() {
// Looks better in SVG animations and avoids rendering issues
gsk::ScalingFilter::Linear
} else if applicable_zoom < 1. {

View file

@ -1,4 +1,4 @@
// Copyright (c) 2023 Sophie Herold
// Copyright (c) 2023-2024 Sophie Herold
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -88,7 +88,7 @@ impl imp::LpImage {
pub(super) fn max_zoom(&self) -> f64 {
let obj = self.obj();
if obj.metadata().format().map_or(false, |x| x.is_svg()) {
if obj.metadata().is_svg() {
let (width, height) = self.original_dimensions();
// Avoid division by 0
let long_side = f64::max(1., i32::max(width, height) as f64);