use gtk4 as gtk; use std::sync::LazyLock; use gtk::{ builders::{BoxBuilder, ButtonBuilder, LabelBuilder}, prelude::{BoxExt, ObjectExt, WidgetExt}, Box, Button, Label, Revealer, RevealerTransitionType, }; use crate::{ event_handlers::button_event_handlers::BtnEventHandler, model::{builder_traits::Product, models::EventHandler}, }; #[derive(Clone)] pub struct InfoBar { instance: Revealer, } pub struct InfoBarBuilder { label: LabelBuilder, r#box: BoxBuilder, button: ButtonBuilder, } // // Singleton pattern implementation // unsafe impl Send for InfoBar {} unsafe impl Sync for InfoBar {} static INFO_BAR_INSTANCE: LazyLock = LazyLock::new(|| InfoBar { instance: Revealer::new(), }); impl InfoBar { pub fn get_instance() -> Self { INFO_BAR_INSTANCE.clone() } pub fn set_text_label(&self, text_label: Option<&str>) { if let Some(text) = text_label { let _ = &INFO_BAR_INSTANCE .instance .child() .unwrap() .first_child() .unwrap() .set_property("label", text); } } pub fn set_reveal_child(&self, is_reveal: bool) { let _ = &INFO_BAR_INSTANCE.instance.set_reveal_child(is_reveal); } } // // Builder pattern implementation // impl InfoBarBuilder { pub fn build(self) -> &'static InfoBar { let info_bar_label = self.label.build(); let info_bar_box = self.r#box.build(); let info_bar_close_btn = self.button.build(); info_bar_label.set_hexpand(true); info_bar_box.append(&info_bar_label); info_bar_box.append(&info_bar_close_btn); info_bar_box.set_widget_name("info_bar"); let info_bar: &Revealer = &INFO_BAR_INSTANCE.instance; info_bar.set_transition_type(RevealerTransitionType::SlideUp); info_bar.set_transition_duration(200); info_bar.set_child(Some(&info_bar_box)); let info_bar_to_close = info_bar.clone(); EventHandler::new(info_bar_close_btn.clone(), move |_| { info_bar_to_close.set_reveal_child(false); }) .on_click(); &INFO_BAR_INSTANCE } pub fn set_text_label(mut self, text: &str) -> Self { self.label = self.label.label(text); self } pub fn set_button_icon(mut self, icon_name: &str) -> Self { self.button = self.button.icon_name(icon_name); self } } impl Product for InfoBar { fn builder() -> InfoBarBuilder { InfoBarBuilder { label: Label::builder(), r#box: Box::builder(), button: Button::builder(), } } fn get(self) -> &'static Revealer { &INFO_BAR_INSTANCE.instance } }