You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
4.1 KiB
133 lines
4.1 KiB
use adw::{prelude::*, subclass::prelude::*}; |
|
use gtk::{glib, glib::clone}; |
|
|
|
use crate::utils::bool_to_accessible_tristate; |
|
|
|
mod imp { |
|
use std::{cell::Cell, marker::PhantomData}; |
|
|
|
use glib::subclass::InitializingObject; |
|
|
|
use super::*; |
|
|
|
#[derive(Debug, Default, gtk::CompositeTemplate, glib::Properties)] |
|
#[template(resource = "/org/gnome/Fractal/ui/components/rows/switch_loading_row.ui")] |
|
#[properties(wrapper_type = super::SwitchLoadingRow)] |
|
pub struct SwitchLoadingRow { |
|
#[template_child] |
|
spinner: TemplateChild<adw::Spinner>, |
|
#[template_child] |
|
switch: TemplateChild<gtk::Switch>, |
|
/// Whether the switch is active. |
|
#[property(get = Self::is_active, set = Self::set_is_active)] |
|
is_active: PhantomData<bool>, |
|
/// Whether the row is loading. |
|
#[property(get = Self::is_loading, set = Self::set_is_loading)] |
|
is_loading: PhantomData<bool>, |
|
/// Whether the row is read-only. |
|
#[property(get, set = Self::set_read_only, explicit_notify)] |
|
read_only: Cell<bool>, |
|
} |
|
|
|
#[glib::object_subclass] |
|
impl ObjectSubclass for SwitchLoadingRow { |
|
const NAME: &'static str = "SwitchLoadingRow"; |
|
type Type = super::SwitchLoadingRow; |
|
type ParentType = adw::ActionRow; |
|
|
|
fn class_init(klass: &mut Self::Class) { |
|
Self::bind_template(klass); |
|
|
|
klass.set_accessible_role(gtk::AccessibleRole::Switch); |
|
} |
|
|
|
fn instance_init(obj: &InitializingObject<Self>) { |
|
obj.init_template(); |
|
} |
|
} |
|
|
|
#[glib::derived_properties] |
|
impl ObjectImpl for SwitchLoadingRow { |
|
fn constructed(&self) { |
|
self.parent_constructed(); |
|
let obj = self.obj(); |
|
|
|
self.switch.connect_active_notify(clone!( |
|
#[weak] |
|
obj, |
|
move |switch| { |
|
obj.update_state(&[gtk::accessible::State::Checked( |
|
bool_to_accessible_tristate(switch.is_active()), |
|
)]); |
|
obj.notify_is_active(); |
|
} |
|
)); |
|
obj.update_state(&[gtk::accessible::State::Checked( |
|
bool_to_accessible_tristate(self.switch.is_active()), |
|
)]); |
|
} |
|
} |
|
|
|
impl WidgetImpl for SwitchLoadingRow {} |
|
impl ListBoxRowImpl for SwitchLoadingRow {} |
|
impl PreferencesRowImpl for SwitchLoadingRow {} |
|
impl ActionRowImpl for SwitchLoadingRow {} |
|
|
|
impl SwitchLoadingRow { |
|
/// Whether the switch is active. |
|
fn is_active(&self) -> bool { |
|
self.switch.is_active() |
|
} |
|
|
|
/// Set whether the switch is active. |
|
fn set_is_active(&self, active: bool) { |
|
if self.is_active() == active { |
|
return; |
|
} |
|
|
|
self.switch.set_active(active); |
|
self.obj().notify_is_active(); |
|
} |
|
|
|
/// Whether the row is loading. |
|
fn is_loading(&self) -> bool { |
|
self.spinner.is_visible() |
|
} |
|
|
|
/// Set whether the row is loading. |
|
fn set_is_loading(&self, loading: bool) { |
|
if self.is_loading() == loading { |
|
return; |
|
} |
|
|
|
self.spinner.set_visible(loading); |
|
self.obj().notify_is_loading(); |
|
} |
|
|
|
/// Set whether the row is read-only. |
|
fn set_read_only(&self, read_only: bool) { |
|
if self.read_only.get() == read_only { |
|
return; |
|
} |
|
let obj = self.obj(); |
|
|
|
self.read_only.set(read_only); |
|
|
|
obj.update_property(&[gtk::accessible::Property::ReadOnly(read_only)]); |
|
obj.notify_read_only(); |
|
} |
|
} |
|
} |
|
|
|
glib::wrapper! { |
|
/// An `AdwActionRow` with a switch and a loading state. |
|
pub struct SwitchLoadingRow(ObjectSubclass<imp::SwitchLoadingRow>) |
|
@extends gtk::Widget, gtk::ListBoxRow, adw::PreferencesRow, adw::ActionRow, |
|
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Actionable; |
|
} |
|
|
|
impl SwitchLoadingRow { |
|
pub fn new() -> Self { |
|
glib::Object::new() |
|
} |
|
}
|
|
|