[fractal/wip/cdavis/next-style-cleanup: 5/6] components: Add RoomTitle component
- From: Christopher Davis <christopherdavis src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [fractal/wip/cdavis/next-style-cleanup: 5/6] components: Add RoomTitle component
- Date: Fri, 25 Jun 2021 21:23:02 +0000 (UTC)
commit 524873a7b85cb903c185da1482f24c62572ad84e
Author: Christopher Davis <christopherdavis gnome org>
Date: Fri Jun 25 13:49:18 2021 -0700
components: Add RoomTitle component
Adds a custom RoomTitle widget in place of AdwWindowTitle.
This will allow us to have markup in titles and subtitles,
and allow us to have tooltips set appropriately.
data/resources/resources.gresource.xml | 1 +
data/resources/ui/content-room-history.ui | 2 +-
data/resources/ui/room-title.ui | 43 +++++++++
src/components/mod.rs | 2 +
src/components/room_title.rs | 140 ++++++++++++++++++++++++++++++
src/meson.build | 1 +
src/session/content/room_history.rs | 3 +
7 files changed, 191 insertions(+), 1 deletion(-)
---
diff --git a/data/resources/resources.gresource.xml b/data/resources/resources.gresource.xml
index e3fa5bdb..2bde98bb 100644
--- a/data/resources/resources.gresource.xml
+++ b/data/resources/resources.gresource.xml
@@ -25,6 +25,7 @@
<file compressed="true" preprocess="xml-stripblanks" alias="window.ui">ui/window.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="context-menu-bin.ui">ui/context-menu-bin.ui</file>
<file compressed="true" preprocess="xml-stripblanks" alias="pill.ui">ui/pill.ui</file>
+ <file compressed="true" preprocess="xml-stripblanks" alias="room-title.ui">ui/room-title.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="spinner-button.ui">ui/spinner-button.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="in-app-notification.ui">ui/in-app-notification.ui</file>
<file compressed="true" preprocess="xml-stripblanks"
alias="components-avatar.ui">ui/components-avatar.ui</file>
diff --git a/data/resources/ui/content-room-history.ui b/data/resources/ui/content-room-history.ui
index 977d8238..cab3b0f0 100644
--- a/data/resources/ui/content-room-history.ui
+++ b/data/resources/ui/content-room-history.ui
@@ -31,7 +31,7 @@
</object>
</child>
<child type="title">
- <object class="AdwWindowTitle">
+ <object class="RoomTitle" id="room_title">
<binding name="title">
<lookup name="display-name">
<lookup name="room">ContentRoomHistory</lookup>
diff --git a/data/resources/ui/room-title.ui b/data/resources/ui/room-title.ui
new file mode 100644
index 00000000..366d5ae8
--- /dev/null
+++ b/data/resources/ui/room-title.ui
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <requires lib="gtk" version="4.0"/>
+ <template class="RoomTitle" parent="AdwBin">
+ <child>
+ <object class="GtkBox" id="box">
+ <property name="orientation">vertical</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <child>
+ <object class="GtkLabel" id="title_label">
+ <property name="ellipsize">end</property>
+ <property name="halign">center</property>
+ <property name="wrap">False</property>
+ <property name="single-line-mode">True</property>
+ <property name="use-markup">True</property>
+ <property name="width-chars">5</property>
+ <property name="label" bind-source="RoomTitle" bind-property="title" bind-flags="sync-create"/>
+ <property name="tooltip-markup" bind-source="RoomTitle" bind-property="title"
bind-flags="sync-create"/>
+ <style>
+ <class name="title"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel" id="subtitle_label">
+ <property name="ellipsize">end</property>
+ <property name="halign">center</property>
+ <property name="wrap">False</property>
+ <property name="single-line-mode">True</property>
+ <property name="use-markup">True</property>
+ <property name="visible">False</property>
+ <property name="label" bind-source="RoomTitle" bind-property="subtitle"
bind-flags="sync-create"/>
+ <property name="tooltip-markup" bind-source="RoomTitle" bind-property="subtitle"
bind-flags="sync-create"/>
+ <style>
+ <class name="subtitle"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/src/components/mod.rs b/src/components/mod.rs
index 7296e89d..5d2e3e74 100644
--- a/src/components/mod.rs
+++ b/src/components/mod.rs
@@ -3,6 +3,7 @@ mod context_menu_bin;
mod in_app_notification;
mod label_with_widgets;
mod pill;
+mod room_title;
mod spinner_button;
pub use self::avatar::Avatar;
@@ -10,4 +11,5 @@ pub use self::context_menu_bin::{ContextMenuBin, ContextMenuBinExt, ContextMenuB
pub use self::in_app_notification::InAppNotification;
pub use self::label_with_widgets::LabelWithWidgets;
pub use self::pill::Pill;
+pub use self::room_title::RoomTitle;
pub use self::spinner_button::SpinnerButton;
diff --git a/src/components/room_title.rs b/src/components/room_title.rs
new file mode 100644
index 00000000..26698a66
--- /dev/null
+++ b/src/components/room_title.rs
@@ -0,0 +1,140 @@
+use adw::subclass::prelude::*;
+use gtk::prelude::*;
+use gtk::subclass::prelude::*;
+use gtk::{glib, CompositeTemplate};
+
+mod imp {
+ use super::*;
+ use glib::subclass::InitializingObject;
+ use std::cell::RefCell;
+
+ #[derive(Debug, Default, CompositeTemplate)]
+ #[template(resource = "/org/gnome/FractalNext/room-title.ui")]
+ pub struct RoomTitle {
+ // The markup for the title
+ pub title: RefCell<Option<String>>,
+ // The markup for the subtitle
+ pub subtitle: RefCell<Option<String>>,
+ #[template_child]
+ pub title_label: TemplateChild<gtk::Label>,
+ #[template_child]
+ pub subtitle_label: TemplateChild<gtk::Label>,
+ }
+
+ #[glib::object_subclass]
+ impl ObjectSubclass for RoomTitle {
+ const NAME: &'static str = "RoomTitle";
+ type Type = super::RoomTitle;
+ type ParentType = adw::Bin;
+
+ fn class_init(klass: &mut Self::Class) {
+ Self::bind_template(klass);
+ }
+
+ fn instance_init(obj: &InitializingObject<Self>) {
+ obj.init_template();
+ }
+ }
+
+ impl ObjectImpl for RoomTitle {
+ fn properties() -> &'static [glib::ParamSpec] {
+ use once_cell::sync::Lazy;
+ static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
+ vec![
+ glib::ParamSpec::new_string(
+ "title",
+ "Title",
+ "The title of the room",
+ None,
+ glib::ParamFlags::READWRITE | glib::ParamFlags::EXPLICIT_NOTIFY,
+ ),
+ glib::ParamSpec::new_string(
+ "subtitle",
+ "Subtitle",
+ "The subtitle of the room",
+ None,
+ glib::ParamFlags::READWRITE | glib::ParamFlags::EXPLICIT_NOTIFY,
+ ),
+ ]
+ });
+
+ PROPERTIES.as_ref()
+ }
+
+ fn property(&self, obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
+ match pspec.name() {
+ "title" => obj.title().to_value(),
+ "subtitle" => obj.subtitle().to_value(),
+ _ => unimplemented!(),
+ }
+ }
+
+ fn set_property(
+ &self,
+ obj: &Self::Type,
+ _id: usize,
+ value: &glib::Value,
+ pspec: &glib::ParamSpec,
+ ) {
+ match pspec.name() {
+ "title" => obj.set_title(value.get().unwrap()),
+ "subtitle" => obj.set_subtitle(value.get().unwrap()),
+ _ => unimplemented!(),
+ }
+ }
+
+ fn constructed(&self, obj: &Self::Type) {
+ self.parent_constructed(obj);
+ }
+ }
+
+ impl WidgetImpl for RoomTitle {}
+ impl BinImpl for RoomTitle {}
+}
+
+glib::wrapper! {
+ pub struct RoomTitle(ObjectSubclass<imp::RoomTitle>)
+ @extends gtk::Widget, adw::Bin, @implements gtk::Accessible;
+}
+
+impl RoomTitle {
+ pub fn new() -> Self {
+ glib::Object::new(&[]).expect("Failed to create RoomTitle")
+ }
+
+ pub fn set_title(&self, title: Option<String>) {
+ let priv_ = imp::RoomTitle::from_instance(self);
+ // If there's an existing title, check that current title and new title aren't equal
+ if priv_.title.borrow().as_deref() != title.as_deref() {
+ priv_.title.replace(title);
+ priv_
+ .title_label
+ .set_visible(priv_.title.borrow().is_some());
+ }
+
+ self.notify("title");
+ }
+
+ pub fn title(&self) -> Option<String> {
+ let priv_ = imp::RoomTitle::from_instance(self);
+ priv_.title.borrow().clone()
+ }
+
+ pub fn set_subtitle(&self, subtitle: Option<String>) {
+ let priv_ = imp::RoomTitle::from_instance(self);
+ // If there's an existing subtitle, check that current subtitle and new subtitle aren't equal
+ if priv_.subtitle.borrow().as_deref() != subtitle.as_deref() {
+ priv_.subtitle.replace(subtitle);
+ priv_
+ .subtitle_label
+ .set_visible(priv_.subtitle.borrow().is_some());
+ }
+
+ self.notify("subtitle");
+ }
+
+ pub fn subtitle(&self) -> Option<String> {
+ let priv_ = imp::RoomTitle::from_instance(self);
+ priv_.subtitle.borrow().clone()
+ }
+}
diff --git a/src/meson.build b/src/meson.build
index db9f9599..b3e129b7 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -25,6 +25,7 @@ sources = files(
'components/label_with_widgets.rs',
'components/mod.rs',
'components/pill.rs',
+ 'components/room_title.rs',
'components/in_app_notification.rs',
'components/spinner_button.rs',
'config.rs',
diff --git a/src/session/content/room_history.rs b/src/session/content/room_history.rs
index d6c902c3..cb06ea94 100644
--- a/src/session/content/room_history.rs
+++ b/src/session/content/room_history.rs
@@ -1,3 +1,4 @@
+use crate::components::RoomTitle;
use crate::session::{content::ItemRow, content::MarkdownPopover, room::Room, room::RoomType};
use adw::subclass::prelude::*;
use gtk::{
@@ -22,6 +23,8 @@ mod imp {
#[template_child]
pub headerbar: TemplateChild<adw::HeaderBar>,
#[template_child]
+ pub room_title: TemplateChild<RoomTitle>,
+ #[template_child]
pub room_menu: TemplateChild<gtk::MenuButton>,
#[template_child]
pub listview: TemplateChild<gtk::ListView>,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]