slidingView: Allocate LpImage more correctly

Allocate the ScrolledWindow instead of the LpImage
to include non-overlayed scrollbars.

General cleanup how we measure things.

Part-of: <https://gitlab.gnome.org/Incubator/loupe/-/merge_requests/150>
This commit is contained in:
Sophie Herold 2023-03-21 21:50:54 +01:00 • committed by Marge Bot
parent e5fc4bc85c
commit 7b7ece1dc3
3 changed files with 18 additions and 25 deletions

View file

@ -48,6 +48,8 @@ mod imp {
#[template_child]
pub(super) image_stack_page: TemplateChild<gtk::Widget>,
#[template_child]
pub(super) scrolled_window: TemplateChild<gtk::ScrolledWindow>,
#[template_child]
pub(super) image: TemplateChild<LpImage>,
#[template_child]
pub(super) popover: TemplateChild<gtk::PopoverMenu>,
@ -165,6 +167,10 @@ impl LpImagePage {
self.image().path().unwrap()
}
pub fn scrolled_window(&self) -> gtk::ScrolledWindow {
self.imp().scrolled_window.clone()
}
pub fn image(&self) -> LpImage {
self.imp().image.get()
}

View file

@ -194,14 +194,7 @@ mod imp {
}
impl WidgetImpl for LpImageView {
/// The main target of this manual implementation is to provide a good
/// natural width that allows to have a neat size for newly opened `LpWindow`s.
/// The actual calculation of the image natural width happens in
/// the measure function of `LpImage`.
///
/// This manual implementation is necessary since AdwCarousel gives the
/// largest natural width of all of it's children. But we actually want the
/// one of the opened (current) image.
/// This manual implementation makes sure left an right overlay both fit into the window
fn measure(&self, orientation: gtk::Orientation, for_size: i32) -> (i32, i32, i32, i32) {
// Measure child of AdwBin
let (child_min, child_natural, _, _) = self.bin_child.measure(orientation, for_size);
@ -212,19 +205,10 @@ mod imp {
// take as minimum whatever is larger
let min = i32::max(child_min, overlay1_min + overlay2_min);
// take as natural whatever is larger
let natural = i32::max(child_natural, min);
if let Some(page) = self.obj().current_page() {
// measure `LpImage`
let (_, image_natural, _, _) = page.image().measure(orientation, for_size);
// Ensure that minimum size is not smaller than the one of the child.
// Also ensure that the natural width is not smaller than the minimal size.
// Both things are required by GTK.
(min, i32::max(min, image_natural), -1, -1)
} else {
// also include controls overlays when mostly passing through child measurements
(min, i32::max(child_natural, min), -1, -1)
}
(min, natural, -1, -1)
}
/// this is necessary because we do layout manually

View file

@ -165,14 +165,17 @@ mod imp {
if page_position == (scroll_position + position_shift).floor()
|| page_position == (scroll_position + position_shift).ceil()
{
page.set_visible(true);
page.set_child_visible(true);
let transform = gsk::Transform::new().translate(&graphene::Point::new(x, 0.));
page.allocate(width, height, 0, Some(transform));
} else {
page.set_visible(false);
page.set_child_visible(false);
}
let transform = gsk::Transform::new().translate(&graphene::Point::new(x, 0.));
page.allocate(width, height, 0, Some(transform));
page.image().allocate(width, height, 0, None);
if !page.scrolled_window().is_mapped() {
// SVG needs to know a widget size before rendering something in LpImage
page.scrolled_window().allocate(width, height, 0, None);
}
}
}