Add active buffer

This commit is contained in:
2023-11-01 14:33:20 +01:00
parent 41bf892e74
commit b81906c318
8 changed files with 108 additions and 16 deletions

View File

@ -7,10 +7,12 @@
],
"keybindings": {
"Home": {
"<q>": "/quit", // Quit the application
"<Ctrl-d>": "/quit", // Another way to quit
"<Ctrl-c>": "/quit", // Yet another way to quit
"<Ctrl-z>": "/suspend" // Suspend the application
"<q>": "/quit",
"<Ctrl-d>": "/quit",
"<Ctrl-c>": "/quit",
"<Ctrl-z>": "/suspend",
"<Alt-left>": "/previous",
"<Alt-right>": "/next",
},
}
}

View File

@ -15,6 +15,8 @@ pub enum Action {
Quit,
Refresh,
Error(String),
PreviousBuffer,
NextBuffer,
Help,
}

View File

@ -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| {

31
src/buffers/log.rs Normal file
View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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()
}
}

View File

@ -14,6 +14,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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<Box<dyn Buffer>>);
pub struct Buffers {
buffers: NonEmpty<Box<dyn Buffer>>,
active_index: usize,
}
impl Buffers {
pub fn new() -> Self {
Self(Vec::new())
pub fn new(initial_buffer: Box<dyn Buffer>) -> Self {
Self {
buffers: NonEmpty::new(initial_buffer),
active_index: 0,
}
}
pub fn iter(&self) -> impl Iterator<Item = &dyn Buffer> {
self.0.iter().map(|buffer_box| &**buffer_box)
self.buffers.iter().map(|buffer_box| &**buffer_box)
}
pub fn push(&mut self, buffer: Box<dyn Buffer>) {
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")
}
}

View File

@ -67,9 +67,15 @@ impl Component for Buflist {
Paragraph::new(
buffers
.iter()
.map(|buf| buf.short_name())
.collect::<Vec<_>>()
.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::<Vec<Line<'_>>>(),
)
.block(Block::new().borders(Borders::ALL)),
area,

View File

@ -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(())

View File

@ -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")
})
}
}