[fractal/fractal-next] components: Create ButtonRow
- From: Julian Sparber <jsparber src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [fractal/fractal-next] components: Create ButtonRow
- Date: Fri, 25 Feb 2022 09:48:44 +0000 (UTC)
commit 577f582b6e71a1ea88c89cea064c004ea5bb597f
Author: Kévin Commaille <zecakeh tedomum fr>
Date: Sun Feb 13 14:20:38 2022 +0100
components: Create ButtonRow
data/resources/resources.gresource.xml | 1 +
data/resources/style.css | 4 +
data/resources/ui/components-button-row.ui | 32 +++++++
src/components/button_row.rs | 144 +++++++++++++++++++++++++++++
src/components/mod.rs | 2 +
5 files changed, 183 insertions(+)
---
diff --git a/data/resources/resources.gresource.xml b/data/resources/resources.gresource.xml
index c43246189..8150002c1 100644
--- a/data/resources/resources.gresource.xml
+++ b/data/resources/resources.gresource.xml
@@ -20,6 +20,7 @@
<file compressed="true" preprocess="xml-stripblanks"
alias="components-audio-player.ui">ui/components-audio-player.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="components-auth-dialog.ui">ui/components-auth-dialog.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="components-avatar.ui">ui/components-avatar.ui</file>
+ <file compressed="true" preprocess="xml-stripblanks"
alias="components-button-row.ui">ui/components-button-row.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="components-editable-avatar.ui">ui/components-editable-avatar.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="components-entry-row.ui">ui/components-entry-row.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="components-loading-listbox-row.ui">ui/components-loading-listbox-row.ui</file>
diff --git a/data/resources/style.css b/data/resources/style.css
index 2725cc6e3..335667d63 100644
--- a/data/resources/style.css
+++ b/data/resources/style.css
@@ -166,6 +166,10 @@ row.entry.error levelbar.discrete block.filled {
background-color: @error_color;
}
+row .heading {
+ font-weight: 600;
+}
+
/* Login */
diff --git a/data/resources/ui/components-button-row.ui b/data/resources/ui/components-button-row.ui
new file mode 100644
index 000000000..e24531431
--- /dev/null
+++ b/data/resources/ui/components-button-row.ui
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="ComponentsButtonRow" parent="AdwPreferencesRow">
+ <property name="activatable">true</property>
+ <property name="selectable">false</property>
+ <child>
+ <object class="GtkBox">
+ <style>
+ <class name="header"/>
+ </style>
+ <property name="spacing">6</property>
+ <property name="valign">center</property>
+ <property name="halign">center</property>
+ <child>
+ <object class="GtkLabel">
+ <style>
+ <class name="heading"/>
+ </style>
+ <property name="label" bind-source="ComponentsButtonRow" bind-property="title"
bind-flags="sync-create"/>
+ <property name="ellipsize">end</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImage">
+ <property name="visible" bind-source="ComponentsButtonRow" bind-property="to-subpage"
bind-flags="sync-create"/>
+ <property name="icon-name">go-next-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/src/components/button_row.rs b/src/components/button_row.rs
new file mode 100644
index 000000000..d5db93038
--- /dev/null
+++ b/src/components/button_row.rs
@@ -0,0 +1,144 @@
+use adw::subclass::prelude::*;
+use gtk::{
+ glib,
+ glib::{clone, closure_local},
+ prelude::*,
+ subclass::prelude::*,
+ CompositeTemplate,
+};
+
+mod imp {
+ use std::cell::Cell;
+
+ use glib::subclass::{InitializingObject, Signal};
+ use once_cell::sync::Lazy;
+
+ use super::*;
+
+ #[derive(Debug, Default, CompositeTemplate)]
+ #[template(resource = "/org/gnome/FractalNext/components-button-row.ui")]
+ pub struct ButtonRow {
+ /// Whether activating this button opens a subpage.
+ pub to_subpage: Cell<bool>,
+ }
+
+ #[glib::object_subclass]
+ impl ObjectSubclass for ButtonRow {
+ const NAME: &'static str = "ComponentsButtonRow";
+ type Type = super::ButtonRow;
+ type ParentType = adw::PreferencesRow;
+
+ fn class_init(klass: &mut Self::Class) {
+ Self::bind_template(klass);
+ }
+
+ fn instance_init(obj: &InitializingObject<Self>) {
+ obj.init_template();
+ }
+ }
+
+ impl ObjectImpl for ButtonRow {
+ fn signals() -> &'static [Signal] {
+ static SIGNALS: Lazy<Vec<Signal>> = Lazy::new(|| {
+ vec![Signal::builder("activated", &[], <()>::static_type().into()).build()]
+ });
+ SIGNALS.as_ref()
+ }
+
+ fn properties() -> &'static [glib::ParamSpec] {
+ static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
+ vec![glib::ParamSpecBoolean::new(
+ "to-subpage",
+ "To Subpage",
+ "Whether activating this button opens a subpage",
+ false,
+ glib::ParamFlags::READWRITE | glib::ParamFlags::EXPLICIT_NOTIFY,
+ )]
+ });
+
+ PROPERTIES.as_ref()
+ }
+
+ fn set_property(
+ &self,
+ obj: &Self::Type,
+ _id: usize,
+ value: &glib::Value,
+ pspec: &glib::ParamSpec,
+ ) {
+ match pspec.name() {
+ "to-subpage" => obj.set_to_subpage(value.get().unwrap()),
+ _ => unimplemented!(),
+ }
+ }
+
+ fn property(&self, obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
+ match pspec.name() {
+ "to-subpage" => obj.to_subpage().to_value(),
+ _ => unimplemented!(),
+ }
+ }
+
+ fn constructed(&self, obj: &Self::Type) {
+ self.parent_constructed(obj);
+
+ obj.connect_parent_notify(|obj| {
+ if let Some(listbox) = obj
+ .parent()
+ .as_ref()
+ .and_then(|parent| parent.downcast_ref::<gtk::ListBox>())
+ {
+ listbox.connect_row_activated(clone!(@weak obj => move |_, row| {
+ if row == obj.upcast_ref::<gtk::ListBoxRow>() {
+ obj.emit_by_name::<()>("activated", &[]);
+ }
+ }));
+ }
+ });
+ }
+ }
+ impl WidgetImpl for ButtonRow {}
+ impl ListBoxRowImpl for ButtonRow {}
+ impl PreferencesRowImpl for ButtonRow {}
+}
+
+glib::wrapper! {
+ /// An `AdwPreferencesRow` usable as a button.
+ pub struct ButtonRow(ObjectSubclass<imp::ButtonRow>)
+ @extends gtk::Widget, gtk::ListBoxRow, adw::PreferencesRow, @implements gtk::Accessible;
+}
+
+impl ButtonRow {
+ pub fn new() -> Self {
+ glib::Object::new(&[]).expect("Failed to create ButtonRow")
+ }
+
+ pub fn to_subpage(&self) -> bool {
+ self.imp().to_subpage.get()
+ }
+
+ pub fn set_to_subpage(&self, to_subpage: bool) {
+ if self.to_subpage() == to_subpage {
+ return;
+ }
+
+ self.imp().to_subpage.replace(to_subpage);
+ self.notify("to-subpage");
+ }
+
+ pub fn connect_activated<F: Fn(&Self) + 'static>(&self, f: F) -> glib::SignalHandlerId {
+ self.connect_closure(
+ "activated",
+ true,
+ closure_local!(move |obj: Self| {
+ f(&obj);
+ }),
+ )
+ }
+}
+
+impl Default for ButtonRow {
+ fn default() -> Self {
+ Self::new()
+ }
+}
diff --git a/src/components/mod.rs b/src/components/mod.rs
index fbc952162..4a7118ca9 100644
--- a/src/components/mod.rs
+++ b/src/components/mod.rs
@@ -3,6 +3,7 @@ mod audio_player;
mod auth_dialog;
mod avatar;
mod badge;
+mod button_row;
mod context_menu_bin;
mod custom_entry;
mod editable_avatar;
@@ -25,6 +26,7 @@ pub use self::{
auth_dialog::{AuthData, AuthDialog, AuthError},
avatar::Avatar,
badge::Badge,
+ button_row::ButtonRow,
context_menu_bin::{ContextMenuBin, ContextMenuBinExt, ContextMenuBinImpl},
custom_entry::CustomEntry,
editable_avatar::EditableAvatar,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]