use gtk::{
ListItem,
glib::{self},
subclass::prelude::*,
};
use crate::widget::unit_properties_selector::{
data_selection::UnitPropertySelection, unit_properties_selection::UnitPropertiesSelectionPanel,
};
glib::wrapper! {
pub struct UnitPropertiesSelectionRow(ObjectSubclass<imp::UnitPropertiesSelectionRowImp>)
@extends gtk::Grid, gtk::Widget,
@implements gtk::Actionable, gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
}
impl UnitPropertiesSelectionRow {
pub fn new(prop_selection: UnitPropertiesSelectionPanel) -> Self {
let obj: UnitPropertiesSelectionRow = glib::Object::new();
obj.imp().prop_selection.replace(Some(prop_selection));
obj
}
pub fn set_data_selection(&self, prop_seletion: &UnitPropertySelection, list_item: &ListItem) {
self.imp().set_data_selection(prop_seletion, list_item)
}
pub fn unbind(&self) {
self.imp().unbind()
}
}
impl Default for UnitPropertiesSelectionRow {
fn default() -> Self {
glib::Object::new()
}
}
mod imp {
use std::cell::RefCell;
use crate::widget::unit_properties_selector::{
data_selection::UnitPropertySelection,
unit_properties_selection::UnitPropertiesSelectionPanel,
};
use super::UnitPropertiesSelectionRow;
use gio::glib::Binding;
use glib::GString;
use gtk::{
glib::{self},
prelude::*,
subclass::prelude::*,
};
use tracing::warn;
#[derive(Default, gtk::CompositeTemplate)]
#[template(resource = "/io/github/plrigaux/sysd-manager/unit_properties_selection_row.ui")]
pub struct UnitPropertiesSelectionRowImp {
#[template_child]
interface: TemplateChild<gtk::Label>,
#[template_child]
property_label: TemplateChild<gtk::Label>,
#[template_child]
hidden_ckeck: TemplateChild<gtk::CheckButton>,
#[template_child]
title_entry: TemplateChild<gtk::Entry>,
#[template_child]
width_spin: TemplateChild<gtk::SpinButton>,
#[template_child]
resizable_switch: TemplateChild<gtk::Switch>,
#[template_child]
expand_switch: TemplateChild<gtk::Switch>,
pub prop_selection: RefCell<Option<UnitPropertiesSelectionPanel>>,
list_item: RefCell<Option<gtk::ListItem>>,
binds: RefCell<Vec<Binding>>,
}
#[gtk::template_callbacks]
impl UnitPropertiesSelectionRowImp {
pub(super) fn set_data_selection(
&self,
prop_selection: &UnitPropertySelection,
list_item: >k::ListItem,
) {
self.list_item.replace(Some(list_item.clone()));
let interface = prop_selection.interface();
if let Some(token) = interface.split('.').next_back() {
self.interface.set_label(token);
} else {
self.interface.set_label(&interface);
}
self.property_label
.set_label(&prop_selection.unit_property());
self.hidden_ckeck.set_active(prop_selection.visible());
let bind = self
.hidden_ckeck
.bind_property("active", prop_selection, "visible")
.build();
self.binds.borrow_mut().push(bind);
let title = prop_selection.title().unwrap_or_default();
self.title_entry.buffer().set_text(title);
let bind = self
.title_entry
.buffer()
.bind_property("text", prop_selection, "title")
.transform_to(|_b, s: GString| Some(s))
.build();
self.binds.borrow_mut().push(bind);
self.width_spin
.set_value(prop_selection.fixed_width() as f64);
let bind = self
.width_spin
.bind_property("value", prop_selection, "fixed-width")
.transform_to(|_b, v: f64| Some(v as i32))
.build();
self.binds.borrow_mut().push(bind);
self.resizable_switch.set_active(prop_selection.resizable());
let bind = self
.resizable_switch
.bind_property("active", prop_selection, "resizable")
.build();
self.binds.borrow_mut().push(bind);
self.expand_switch.set_active(prop_selection.expands());
let bind = self
.expand_switch
.bind_property("active", prop_selection, "expands")
.build();
self.binds.borrow_mut().push(bind);
}
pub(super) fn unbind(&self) {
{
for b in self.binds.borrow().iter() {
b.unbind()
}
}
self.binds.borrow_mut().clear();
self.list_item.replace(None);
}
#[template_callback]
fn move_up_clicked(&self, _b: >k::Button) {
let Some(ref list_item) = *self.list_item.borrow() else {
return;
};
let pos = list_item.position();
if pos == 0 {
return;
}
if let Some(list_store) = self
.prop_selection
.borrow()
.as_ref()
.and_then(|prop_selection| prop_selection.list_store())
&& let Some(ref prop_seletion) = list_store.item(pos)
{
list_store.remove(pos);
list_store.insert(pos - 1, prop_seletion);
} else {
warn!("list_store of data None");
};
}
#[template_callback]
fn move_down_clicked(&self, _b: >k::Button) {
let Some(ref list_item) = *self.list_item.borrow() else {
return;
};
if let Some(prop_selection) = self.prop_selection.borrow().as_ref() {
let pos = list_item.position();
prop_selection.move_down(pos);
}
}
#[template_callback]
fn delete_clicked(&self, _b: >k::Button) {
let Some(ref list_item) = *self.list_item.borrow() else {
return;
};
if let Some(prop_selection) = self.prop_selection.borrow().as_ref() {
let pos = list_item.position();
prop_selection.delete(pos);
}
}
}
#[glib::object_subclass]
impl ObjectSubclass for UnitPropertiesSelectionRowImp {
const NAME: &'static str = "UnitPropertiesSelectorRow";
type Type = UnitPropertiesSelectionRow;
type ParentType = gtk::Grid;
fn class_init(klass: &mut Self::Class) {
klass.bind_template();
klass.bind_template_callbacks();
}
fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
obj.init_template();
}
}
impl ObjectImpl for UnitPropertiesSelectionRowImp {
fn constructed(&self) {
self.parent_constructed();
}
}
impl WidgetImpl for UnitPropertiesSelectionRowImp {}
impl GridImpl for UnitPropertiesSelectionRowImp {}
}