Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_tui/src/lib_tui/draw/status.rs

4.7 KiB, 9 runs

created by r1870400018:1183, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1use crate::lib_tui::{
2 render::{
3 Drawable,
4 Drawer,
5 Renderer,
6 Sink,
7 When,
8 },
9 style::Style,
10 text::edit::EditorMode,
11};
12
13use oxedyne_fe2o3_core::prelude::*;
14use oxedyne_fe2o3_geom::{
15 dim::{
16 Coord,
17 Dim,
18 },
19 rect::AbsRect,
20};
21use oxedyne_fe2o3_text::string::Stringer;
22
23use std::fmt;
24
25
26#[derive(Clone, Debug, Default)]
27pub enum StatusStripType {
28 #[default]
29 Header,
30 Footer,
31}
32
33#[derive(Clone, Debug)]
34pub enum StatusStripLeft {
35 Origin(String),
36}
37
38impl StatusStripLeft {
39
40 pub fn display_fit(&self, avail_len: usize) -> String {
41 match self {
42 Self::Origin(origin) => {
43 let mut origin = Stringer::new(origin);
44 origin.fit_into(avail_len, "...");
45 origin.to_string()
46 }
47 }
48 }
49}
50
51#[derive(Clone, Debug)]
52pub enum StatusStripRight {
53 Cursor(Coord),
54 Label(String),
55 Mode(Option<EditorMode>),
56 ModeLabel(Option<EditorMode>, String),
57}
58
59impl fmt::Display for StatusStripRight {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 match self {
62 Self::Cursor(coord) => write!(f, "{},{}", coord.x, coord.y),
63 Self::Label(label) => write!(f, "{}", label),
64 Self::Mode(mode_opt) => match mode_opt {
65 Some(mode) => write!(f, "{}", mode),
66 None => write!(f, ""),
67 }
68 Self::ModeLabel(mode_opt, label) => match mode_opt {
69 Some(mode) => write!(f, "{} {}", mode, label),
70 None => write!(f, "{}", label),
71 }
72 }
73 }
74}
75
76#[derive(Clone, Debug, Default)]
77pub struct StatusStripContent {
78 pub left: Option<StatusStripLeft>,
79 pub right: Option<StatusStripRight>,
80 //pub cursor: Coord,
81}
82
83#[derive(Clone, Debug)]
84pub struct StatusStripConfig {
85 pub style: Style,
86 pub typ: StatusStripType,
87 pub right_len: Dim,
88}
89
90impl Default for StatusStripConfig {
91 fn default() -> Self {
92 Self {
93 style: Style::default(),
94 typ: StatusStripType::default(),
95 right_len: Dim(10),
96 }
97 }
98}
99
100#[derive(Clone, Debug)]
101pub struct StatusStrip {
102 pub cfg: StatusStripConfig,
103 pub content: StatusStripContent,
104 pub rect: AbsRect, // The window rectangle to which the strip is attached.
105}
106
107impl Drawable for StatusStrip {
108 fn render<S: Sink, R: Renderer<S>>(
109 &mut self,
110 drawer: &mut Drawer<S, R>,
111 when: When,
112 )
113 -> Outcome<()>
114 {
115 let (x, y, w, h) = self.rect.tup();
116
117 res!(self.cfg.style.render(drawer, When::Later));
118 let ys = match self.cfg.typ {
119 StatusStripType::Header => y,
120 StatusStripType::Footer => y + h - 1,
121 };
122 res!(drawer.rend.set_cursor(Coord::new((x, ys)), When::Later));
123
124 let right_str = if let Some(right) = &self.content.right {
125 fmt!("{} ", right)
126 } else {
127 fmt!(" ")
128 };
129 let right_len = Dim::new(right_str.chars().count());
130 let avail_len = w - right_len - Dim(2);
131
132 let left_str = if let Some(left) = &self.content.left {
133 fmt!(" {}", left.display_fit(avail_len.as_usize()))
134 } else {
135 fmt!(" ")
136 };
137 let left_len = Dim::new(left_str.chars().count());
138 let pad = w - left_len - right_len;
139 let strip_str = fmt!("{}{}{}", left_str, " ".repeat(pad.as_usize()), right_str);
140
141
142 //let right_len = right_str.chars().count();
143 //let coord = fmt!("{},{}", self.content.cursor.x, self.content.cursor.y);
144 //if coord.len() + strip_str.len() < w {
145 // strip_str = fmt!("{} {}", coord, strip_str);
146 //}
147 //let mut origin = Stringer::new(self.content.origin.clone());
148 //let avail_len = w - right_str.len() - 2;
149 //origin.fit_into(*avail_len, "...");
150 //let origin_len = origin.chars().count();
151 //if origin_len > 0 {
152 // let pad = w - strip_str.len() - origin_len - 2;
153 // strip_str = fmt!(" {} {}{}", origin, &" ".repeat(*pad), strip_str);
154 //} else {
155 // let pad = w - strip_str.len();
156 // strip_str = fmt!("{}{}", &" ".repeat(*pad), strip_str);
157 //}
158 res!(drawer.rend.print(&strip_str, When::Later));
159
160 res!(drawer.rend.reset_style(When::Later));
161
162 if when == When::Now {
163 res!(drawer.rend.flush());
164 }
165 Ok(())
166 }
167}
168
169impl StatusStrip {
170 pub fn new(
171 cfg: StatusStripConfig,
172 content: StatusStripContent,
173 rect: AbsRect,
174 )
175 -> Self
176 {
177 Self {
178 cfg,
179 content,
180 rect,
181 }
182 }
183}