Added support for inversion of scrolling (#270)

This commit is contained in:
Xithrius 2022-12-19 20:59:58 -08:00 committed by GitHub
parent 21488160f7
commit 3d6d8b9701
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 91 additions and 19 deletions

View File

@ -53,3 +53,5 @@ theme = "dark"
username_highlight = true
# The shape of the cursor, block (default), underscore, or line.
cursor_shape = "block"
# If the scrolling should be inverted.
inverted_scrolling = false

View File

@ -61,7 +61,44 @@ impl ToString for State {
}
}
#[derive(Debug)]
pub struct Scrolling {
/// Offset of scroll
offset: usize,
/// If the scrolling is currently inverted
inverted: bool,
}
impl Scrolling {
pub const fn new(inverted: bool) -> Self {
Self {
offset: 0,
inverted,
}
}
/// Scrolling upwards, towards the start of the chat
pub fn up(&mut self) {
self.offset += 1;
}
/// Scrolling downwards, towards the most recent message(s)
pub fn down(&mut self) {
self.offset = self.offset.saturating_sub(1);
}
pub const fn inverted(&self) -> bool {
self.inverted
}
pub fn jump_to(&mut self, index: usize) {
self.offset = index;
}
pub const fn get_offset(&self) -> usize {
self.offset
}
}
pub struct App {
/// History of recorded messages (time, username, message, etc.)
pub messages: VecDeque<Data>,
@ -75,8 +112,8 @@ pub struct App {
pub input_buffer: LineBuffer,
/// The current suggestion, if any
pub buffer_suggestion: Option<String>,
/// Scrolling offset for the main window
pub scroll_offset: usize,
/// Interactions with scrolling of the application
pub scrolling: Scrolling,
/// The theme selected by the user
pub theme_style: Style,
}
@ -90,11 +127,11 @@ impl App {
state: config.terminal.start_state.clone(),
input_buffer: LineBuffer::with_capacity(INPUT_BUFFER_LIMIT),
buffer_suggestion: None,
scroll_offset: 0,
theme_style: match config.frontend.theme {
Theme::Light => BORDER_NAME_LIGHT,
_ => BORDER_NAME_DARK,
},
scrolling: Scrolling::new(config.frontend.inverted_scrolling),
}
}
@ -105,6 +142,25 @@ impl App {
pub fn clear_messages(&mut self) {
self.messages.clear();
self.scroll_offset = 0;
self.scrolling.jump_to(0);
}
#[allow(dead_code)]
pub fn rotate_theme(&mut self) {
todo!("Rotate through different themes")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_no_scroll_overflow_not_inverted() {
let mut scroll = Scrolling::new(false);
assert_eq!(scroll.get_offset(), 0);
scroll.down();
assert_eq!(scroll.get_offset(), 0);
}
}

View File

@ -107,6 +107,8 @@ pub struct FrontendConfig {
pub state_tabs: bool,
/// The shape of the cursor in insert boxes.
pub cursor_shape: CursorType,
/// If the scrolling should be inverted
pub inverted_scrolling: bool,
}
impl Default for TwitchConfig {
@ -147,6 +149,7 @@ impl Default for FrontendConfig {
username_highlight: true,
state_tabs: false,
cursor_shape: CursorType::default(),
inverted_scrolling: false,
}
}
}

View File

@ -188,19 +188,29 @@ async fn handle_insert_type_movements(action: &mut UserActionAttributes<'_, '_>)
fn handle_user_scroll(app: &mut App, key: Key) {
match app.state {
State::Insert | State::MessageSearch | State::Normal => match key {
Key::ScrollUp => {
if app.scroll_offset < app.messages.len() {
app.scroll_offset += 1;
State::Insert | State::MessageSearch | State::Normal => {
let limit = app.scrolling.get_offset() < app.messages.len();
match key {
Key::ScrollUp => {
if limit {
app.scrolling.up();
} else if app.scrolling.inverted() {
app.scrolling.down();
}
}
}
Key::ScrollDown => {
if app.scroll_offset > 0 {
app.scroll_offset -= 1;
Key::ScrollDown => {
if app.scrolling.inverted() {
if limit {
app.scrolling.up();
}
} else {
app.scrolling.down();
}
}
_ => {}
}
_ => {}
},
}
_ => {}
}
}
@ -251,7 +261,8 @@ pub async fn handle_stateful_user_input(
return Some(TerminalAction::Quitting);
}
Key::Esc => {
app.scroll_offset = 0;
app.scrolling.jump_to(0);
app.state = State::Normal;
}
_ => {}

View File

@ -119,8 +119,8 @@ pub async fn ui_driver(
app.messages.push_front(info);
// If scrolling is enabled, pad for more messages.
if app.scroll_offset > 0 {
app.scroll_offset += 1;
if app.scrolling.get_offset() > 0 {
app.scrolling.up();
}
}

View File

@ -139,7 +139,7 @@ pub fn draw_ui<T: Backend>(frame: &mut Frame<T>, app: &mut App, config: &Complet
let mut total_row_height: usize = 0;
let mut display_rows = VecDeque::new();
let mut scroll_offset = app.scroll_offset;
let mut scroll_offset = app.scrolling.get_offset();
let mut total_num_search_results = 0;
'outer: for data in &app.messages {