BufferView stores all lines in view after update()

This commit is contained in:
Josh Holtrop 2017-09-03 17:31:56 -04:00
parent 4b3e1ea7e7
commit 5b35a35b24
2 changed files with 39 additions and 27 deletions

View File

@ -66,21 +66,34 @@ void BufferView::update()
m_cursor_screen_row = std::min(rows_above, m_cursor_screen_row); m_cursor_screen_row = std::min(rows_above, m_cursor_screen_row);
/* Determine the first line that is visible in this view. */ /* Determine the first line that is visible in this view. */
m_first_line = std::make_shared<Buffer::Iterator>(*m_iterator); auto line_iterator = std::make_shared<Buffer::Iterator>(*m_iterator);
m_first_line_row_offset = m_cursor_screen_row - m_cursor_row_offset; int row_offset = m_cursor_screen_row - m_cursor_row_offset;
if (m_first_line_row_offset <= 0) if (row_offset <= 0)
{ {
m_first_line->go_start_of_line(); line_iterator->go_start_of_line();
} }
else for (auto rows_iterator_pair : backward_lines) else for (auto rows_iterator_pair : backward_lines)
{ {
m_first_line_row_offset -= rows_iterator_pair.first; row_offset -= rows_iterator_pair.first;
m_first_line = rows_iterator_pair.second; line_iterator = rows_iterator_pair.second;
if (m_first_line_row_offset <= 0) if (row_offset <= 0)
{ {
break; break;
} }
} }
/* Now start with first visible line and build up all lines visible in the view. */
m_lines.clear();
while ((row_offset < m_height) && (line_iterator->valid()))
{
LineDescriptor ld;
ld.row_offset = row_offset;
ld.n_rows = calculate_rows_in_line(line_iterator);
ld.line = std::make_shared<Buffer::Iterator>(*line_iterator);
m_lines.push_back(ld);
row_offset += ld.n_rows;
line_iterator->go_next_line();
}
} }
int BufferView::calculate_rows_in_line(std::shared_ptr<Buffer::Iterator> start_of_line) int BufferView::calculate_rows_in_line(std::shared_ptr<Buffer::Iterator> start_of_line)

View File

@ -5,6 +5,7 @@
#include "CharacterWidthDeterminer.h" #include "CharacterWidthDeterminer.h"
#include <functional> #include <functional>
#include "BufferLineWalker.h" #include "BufferLineWalker.h"
#include <vector>
/** /**
* Tracks a "view" of a buffer, which is a two-dimensional grid of characters * Tracks a "view" of a buffer, which is a two-dimensional grid of characters
@ -18,11 +19,7 @@ public:
public: public:
Iterator(BufferView & bv) : m_buffer_view(bv) Iterator(BufferView & bv) : m_buffer_view(bv)
{ {
if (bv.m_iterator->valid()) m_index = 0u;
{
m_iterator = std::make_shared<Buffer::Iterator>(*m_buffer_view.m_first_line);
m_row_offset = m_buffer_view.m_first_line_row_offset;
}
} }
void operator++() void operator++()
{ {
@ -30,32 +27,28 @@ public:
} }
void operator++(int unused) void operator++(int unused)
{ {
if (is_valid()) m_index++;
{
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() bool is_valid()
{ {
return (bool)m_iterator; return m_index < m_buffer_view.m_lines.size();
} }
int row_offset() const int row_offset() const
{ {
return m_row_offset; return m_buffer_view.m_lines[m_index].row_offset;
}
int n_rows() const
{
return m_buffer_view.m_lines[m_index].n_rows;
} }
std::shared_ptr<Buffer::Iterator> iterator() const std::shared_ptr<Buffer::Iterator> iterator() const
{ {
return m_iterator; return m_buffer_view.m_lines[m_index].line;
} }
protected: protected:
BufferView & m_buffer_view; BufferView & m_buffer_view;
std::shared_ptr<Buffer::Iterator> m_iterator; size_t m_index;
int m_row_offset;
}; };
BufferView(std::shared_ptr<Buffer> buffer, BufferView(std::shared_ptr<Buffer> buffer,
@ -75,8 +68,6 @@ public:
protected: protected:
std::shared_ptr<Buffer> m_buffer; std::shared_ptr<Buffer> m_buffer;
std::shared_ptr<Buffer::Iterator> m_iterator; std::shared_ptr<Buffer::Iterator> m_iterator;
std::shared_ptr<Buffer::Iterator> m_first_line;
int m_first_line_row_offset;
int m_width; int m_width;
int m_height; int m_height;
int m_scroll_offset; int m_scroll_offset;
@ -86,6 +77,13 @@ protected:
int m_cursor_row_offset; int m_cursor_row_offset;
CharacterWidthDeterminer & m_character_width_determiner; CharacterWidthDeterminer & m_character_width_determiner;
struct LineDescriptor
{
int row_offset;
int n_rows;
std::shared_ptr<Buffer::Iterator> line;
};
int effective_scroll_offset() int effective_scroll_offset()
{ {
return std::min(m_scroll_offset, (m_height - 1) / 2); return std::min(m_scroll_offset, (m_height - 1) / 2);
@ -97,6 +95,7 @@ protected:
int screen_rows_above_line( int screen_rows_above_line(
std::shared_ptr<Buffer::Iterator> line, std::shared_ptr<Buffer::Iterator> line,
std::list<std::pair<int, std::shared_ptr<Buffer::Iterator>>> & backward_lines); std::list<std::pair<int, std::shared_ptr<Buffer::Iterator>>> & backward_lines);
std::vector<LineDescriptor> m_lines;
}; };
#endif #endif