#pragma once #include #include #include enum WindowStatus { Normal, DoNewLine, }; class TerminalView : public UI::View { UI_OBJECT(); public: TerminalView(UI::View* superview, const LG::Rect&, int ptmx); TerminalView(UI::View* superview, UI::Window* window, const LG::Rect&, int ptmx); const LG::Color& font_color() const { return m_font_color; } const LG::Color cursor_color() const { return m_cursor_visible ? LG::Color(80, 80, 80, 255) : background_color(); } const LG::Color& background_color() const { return m_background_color; } inline const LG::Font& font() const { return *m_font_ptr; } inline int glyph_width() const { return font().glyph('.').width(); } inline int glyph_height() const { return font().size() + 2; } inline LG::Point pos_on_screen() const { return { (int)m_col * glyph_width() + padding(), (int)m_row * glyph_height() + padding() }; } inline int pos_in_data() const { return m_max_cols * m_row + m_col; } void put_char(char c); void put_text(const std::string& data); void display(const LG::Rect& rect) override; void receive_keyup_event(UI::KeyUpEvent&) override; void receive_keydown_event(UI::KeyDownEvent&) override; int ptmx() const { return m_ptmx; } private: void terminal_init(); WindowStatus cursor_positions_do_new_line(); WindowStatus cursor_position_move_right(); WindowStatus cursor_position_move_left(); void data_do_new_line(); inline void data_set_char(char c) { m_display_data[pos_in_data()] = c; } void scroll_line(); void new_line(); void increment_counter(); void decrement_counter(); void recalc_dimensions(const LG::Rect&); void push_back_char(char c); void send_input(); inline void invalidate_cursor_glyph() { auto pt = pos_on_screen(); set_needs_display(LG::Rect(pt.x(), pt.y(), cursor_width() + spacing(), glyph_height())); } inline void will_move_cursor() { invalidate_cursor_glyph(); } inline void did_move_cursor() { invalidate_cursor_glyph(); } constexpr int padding() const { return 2; } constexpr int spacing() const { return 2; } constexpr int cursor_width() const { return 5; } int m_ptmx { -1 }; std::string m_input {}; bool m_cursor_visible { true }; LG::Color m_background_color { LG::Color(47, 47, 53) }; LG::Color m_font_color { LG::Color::LightSystemText }; LG::Font* m_font_ptr { LG::Font::load_from_file("/res/fonts/Liza.font/10/regular.font") }; size_t m_max_cols { 0 }; size_t m_max_rows { 0 }; size_t m_col { 0 }; size_t m_row { 0 }; char* m_display_data { nullptr }; };