use ncurses::*;
use core::buffer::BufferLines;
use ui::readline;
use ui::color;
use ui::input::read_key;
use ui::event::{EventBuilder, Event};
use ui::navigation::{Navigation, HEIGHT as NAVIGATION_HEIGHT};
use ui::content::Content;
use ui::printer::LinesPrinter;
use ui::search::Query;
use ui::rendered_line::RenderedLineCollection;
pub static NORMAL_HIGHLIGHT_COLOR: i16 = 5;
pub static CURRENT_HIGHLIGHT_COLOR: i16 = 6;
pub struct Frame {
pub width: i32,
pub height: i32,
pub rendered_lines: RenderedLineCollection,
pub initial_rendered_lines: Option<RenderedLineCollection>,
pub navigation: Navigation,
pub content: Content,
}
impl Frame {
pub fn new(menu_item_names: Vec<String>) -> Frame {
env_init();
readline::init();
ncurses_init();
color::generate_pairs();
Frame {
width: COLS(),
height: LINES(),
rendered_lines: RenderedLineCollection::default(),
initial_rendered_lines: None,
navigation: Navigation::new(LINES() - NAVIGATION_HEIGHT, 0, &menu_item_names),
content: Content::new(COLS()),
}
}
pub fn render(&self) {
readline::render("Search:", self.navigation.search.input_field.window);
self.navigation.render();
}
pub fn select_left_menu_item(&self) {
self.navigation.menu.select(REQ_LEFT_ITEM);
}
pub fn select_right_menu_item(&self) {
self.navigation.menu.select(REQ_RIGHT_ITEM);
}
pub fn destroy(&self) {
self.navigation.destroy();
endwin();
readline::terminate();
}
pub fn resize(&mut self) {
getmaxyx(stdscr(), &mut self.height, &mut self.width);
self.content.resize(self.width);
self.navigation.resize(self.width, self.content_height());
}
pub fn print(&mut self, buffer_lines: &mut BufferLines, query: Option<Query>) {
buffer_lines.width = self.width as usize;
LinesPrinter::new(self, buffer_lines, query).draw();
self.scroll(buffer_lines.buffer.reverse_index.get() as i32);
}
pub fn scroll(&self, reversed_offset: i32) {
let offset = self.rendered_lines.height() - self.height + NAVIGATION_HEIGHT -
reversed_offset;
prefresh(self.content.window,
offset,
0,
0,
0,
self.content_height() - 1,
self.width);
}
pub fn watch(&self) -> Event {
let (input, key) = read_key();
EventBuilder::new(input, key).construct(&self.navigation.state)
}
pub fn reset(&mut self) {
self.rendered_lines.clear();
self.initial_rendered_lines = None;
self.content.clear();
self.navigation.search.matches_found = false;
}
pub fn max_scroll_value(&self) -> usize {
(self.rendered_lines.height() - self.content_height()) as usize
}
pub fn content_height(&self) -> i32 {
self.height - NAVIGATION_HEIGHT
}
pub fn replace_rendered_lines(&mut self, rendered_lines: RenderedLineCollection) {
if self.initial_rendered_lines.is_none() {
self.initial_rendered_lines = Some(self.rendered_lines.clone());
}
self.rendered_lines = rendered_lines;
}
}
fn env_init() {
::std::env::set_var("ESCDELAY", "25");
setlocale(LcCategory::all, "");
}
fn ncurses_init() {
initscr();
start_color();
use_default_colors();
cbreak();
noecho();
curs_set(CURSOR_VISIBILITY::CURSOR_INVISIBLE);
halfdelay(1);
keypad(stdscr(), true);
init_pair(1, COLOR_WHITE, COLOR_BLUE);
init_pair(2, COLOR_BLACK, COLOR_YELLOW);
init_pair(3, COLOR_YELLOW, COLOR_BLUE);
init_pair(4, COLOR_WHITE, COLOR_MAGENTA);
init_pair(5, COLOR_BLACK, COLOR_WHITE);
init_pair(6, COLOR_BLACK, COLOR_YELLOW);
}