Browse Source

Add base layout

merge-requests/1327/merge
Julian Sparber 5 years ago
parent
commit
9e8fa8aab5
  1. 2
      Cargo.toml
  2. 14
      data/resources.gresource.xml
  3. 52
      data/resources/icons/scalable/actions/send-symbolic.svg
  4. 14
      data/resources/style.css
  5. 88
      data/resources/ui/content.ui
  6. 18
      data/resources/ui/login.ui
  7. 19
      data/resources/ui/session.ui
  8. 56
      data/resources/ui/sidebar.ui
  9. 44
      data/resources/ui/window.ui
  10. 21
      src/application.rs
  11. 4
      src/main.rs
  12. 7
      src/meson.build
  13. 110
      src/widgets/content.rs
  14. 58
      src/widgets/login.rs
  15. 11
      src/widgets/mod.rs
  16. 63
      src/widgets/session.rs
  17. 110
      src/widgets/sidebar.rs
  18. 63
      src/widgets/window.rs

2
Cargo.toml

@ -17,6 +17,6 @@ git = "https://github.com/gtk-rs/gtk4-rs"
# We need to use the same version as libadwaita does
#rev = "abea0c9980bc083494eceb30dfab5eeb99a73118"
[dependencies.libadwaita]
[dependencies.adw]
package = "libadwaita"
git = "https://gitlab.gnome.org/bilelmoussaoui/libadwaita-rs.git"

14
data/resources.gresource.xml

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/FractalNext/">
<file compressed="true" preprocess="xml-stripblanks" alias="shortcuts.ui">resources/ui/shortcuts.ui</file>
<file compressed="true" preprocess="xml-stripblanks" alias="content.ui">resources/ui/content.ui</file>
<file compressed="true" preprocess="xml-stripblanks" alias="login.ui">resources/ui/login.ui</file>
<file compressed="true" preprocess="xml-stripblanks" alias="session.ui">resources/ui/session.ui</file>
<file compressed="true" preprocess="xml-stripblanks" alias="sidebar.ui">resources/ui/sidebar.ui</file>
<file compressed="true" preprocess="xml-stripblanks" alias="window.ui">resources/ui/window.ui</file>
<file compressed="true" alias="style.css">resources/style.css</file>
<file preprocess="xml-stripblanks" alias="icons/scalable/actions/send-symbolic.svg">resources/icons/scalable/actions/send-symbolic.svg</file>
</gresource>
</gresources>

52
data/resources/icons/scalable/actions/send-symbolic.svg

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
height="16"
id="svg7384"
version="1.1"
width="16">
<metadata
id="metadata90">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Gnome Symbolic Icon Theme</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<title
id="title9167">Gnome Symbolic Icon Theme</title>
<defs
id="defs7386">
<linearGradient
id="linearGradient7212"
osb:paint="solid">
<stop
id="stop7214"
offset="0"
style="stop-color:#000000;stop-opacity:1;" />
</linearGradient>
</defs>
<g
id="layer9"
style="display:inline"
transform="translate(-323.0002,125)">
<g
style="enable-background:new"
id="g876"
transform="translate(311.00017,-893)">
<path
id="path20012"
d="m 12.999904,769 14.000126,7.00002 -14.000126,6.99999 v -6 L 22.000471,776.00002 12.999904,775 Z"
style="fill:#241f31;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

14
data/resources/style.css

