#ifndef BUFFERVIEW_H #define BUFFERVIEW_H #include "Buffer.h" #include "CharacterWidthDeterminer.h" #include #include "BufferLineWalker.h" /** * Tracks a "view" of a buffer, which is a two-dimensional grid of characters * that displays a section of a buffer's contents. */ class BufferView { public: class Iterator { public: Iterator(BufferView & bv) : m_buffer_view(bv) { if (bv.m_iterator->valid()) { m_iterator = std::make_shared(*m_buffer_view.m_first_line); m_row_offset = m_buffer_view.m_first_line_row_offset; } } void operator++() { (*this)++; } void operator++(int unused) { if (is_valid()) { m_row_offset += m_buffer_view.calculate_rows_in_line(m_iterator); if ((m_row_offset >= m_buffer_view.m_height) || (!m_iterator->go_next_line())) { m_iterator.reset(); } } } bool is_valid() { return (bool)m_iterator; } int row_offset() const { return m_row_offset; } std::shared_ptr iterator() const { return m_iterator; } protected: BufferView & m_buffer_view; std::shared_ptr m_iterator; int m_row_offset; }; BufferView(std::shared_ptr buffer, std::shared_ptr iterator, CharacterWidthDeterminer & character_width_determiner); void resize(int width, int height); void set_scroll_offset(int scroll_offset); Iterator vert_iter(); BufferLineWalker horiz_iter(std::shared_ptr start_of_line) { return BufferLineWalker(m_buffer, start_of_line, m_width, m_character_width_determiner); } int cursor_screen_row() const { return m_cursor_screen_row; } int cursor_screen_column() const { return m_cursor_screen_column; } int cursor_virtual_column() const { return m_cursor_virtual_column; } protected: std::shared_ptr m_buffer; std::shared_ptr m_iterator; std::shared_ptr m_first_line; int m_first_line_row_offset; int m_width; int m_height; int m_scroll_offset; int m_cursor_screen_row; int m_cursor_screen_column; int m_cursor_virtual_column; int m_cursor_row_offset; CharacterWidthDeterminer & m_character_width_determiner; int effective_scroll_offset() { return std::min(m_scroll_offset, (m_height - 1) / 2); } void update(); int calculate_rows_in_line(std::shared_ptr start_of_line); int calculate_rows_in_cursor_line(std::shared_ptr start_of_line); int screen_rows_below_line(std::shared_ptr line); int screen_rows_above_line( std::shared_ptr line, std::list>> & backward_lines); }; #endif