Skip to content

Commit

Permalink
Merge pull request #7 from TehPers/icon-packs
Browse files Browse the repository at this point in the history
Add static icon packs
  • Loading branch information
TehPers authored Nov 8, 2021
2 parents 548ae12 + 363546f commit 680fc96
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 73 deletions.
2 changes: 2 additions & 0 deletions src/widgets.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod controls;
mod formatted_log;
mod icons;
mod lazy_paragraph;
mod raw_log;
mod root;
Expand All @@ -8,6 +9,7 @@ mod state;

pub use controls::*;
pub use formatted_log::*;
pub use icons::*;
pub use lazy_paragraph::*;
pub use raw_log::*;
pub use root::*;
Expand Down
101 changes: 41 additions & 60 deletions src/widgets/controls.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
use crate::{events::AppEvent, widgets::State};
use crate::{
events::AppEvent,
widgets::{DefaultIconPack, IconPack, State},
};
use crossterm::event::{KeyCode, KeyModifiers, MouseButton};
use indexmap::IndexMap;
use itertools::Itertools;
use std::fmt::{Display, Formatter};
use std::{
fmt::{Display, Formatter},
marker::PhantomData,
};
use tui::{
buffer::Buffer,
layout::Rect,
Expand All @@ -14,69 +20,40 @@ use unicode_width::UnicodeWidthStr;

#[allow(dead_code)] // TODO: Add support for mouse events
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
pub enum BindingDisplay {
pub enum BindingDisplay<I: IconPack> {
Key {
key_code: KeyCode,
modifiers: KeyModifiers,
},
Mouse(MouseButton),
Custom(&'static str),
#[doc(hidden)]
__Marker(PhantomData<*const I>),
}

impl BindingDisplay {
pub const CONTROL_ICON: &'static str = if cfg!(target_os = "macos") {
"\u{2318}"
} else {
"\u{2303}"
};
pub const ALT_ICON: &'static str = "\u{2325}";
pub const SHIFT_ICON: &'static str = "\u{21e7}";

pub const BACKSPACE_ICON: &'static str = "\u{232b}";
pub const ENTER_ICON: &'static str = "\u{23ce}";
pub const LEFT_ICON: &'static str = "\u{2190}";
pub const RIGHT_ICON: &'static str = "\u{2192}";
pub const UP_ICON: &'static str = "\u{2191}";
pub const DOWN_ICON: &'static str = "\u{2193}";
pub const HOME_ICON: &'static str = "\u{2196}";
pub const END_ICON: &'static str = "\u{2198}";
pub const PAGEUP_ICON: &'static str = "\u{21de}";
pub const PAGEDOWN_ICON: &'static str = "\u{21df}";
pub const TAB_ICON: &'static str = "\u{21e5}";
pub const BACKTAB_ICON: &'static str = "\u{21e4}";
pub const DELETE_ICON: &'static str = "\u{2326}";
pub const INSERT_ICON: &'static str = "INS";
pub const NULL_ICON: &'static str = "NUL";
pub const ESC_ICON: &'static str = "\u{238b}";
pub const SPACE_ICON: &'static str = "\u{2423}";

#[allow(dead_code)] // For future use
pub const UP_DOWN: &'static str = "\u{2191}\u{2193}";
pub const LEFT_RIGHT: &'static str = "\u{2192}\u{2190}";
pub const ARROWS: &'static str = "\u{2191}\u{2193}\u{2192}\u{2190}";

impl<I: IconPack> BindingDisplay<I> {
const MODIFIER_DISPLAYS: [(KeyModifiers, &'static str); 3] = [
(KeyModifiers::CONTROL, BindingDisplay::CONTROL_ICON),
(KeyModifiers::ALT, BindingDisplay::ALT_ICON),
(KeyModifiers::SHIFT, BindingDisplay::SHIFT_ICON),
(KeyModifiers::CONTROL, I::CONTROL_ICON),
(KeyModifiers::ALT, I::ALT_ICON),
(KeyModifiers::SHIFT, I::SHIFT_ICON),
];

pub const fn key(key_code: KeyCode, modifiers: KeyModifiers) -> Self {
pub fn key(key_code: KeyCode, modifiers: KeyModifiers) -> Self {
BindingDisplay::Key {
key_code,
modifiers,
}
}

pub const fn simple_key(key_code: KeyCode) -> Self {
pub fn simple_key(key_code: KeyCode) -> Self {
BindingDisplay::Key {
key_code,
modifiers: KeyModifiers::empty(),
}
}
}

impl Display for BindingDisplay {
impl<I: IconPack> Display for BindingDisplay<I> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
BindingDisplay::Key {
Expand All @@ -94,31 +71,32 @@ impl Display for BindingDisplay {

// Write key code
match key_code {
KeyCode::BackTab => write!(f, "{}", Self::BACKTAB_ICON),
KeyCode::Backspace => write!(f, "{}", Self::BACKSPACE_ICON),
KeyCode::Char(' ') => write!(f, "{}", Self::SPACE_ICON),
KeyCode::BackTab => write!(f, "{}", I::BACKTAB_ICON),
KeyCode::Backspace => write!(f, "{}", I::BACKSPACE_ICON),
KeyCode::Char(' ') => write!(f, "{}", I::SPACE_ICON),
KeyCode::Char(c) => write!(f, "{}", c),
KeyCode::Delete => write!(f, "{}", Self::DELETE_ICON),
KeyCode::Down => write!(f, "{}", Self::DOWN_ICON),
KeyCode::End => write!(f, "{}", Self::END_ICON),
KeyCode::Enter => write!(f, "{}", Self::ENTER_ICON),
KeyCode::Esc => write!(f, "{}", Self::ESC_ICON),
KeyCode::Delete => write!(f, "{}", I::DELETE_ICON),
KeyCode::Down => write!(f, "{}", I::DOWN_ICON),
KeyCode::End => write!(f, "{}", I::END_ICON),
KeyCode::Enter => write!(f, "{}", I::ENTER_ICON),
KeyCode::Esc => write!(f, "{}", I::ESC_ICON),
KeyCode::F(n) => write!(f, "F{}", n),
KeyCode::Home => write!(f, "{}", Self::HOME_ICON),
KeyCode::Insert => write!(f, "{}", Self::INSERT_ICON),
KeyCode::Left => write!(f, "{}", Self::LEFT_ICON),
KeyCode::Null => write!(f, "{}", Self::NULL_ICON),
KeyCode::PageDown => write!(f, "{}", Self::PAGEDOWN_ICON),
KeyCode::PageUp => write!(f, "{}", Self::PAGEUP_ICON),
KeyCode::Right => write!(f, "{}", Self::RIGHT_ICON),
KeyCode::Tab => write!(f, "{}", Self::TAB_ICON),
KeyCode::Up => write!(f, "{}", Self::UP_ICON),
KeyCode::Home => write!(f, "{}", I::HOME_ICON),
KeyCode::Insert => write!(f, "{}", I::INSERT_ICON),
KeyCode::Left => write!(f, "{}", I::LEFT_ICON),
KeyCode::Null => write!(f, "{}", I::NULL_ICON),
KeyCode::PageDown => write!(f, "{}", I::PAGEDOWN_ICON),
KeyCode::PageUp => write!(f, "{}", I::PAGEUP_ICON),
KeyCode::Right => write!(f, "{}", I::RIGHT_ICON),
KeyCode::Tab => write!(f, "{}", I::TAB_ICON),
KeyCode::Up => write!(f, "{}", I::UP_ICON),
}
}
BindingDisplay::Mouse(MouseButton::Left) => write!(f, "M1"),
BindingDisplay::Mouse(MouseButton::Right) => write!(f, "M2"),
BindingDisplay::Mouse(MouseButton::Middle) => write!(f, "M3"),
BindingDisplay::Custom(label) => write!(f, "{}", label),
_ => Ok(()),
}
}
}
Expand Down Expand Up @@ -211,12 +189,15 @@ impl StatefulWidget for Controls {

#[derive(Clone, Debug, Default)]
pub struct ControlsState {
controls: IndexMap<BindingDisplay, &'static str>,
controls: IndexMap<BindingDisplay<DefaultIconPack>, &'static str>,
page: usize,
}

impl ControlsState {
pub fn set_controls(&mut self, controls: IndexMap<BindingDisplay, &'static str>) -> &mut Self {
pub fn set_controls(
&mut self,
controls: IndexMap<BindingDisplay<DefaultIconPack>, &'static str>,
) -> &mut Self {
self.controls = controls;
self
}
Expand Down
8 changes: 4 additions & 4 deletions src/widgets/formatted_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{
ast::{Level, Message},
events::AppEvent,
log::Log,
widgets::{BindingDisplay, LazyParagraph, LazyParagraphState, State, WithLog},
widgets::{BindingDisplay, IconPack, LazyParagraph, LazyParagraphState, State, WithLog},
};
use crossterm::event::{Event, KeyCode};
use indexmap::IndexMap;
Expand Down Expand Up @@ -287,7 +287,7 @@ impl<'i> State for FormattedLogState<'i> {
}
}

fn add_controls(&self, controls: &mut IndexMap<BindingDisplay, &'static str>) {
fn add_controls<I: IconPack>(&self, controls: &mut IndexMap<BindingDisplay<I>, &'static str>) {
match self.filters_list_state.as_ref() {
None => {
controls.insert(BindingDisplay::simple_key(KeyCode::Char('f')), "Filters");
Expand Down Expand Up @@ -591,8 +591,8 @@ impl State for FiltersListState {
}
}

fn add_controls(&self, controls: &mut IndexMap<BindingDisplay, &'static str>) {
controls.insert(BindingDisplay::Custom(BindingDisplay::LEFT_RIGHT), "Nav");
fn add_controls<I: IconPack>(&self, controls: &mut IndexMap<BindingDisplay<I>, &'static str>) {
controls.insert(BindingDisplay::Custom(I::LEFT_RIGHT), "Nav");
}
}

Expand Down
101 changes: 101 additions & 0 deletions src/widgets/icons.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
use std::{fmt::Debug, hash::Hash};

pub trait IconPack: Clone + Copy + PartialEq + Eq + Debug + Hash + Default + 'static {
const CONTROL_ICON: &'static str;
const ALT_ICON: &'static str;
const SHIFT_ICON: &'static str;

const LEFT_ICON: &'static str;
const RIGHT_ICON: &'static str;
const UP_ICON: &'static str;
const DOWN_ICON: &'static str;
const INSERT_ICON: &'static str;
const NULL_ICON: &'static str;
const BACKSPACE_ICON: &'static str;
const ENTER_ICON: &'static str;
const HOME_ICON: &'static str;
const END_ICON: &'static str;
const PAGEUP_ICON: &'static str;
const PAGEDOWN_ICON: &'static str;
const TAB_ICON: &'static str;
const BACKTAB_ICON: &'static str;
const DELETE_ICON: &'static str;
const ESC_ICON: &'static str;
const SPACE_ICON: &'static str;

const UP_DOWN: &'static str;
const LEFT_RIGHT: &'static str;
const ARROWS: &'static str;
}

#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
pub struct UnicodeIconPack;

impl IconPack for UnicodeIconPack {
const CONTROL_ICON: &'static str = if cfg!(target_os = "macos") {
"\u{2318}"
} else {
"\u{2303}"
};
const ALT_ICON: &'static str = "\u{2325}";
const SHIFT_ICON: &'static str = "\u{21e7}";

const LEFT_ICON: &'static str = "\u{2190}";
const RIGHT_ICON: &'static str = "\u{2192}";
const UP_ICON: &'static str = "\u{2191}";
const DOWN_ICON: &'static str = "\u{2193}";
const INSERT_ICON: &'static str = "INS";
const NULL_ICON: &'static str = "NUL";
const BACKSPACE_ICON: &'static str = "\u{232b}";
const ENTER_ICON: &'static str = "\u{23ce}";
const HOME_ICON: &'static str = "\u{2196}";
const END_ICON: &'static str = "\u{2198}";
const PAGEUP_ICON: &'static str = "\u{21de}";
const PAGEDOWN_ICON: &'static str = "\u{21df}";
const TAB_ICON: &'static str = "\u{21e5}";
const BACKTAB_ICON: &'static str = "\u{21e4}";
const DELETE_ICON: &'static str = "\u{2326}";
const ESC_ICON: &'static str = "\u{238b}";
const SPACE_ICON: &'static str = "\u{2423}";

const UP_DOWN: &'static str = "\u{2191}\u{2193}";
const LEFT_RIGHT: &'static str = "\u{2192}\u{2190}";
const ARROWS: &'static str = "\u{2191}\u{2193}\u{2192}\u{2190}";
}

#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Default)]
pub struct NonUnicodeIconPack;

impl IconPack for NonUnicodeIconPack {
const CONTROL_ICON: &'static str = "CTRL+";
const ALT_ICON: &'static str = "ALT+";
const SHIFT_ICON: &'static str = "SHFT+";

const LEFT_ICON: &'static str = UnicodeIconPack::LEFT_ICON;
const RIGHT_ICON: &'static str = UnicodeIconPack::RIGHT_ICON;
const UP_ICON: &'static str = UnicodeIconPack::UP_ICON;
const DOWN_ICON: &'static str = UnicodeIconPack::DOWN_ICON;
const INSERT_ICON: &'static str = "INS";
const NULL_ICON: &'static str = "NUL";
const BACKSPACE_ICON: &'static str = "BKSP";
const ENTER_ICON: &'static str = "ENTR";
const HOME_ICON: &'static str = "HOME";
const END_ICON: &'static str = "END";
const PAGEUP_ICON: &'static str = "PGUP";
const PAGEDOWN_ICON: &'static str = "PGDN";
const TAB_ICON: &'static str = "TAB";
const BACKTAB_ICON: &'static str = "BTAB";
const DELETE_ICON: &'static str = "DEL";
const ESC_ICON: &'static str = "ESC";
const SPACE_ICON: &'static str = "SPC";

const UP_DOWN: &'static str = UnicodeIconPack::UP_DOWN;
const LEFT_RIGHT: &'static str = UnicodeIconPack::LEFT_RIGHT;
const ARROWS: &'static str = UnicodeIconPack::ARROWS;
}

#[cfg(not(target_os = "windows"))]
pub type DefaultIconPack = UnicodeIconPack;

#[cfg(target_os = "windows")]
pub type DefaultIconPack = NonUnicodeIconPack;
6 changes: 3 additions & 3 deletions src/widgets/lazy_paragraph.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
events::AppEvent,
widgets::{BindingDisplay, Scrollbar, State},
widgets::{BindingDisplay, IconPack, Scrollbar, State},
};
use crossterm::event::{Event, KeyCode};
use indexmap::IndexMap;
Expand Down Expand Up @@ -238,8 +238,8 @@ impl State for LazyParagraphState {
}
}

fn add_controls(&self, controls: &mut IndexMap<BindingDisplay, &'static str>) {
controls.insert(BindingDisplay::Custom(BindingDisplay::ARROWS), "Nav");
fn add_controls<I: IconPack>(&self, controls: &mut IndexMap<BindingDisplay<I>, &'static str>) {
controls.insert(BindingDisplay::Custom(I::ARROWS), "Nav");
controls.insert(BindingDisplay::simple_key(KeyCode::PageUp), "Up 10");
controls.insert(BindingDisplay::simple_key(KeyCode::PageDown), "Down 10");
controls.insert(BindingDisplay::simple_key(KeyCode::Home), "Top");
Expand Down
4 changes: 2 additions & 2 deletions src/widgets/raw_log.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
events::AppEvent,
log::Log,
widgets::{BindingDisplay, LazyParagraph, LazyParagraphState, State, WithLog},
widgets::{BindingDisplay, IconPack, LazyParagraph, LazyParagraphState, State, WithLog},
};
use indexmap::IndexMap;
use std::marker::PhantomData;
Expand Down Expand Up @@ -67,7 +67,7 @@ impl<'i> State for RawLogState<'i> {
self.paragraph_state.update(event)
}

fn add_controls(&self, controls: &mut IndexMap<BindingDisplay, &'static str>) {
fn add_controls<I: IconPack>(&self, controls: &mut IndexMap<BindingDisplay<I>, &'static str>) {
self.paragraph_state.add_controls(controls);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/widgets/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{
events::AppEvent,
log::Log,
widgets::{
BindingDisplay, Controls, ControlsState, FormattedLog, FormattedLogState, RawLog,
BindingDisplay, Controls, ControlsState, FormattedLog, FormattedLogState, IconPack, RawLog,
RawLogState, State, WithLog,
},
};
Expand Down Expand Up @@ -124,7 +124,7 @@ impl<'i> State for RootState<'i> {
}
}

fn add_controls(&self, controls: &mut IndexMap<BindingDisplay, &'static str>) {
fn add_controls<I: IconPack>(&self, controls: &mut IndexMap<BindingDisplay<I>, &'static str>) {
// Root controls
controls.insert(
BindingDisplay::key(KeyCode::Char('c'), KeyModifiers::CONTROL),
Expand Down
9 changes: 7 additions & 2 deletions src/widgets/state.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
use crate::{events::AppEvent, log::Log, widgets::BindingDisplay};
use crate::{
events::AppEvent,
log::Log,
widgets::{BindingDisplay, IconPack},
};
use indexmap::IndexMap;

pub trait State {
fn update(&mut self, event: &AppEvent) -> bool;
fn add_controls(&self, _controls: &mut IndexMap<BindingDisplay, &'static str>) {}
fn add_controls<I: IconPack>(&self, _controls: &mut IndexMap<BindingDisplay<I>, &'static str>) {
}
}

impl State for () {
Expand Down

0 comments on commit 680fc96

Please sign in to comment.