feat(tui): support scrolling to top/bottom

This commit is contained in:
Orhun Parmaksız 2022-01-20 19:04:00 +03:00
parent a90fa2768f
commit 990acbc1dd
No known key found for this signature in database
GPG key ID: F83424824B3E4B90
3 changed files with 78 additions and 44 deletions

View file

@ -1,6 +1,7 @@
use crate::command::Command;
use crate::error::Result;
use crate::options::CopyOption;
use crate::options::Direction;
use crate::widgets::StatefulTable;
#[cfg(feature = "clipboard")]
use copypasta_ext::{display::DisplayServer, prelude::ClipboardProvider};
@ -164,20 +165,30 @@ impl<'a> App<'a> {
self.input_time = Some(Instant::now());
}
}
Command::ScrollUp => {
Command::Scroll(Direction::Up) => {
if let Some(options) = self.options.as_mut() {
options.previous();
} else if !self.parameter_list.items.is_empty() {
self.parameter_list.previous();
}
}
Command::ScrollDown => {
Command::Scroll(Direction::Down) => {
if let Some(options) = self.options.as_mut() {
options.next();
} else if !self.parameter_list.items.is_empty() {
self.parameter_list.next();
}
}
Command::Scroll(Direction::Top) => {
if !self.parameter_list.items.is_empty() {
self.parameter_list.state.select(Some(0));
}
}
Command::Scroll(Direction::Bottom) => {
if let Some(last_index) = self.parameter_list.items.len().checked_sub(1) {
self.parameter_list.state.select(Some(last_index))
}
}
Command::EnableSearch => {
if self.input_time.is_some() {
self.input_time = None;

View file

@ -1,3 +1,4 @@
use crate::options::Direction;
use std::str::FromStr;
use termion::event::Key;
@ -8,10 +9,8 @@ pub enum Command {
Select,
/// Set the value of a parameter.
Set(String, String),
/// Scroll up on the widget.
ScrollUp,
/// Scroll down on the widget.
ScrollDown,
/// Scroll the widget.
Scroll(Direction),
/// Move cursor to right/left.
MoveCursor(u8),
/// Enable the search mode.
@ -38,8 +37,6 @@ impl FromStr for Command {
match s {
"search" => Ok(Command::EnableSearch),
"select" => Ok(Command::Select),
"up" => Ok(Command::ScrollUp),
"down" => Ok(Command::ScrollDown),
"copy" => Ok(Command::Copy),
"refresh" => Ok(Command::Refresh),
"exit" | "quit" | "q" | "q!" => Ok(Command::Exit),
@ -50,6 +47,13 @@ impl FromStr for Command {
values.next().ok_or(())?.to_string(),
values.next().ok_or(())?.to_string(),
))
} else if s.starts_with("scroll") {
Ok(Command::Scroll(Direction::try_from(
*(s.split_whitespace()
.collect::<Vec<&str>>()
.get(1)
.ok_or(())?),
)?))
} else {
Err(())
}
@ -74,8 +78,10 @@ impl Command {
}
} else {
match key {
Key::Up => Command::ScrollUp,
Key::Down => Command::ScrollDown,
Key::Up => Command::Scroll(Direction::Up),
Key::Down => Command::Scroll(Direction::Down),
Key::Char('t') => Command::Scroll(Direction::Top),
Key::Char('b') => Command::Scroll(Direction::Bottom),
Key::Char(':') => Command::UpdateInput(' '),
Key::Char('/') => Command::EnableSearch,
Key::Char('\n') => Command::Select,

View file

@ -1,39 +1,56 @@
use std::convert::TryFrom;
/// Available copying options.
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum CopyOption {
/// Copy the name of the parameter.
Name,
/// Copy the value of the parameter.
Value,
/// Copy the documentation of the parameter.
Documentation,
}
impl<'a> TryFrom<&'a str> for CopyOption {
type Error = ();
fn try_from(value: &'a str) -> Result<Self, Self::Error> {
Self::variants()
.iter()
.find(|v| value == v.as_str())
.copied()
.ok_or(())
}
}
impl CopyOption {
/// Returns the string representation of the option.
pub fn as_str(&self) -> &'static str {
match self {
Self::Name => "Parameter name",
Self::Value => "Parameter value",
Self::Documentation => "Documentation",
macro_rules! generate_option {
($name: ident,
$($variant: ident => $str_repr: expr,)+
) => {
/// Available options.
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum $name {
$(
/// Option.
$variant
),+
}
}
/// Returns the variants.
pub fn variants() -> &'static [Self] {
&[Self::Name, Self::Value, Self::Documentation]
}
impl<'a> TryFrom<&'a str> for $name {
type Error = ();
fn try_from(value: &'a str) -> Result<Self, Self::Error> {
Self::variants()
.iter()
.find(|v| value == v.as_str())
.copied()
.ok_or(())
}
}
impl $name {
/// Returns the variants.
pub fn variants() -> &'static [Self] {
&[$(Self::$variant,)+]
}
/// Returns the string representation.
pub fn as_str(&self) -> &'static str {
match self {
$(Self::$variant => $str_repr,)+
}
}
}
};
}
generate_option!(
CopyOption,
Name => "Parameter name",
Value => "Parameter value",
Documentation => "Documentation",
);
generate_option!(
Direction,
Up => "up",
Down => "down",
Top => "top",
Bottom => "bottom",
);