From 33226ecae22046779a8159dc6cdf344de9053cde Mon Sep 17 00:00:00 2001 From: doryan Date: Sat, 27 Jul 2024 22:42:10 +0400 Subject: [PATCH] feat(infobar): add implementation of infobar for use instead deprecated built-in infobar --- src/view/components/info_bar.rs | 118 ++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 src/view/components/info_bar.rs diff --git a/src/view/components/info_bar.rs b/src/view/components/info_bar.rs new file mode 100644 index 0000000..56f2d2b --- /dev/null +++ b/src/view/components/info_bar.rs @@ -0,0 +1,118 @@ +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 + } +}