From b81906c318b4aac5f2c500ee35919562ff09da14 Mon Sep 17 00:00:00 2001 From: Val Lorentz Date: Wed, 1 Nov 2023 14:33:20 +0100 Subject: [PATCH] Add active buffer --- .config/config.json5 | 10 ++++++---- src/action.rs | 2 ++ src/app.rs | 16 ++++++++++++++-- src/buffers/log.rs | 31 +++++++++++++++++++++++++++++++ src/buffers/mod.rs | 35 ++++++++++++++++++++++++++++++----- src/components/buflist.rs | 12 +++++++++--- src/components/home.rs | 6 +++++- src/plugins/core.rs | 12 +++++++++++- 8 files changed, 108 insertions(+), 16 deletions(-) create mode 100644 src/buffers/log.rs diff --git a/.config/config.json5 b/.config/config.json5 index 8189b8d..36f527e 100644 --- a/.config/config.json5 +++ b/.config/config.json5 @@ -7,10 +7,12 @@ ], "keybindings": { "Home": { - "": "/quit", // Quit the application - "": "/quit", // Another way to quit - "": "/quit", // Yet another way to quit - "": "/suspend" // Suspend the application + "": "/quit", + "": "/quit", + "": "/quit", + "": "/suspend", + "": "/previous", + "": "/next", }, } } diff --git a/src/action.rs b/src/action.rs index 7ed2b77..38e97ed 100644 --- a/src/action.rs +++ b/src/action.rs @@ -15,6 +15,8 @@ pub enum Action { Quit, Refresh, Error(String), + PreviousBuffer, + NextBuffer, Help, } diff --git a/src/app.rs b/src/app.rs index 329d35e..1896520 100644 --- a/src/app.rs +++ b/src/app.rs @@ -28,7 +28,7 @@ use tokio::sync::mpsc; use crate::{ action::Action, - buffers::{Buffers, RoomBuffer}, + buffers::{Buffers, LogBuffer, RoomBuffer}, commands::RataCommands, components::{Component, FpsCounter, Home}, config::Config, @@ -116,7 +116,7 @@ impl App { components: vec![Box::new(home), Box::new(fps)], should_quit: AtomicBool::new(false), should_suspend: false, - buffers: Buffers::new(), + buffers: Buffers::new(Box::new(LogBuffer::new())), clients, config, commands: RataCommands::new(), @@ -223,6 +223,18 @@ impl App { Action::Quit => self.should_quit.store(true, Ordering::Release), Action::Suspend => self.should_suspend = true, Action::Resume => self.should_suspend = false, + Action::NextBuffer => { + // self.buffer implements wrap-around itself + self + .buffers + .set_active_index(self.buffers.active_index() as isize + 1) + }, + Action::PreviousBuffer => { + // self.buffer implements wrap-around itself + self + .buffers + .set_active_index(self.buffers.active_index() as isize - 1) + }, Action::Resize(w, h) => { tui.resize(Rect::new(0, 0, w, h))?; tui.draw(|f| { diff --git a/src/buffers/log.rs b/src/buffers/log.rs new file mode 100644 index 0000000..488c83f --- /dev/null +++ b/src/buffers/log.rs @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2023 Valentin Lorentz + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +use super::Buffer; + +pub struct LogBuffer {} + +impl LogBuffer { + pub fn new() -> Self { + LogBuffer {} + } +} + +impl Buffer for LogBuffer { + fn short_name(&self) -> String { + "ratatrix".to_owned() + } +} diff --git a/src/buffers/mod.rs b/src/buffers/mod.rs index 1f645c4..4fd5a86 100644 --- a/src/buffers/mod.rs +++ b/src/buffers/mod.rs @@ -14,6 +14,10 @@ * along with this program. If not, see . */ +use nonempty::NonEmpty; + +mod log; +pub use log::LogBuffer; mod room; pub use room::RoomBuffer; @@ -22,18 +26,39 @@ pub trait Buffer { fn short_name(&self) -> String; } -pub struct Buffers(Vec>); +pub struct Buffers { + buffers: NonEmpty>, + active_index: usize, +} impl Buffers { - pub fn new() -> Self { - Self(Vec::new()) + pub fn new(initial_buffer: Box) -> Self { + Self { + buffers: NonEmpty::new(initial_buffer), + active_index: 0, + } } pub fn iter(&self) -> impl Iterator { - self.0.iter().map(|buffer_box| &**buffer_box) + self.buffers.iter().map(|buffer_box| &**buffer_box) } pub fn push(&mut self, buffer: Box) { - self.0.push(buffer) + self.buffers.push(buffer) + } + + pub fn active_index(&self) -> usize { + self.active_index + } + + pub fn set_active_index(&mut self, index: isize) { + self.active_index = index.wrapping_rem_euclid(self.buffers.len() as isize) as usize; + } + + pub fn active_buffer(&self) -> &dyn Buffer { + &**self + .buffers + .get(self.active_index) + .expect("Active buffer index does not exist") } } diff --git a/src/components/buflist.rs b/src/components/buflist.rs index 2136917..f337ccc 100644 --- a/src/components/buflist.rs +++ b/src/components/buflist.rs @@ -67,9 +67,15 @@ impl Component for Buflist { Paragraph::new( buffers .iter() - .map(|buf| buf.short_name()) - .collect::>() - .join("\n"), + .enumerate() + .map(|(i, buf)| { + let mut style = Style::default(); + if i == buffers.active_index() { + style = style.bold(); + } + Span::styled(buf.short_name(), style).into() + }) + .collect::>>(), ) .block(Block::new().borders(Borders::ALL)), area, diff --git a/src/components/home.rs b/src/components/home.rs index 4a93a06..d2f2f26 100644 --- a/src/components/home.rs +++ b/src/components/home.rs @@ -67,7 +67,11 @@ impl Component for Home { .draw(frame, layout[0], buffers) .context("Error drawing buflist")?; frame.render_widget( - Paragraph::new("buffer goes here").block(Block::new().borders(Borders::ALL)), + Paragraph::new(format!( + "content of {} goes here", + buffers.active_buffer().short_name() + )) + .block(Block::new().borders(Borders::ALL)), layout[1], ); Ok(()) diff --git a/src/plugins/core.rs b/src/plugins/core.rs index 5b61592..98358b4 100644 --- a/src/plugins/core.rs +++ b/src/plugins/core.rs @@ -51,6 +51,16 @@ impl PrePlugin for Core { "Puts the process in the background", Action::Suspend, )); + app.commands.register(ActionCommand::new( + "previous", + "Makes the previous buffer active", + Action::PreviousBuffer, + )); + app.commands.register(ActionCommand::new( + "next", + "Makes the next buffer active", + Action::NextBuffer, + )); Ok(self) } } @@ -81,7 +91,7 @@ impl RataCommand for ActionCommand { Box::new(move |_name, _args, action_tx| { action_tx .send(action.clone()) - .context("Could not queue quit action") + .context("Could not queue action") }) } }