1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/**
 * Flow - Realtime log analyzer
 * Copyright (C) 2016 Daniel Mircea
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

use std::cell::RefCell;

use ncurses::*;

use ui::color::COLOR_DEFAULT;
use ui::rendered_line::MatchedLine;

static WINDOW_HEIGHT: i32 = 2500;

pub struct Content {
    pub window: WINDOW,
    pub state: RefCell<State>,
}

impl Content {
    pub fn new(width: i32) -> Content {
        Content {
            window: newpad(WINDOW_HEIGHT, width),
            state: RefCell::new(State::default()),
        }
    }

    pub fn clear(&self) {
        wclear(self.window);
    }

    pub fn resize(&self, width: i32) {
        wresize(self.window, WINDOW_HEIGHT, width);
        wrefresh(self.window);
    }

    pub fn height(&self) -> i32 {
        let mut current_x: i32 = 0;
        let mut current_y: i32 = 0;
        getyx(self.window, &mut current_y, &mut current_x);

        current_y
    }

    pub fn calculate_height_change<F>(&self, callback: F) -> i32
        where F: Fn()
    {
        let initial_height = self.height();
        callback();
        self.height() - initial_height
    }

    pub fn highlighted_line(&self) -> MatchedLine {
        let state = self.state.borrow();

        MatchedLine::new(state.highlighted_line, state.highlighted_match)
    }
}

pub struct State {
    pub attributes: Vec<(usize, fn() -> u32)>,
    pub foreground: i16,
    pub background: i16,
    pub highlighted_line: usize,
    pub highlighted_match: usize,
}

impl State {
    pub fn default() -> State {
        State {
            attributes: vec![],
            foreground: COLOR_DEFAULT,
            background: COLOR_DEFAULT,
            highlighted_line: 0,
            highlighted_match: 0,
        }
    }

    pub fn remove_attribute(&mut self, attr_id: usize) {
        let index_option = self.attributes.iter().position(|cur| cur.0 == attr_id);

        if let Some(index) = index_option {
            self.attributes.remove(index);
        }
    }
}