tuigui 0.23.0

An easy-to-use, highly extensible, and speedy TUI library.
Documentation
use std::rc::Rc;
use std::sync::Mutex;

use crate::preludes::widget_creation::*;

#[derive(Debug, Clone)]
/// This widget isn't so special on its own,
/// but if you need direct access to a widget
/// that you cannot otherwise access, this is
/// what you would use
///
/// # Examples:
/// ```rust
/// use tuigui::{ widgets, Style };
///
/// fn main() {
///     // Let's say I wanna change this label's text
///     // after passing it to another widget which doesn't
///     // let me directly access this label widget.
///     let my_label = widgets::label::Label::new(
///         "foobar",
///         widgets::label::LabelStyle::Single(Style::new()),
///         false,
///     );
///
///     // Well in a BoxContainer or other widgets that use dynamic
///     // dispatch or have private fields, you cannot directly
///     // access the widget directly. So... you need a pointer!
///     // The reason there is a dedicated WidgetPointer type is
///     // because it implements the tuigui::Widget trait, thus it
///     // can be used as a normal wrapper widget around our real widget.
///     let my_label_ptr = widgets::widget_pointer::WidgetPointer::new(my_label);
///
///     // This is a perfect example, since BoxContainer uses
///     // Vec<Box<dyn tuigui::Widget>> under the hood to store
///     // its widgets. This is a problem when you want to access
///     // your widget, since it is stored in a vector that uses
///     // dynamic dispatch.
///     let box_container = widgets::box_container::BoxContainer::new(
///         widgets::box_container::Orientation::Vertical,
///         vec![
///             my_label_ptr.clone(),
///         ],
///     );
///
///     // But, since we passed in a clone of the label pointer,
///     // we can access its data!
///     let old_label_text: String = my_label_ptr.pointer.lock().unwrap().label.clone();
///     my_label_ptr.pointer.lock().unwrap().set_label("ABC XYZ");
/// }
/// ```
pub struct WidgetPointer<W: Widget> {
    pub pointer: Rc<Mutex<W>>,
    widget_data: WidgetData,
}

impl<W: Widget> WidgetPointer<W> {
    /// Create new widget pointer
    pub fn new(widget: W) -> Self {
        Self {
            pointer: Rc::new(Mutex::new(widget)),
            widget_data: WidgetData::new(),
        }
    }
}

impl<W: Widget> Widget for WidgetPointer<W> {
    fn draw(&mut self, canvas: &mut Canvas, state_frame: Option<&EventStateFrame>) {
        self.pointer.lock().unwrap().draw(canvas, state_frame);
    }

    fn widget_info(&self) -> WidgetInfo {
        return self.pointer.lock().unwrap().widget_info();
    }

    fn widget_data(&mut self) -> &mut WidgetData {
        return &mut self.widget_data;
    }
}