windowContents: Rename from fullscreenWidget

Also change some naming, comments, and bindings.
This commit is contained in:
Sophie Herold 2024-07-19 14:30:06 +02:00
parent bb9b834a22
commit cd72a30d5f
7 changed files with 214 additions and 206 deletions

View file

@ -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 <http://www.gnu.org/licenses/>.
//
// 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<adw::ToolbarView>,
#[template_child]
pub(super) header_container: TemplateChild<LpShyBin>,
#[property(get, set, nullable)]
headerbar: RefCell<Option<gtk::Widget>>,
#[property(get, set, nullable)]
content: RefCell<Option<gtk::Widget>>,
#[property(get, set)]
fullscreened: Cell<bool>,
#[property(get, set)]
extend_content: Cell<bool>,
#[property(get = LpFullscreenWidget::is_content_extended_to_top, type = bool)]
_is_content_extended_to_top: (),
#[property(get, set)]
is_empty: Cell<bool>,
#[property(get, set)]
headerbar_opacity: Cell<f64>,
}
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<Self>) {
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<imp::LpFullscreenWidget>)
@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();
}
}
}

View file

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="LpFullscreenWidget" parent="AdwBin">
<binding name="fullscreened">
<lookup name="fullscreened" type="GtkWindow">
<lookup name="root">LpFullscreenWidget</lookup>
</lookup>
</binding>
<binding name="is-empty">
<lookup name="is-empty" type="LpWindow">
<lookup name="root">LpFullscreenWidget</lookup>
</lookup>
</binding>
<binding name="headerbar-opacity">
<lookup name="headerbar-opacity" type="LpWindow">
<lookup name="root">LpFullscreenWidget</lookup>
</lookup>
</binding>
<property name="child">
<object class="AdwToolbarView" id="toolbar_view">
<child type="top">
<object class="LpShyBin" id="header_container">
<property name="child" bind-source="LpFullscreenWidget" bind-property="headerbar"/>
</object>
</child>
<property name="content" bind-source="LpFullscreenWidget" bind-property="content"/>
</object>
</property>
</template>
</interface>

View file

@ -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 <http://www.gnu.org/licenses/>.
//
// 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<adw::ToolbarView>,
#[template_child]
pub(super) header_container: TemplateChild<LpShyBin>,
#[property(get, set, nullable)]
headerbar: RefCell<Option<gtk::Widget>>,
#[property(get, set, nullable)]
content: RefCell<Option<gtk::Widget>>,
// Set via binding to window
#[property(get, set)]
fullscreened: Cell<bool>,
// Set via binding to properties toggle button
#[property(get, set)]
show_properties: Cell<bool>,
// Set via binding to window
#[property(get, set)]
is_showing_image: Cell<bool>,
}
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<Self>) {
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<imp::LpWindowContent>)
@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()
}
}

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="LpWindowContent" parent="AdwBin">
<binding name="fullscreened">
<lookup name="fullscreened" type="GtkWindow">
<lookup name="root">LpWindowContent</lookup>
</lookup>
</binding>
<binding name="is-showing-image">
<lookup name="is-showing-image" type="LpWindow">
<lookup name="root">LpWindowContent</lookup>
</lookup>
</binding>
<property name="child">
<object class="AdwToolbarView" id="toolbar_view">
<child type="top">
<object class="LpShyBin" id="header_container">
<property name="child" bind-source="LpWindowContent" bind-property="headerbar" />
</object>
</child>
<property name="content" bind-source="LpWindowContent" bind-property="content" />
</object>
</property>
</template>
</interface>