done for today
This commit is contained in:
@@ -6,199 +6,13 @@ use ratatui::{
|
||||
Frame,
|
||||
};
|
||||
|
||||
use crate::app::{App, CurrentScreen, CurrentlyEditing};
|
||||
use crate::app::App;
|
||||
|
||||
// ANCHOR: method_sig
|
||||
pub fn ui(frame: &mut Frame, app: &App) {
|
||||
// ANCHOR_END: method_sig
|
||||
// Create the layout sections.
|
||||
// ANCHOR: ui_layout
|
||||
let chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints([
|
||||
Constraint::Length(3),
|
||||
Constraint::Min(1),
|
||||
Constraint::Length(3),
|
||||
])
|
||||
.split(frame.area());
|
||||
// ANCHOR_END: ui_layout
|
||||
|
||||
// ANCHOR: title_paragraph
|
||||
let title_block = Block::default()
|
||||
.borders(Borders::ALL)
|
||||
.style(Style::default());
|
||||
|
||||
let title = Paragraph::new(Text::styled(
|
||||
"Create New Json",
|
||||
Style::default().fg(Color::Green),
|
||||
))
|
||||
.block(title_block);
|
||||
|
||||
frame.render_widget(title, chunks[0]);
|
||||
// ANCHOR_END: title_paragraph
|
||||
// ANCHOR: key_value_list
|
||||
let mut list_items = Vec::<ListItem>::new();
|
||||
|
||||
for key in app.pairs.keys() {
|
||||
list_items.push(ListItem::new(Line::from(Span::styled(
|
||||
format!("{: <25} : {}", key, app.pairs.get(key).unwrap()),
|
||||
Style::default().fg(Color::Yellow),
|
||||
))));
|
||||
}
|
||||
|
||||
let list = List::new(list_items);
|
||||
|
||||
frame.render_widget(list, chunks[1]);
|
||||
// ANCHOR_END: key_value_list
|
||||
// ANCHOR: lower_navigation_current_screen
|
||||
let current_navigation_text = vec![
|
||||
// The first half of the text
|
||||
match app.current_screen {
|
||||
CurrentScreen::Main => Span::styled("Normal Mode", Style::default().fg(Color::Green)),
|
||||
CurrentScreen::Editing => {
|
||||
Span::styled("Editing Mode", Style::default().fg(Color::Yellow))
|
||||
}
|
||||
CurrentScreen::Exiting => Span::styled("Exiting", Style::default().fg(Color::LightRed)),
|
||||
}
|
||||
.to_owned(),
|
||||
// A white divider bar to separate the two sections
|
||||
Span::styled(" | ", Style::default().fg(Color::White)),
|
||||
// The final section of the text, with hints on what the user is editing
|
||||
{
|
||||
if let Some(editing) = &app.currently_editing {
|
||||
match editing {
|
||||
CurrentlyEditing::Key => {
|
||||
Span::styled("Editing Json Key", Style::default().fg(Color::Green))
|
||||
}
|
||||
CurrentlyEditing::Value => {
|
||||
Span::styled("Editing Json Value", Style::default().fg(Color::LightGreen))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Span::styled("Not Editing Anything", Style::default().fg(Color::DarkGray))
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
let mode_footer = Paragraph::new(Line::from(current_navigation_text))
|
||||
.block(Block::default().borders(Borders::ALL));
|
||||
// ANCHOR_END: lower_navigation_current_screen
|
||||
|
||||
// ANCHOR: lower_navigation_key_hint
|
||||
let current_keys_hint = {
|
||||
match app.current_screen {
|
||||
CurrentScreen::Main => Span::styled(
|
||||
"(q) to quit / (e) to make new pair",
|
||||
Style::default().fg(Color::Red),
|
||||
),
|
||||
CurrentScreen::Editing => Span::styled(
|
||||
"(ESC) to cancel/(Tab) to switch boxes/enter to complete",
|
||||
Style::default().fg(Color::Red),
|
||||
),
|
||||
CurrentScreen::Exiting => Span::styled(
|
||||
"(q) to quit / (e) to make new pair",
|
||||
Style::default().fg(Color::Red),
|
||||
),
|
||||
}
|
||||
};
|
||||
|
||||
let key_notes_footer =
|
||||
Paragraph::new(Line::from(current_keys_hint)).block(Block::default().borders(Borders::ALL));
|
||||
// ANCHOR_END: lower_navigation_key_hint
|
||||
|
||||
// ANCHOR: lower_navigation_layout
|
||||
let footer_chunks = Layout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
|
||||
.split(chunks[2]);
|
||||
// ANCHOR_END: lower_navigation_layout
|
||||
|
||||
// ANCHOR: lower_navigation_rendering
|
||||
frame.render_widget(mode_footer, footer_chunks[0]);
|
||||
frame.render_widget(key_notes_footer, footer_chunks[1]);
|
||||
// ANCHOR_END: lower_navigation_rendering
|
||||
|
||||
// ANCHOR: editing_popup
|
||||
if let Some(editing) = &app.currently_editing {
|
||||
let popup_block = Block::default()
|
||||
.title("Enter a new key-value pair")
|
||||
.borders(Borders::NONE)
|
||||
.style(Style::default().bg(Color::DarkGray));
|
||||
|
||||
let area = centered_rect(60, 25, frame.area());
|
||||
frame.render_widget(popup_block, area);
|
||||
// ANCHOR_END: editing_popup
|
||||
|
||||
// ANCHOR: popup_layout
|
||||
let popup_chunks = Layout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
.margin(1)
|
||||
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
|
||||
.split(area);
|
||||
// ANCHOR_END: popup_layout
|
||||
|
||||
// ANCHOR: key_value_blocks
|
||||
let mut key_block = Block::default().title("Key").borders(Borders::ALL);
|
||||
let mut value_block = Block::default().title("Value").borders(Borders::ALL);
|
||||
|
||||
let active_style = Style::default().bg(Color::LightYellow).fg(Color::Black);
|
||||
|
||||
match editing {
|
||||
CurrentlyEditing::Key => key_block = key_block.style(active_style),
|
||||
CurrentlyEditing::Value => value_block = value_block.style(active_style),
|
||||
};
|
||||
|
||||
let key_text = Paragraph::new(app.key_input.clone()).block(key_block);
|
||||
frame.render_widget(key_text, popup_chunks[0]);
|
||||
|
||||
let value_text = Paragraph::new(app.value_input.clone()).block(value_block);
|
||||
frame.render_widget(value_text, popup_chunks[1]);
|
||||
}
|
||||
// ANCHOR_END: key_value_blocks
|
||||
|
||||
// ANCHOR: exit_screen
|
||||
if let CurrentScreen::Exiting = app.current_screen {
|
||||
frame.render_widget(Clear, frame.area()); //this clears the entire screen and anything already drawn
|
||||
let popup_block = Block::default()
|
||||
.title("Y/N")
|
||||
.borders(Borders::NONE)
|
||||
.style(Style::default().bg(Color::DarkGray));
|
||||
|
||||
let exit_text = Text::styled(
|
||||
"Would you like to output the buffer as json? (y/n)",
|
||||
Style::default().fg(Color::Red),
|
||||
);
|
||||
// the `trim: false` will stop the text from being cut off when over the edge of the block
|
||||
let exit_paragraph = Paragraph::new(exit_text)
|
||||
.block(popup_block)
|
||||
.wrap(Wrap { trim: false });
|
||||
|
||||
let area = centered_rect(60, 25, frame.area());
|
||||
frame.render_widget(exit_paragraph, area);
|
||||
}
|
||||
// ANCHOR_END: exit_screen
|
||||
}
|
||||
|
||||
// ANCHOR: centered_rect
|
||||
/// helper function to create a centered rect using up certain percentage of the available rect `r`
|
||||
fn centered_rect(percent_x: u16, percent_y: u16, r: Rect) -> Rect {
|
||||
// Cut the given rectangle into three vertical pieces
|
||||
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),
|
||||
])
|
||||
.split(r);
|
||||
pub fn render(frame: &mut Frame, app: &mut App) {
|
||||
|
||||
// Then cut the middle vertical piece into three width-wise pieces
|
||||
Layout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
.constraints([
|
||||
Constraint::Percentage((100 - percent_x) / 2),
|
||||
Constraint::Percentage(percent_x),
|
||||
Constraint::Percentage((100 - percent_x) / 2),
|
||||
])
|
||||
.split(popup_layout[1])[1] // Return the middle chunk
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user