diff --git a/src/widgets.rs b/src/widgets.rs
index 132d856..1212481 100644
--- a/src/widgets.rs
+++ b/src/widgets.rs
@@ -19,7 +19,6 @@
mod drag_overlay;
mod error_details;
-mod fullscreen_widget;
mod image;
mod image_page;
mod image_view;
@@ -28,10 +27,10 @@ mod print_preview;
mod properties_view;
mod shy_bin;
mod sliding_view;
+mod window_content;
pub use drag_overlay::LpDragOverlay;
pub use error_details::LpErrorDetails;
-pub use fullscreen_widget::LpFullscreenWidget;
pub use image::LpImage;
pub use image_page::LpImagePage;
pub use image_view::LpImageView;
@@ -40,3 +39,4 @@ pub use print_preview::LpPrintPreview;
pub use properties_view::LpPropertiesView;
pub use shy_bin::LpShyBin;
pub use sliding_view::LpSlidingView;
+pub use window_content::LpWindowContent;
diff --git a/src/widgets/fullscreen_widget.rs b/src/widgets/fullscreen_widget.rs
deleted file mode 100644
index 6c699ef..0000000
--- a/src/widgets/fullscreen_widget.rs
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright (c) 2024 Christopher Davis
-//
-// 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
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-use std::cell::{Cell, RefCell};
-
-use adw::prelude::*;
-use adw::subclass::prelude::*;
-use glib::Properties;
-use gtk::CompositeTemplate;
-
-use super::*;
-use crate::deps::*;
-
-mod imp {
- use super::*;
-
- #[derive(Default, Debug, Properties, CompositeTemplate)]
- #[properties(wrapper_type = super::LpFullscreenWidget)]
- #[template(file = "fullscreen_widget.ui")]
- pub struct LpFullscreenWidget {
- #[template_child]
- pub(super) toolbar_view: TemplateChild,
- #[template_child]
- pub(super) header_container: TemplateChild,
-
- #[property(get, set, nullable)]
- headerbar: RefCell>,
- #[property(get, set, nullable)]
- content: RefCell >,
-
- #[property(get, set)]
- fullscreened: Cell,
- #[property(get, set)]
- extend_content: Cell,
- #[property(get = LpFullscreenWidget::is_content_extended_to_top, type = bool)]
- _is_content_extended_to_top: (),
- #[property(get, set)]
- is_empty: Cell,
- #[property(get, set)]
- headerbar_opacity: Cell,
- }
-
- impl LpFullscreenWidget {
- fn is_content_extended_to_top(&self) -> bool {
- let obj = self.obj();
- obj.fullscreened() && obj.extend_content()
- }
- }
-
- #[glib::object_subclass]
- impl ObjectSubclass for LpFullscreenWidget {
- const NAME: &'static str = "LpFullscreenWidget";
- type Type = super::LpFullscreenWidget;
- type ParentType = adw::Bin;
-
- fn class_init(klass: &mut Self::Class) {
- klass.bind_template();
- }
-
- fn instance_init(obj: &gio::glib::subclass::InitializingObject) {
- obj.init_template();
- }
- }
-
- #[glib::derived_properties]
- impl ObjectImpl for LpFullscreenWidget {
- fn constructed(&self) {
- self.parent_constructed();
-
- let obj = self.obj();
- obj.connect_is_empty_notify(|obj| {
- obj.update_headerbar_style();
- });
-
- obj.connect_fullscreened_notify(|obj| {
- obj.update_headerbar_style();
- });
-
- obj.connect_extend_content_notify(|obj| {
- obj.update_headerbar_style();
- });
- }
- }
-
- impl WidgetImpl for LpFullscreenWidget {}
- impl BinImpl for LpFullscreenWidget {}
-}
-
-glib::wrapper! {
- pub struct LpFullscreenWidget(ObjectSubclass)
- @extends gtk::Widget, adw::Bin,
- @implements gtk::Buildable, gtk::ConstraintTarget;
-}
-
-impl LpFullscreenWidget {
- pub fn is_headerbar_flat(&self) -> bool {
- matches!(
- self.imp().toolbar_view.top_bar_style(),
- adw::ToolbarStyle::Flat
- )
- }
-
- fn update_header_opacity(&self) {
- if let Some(headerbar) = self.headerbar() {
- if self.is_headerbar_flat() && !self.is_empty() {
- // Bring headerbar opacity in sync with controls
- headerbar.set_opacity(self.headerbar_opacity());
- } else {
- headerbar.set_opacity(1.);
- };
- }
- }
-
- fn update_headerbar_style(&self) {
- self.imp()
- .toolbar_view
- .set_extend_content_to_top_edge(self.is_content_extended_to_top());
-
- // Flat headerbar for empty state and fullscreen
- let style = if self.is_empty() || self.is_content_extended_to_top() {
- adw::ToolbarStyle::Flat
- } else {
- // Use the border variant of raised to avoid shadows over images
- adw::ToolbarStyle::RaisedBorder
- };
-
- let toolbar_view = self.imp().toolbar_view.get();
- if style != toolbar_view.top_bar_style() {
- toolbar_view.set_top_bar_style(style);
- self.update_header_opacity();
- }
- }
-}
diff --git a/src/widgets/fullscreen_widget.ui b/src/widgets/fullscreen_widget.ui
deleted file mode 100644
index 7ace3a7..0000000
--- a/src/widgets/fullscreen_widget.ui
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
- LpFullscreenWidget
-
-
-
-
- LpFullscreenWidget
-
-
-
-
- LpFullscreenWidget
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/widgets/window_content.rs b/src/widgets/window_content.rs
new file mode 100644
index 0000000..ab9c9f6
--- /dev/null
+++ b/src/widgets/window_content.rs
@@ -0,0 +1,164 @@
+// Copyright (c) 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
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+// Copyright (c) 2024 Christopher Davis
+
+//! Contains the main structure inside the window
+//!
+//! This is it's own widget since it's reused inside different layouts for
+//! different positions of the image properties.
+
+use std::cell::{Cell, RefCell};
+
+use adw::prelude::*;
+use adw::subclass::prelude::*;
+use glib::Properties;
+use gtk::CompositeTemplate;
+
+use super::*;
+use crate::deps::*;
+
+mod imp {
+ use super::*;
+
+ #[derive(Default, Debug, Properties, CompositeTemplate)]
+ #[properties(wrapper_type = super::LpWindowContent)]
+ #[template(file = "window_content.ui")]
+ pub struct LpWindowContent {
+ #[template_child]
+ pub(super) toolbar_view: TemplateChild,
+ #[template_child]
+ pub(super) header_container: TemplateChild,
+
+ #[property(get, set, nullable)]
+ headerbar: RefCell>,
+ #[property(get, set, nullable)]
+ content: RefCell >,
+
+ // Set via binding to window
+ #[property(get, set)]
+ fullscreened: Cell,
+ // Set via binding to properties toggle button
+ #[property(get, set)]
+ show_properties: Cell,
+ // Set via binding to window
+ #[property(get, set)]
+ is_showing_image: Cell,
+ }
+
+ impl LpWindowContent {
+ fn update_header_opacity(&self) {
+ let obj = self.obj();
+
+ if let Some(headerbar) = obj.headerbar() {
+ if obj.is_headerbar_flat() && obj.is_showing_image() {
+ // Bring headerbar opacity in sync with controls
+ headerbar.set_opacity(self.headerbar_opacity());
+ } else {
+ headerbar.set_opacity(1.);
+ };
+ }
+ }
+
+ fn update_headerbar_style(&self) {
+ let obj = self.obj();
+
+ self.toolbar_view
+ .set_extend_content_to_top_edge(obj.is_content_extended_to_top());
+
+ let style = if !obj.is_showing_image() || obj.is_content_extended_to_top() {
+ // Flat headerbar for empty state and fullscreen without properties enabled
+ adw::ToolbarStyle::Flat
+ } else {
+ // Use the border variant of raised to avoid shadows over images
+ adw::ToolbarStyle::RaisedBorder
+ };
+
+ let toolbar_view = self.toolbar_view.get();
+ if style != toolbar_view.top_bar_style() {
+ toolbar_view.set_top_bar_style(style);
+ self.update_header_opacity();
+ }
+ }
+
+ fn headerbar_opacity(&self) -> f64 {
+ self.headerbar
+ .borrow()
+ .as_ref()
+ .map(|x| x.opacity())
+ .unwrap_or(1.)
+ }
+ }
+
+ #[glib::object_subclass]
+ impl ObjectSubclass for LpWindowContent {
+ const NAME: &'static str = "LpWindowContent";
+ type Type = super::LpWindowContent;
+ type ParentType = adw::Bin;
+
+ fn class_init(klass: &mut Self::Class) {
+ klass.bind_template();
+ }
+
+ fn instance_init(obj: &gio::glib::subclass::InitializingObject) {
+ obj.init_template();
+ }
+ }
+
+ #[glib::derived_properties]
+ impl ObjectImpl for LpWindowContent {
+ fn constructed(&self) {
+ self.parent_constructed();
+
+ let obj = self.obj();
+
+ obj.connect_is_showing_image_notify(|obj| {
+ obj.imp().update_headerbar_style();
+ });
+
+ obj.connect_fullscreened_notify(|obj| {
+ obj.imp().update_headerbar_style();
+ });
+
+ obj.connect_show_properties_notify(|obj| {
+ obj.imp().update_headerbar_style();
+ });
+ }
+ }
+
+ impl WidgetImpl for LpWindowContent {}
+ impl BinImpl for LpWindowContent {}
+}
+
+glib::wrapper! {
+ pub struct LpWindowContent(ObjectSubclass)
+ @extends gtk::Widget, adw::Bin,
+ @implements gtk::Buildable, gtk::ConstraintTarget;
+}
+
+impl LpWindowContent {
+ pub fn is_headerbar_flat(&self) -> bool {
+ matches!(
+ self.imp().toolbar_view.top_bar_style(),
+ adw::ToolbarStyle::Flat
+ )
+ }
+
+ pub fn is_content_extended_to_top(&self) -> bool {
+ self.fullscreened() && self.show_properties()
+ }
+}
diff --git a/src/widgets/window_content.ui b/src/widgets/window_content.ui
new file mode 100644
index 0000000..2b5b73c
--- /dev/null
+++ b/src/widgets/window_content.ui
@@ -0,0 +1,25 @@
+
+
+
+
+
+ LpWindowContent
+
+
+
+
+ LpWindowContent
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/window.rs b/src/window.rs
index 47dfe05..c8897bd 100644
--- a/src/window.rs
+++ b/src/window.rs
@@ -1,4 +1,4 @@
-// Copyright (c) 2020-2023 Christopher Davis
+// Copyright (c) 2020-2024 Christopher Davis
// Copyright (c) 2022-2024 Sophie Herold
// Copyright (c) 2022 Elton A Rodrigues
// Copyright (c) 2022 Maximiliano Sandoval R
@@ -42,7 +42,7 @@ use crate::config;
use crate::deps::*;
use crate::util::gettext::*;
use crate::util::Direction;
-use crate::widgets::{LpDragOverlay, LpFullscreenWidget, LpImage, LpImageView, LpPropertiesView};
+use crate::widgets::{LpDragOverlay, LpImage, LpImageView, LpPropertiesView, LpWindowContent};
/// Show window after X milliseconds even if image dimensions are not known yet
const SHOW_WINDOW_AFTER: u64 = 2000;
@@ -81,7 +81,7 @@ mod imp {
// TemplateChild wrapper, where T is the
// object type of the template child.
#[template_child]
- pub(super) fullscreen_widget: TemplateChild,
+ pub(super) window_content: TemplateChild,
#[template_child]
pub(super) headerbar: TemplateChild,
#[template_child]
@@ -111,8 +111,8 @@ mod imp {
#[template_child]
pub(super) backward_click_gesture: TemplateChild,
- #[property(get, set)]
- is_empty: Cell,
+ #[property(get)]
+ pub(super) is_showing_image: Cell,
#[property(get, set)]
headerbar_opacity: Cell,
@@ -340,12 +340,6 @@ mod imp {
),
);
- self.image_view
- .controls_box_start()
- .bind_property("opacity", &*self.obj(), "headerbar-opacity")
- .sync_create()
- .build();
-
// action win.previous status
self.image_view
.connect_is_previous_available_notify(glib::clone!(
@@ -761,7 +755,8 @@ impl LpWindow {
let current_page = imp.image_view.current_page();
// HeaderBar style
- self.set_is_empty(current_page.is_none());
+ imp.is_showing_image.replace(current_page.is_none());
+ self.notify_is_showing_image();
// Window title
self.update_title();
@@ -905,11 +900,11 @@ impl LpWindow {
}
fn is_headerbar_flat(&self) -> bool {
- self.imp().fullscreen_widget.is_headerbar_flat()
+ self.imp().window_content.is_headerbar_flat()
}
fn is_content_extended_to_top(&self) -> bool {
- self.imp().fullscreen_widget.is_content_extended_to_top()
+ self.imp().window_content.is_content_extended_to_top()
}
fn update_accel_status(&self) {
diff --git a/src/window.ui b/src/window.ui
index 4eda902..eedc3fc 100644
--- a/src/window.ui
+++ b/src/window.ui
@@ -64,13 +64,13 @@
max-width: 590sp
- sheet
+ bottom-properties
max-width: 590sp and max-height: 550sp
- short
+ overlay-properties
@@ -79,10 +79,10 @@
- sidebar
+ sidebar-properies
-
-
+
+
headerbar
@@ -111,10 +111,10 @@
- sheet
+ bottom-properties
-
-
+
+
headerbar
@@ -139,7 +139,7 @@
@@ -151,14 +151,14 @@
- short
+ overlay-properties
True
-
-
+
+
headerbar
@@ -189,6 +189,7 @@
+
-
+