summaryrefslogtreecommitdiffstats
path: root/src/cmdbar.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmdbar.rs')
-rw-r--r--src/cmdbar.rs368
1 files changed, 184 insertions, 184 deletions
diff --git a/src/cmdbar.rs b/src/cmdbar.rs
index dc227723..fa8b2842 100644
--- a/src/cmdbar.rs
+++ b/src/cmdbar.rs
@@ -1,205 +1,205 @@
use crate::{
- components::CommandInfo, keys::SharedKeyConfig, strings,
- ui::style::SharedTheme,
+ components::CommandInfo, keys::SharedKeyConfig, strings,
+ ui::style::SharedTheme,
};
use std::borrow::Cow;
use tui::{
- backend::Backend,
- layout::{Alignment, Rect},
- text::{Span, Spans},
- widgets::Paragraph,
- Frame,
+ backend::Backend,
+ layout::{Alignment, Rect},
+ text::{Span, Spans},
+ widgets::Paragraph,
+ Frame,
};
use unicode_width::UnicodeWidthStr;
enum DrawListEntry {
- LineBreak,
- Splitter,
- Command(Command),
+ LineBreak,
+ Splitter,
+ Command(Command),
}
struct Command {
- txt: String,
- enabled: bool,
- line: usize,
+ txt: String,
+ enabled: bool,
+ line: usize,
}
/// helper to be used while drawing
pub struct CommandBar {
- draw_list: Vec<DrawListEntry>,
- cmd_infos: Vec<CommandInfo>,
- theme: SharedTheme,
- key_config: SharedKeyConfig,
- lines: u16,
- width: u16,
- expandable: bool,
- expanded: bool,
+ draw_list: Vec<DrawListEntry>,
+ cmd_infos: Vec<CommandInfo>,
+ theme: SharedTheme,
+ key_config: SharedKeyConfig,
+ lines: u16,
+ width: u16,
+ expandable: bool,
+ expanded: bool,
}
const MORE_WIDTH: u16 = 9;
impl CommandBar {
- pub const fn new(
- theme: SharedTheme,
- key_config: SharedKeyConfig,
- ) -> Self {
- Self {
- draw_list: Vec::new(),
- cmd_infos: Vec::new(),
- theme,
- key_config,
- lines: 0,
- width: 0,
- expandable: false,
- expanded: false,
- }
- }
-
- pub fn refresh_width(&mut self, width: u16) {
- if width != self.width {
- self.refresh_list(width);
- self.width = width;
- }
- }
-
- fn is_multiline(&self, width: u16) -> bool {
- let mut line_width = 0_usize;
- for c in &self.cmd_infos {
- let entry_w =
- UnicodeWidthStr::width(c.text.name.as_str());
-
- if line_width + entry_w > width as usize {
- return true;
- }
-
- line_width += entry_w + 1;
- }
-
- false
- }
-
- fn refresh_list(&mut self, width: u16) {
- self.draw_list.clear();
-
- let width = if self.is_multiline(width) {
- width.saturating_sub(MORE_WIDTH)
- } else {
- width
- };
-
- let mut line_width = 0_usize;
- let mut lines = 1_u16;
-
- for c in &self.cmd_infos {
- let entry_w =
- UnicodeWidthStr::width(c.text.name.as_str());
-
- if line_width + entry_w > width as usize {
- self.draw_list.push(DrawListEntry::LineBreak);
- line_width = 0;
- lines += 1;
- } else if line_width > 0 {
- self.draw_list.push(DrawListEntry::Splitter);
- }
-
- line_width += entry_w + 1;
-
- self.draw_list.push(DrawListEntry::Command(Command {
- txt: c.text.name.to_string(),
- enabled: c.enabled,
- line: lines.saturating_sub(1) as usize,
- }));
- }
-
- self.expandable = lines > 1;
-
- self.lines = lines;
- }
-
- pub fn set_cmds(&mut self, cmds: Vec<CommandInfo>) {
- self.cmd_infos = cmds
- .into_iter()
- .filter(CommandInfo::show_in_quickbar)
- .collect::<Vec<_>>();
- self.cmd_infos.sort_by_key(|e| e.order);
- self.refresh_list(self.width);
- }
-
- pub const fn height(&self) -> u16 {
- if self.expandable && self.expanded {
- self.lines
- } else {
- 1_u16
- }
- }
-
- pub fn toggle_more(&mut self) {
- if self.expandable {
- self.expanded = !self.expanded;
- }
- }
-
- pub fn draw<B: Backend>(&self, f: &mut Frame<B>, r: Rect) {
- if r.width < MORE_WIDTH {
- return;
- }
- let splitter = Span::raw(Cow::from(strings::cmd_splitter(
- &self.key_config,
- )));
-
- let texts = self
- .draw_list
- .split(|c| matches!(c, DrawListEntry::LineBreak))
- .map(|c_arr| {
- Spans::from(
- c_arr
- .iter()
- .map(|c| match c {
- DrawListEntry::Command(c) => {
- Span::styled(
- Cow::from(c.txt.as_str()),
- self.theme.commandbar(
- c.enabled, c.line,
- ),
- )
- }
- DrawListEntry::LineBreak => {
- // Doesn't exist in split array
- Span::raw("")
- }
- DrawListEntry::Splitter => {
- splitter.clone()
- }
- })
- .collect::<Vec<Span>>(),
- )
- })
- .collect::<Vec<Spans>>();
-
- f.render_widget(
- Paragraph::new(texts).alignment(Alignment::Left),
- r,
- );
-
- if self.expandable {
- let r = Rect::new(
- r.width.saturating_sub(MORE_WIDTH),
- r.y + r.height.saturating_sub(1),
- MORE_WIDTH.min(r.width),
- 1.min(r.height),
- );
-
- f.render_widget(
- Paragraph::new(Spans::from(vec![Span::raw(
- Cow::from(if self.expanded {
- "less [.]"
- } else {
- "more [.]"
- }),
- )]))
- .alignment(Alignment::Right),
- r,
- );
- }
- }
+ pub const fn new(
+ theme: SharedTheme,
+ key_config: SharedKeyConfig,
+ ) -> Self {
+ Self {
+ draw_list: Vec::new(),
+ cmd_infos: Vec::new(),
+ theme,
+ key_config,
+ lines: 0,
+ width: 0,
+ expandable: false,
+ expanded: false,
+ }
+ }
+
+ pub fn refresh_width(&mut self, width: u16) {
+ if width != self.width {
+ self.refresh_list(width);
+ self.width = width;
+ }
+ }
+
+ fn is_multiline(&self, width: u16) -> bool {
+ let mut line_width = 0_usize;
+ for c in &self.cmd_infos {
+ let entry_w =
+ UnicodeWidthStr::width(c.text.name.as_str());
+
+ if line_width + entry_w > width as usize {
+ return true;
+ }
+
+ line_width += entry_w + 1;
+ }
+
+ false
+ }
+
+ fn refresh_list(&mut self, width: u16) {
+ self.draw_list.clear();
+
+ let width = if self.is_multiline(width) {
+ width.saturating_sub(MORE_WIDTH)
+ } else {
+ width
+ };
+
+ let mut line_width = 0_usize;
+ let mut lines = 1_u16;
+
+ for c in &self.cmd_infos {
+ let entry_w =
+ UnicodeWidthStr::width(c.text.name.as_str());
+
+ if line_width + entry_w > width as usize {
+ self.draw_list.push(DrawListEntry::LineBreak);
+ line_width = 0;
+ lines += 1;
+ } else if line_width > 0 {
+ self.draw_list.push(DrawListEntry::Splitter);
+ }
+
+ line_width += entry_w + 1;
+
+ self.draw_list.push(DrawListEntry::Command(Command {
+ txt: c.text.name.to_string(),
+ enabled: c.enabled,
+ line: lines.saturating_sub(1) as usize,
+ }));
+ }
+
+ self.expandable = lines > 1;
+
+ self.lines = lines;
+ }
+
+ pub fn set_cmds(&mut self, cmds: Vec<CommandInfo>) {
+ self.cmd_infos = cmds
+ .into_iter()
+ .filter(CommandInfo::show_in_quickbar)
+ .collect::<Vec<_>>();
+ self.cmd_infos.sort_by_key(|e| e.order);
+ self.refresh_list(self.width);
+ }
+
+ pub const fn height(&self) -> u16 {
+ if self.expandable && self.expanded {
+ self.lines
+ } else {
+ 1_u16
+ }
+ }
+
+ pub fn toggle_more(&mut self) {
+ if self.expandable {
+ self.expanded = !self.expanded;
+ }
+ }
+
+ pub fn draw<B: Backend>(&self, f: &mut Frame<B>, r: Rect) {
+ if r.width < MORE_WIDTH {
+ return;
+ }
+ let splitter = Span::raw(Cow::from(strings::cmd_splitter(
+ &self.key_config,
+ )));
+
+ let texts = self
+ .draw_list
+ .split(|c| matches!(c, DrawListEntry::LineBreak))
+ .map(|c_arr| {
+ Spans::from(
+ c_arr
+ .iter()
+ .map(|c| match c {
+ DrawListEntry::Command(c) => {
+ Span::styled(
+ Cow::from(c.txt.as_str()),
+ self.theme.commandbar(
+ c.enabled, c.line,
+ ),
+ )
+ }
+ DrawListEntry::LineBreak => {
+ // Doesn't exist in split array
+ Span::raw("")
+ }
+ DrawListEntry::Splitter => {
+ splitter.clone()
+ }
+ })
+ .collect::<Vec<Span>>(),
+ )
+ })
+ .collect::<Vec<Spans>>();
+
+ f.render_widget(
+ Paragraph::new(texts).alignment(Alignment::Left),
+ r,
+ );
+
+ if self.expandable {
+ let r = Rect::new(
+ r.width.saturating_sub(MORE_WIDTH),
+ r.y + r.height.saturating_sub(1),
+ MORE_WIDTH.min(r.width),
+ 1.min(r.height),
+ );
+
+ f.render_widget(
+ Paragraph::new(Spans::from(vec![Span::raw(
+ Cow::from(if self.expanded {
+ "less [.]"
+ } else {
+ "more [.]"
+ }),
+ )]))
+ .alignment(Alignment::Right),
+ r,
+ );
+ }
+ }
}