@ -1,4 +1,16 @@
.title-header{
.title-header {
font-size: 36px;
font-weight: bold;
}
.content {
background-color: @theme_base_color;
}
.content:backdrop {
background-color: @theme_unfocused_base_color;
}
.send-message-area {
margin: 6px;
}

88
data/resources/ui/content.ui

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="FrctlContent" parent="AdwBin">
<property name="vexpand">True</property>
<property name="hexpand">True</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="AdwHeaderBar" id="headerbar">
<property name="show-start-title-buttons" bind-source="FrctlContent" bind-property="compact" bind-flags="sync-create" />
<child type="end">
<object class="GtkMenuButton" id="room_menu">
<property name="icon-name">view-more-symbolic</property>
</object>
</child>
<child type="end">
<object class="GtkToggleButton" id="search_content_button">
<property name="icon-name">system-search-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkSearchBar" id="room_search">
<property name="search-mode-enabled" bind-source="search_content_button" bind-property="active" />
<property name="child">
<object class="AdwClamp">
<property name="hexpand">True</property>
<child>
<object class="GtkSearchEntry"/>
</child>
</object>
</property>
</object>
</child>
<child>
<object class="AdwClamp">
<property name="vexpand">True</property>
<property name="hexpand">True</property>
<style>
<class name="content"/>
</style>
<child>
<object class="GtkListView" id="room_history">
</object>
</child>
</object>
</child>
<child>
<object class="GtkSeparator" />
</child>
<child>
<object class="AdwClamp">
<child>
<object class="GtkBox">
<property name="spacing">6</property>
<style>
<class name="send-message-area"/>
</style>
<child>
<object class="GtkButton">
<property name="icon-name">mail-attachment-symbolic</property>
</object>
</child>
<child>
<object class="GtkButton">
<property name="icon-name">format-justify-left-symbolic</property>
</object>
</child>
<child>
<object class="GtkEntry" id="message_entry">
<property name="hexpand">True</property>
</object>
</child>
<child>
<object class="GtkButton">
<property name="icon-name">send-symbolic</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</template>
</interface>

18
data/resources/ui/login.ui

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="FrctlLogin" parent="AdwBin">
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkHeaderBar" id="headerbar" />
</child>
<child>
<object class="AdwStatusPage">
<!-- TODO implement login -->
</object>
</child>
</object>
</child>
</template>
</interface>

19
data/resources/ui/session.ui

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="FrctlSession" parent="AdwBin">
<child>
<object class="AdwLeaflet" id="session">
<child>
<object class="FrctlSidebar" id="sidebar">
<property name="compact" bind-source="session" bind-property="folded" bind-flags="sync-create" />
</object>
</child>
<child>
<object class="FrctlContent" id="content">
<property name="compact" bind-source="session" bind-property="folded" bind-flags="sync-create" />
</object>
</child>
</object>
</child>
</template>
</interface>

56
data/resources/ui/sidebar.ui

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id="primary_menu">
<section>
<item>
<attribute name="label" translatable="yes">_Preferences</attribute>
<attribute name="action">app.preferences</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Keyboard Shortcuts</attribute>
<attribute name="action">win.show-help-overlay</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_About Fractal</attribute>
<attribute name="action">app.about</attribute>
</item>
</section>
</menu>
<template class="FrctlSidebar" parent="AdwBin">
<style>
<class name="sidebar"/>
</style>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="AdwHeaderBar" id="headerbar">
<property name="show-end-title-buttons" bind-source="FrctlSidebar" bind-property="compact" bind-flags="sync-create" />
<child type="start">
<object class="GtkToggleButton" id="search_button">
<property name="icon-name">system-search-symbolic</property>
</object>
</child>
<child type="end">
<object class="GtkMenuButton" id="appmenu_button">
<property name="icon-name">open-menu-symbolic</property>
<property name="menu-model">primary_menu</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkSearchBar" id="room_search">
<property name="search-mode-enabled" bind-source="search_button" bind-property="active" />
<property name="child">
<object class="GtkSearchEntry"/>
</property>
</object>
</child>
<child>
<object class="GtkListView" id="listview" />
</child>
</object>
</child>
</template>
</interface>

44
data/resources/ui/window.ui

@ -1,39 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id="primary_menu">
<section>
<item>
<attribute name="label" translatable="yes">_Preferences</attribute>
<attribute name="action">app.preferences</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Keyboard Shortcuts</attribute>
<attribute name="action">win.show-help-overlay</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_About GTK Rust Template</attribute>
<attribute name="action">app.about</attribute>
</item>
</section>
</menu>
<template class="ExampleApplicationWindow" parent="GtkApplicationWindow">
<template class="FrctlWindow" parent="AdwApplicationWindow">
<property name="default-width">600</property>
<property name="default-height">400</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="headerbar">
<child type="end">
<object class="GtkMenuButton" id="appmenu_button">
<property name="icon-name">open-menu-symbolic</property>
<property name="menu-model">primary_menu</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel" id="label">
<property name="label" translatable="yes">Hello world!</property>
<style>
<class name="title-header"/>
</style>
<object class="GtkStack" id="main_stack">
<property name="visible-child">session</property>
<property name="transition-type">crossfade</property>
<child>
<object class="FrctlLogin" id="login" />
</child>
<!-- We currently only support one session, add other sessions to the main_Stack -->
<child>
<object class="FrctlSession" id="session" />
</child>
</object>
</child>
</template>

21
src/application.rs

@ -1,5 +1,5 @@
use crate::config;
use crate::window::ExampleApplicationWindow;
use crate::widgets::FrctlWindow;
use gio::ApplicationFlags;
use glib::clone;
use glib::WeakRef;
@ -17,7 +17,7 @@ mod imp {
#[derive(Debug)]
pub struct ExampleApplication {
pub window: OnceCell<WeakRef<ExampleApplicationWindow>>,
pub window: OnceCell<WeakRef<FrctlWindow>>,
}
impl ObjectSubclass for ExampleApplication {
@ -43,8 +43,7 @@ mod imp {
fn activate(&self, app: &Self::Type) {
debug!("GtkApplication<ExampleApplication>::activate");
let priv_ = ExampleApplication::from_instance(app);
if let Some(window) = priv_.window.get() {
if let Some(window) = self.window.get() {
let window = window.upgrade().unwrap();
window.show();
window.present();
@ -54,7 +53,7 @@ mod imp {
app.set_resource_base_path(Some("/org/gnome/FractalNext/"));
app.setup_css();
let window = ExampleApplicationWindow::new(app);
let window = FrctlWindow::new(app);
self.window
.set(window.downgrade())
.expect("Window already set.");
@ -83,14 +82,18 @@ impl ExampleApplication {
pub fn new() -> Self {
glib::Object::new(&[
("application-id", &Some(config::APP_ID)),
("flags", &ApplicationFlags::empty()),
("flags", &ApplicationFlags::default()),
])
.expect("Application initialization failed...")
}
fn get_main_window(&self) -> ExampleApplicationWindow {
let priv_ = imp::ExampleApplication::from_instance(self);
priv_.window.get().unwrap().upgrade().unwrap()
fn get_main_window(&self) -> FrctlWindow {
imp::ExampleApplication::from_instance(self)
.window
.get()
.unwrap()
.upgrade()
.unwrap()
}
fn setup_gactions(&self) {

4
src/main.rs

@ -1,8 +1,9 @@
mod application;
#[rustfmt::skip]
mod config;
mod window;
mod widgets;
use adw;
use application::ExampleApplication;
use config::{GETTEXT_PACKAGE, LOCALEDIR, RESOURCES_FILE};
use gettextrs::*;
@ -23,6 +24,7 @@ fn main() {
gtk::glib::set_prgname(Some("fractal"));
gtk::init().expect("Unable to start GTK4");
adw::init();
let res = gio::Resource::load(RESOURCES_FILE).expect("Could not load gresource file");
gio::resources_register(&res);

7
src/meson.build

@ -22,7 +22,12 @@ sources = files(
'application.rs',
'config.rs',
'main.rs',
'window.rs',
'widgets/window.rs',
'widgets/content.rs',
'widgets/sidebar.rs',
'widgets/login.rs',
'widgets/mod.rs',
'widgets/session.rs',
)
custom_target(

110
src/widgets/content.rs

@ -0,0 +1,110 @@
use adw;
use adw::subclass::prelude::BinImpl;
use gtk::subclass::prelude::*;
use gtk::{self, prelude::*};
use gtk::{glib, CompositeTemplate};
mod imp {
use super::*;
use glib::subclass;
use std::cell::Cell;
#[derive(Debug, CompositeTemplate)]
#[template(resource = "/org/gnome/FractalNext/content.ui")]
pub struct FrctlContent {
pub compact: Cell<bool>,
#[template_child]
pub headerbar: TemplateChild<adw::HeaderBar>,
#[template_child]
pub room_history: TemplateChild<gtk::ListView>,
}
impl ObjectSubclass for FrctlContent {
const NAME: &'static str = "FrctlContent";
type Type = super::FrctlContent;
type ParentType = adw::Bin;
type Interfaces = ();
type Instance = subclass::simple::InstanceStruct<Self>;
type Class = subclass::simple::ClassStruct<Self>;
glib::object_subclass!();
fn new() -> Self {
Self {
compact: Cell::new(false),
headerbar: TemplateChild::default(),
room_history: TemplateChild::default(),
}
}
fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
}
// You must call `Widget`'s `init_template()` within `instance_init()`.
fn instance_init(obj: &glib::subclass::InitializingObject<Self::Type>) {
obj.init_template();
}
}
impl ObjectImpl for FrctlContent {
fn properties() -> &'static [glib::ParamSpec] {
use once_cell::sync::Lazy;
static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
vec![glib::ParamSpec::boolean(
"compact",
"Compact",
"Wheter a compact view is used or not",
false,
glib::ParamFlags::READWRITE,
)]
});
PROPERTIES.as_ref()
}
fn set_property(
&self,
_obj: &Self::Type,
_id: usize,
value: &glib::Value,
pspec: &glib::ParamSpec,
) {
match pspec.get_name() {
"compact" => {
let compact = value
.get()
.expect("type conformity checked by `Object::set_property`");
self.compact.set(compact.unwrap());
}
_ => unimplemented!(),
}
}
fn get_property(
&self,
_obj: &Self::Type,
_id: usize,
pspec: &glib::ParamSpec,
) -> glib::Value {
match pspec.get_name() {
"compact" => self.compact.get().to_value(),
_ => unimplemented!(),
}
}
}
impl WidgetImpl for FrctlContent {}
impl BinImpl for FrctlContent {}
}
glib::wrapper! {
pub struct FrctlContent(ObjectSubclass<imp::FrctlContent>)
@extends gtk::Widget, adw::Bin, @implements gtk::Accessible;
}
impl FrctlContent {
pub fn new() -> Self {
glib::Object::new(&[]).expect("Failed to create FrctlContent")
}
}

58
src/widgets/login.rs

@ -0,0 +1,58 @@
use adw;
use adw::subclass::prelude::BinImpl;
use gtk::subclass::prelude::*;
use gtk::{self, prelude::*};
use gtk::{glib, CompositeTemplate};
mod imp {
use super::*;
use glib::subclass;
#[derive(Debug, CompositeTemplate)]
#[template(resource = "/org/gnome/FractalNext/login.ui")]
pub struct FrctlLogin {
#[template_child]
pub headerbar: TemplateChild<gtk::HeaderBar>,
}
impl ObjectSubclass for FrctlLogin {
const NAME: &'static str = "FrctlLogin";
type Type = super::FrctlLogin;
type ParentType = adw::Bin;
type Interfaces = ();
type Instance = subclass::simple::InstanceStruct<Self>;
type Class = subclass::simple::ClassStruct<Self>;
glib::object_subclass!();
fn new() -> Self {
Self {
headerbar: TemplateChild::default(),
}
}
fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
}
// You must call `Widget`'s `init_template()` within `instance_init()`.
fn instance_init(obj: &glib::subclass::InitializingObject<Self::Type>) {
obj.init_template();
}
}
impl ObjectImpl for FrctlLogin {}
impl WidgetImpl for FrctlLogin {}
impl BinImpl for FrctlLogin {}
}
glib::wrapper! {
pub struct FrctlLogin(ObjectSubclass<imp::FrctlLogin>)
@extends gtk::Widget, adw::Bin, @implements gtk::Accessible;
}
impl FrctlLogin {
pub fn new() -> Self {
glib::Object::new(&[]).expect("Failed to create FrctlLogin")
}
}

11
src/widgets/mod.rs

@ -0,0 +1,11 @@
mod content;
mod login;
mod session;
mod sidebar;
mod window;
pub use crate::widgets::content::FrctlContent;
pub use crate::widgets::login::FrctlLogin;
pub use crate::widgets::session::FrctlSession;
pub use crate::widgets::sidebar::FrctlSidebar;
pub use crate::widgets::window::FrctlWindow;

63
src/widgets/session.rs

@ -0,0 +1,63 @@
use crate::widgets::FrctlContent;
use crate::widgets::FrctlSidebar;
use adw;
use adw::subclass::prelude::BinImpl;
use gtk::subclass::prelude::*;
use gtk::{self, prelude::*};
use gtk::{glib, CompositeTemplate};
mod imp {
use super::*;
use glib::subclass;
#[derive(Debug, CompositeTemplate)]
#[template(resource = "/org/gnome/FractalNext/session.ui")]
pub struct FrctlSession {
#[template_child]
pub sidebar: TemplateChild<FrctlSidebar>,
#[template_child]
pub content: TemplateChild<FrctlContent>,
}
impl ObjectSubclass for FrctlSession {
const NAME: &'static str = "FrctlSession";
type Type = super::FrctlSession;
type ParentType = adw::Bin;
type Interfaces = ();
type Instance = subclass::simple::InstanceStruct<Self>;
type Class = subclass::simple::ClassStruct<Self>;
glib::object_subclass!();
fn new() -> Self {
Self {
sidebar: TemplateChild::default(),
content: TemplateChild::default(),
}
}
fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
}
// You must call `Widget`'s `init_template()` within `instance_init()`.
fn instance_init(obj: &glib::subclass::InitializingObject<Self::Type>) {
obj.init_template();
}
}
impl ObjectImpl for FrctlSession {}
impl WidgetImpl for FrctlSession {}
impl BinImpl for FrctlSession {}
}
glib::wrapper! {
pub struct FrctlSession(ObjectSubclass<imp::FrctlSession>)
@extends gtk::Widget, adw::Bin, @implements gtk::Accessible;
}
impl FrctlSession {
pub fn new() -> Self {
glib::Object::new(&[]).expect("Failed to create FrctlSession")
}
}

110
src/widgets/sidebar.rs

@ -0,0 +1,110 @@
use adw;
use adw::subclass::prelude::BinImpl;
use gtk::subclass::prelude::*;
use gtk::{self, prelude::*};
use gtk::{glib, CompositeTemplate};
mod imp {
use super::*;
use glib::subclass;
use std::cell::Cell;
#[derive(Debug, CompositeTemplate)]
#[template(resource = "/org/gnome/FractalNext/sidebar.ui")]
pub struct FrctlSidebar {
pub compact: Cell<bool>,
#[template_child]
pub headerbar: TemplateChild<adw::HeaderBar>,
#[template_child]
pub listview: TemplateChild<gtk::ListView>,
}
impl ObjectSubclass for FrctlSidebar {
const NAME: &'static str = "FrctlSidebar";
type Type = super::FrctlSidebar;
type ParentType = adw::Bin;
type Interfaces = ();
type Instance = subclass::simple::InstanceStruct<Self>;
type Class = subclass::simple::ClassStruct<Self>;
glib::object_subclass!();
fn new() -> Self {
Self {
compact: Cell::new(false),
listview: TemplateChild::default(),
headerbar: TemplateChild::default(),
}
}
fn class_init(klass: &mut Self::Class) {
Self::bind_template(klass);
}
// You must call `Widget`'s `init_template()` within `instance_init()`.
fn instance_init(obj: &glib::subclass::InitializingObject<Self::Type>) {
obj.init_template();
}
}
impl ObjectImpl for FrctlSidebar {
fn properties() -> &'static [glib::ParamSpec] {
use once_cell::sync::Lazy;
static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
vec![glib::ParamSpec::boolean(
"compact",
"Compact",
"Wheter a compact view is used or not",
false,
glib::ParamFlags::READWRITE,
)]
});
PROPERTIES.as_ref()
}
fn set_property(
&self,
_obj: &Self::Type,
_id: usize,
value: &glib::Value,
pspec: &glib::ParamSpec,
) {
match pspec.get_name() {
"compact" => {
let compact = value
.get()
.expect("type conformity checked by `Object::set_property`");
self.compact.set(compact.unwrap());
}
_ => unimplemented!(),
}
}
fn get_property(
&self,
_obj: &Self::Type,
_id: usize,
pspec: &glib::ParamSpec,
) -> glib::Value {
match pspec.get_name() {
"compact" => self.compact.get().to_value(),
_ => unimplemented!(),
}
}
}
impl WidgetImpl for FrctlSidebar {}
impl BinImpl for FrctlSidebar {}
}
glib::wrapper! {
pub struct FrctlSidebar(ObjectSubclass<imp::FrctlSidebar>)
@extends gtk::Widget, adw::Bin, @implements gtk::Accessible;
}
impl FrctlSidebar {
pub fn new() -> Self {
glib::Object::new(&[]).expect("Failed to create FrctlSidebar")
}
}

63
src/window.rs → src/widgets/window.rs

@ -1,5 +1,8 @@
use crate::application::ExampleApplication;
use crate::config::{APP_ID, PROFILE};
use crate::widgets::FrctlLogin;
use crate::widgets::FrctlSession;
use adw::subclass::prelude::AdwApplicationWindowImpl;
use glib::signal::Inhibit;
use gtk::subclass::prelude::*;
use gtk::{self, prelude::*};
@ -12,16 +15,22 @@ mod imp {
#[derive(Debug, CompositeTemplate)]
#[template(resource = "/org/gnome/FractalNext/window.ui")]
pub struct ExampleApplicationWindow {
pub struct FrctlWindow {
#[template_child]
pub headerbar: TemplateChild<gtk::HeaderBar>,
pub main_stack: TemplateChild<gtk::Stack>,
#[template_child]
pub login: TemplateChild<FrctlLogin>,
// Eventually we want to create the session dynamically, since we want multi account
// support
#[template_child]
pub session: TemplateChild<FrctlSession>,
pub settings: gio::Settings,
}
impl ObjectSubclass for ExampleApplicationWindow {
const NAME: &'static str = "ExampleApplicationWindow";
type Type = super::ExampleApplicationWindow;
type ParentType = gtk::ApplicationWindow;
impl ObjectSubclass for FrctlWindow {
const NAME: &'static str = "FrctlWindow";
type Type = super::FrctlWindow;
type ParentType = adw::ApplicationWindow;
type Interfaces = ();
type Instance = subclass::simple::InstanceStruct<Self>;
type Class = subclass::simple::ClassStruct<Self>;
@ -30,7 +39,9 @@ mod imp {
fn new() -> Self {
Self {
headerbar: TemplateChild::default(),
main_stack: TemplateChild::default(),
login: TemplateChild::default(),
session: TemplateChild::default(),
settings: gio::Settings::new(APP_ID),
}
}
@ -45,7 +56,7 @@ mod imp {
}
}
impl ObjectImpl for ExampleApplicationWindow {
impl ObjectImpl for FrctlWindow {
fn constructed(&self, obj: &Self::Type) {
self.parent_constructed(obj);
@ -55,7 +66,7 @@ mod imp {
// Devel Profile
if PROFILE == "Devel" {
obj.get_style_context().add_class("devel");
obj.add_css_class("devel");
}
// load latest window state
@ -63,7 +74,7 @@ mod imp {
}
}
impl WindowImpl for ExampleApplicationWindow {
impl WindowImpl for FrctlWindow {
// save window state on delete event
fn close_request(&self, obj: &Self::Type) -> Inhibit {
if let Err(err) = obj.save_window_size() {
@ -73,29 +84,24 @@ mod imp {
}
}
impl WidgetImpl for ExampleApplicationWindow {}
impl ApplicationWindowImpl for ExampleApplicationWindow {}
impl WidgetImpl for FrctlWindow {}
impl ApplicationWindowImpl for FrctlWindow {}
impl AdwApplicationWindowImpl for FrctlWindow {}
}
glib::wrapper! {
pub struct ExampleApplicationWindow(ObjectSubclass<imp::ExampleApplicationWindow>)
@extends gtk::Widget, gtk::Window, gtk::ApplicationWindow, @implements gio::ActionMap, gio::ActionGroup;
pub struct FrctlWindow(ObjectSubclass<imp::FrctlWindow>)
@extends gtk::Widget, gtk::Window, gtk::ApplicationWindow, adw::ApplicationWindow, @implements gio::ActionMap, gio::ActionGroup;
}
impl ExampleApplicationWindow {
pub fn new(app: &ExampleApplication) -> Self {
let window: Self =
glib::Object::new(&[]).expect("Failed to create ExampleApplicationWindow");
window.set_application(Some(app));
// Set icons for shell
gtk::Window::set_default_icon_name(APP_ID);
window
impl FrctlWindow {
pub fn new(app: &FrctlApplication) -> Self {
glib::Object::new(&[("application", &Some(app)), ("icon-name", &Some(APP_ID))])
.expect("Failed to create FrctlWindow")
}
pub fn save_window_size(&self) -> Result<(), glib::BoolError> {
let settings = &imp::ExampleApplicationWindow::from_instance(self).settings;
let settings = &imp::FrctlWindow::from_instance(self).settings;
let size = self.get_default_size();
@ -108,16 +114,13 @@ impl ExampleApplicationWindow {
}
fn load_window_size(&self) {
let settings = &imp::ExampleApplicationWindow::from_instance(self).settings;
let settings = &imp::FrctlWindow::from_instance(self).settings;
let width = settings.get_int("window-width");
let height = settings.get_int("window-height");
let is_maximized = settings.get_boolean("is-maximized");
self.set_default_size(width, height);
if is_maximized {
self.maximize();
}
self.set_property_maximized(is_maximized);
}
}
Loading…
Cancel
Save