window: Rework fullscreen

We can use AdwFlap and have one single headerbar for both
fullscreen and unfullscreened.
This commit is contained in:
Christopher Davis 2021-09-24 01:14:56 -07:00
parent e589028f1b
commit e45b89f854
5 changed files with 87 additions and 105 deletions

View file

@ -14,32 +14,6 @@
</object>
</child>
<child type="overlay">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkHeaderBar" id="headerbar">
<property name="valign">start</property>
<property name="show-title-buttons">False</property>
<property name="visible" bind-source="IvImageView" bind-property="header-visible" bind-flags="sync-create"/>
<child type="end">
<object class="GtkButton">
<property name="margin-start">6</property>
<property name="has-frame">False</property>
<property name="icon-name">view-restore-symbolic</property>
<property name="action-name">win.toggle-fullscreen</property>
</object>
</child>
<child type="end">
<object class="GtkMenuButton" id="menu_button">
<property name="icon-name">open-menu-symbolic</property>
</object>
</child>
<style>
<class name="osd"/>
</style>
</object>
</child>
<child>
<object class="GtkBox">
<property name="vexpand">True</property>
<child>
@ -89,8 +63,6 @@
</object>
</child>
</object>
</child>
</object>
</property>
<child>
<object class="GtkShortcutController">

View file

@ -6,12 +6,15 @@
<property name="width-request">360</property>
<property name="title">Image Viewer</property>
<property name="content">
<object class="GtkBox">
<object class="AdwFlap" id="flap">
<property name="orientation">vertical</property>
<child>
<property name="fold-policy">never</property>
<property name="locked">true</property>
<property name="modal">false</property>
<property name="flap">
<object class="GtkHeaderBar" id="headerbar">
<property name="css-classes">titlebar</property>
<property name="visible" bind-source="IvWindow" bind-property="fullscreened" bind-flags="sync-create|invert-boolean"/>
<property name="show_title_buttons" bind-source="IvWindow" bind-property="fullscreened" bind-flags="sync-create|invert-boolean"/>
<child type="end">
<object class="GtkMenuButton" id="menu_button">
<property name="icon-name">open-menu-symbolic</property>
@ -19,14 +22,14 @@
</object>
</child>
<child type="end">
<object class="GtkButton">
<object class="GtkButton" id="fullscreen_button">
<property name="icon-name">view-fullscreen-symbolic</property>
<property name="action-name">win.toggle-fullscreen</property>
</object>
</child>
</object>
</child>
<child>
</property>
<property name="content">
<object class="GtkStack" id="stack">
<property name="visible-child">status_page</property>
<property name="vexpand">True</property>
@ -41,13 +44,14 @@
</child>
<child>
<object class="IvImageView" id="image_view">
<property name="header-visible" bind-source="IvWindow" bind-property="fullscreened" bind-flags="sync-create"/>
<property name="primary-menu-model">primary_menu</property>
<property name="popover-menu-model">image_menu</property>
</object>
</child>
</object>
</child>
</property>
<style>
<class name="fullscreen-widget"/>
</style>
</object>
</property>
</template>

View file

@ -8,6 +8,10 @@ button.circular {
background-color: @theme_base_color;
}
flap.fullscreen-widget dimming, shadow, border, outline {
background: none;
}
.checkerboard {
background-color: #7f7f7f;
background-image: linear-gradient(

View file

@ -41,10 +41,6 @@ mod imp {
#[derive(Debug, Default, CompositeTemplate)]
#[template(resource = "/org/gnome/ImageViewer/gtk/image_view.ui")]
pub struct IvImageView {
#[template_child]
pub headerbar: TemplateChild<gtk::HeaderBar>,
#[template_child]
pub menu_button: TemplateChild<gtk::MenuButton>,
#[template_child]
pub picture: TemplateChild<gtk::Picture>,
#[template_child]
@ -54,9 +50,7 @@ mod imp {
#[template_child]
pub press_gesture: TemplateChild<gtk::GestureLongPress>,
// Cell<T> allows for interior mutability of primitive types
pub header_visible: Cell<bool>,
// RefCell<T> does the same for non-primitive types.
// RefCell<T> allows for interior mutability of non-primitive types.
pub menu_model: RefCell<Option<gio::MenuModel>>,
pub popover_menu_model: RefCell<Option<gio::MenuModel>>,
@ -64,6 +58,7 @@ mod imp {
pub filename: RefCell<Option<String>>,
// Path of filenames
pub directory_pictures: RefCell<Vec<String>>,
// Cell<T> allows for interior mutability of primitive types
pub index: Cell<usize>,
}
@ -94,20 +89,6 @@ mod imp {
fn properties() -> &'static [glib::ParamSpec] {
static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
vec![
glib::ParamSpec::new_boolean(
"header-visible",
"Header visible",
"Whether or not the headerbar is visible",
false,
glib::ParamFlags::READWRITE,
),
glib::ParamSpec::new_object(
"primary-menu-model",
"Primary Menu Model",
"The menu model for the menu button",
gio::MenuModel::static_type(),
glib::ParamFlags::READWRITE,
),
glib::ParamSpec::new_object(
"popover-menu-model",
"Popover Menu Model",
@ -150,8 +131,6 @@ mod imp {
fn property(&self, _obj: &Self::Type, _id: usize, psec: &glib::ParamSpec) -> glib::Value {
match psec.name() {
"header-visible" => self.header_visible.get().to_value(),
"primary-menu-model" => self.menu_model.borrow().to_value(),
"popover-menu-model" => self.popover_menu_model.borrow().to_value(),
"filename" => self.filename.borrow().to_value(),
_ => unimplemented!(),
@ -166,14 +145,6 @@ mod imp {
psec: &glib::ParamSpec,
) {
match psec.name() {
"header-visible" => {
self.header_visible.set(value.get::<bool>().unwrap());
}
"primary-menu-model" => {
let model: Option<gio::MenuModel> = value.get().unwrap();
self.menu_button.set_menu_model(model.as_ref());
*self.menu_model.borrow_mut() = model;
}
"popover-menu-model" => {
let model: Option<gio::MenuModel> = value.get().unwrap();
self.popover.set_menu_model(model.as_ref());

View file

@ -52,8 +52,14 @@ mod imp {
// TemplateChild<T> wrapper, where T is the
// object type of the template child.
#[template_child]
pub flap: TemplateChild<libadwaita::Flap>,
#[template_child]
pub headerbar: TemplateChild<gtk::HeaderBar>,
#[template_child]
pub menu_button: TemplateChild<gtk::MenuButton>,
#[template_child]
pub fullscreen_button: TemplateChild<gtk::Button>,
#[template_child]
pub stack: TemplateChild<gtk::Stack>,
#[template_child]
pub status_page: TemplateChild<libadwaita::StatusPage>,
@ -76,7 +82,7 @@ mod imp {
// Set up actions
klass.install_action("win.toggle-fullscreen", None, move |win, _, _| {
win.set_fullscreened(!win.is_fullscreened());
win.toggle_fullscreen(!win.is_fullscreened());
});
klass.install_action("win.open", None, move |win, _, _| {
@ -163,6 +169,31 @@ impl IvWindow {
glib::Object::new(&[("application", app)]).expect("Failed to create IvWindow")
}
fn toggle_fullscreen(&self, fullscreen: bool) {
let imp = imp::IvWindow::from_instance(&self);
if fullscreen {
imp.flap.set_fold_policy(libadwaita::FlapFoldPolicy::Always);
imp.headerbar.add_css_class("osd");
imp.menu_button.unparent();
imp.fullscreen_button.unparent();
imp.headerbar.pack_end(&*imp.fullscreen_button);
imp.headerbar.pack_end(&*imp.menu_button);
imp.fullscreen_button.set_icon_name("view-restore-symbolic");
} else {
imp.flap.set_fold_policy(libadwaita::FlapFoldPolicy::Never);
imp.headerbar.remove_css_class("osd");
imp.menu_button.unparent();
imp.fullscreen_button.unparent();
imp.headerbar.pack_end(&*imp.menu_button);
imp.headerbar.pack_end(&*imp.fullscreen_button);
imp.fullscreen_button
.set_icon_name("view-fullscreen-symbolic");
}
self.set_fullscreened(fullscreen);
}
fn pick_file(&self) {
let chooser = gtk::FileChooserNative::new(
Some(&"Open Image".to_string()),