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}