Browse Source
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.merge-requests/1327/merge
7 changed files with 190 additions and 1 deletions
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<interface> |
||||
<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> |
||||
@ -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() |
||||
} |
||||
} |
||||
Loading…
Reference in new issue