use adw::subclass::bin::BinImpl; use gtk::glib::prelude::*; use gtk::prelude::*; use gtk::subclass::prelude::*; use std::cell::{Cell, RefCell}; use std::num::NonZeroU32; pub struct DynamicCol { pub(super) child: RefCell>, pub(super) ratio: RefCell>, width: Cell, pub(super) start_width: Cell>, pub(super) end_width: Cell>, } impl Default for DynamicCol { fn default() -> Self { Self { child: RefCell::new(None), ratio: RefCell::new(None), width: Cell::new(0), start_width: Cell::new(None), end_width: Cell::new(None), } } } #[glib::object_subclass] impl ObjectSubclass for DynamicCol { const NAME: &'static str = "DynamicCol"; type Type = super::DynamicCol; type ParentType = gtk::Widget; } impl ObjectImpl for DynamicCol { fn dispose(&self) { if let Some(child) = self.child.borrow_mut().take() { child.unparent(); } } } impl WidgetImpl for DynamicCol { fn measure(&self, orientation: gtk::Orientation, for_size: i32) -> (i32, i32, i32, i32) { let widget = self.obj(); let child = self.child.borrow(); let child = match child.as_ref() { Some(child) => child, None => return (0, 0, -1, -1), }; child.measure(orientation, for_size) } fn size_allocate(&self, width: i32, height: i32, baseline: i32) { let widget = self.obj(); let child = self.child.borrow(); let child = match child.as_ref() { Some(child) => child, None => return, }; child.size_allocate(>k::Allocation::new(0, 0, width, height), baseline); let ratio = self.ratio.borrow(); let position = if let Some(ratio) = *ratio { (width as f64 * ratio) as i32 } else { self.start_width.get().or(Some(width - self.end_width.get().unwrap())).unwrap() }; child.set_position(position); } }