duat_base/widgets/
info.rs

1//! The simplest widget, just shows [`Text`]
2//!
3//! This is a very simple `Widget`, it basically just exists so I
4//! don't have to define a new `Widget` every time I want to show
5//! static information.
6use duat_core::{
7    context::Handle,
8    data::Pass,
9    mode::{MouseEvent, MouseEventKind},
10    opts::PrintOpts,
11    text::{Text, TextMut},
12    ui::Widget,
13};
14
15/// A simple static widget, meant to just convey information
16///
17/// This is the most flexible of widgets, you can use it anywhere,
18/// just by pushing it around, or spawning it however you want, by
19/// making use of the [`PushSpecs`], [`DynSpawnSpecs`] o
20/// [`StaticSpawnSpecs`].
21///
22/// [`PushSpecs`]: duat_core::ui::PushSpecs
23/// [`DynSpawnSpecs`]: duat_core::ui::DynSpawnSpecs
24/// [`StaticSpawnSpecs`]: duat_core::ui::StaticSpawnSpecs
25pub struct Info {
26    /// The [`Text`] that will be shown by this widget
27    pub text: Text,
28}
29
30impl Info {
31    /// Returns a new `Info` widget
32    ///
33    /// This is the only [`Widget`] in `duat-base` that can be
34    /// acquired this way, since it's supposed to be versatile in
35    /// where you position it. Every other widget has to be placed in
36    /// specific locations, so they don't offer a `new` method, which
37    /// could be used in order to place them willy nilly.
38    pub fn new(text: Text) -> Self {
39        Self { text }
40    }
41}
42
43impl Widget for Info {
44    fn update(pa: &mut Pass, handle: &Handle<Self>) {
45        let (info, area) = handle.write_with_area(pa);
46        let size = area
47            .size_of_text(info.get_print_opts(), &info.text)
48            .unwrap();
49        _ = area.set_width(size.x);
50        _ = area.set_height(size.y);
51    }
52
53    fn needs_update(&self, _: &Pass) -> bool {
54        false
55    }
56
57    fn text(&self) -> &Text {
58        &self.text
59    }
60
61    fn text_mut(&mut self) -> TextMut<'_> {
62        self.text.as_mut()
63    }
64
65    fn on_mouse_event(pa: &mut Pass, handle: &Handle<Self>, event: MouseEvent) {
66        use MouseEventKind::{ScrollDown, ScrollUp};
67        match event.kind {
68            ScrollDown | ScrollUp => {
69                let (info, area) = handle.write_with_area(pa);
70                let scroll = if let ScrollDown = event.kind { 3 } else { -3 };
71                area.scroll_ver(&info.text, scroll, info.get_print_opts());
72            }
73            _ => {}
74        }
75    }
76
77    fn get_print_opts(&self) -> PrintOpts {
78        let mut opts = PrintOpts::new();
79        opts.wrap_lines = true;
80        opts.tabstop = 2;
81        opts
82    }
83}