window: Rework fullscreen
We can use AdwFlap and have one single headerbar for both fullscreen and unfullscreened.
This commit is contained in:
parent
e589028f1b
commit
e45b89f854
5 changed files with 87 additions and 105 deletions
|
|
@ -15,77 +15,49 @@
|
||||||
</child>
|
</child>
|
||||||
<child type="overlay">
|
<child type="overlay">
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="orientation">vertical</property>
|
<property name="vexpand">True</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkHeaderBar" id="headerbar">
|
<object class="GtkButton" id="prev_button">
|
||||||
<property name="valign">start</property>
|
<property name="halign">start</property>
|
||||||
<property name="show-title-buttons">False</property>
|
<property name="valign">center</property>
|
||||||
<property name="visible" bind-source="IvImageView" bind-property="header-visible" bind-flags="sync-create"/>
|
<property name="margin-start">18</property>
|
||||||
<child type="end">
|
<property name="margin-end">18</property>
|
||||||
<object class="GtkButton">
|
<property name="icon-name">go-previous-symbolic</property>
|
||||||
<property name="margin-start">6</property>
|
<property name="action-name">iv.previous</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>
|
<style>
|
||||||
<class name="osd"/>
|
<class name="osd"/>
|
||||||
|
<class name="circular"/>
|
||||||
</style>
|
</style>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkButton" id="next_button">
|
||||||
<property name="vexpand">True</property>
|
<property name="hexpand">True</property>
|
||||||
<child>
|
<property name="halign">end</property>
|
||||||
<object class="GtkButton" id="prev_button">
|
<property name="valign">center</property>
|
||||||
<property name="halign">start</property>
|
<property name="margin-start">18</property>
|
||||||
<property name="valign">center</property>
|
<property name="margin-end">18</property>
|
||||||
<property name="margin-start">18</property>
|
<property name="icon-name">go-next-symbolic</property>
|
||||||
<property name="margin-end">18</property>
|
<property name="action-name">iv.next</property>
|
||||||
<property name="icon-name">go-previous-symbolic</property>
|
<style>
|
||||||
<property name="action-name">iv.previous</property>
|
<class name="osd"/>
|
||||||
<style>
|
<class name="circular"/>
|
||||||
<class name="osd"/>
|
</style>
|
||||||
<class name="circular"/>
|
</object>
|
||||||
</style>
|
</child>
|
||||||
</object>
|
<child>
|
||||||
</child>
|
<object class="GtkGestureClick" id="click_gesture">
|
||||||
<child>
|
<property name="button">3</property>
|
||||||
<object class="GtkButton" id="next_button">
|
</object>
|
||||||
<property name="hexpand">True</property>
|
</child>
|
||||||
<property name="halign">end</property>
|
<child>
|
||||||
<property name="valign">center</property>
|
<object class="GtkGestureLongPress" id="press_gesture">
|
||||||
<property name="margin-start">18</property>
|
<property name="touch-only">True</property>
|
||||||
<property name="margin-end">18</property>
|
</object>
|
||||||
<property name="icon-name">go-next-symbolic</property>
|
</child>
|
||||||
<property name="action-name">iv.next</property>
|
<child>
|
||||||
<style>
|
<object class="GtkPopoverMenu" id="popover">
|
||||||
<class name="osd"/>
|
<property name="has-arrow">False</property>
|
||||||
<class name="circular"/>
|
|
||||||
</style>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkGestureClick" id="click_gesture">
|
|
||||||
<property name="button">3</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkGestureLongPress" id="press_gesture">
|
|
||||||
<property name="touch-only">True</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkPopoverMenu" id="popover">
|
|
||||||
<property name="has-arrow">False</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,15 @@
|
||||||
<property name="width-request">360</property>
|
<property name="width-request">360</property>
|
||||||
<property name="title">Image Viewer</property>
|
<property name="title">Image Viewer</property>
|
||||||
<property name="content">
|
<property name="content">
|
||||||
<object class="GtkBox">
|
<object class="AdwFlap" id="flap">
|
||||||
<property name="orientation">vertical</property>
|
<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">
|
<object class="GtkHeaderBar" id="headerbar">
|
||||||
<property name="css-classes">titlebar</property>
|
<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">
|
<child type="end">
|
||||||
<object class="GtkMenuButton" id="menu_button">
|
<object class="GtkMenuButton" id="menu_button">
|
||||||
<property name="icon-name">open-menu-symbolic</property>
|
<property name="icon-name">open-menu-symbolic</property>
|
||||||
|
|
@ -19,14 +22,14 @@
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child type="end">
|
<child type="end">
|
||||||
<object class="GtkButton">
|
<object class="GtkButton" id="fullscreen_button">
|
||||||
<property name="icon-name">view-fullscreen-symbolic</property>
|
<property name="icon-name">view-fullscreen-symbolic</property>
|
||||||
<property name="action-name">win.toggle-fullscreen</property>
|
<property name="action-name">win.toggle-fullscreen</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</property>
|
||||||
<child>
|
<property name="content">
|
||||||
<object class="GtkStack" id="stack">
|
<object class="GtkStack" id="stack">
|
||||||
<property name="visible-child">status_page</property>
|
<property name="visible-child">status_page</property>
|
||||||
<property name="vexpand">True</property>
|
<property name="vexpand">True</property>
|
||||||
|
|
@ -41,13 +44,14 @@
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="IvImageView" id="image_view">
|
<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>
|
<property name="popover-menu-model">image_menu</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</property>
|
||||||
|
<style>
|
||||||
|
<class name="fullscreen-widget"/>
|
||||||
|
</style>
|
||||||
</object>
|
</object>
|
||||||
</property>
|
</property>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,10 @@ button.circular {
|
||||||
background-color: @theme_base_color;
|
background-color: @theme_base_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flap.fullscreen-widget dimming, shadow, border, outline {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
.checkerboard {
|
.checkerboard {
|
||||||
background-color: #7f7f7f;
|
background-color: #7f7f7f;
|
||||||
background-image: linear-gradient(
|
background-image: linear-gradient(
|
||||||
|
|
|
||||||
|
|
@ -41,10 +41,6 @@ mod imp {
|
||||||
#[derive(Debug, Default, CompositeTemplate)]
|
#[derive(Debug, Default, CompositeTemplate)]
|
||||||
#[template(resource = "/org/gnome/ImageViewer/gtk/image_view.ui")]
|
#[template(resource = "/org/gnome/ImageViewer/gtk/image_view.ui")]
|
||||||
pub struct IvImageView {
|
pub struct IvImageView {
|
||||||
#[template_child]
|
|
||||||
pub headerbar: TemplateChild<gtk::HeaderBar>,
|
|
||||||
#[template_child]
|
|
||||||
pub menu_button: TemplateChild<gtk::MenuButton>,
|
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub picture: TemplateChild<gtk::Picture>,
|
pub picture: TemplateChild<gtk::Picture>,
|
||||||
#[template_child]
|
#[template_child]
|
||||||
|
|
@ -54,9 +50,7 @@ mod imp {
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub press_gesture: TemplateChild<gtk::GestureLongPress>,
|
pub press_gesture: TemplateChild<gtk::GestureLongPress>,
|
||||||
|
|
||||||
// Cell<T> allows for interior mutability of primitive types
|
// RefCell<T> allows for interior mutability of non-primitive types.
|
||||||
pub header_visible: Cell<bool>,
|
|
||||||
// RefCell<T> does the same for non-primitive types.
|
|
||||||
pub menu_model: RefCell<Option<gio::MenuModel>>,
|
pub menu_model: RefCell<Option<gio::MenuModel>>,
|
||||||
pub popover_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>>,
|
pub filename: RefCell<Option<String>>,
|
||||||
// Path of filenames
|
// Path of filenames
|
||||||
pub directory_pictures: RefCell<Vec<String>>,
|
pub directory_pictures: RefCell<Vec<String>>,
|
||||||
|
// Cell<T> allows for interior mutability of primitive types
|
||||||
pub index: Cell<usize>,
|
pub index: Cell<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -94,20 +89,6 @@ mod imp {
|
||||||
fn properties() -> &'static [glib::ParamSpec] {
|
fn properties() -> &'static [glib::ParamSpec] {
|
||||||
static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
|
static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
|
||||||
vec![
|
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(
|
glib::ParamSpec::new_object(
|
||||||
"popover-menu-model",
|
"popover-menu-model",
|
||||||
"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 {
|
fn property(&self, _obj: &Self::Type, _id: usize, psec: &glib::ParamSpec) -> glib::Value {
|
||||||
match psec.name() {
|
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(),
|
"popover-menu-model" => self.popover_menu_model.borrow().to_value(),
|
||||||
"filename" => self.filename.borrow().to_value(),
|
"filename" => self.filename.borrow().to_value(),
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
|
|
@ -166,14 +145,6 @@ mod imp {
|
||||||
psec: &glib::ParamSpec,
|
psec: &glib::ParamSpec,
|
||||||
) {
|
) {
|
||||||
match psec.name() {
|
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" => {
|
"popover-menu-model" => {
|
||||||
let model: Option<gio::MenuModel> = value.get().unwrap();
|
let model: Option<gio::MenuModel> = value.get().unwrap();
|
||||||
self.popover.set_menu_model(model.as_ref());
|
self.popover.set_menu_model(model.as_ref());
|
||||||
|
|
|
||||||
|
|
@ -52,8 +52,14 @@ mod imp {
|
||||||
// TemplateChild<T> wrapper, where T is the
|
// TemplateChild<T> wrapper, where T is the
|
||||||
// object type of the template child.
|
// object type of the template child.
|
||||||
#[template_child]
|
#[template_child]
|
||||||
|
pub flap: TemplateChild<libadwaita::Flap>,
|
||||||
|
#[template_child]
|
||||||
pub headerbar: TemplateChild<gtk::HeaderBar>,
|
pub headerbar: TemplateChild<gtk::HeaderBar>,
|
||||||
#[template_child]
|
#[template_child]
|
||||||
|
pub menu_button: TemplateChild<gtk::MenuButton>,
|
||||||
|
#[template_child]
|
||||||
|
pub fullscreen_button: TemplateChild<gtk::Button>,
|
||||||
|
#[template_child]
|
||||||
pub stack: TemplateChild<gtk::Stack>,
|
pub stack: TemplateChild<gtk::Stack>,
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub status_page: TemplateChild<libadwaita::StatusPage>,
|
pub status_page: TemplateChild<libadwaita::StatusPage>,
|
||||||
|
|
@ -76,7 +82,7 @@ mod imp {
|
||||||
|
|
||||||
// Set up actions
|
// Set up actions
|
||||||
klass.install_action("win.toggle-fullscreen", None, move |win, _, _| {
|
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, _, _| {
|
klass.install_action("win.open", None, move |win, _, _| {
|
||||||
|
|
@ -163,6 +169,31 @@ impl IvWindow {
|
||||||
glib::Object::new(&[("application", app)]).expect("Failed to create 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) {
|
fn pick_file(&self) {
|
||||||
let chooser = gtk::FileChooserNative::new(
|
let chooser = gtk::FileChooserNative::new(
|
||||||
Some(&"Open Image".to_string()),
|
Some(&"Open Image".to_string()),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue