/* Copyright 2024, Savanni D'Gerinel This file is part of FitnessTrax. FitnessTrax is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. FitnessTrax is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with FitnessTrax. If not, see . */ //! A Widget container for a single components use glib::Object; use gtk::{prelude::*, subclass::prelude::*}; use std::cell::RefCell; pub struct SingletonPrivate { widget: RefCell, } impl Default for SingletonPrivate { fn default() -> Self { Self { widget: RefCell::new(gtk::Label::new(None).upcast()), } } } #[glib::object_subclass] impl ObjectSubclass for SingletonPrivate { const NAME: &'static str = "Singleton"; type Type = Singleton; type ParentType = gtk::Box; } impl ObjectImpl for SingletonPrivate {} impl WidgetImpl for SingletonPrivate {} impl BoxImpl for SingletonPrivate {} glib::wrapper! { /// The Singleton component contains exactly one child widget. The swap function makes it easy /// to handle the job of swapping that child out for a different one. pub struct Singleton(ObjectSubclass) @extends gtk::Box, gtk::Widget; } impl Default for Singleton { fn default() -> Self { let s: Self = Object::builder().build(); s.append(&*s.imp().widget.borrow()); s } } impl Singleton { pub fn swap(&self, new_widget: &impl IsA) { let new_widget = new_widget.clone().upcast(); self.remove(&*self.imp().widget.borrow()); self.append(&new_widget); *self.imp().widget.borrow_mut() = new_widget; } } pub trait SingletonImpl: WidgetImpl + BoxImpl {} unsafe impl IsSubclassable for Singleton {}