Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
francisdb committed Oct 4, 2023
1 parent de91b43 commit f7778ab
Show file tree
Hide file tree
Showing 2 changed files with 163 additions and 32 deletions.
56 changes: 54 additions & 2 deletions src/frontend/app.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,65 @@
use ratatui::widgets::ListState;

/// Application.

#[derive(Debug, Default)]
pub struct StatefulList<T> {
pub state: ListState,
pub items: Vec<T>,
}

impl<T> StatefulList<T> {
fn with_items(items: Vec<T>) -> StatefulList<T> {
StatefulList {
state: ListState::default(),
items,
}
}

fn next(&mut self) {
let i = match self.state.selected() {
Some(i) => {
if i >= self.items.len() - 1 {
0
} else {
i + 1
}
}
None => 0,
};
self.state.select(Some(i));
}

fn previous(&mut self) {
let i = match self.state.selected() {
Some(i) => {
if i == 0 {
self.items.len() - 1
} else {
i - 1
}
}
None => 0,
};
self.state.select(Some(i));
}

fn unselect(&mut self) {
self.state.select(None);
}
}

#[derive(Debug, Default)]
pub struct App {
pub struct App<'a> {
/// should the application exit?
pub should_quit: bool,
/// counter
pub counter: u8,

pub items: StatefulList<(&'a str, usize)>,
}

impl App {
impl<'a> App<'a> {
/// Constructs a new instance of [`App`].
pub fn new() -> Self {
Self::default()
Expand Down
139 changes: 109 additions & 30 deletions src/frontend/ui.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,109 @@
use ratatui::{
layout::Alignment,
style::{Color, Style},
widgets::{Block, BorderType, Borders, Paragraph},
};

use crate::{frontend::app::App, frontend::tui::Frame};

pub fn render(app: &mut App, f: &mut Frame) {
f.render_widget(
Paragraph::new(format!(
"
Press `Esc`, `Ctrl-C` or `q` to stop running.\n\
Press `j` and `k` to increment and decrement the counter respectively.\n\
Counter: {}
",
app.counter
))
.block(
Block::default()
.title("Counter App")
.title_alignment(Alignment::Center)
.borders(Borders::ALL)
.border_type(BorderType::Rounded),
)
.style(Style::default().fg(Color::Yellow))
.alignment(Alignment::Center),
f.size(),
)
}
use ratatui::layout::{Constraint, Direction, Layout, Rect};
use ratatui::prelude::Stylize;
use ratatui::style::Modifier;
use ratatui::text::Line;
use ratatui::widgets::{Clear, ListItem};
use ratatui::{
layout::Alignment,
style::{Color, Style},
widgets::{Block, BorderType, Borders, Paragraph},
};

use crate::{frontend::app::App, frontend::tui::Frame};

pub fn render(app: &mut App, f: &mut Frame) {
let chunks = Layout::default()
.direction(Direction::Horizontal)
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
.split(f.size());

// Iterate through all elements in the `items` app and append some debug text to it.
let items: Vec<ListItem> = app
.items
.items
.iter()
.map(|i| {
let mut lines = vec![Line::from(i.0)];
for _ in 0..i.1 {
lines.push(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit."
.italic()
.into(),
);
}
ListItem::new(lines).style(Style::default().fg(Color::Black).bg(Color::White))
})
.collect();

let items = ratatui::widgets::List::new(items)
.block(Block::default().borders(Borders::ALL).title("List"))
.highlight_style(
Style::default()
.bg(Color::LightGreen)
.add_modifier(Modifier::BOLD),
)
.highlight_symbol(">> ");

f.render_stateful_widget(items, chunks[0], &mut app.items.state);
f.render_widget(
Paragraph::new("Hello World!").block(
Block::default()
.borders(Borders::ALL)
.border_type(BorderType::Rounded),
),
chunks[1],
);

dialog(app, f);
}

fn dialog(app: &mut App, f: &mut Frame) {
let dialog_rect = centered_rect(f.size(), 50, 50);
f.render_widget(Clear, dialog_rect);
f.render_widget(
Paragraph::new(format!(
"
Press `Esc`, `Ctrl-C` or `q` to stop running.\n\
Press `j` and `k` to increment and decrement the counter respectively.\n\
Counter: {}
",
app.counter
))
.block(
Block::default()
.title("Counter App")
.title_alignment(Alignment::Center)
.borders(Borders::ALL)
.border_type(BorderType::Rounded),
)
.style(Style::default().fg(Color::Yellow))
.alignment(Alignment::Center),
dialog_rect,
)
}

fn centered_rect(r: Rect, percent_x: u16, percent_y: u16) -> Rect {
let popup_layout = Layout::default()
.direction(Direction::Vertical)
.constraints(
[
Constraint::Percentage((100 - percent_y) / 2),
Constraint::Percentage(percent_y),
Constraint::Percentage((100 - percent_y) / 2),
]
.as_ref(),
)
.split(r);

Layout::default()
.direction(Direction::Horizontal)
.constraints(
[
Constraint::Percentage((100 - percent_x) / 2),
Constraint::Percentage(percent_x),
Constraint::Percentage((100 - percent_x) / 2),
]
.as_ref(),
)
.split(popup_layout[1])[1]
}

0 comments on commit f7778ab

Please sign in to comment.