125 lines
3.4 KiB
C++
125 lines
3.4 KiB
C++
#ifndef BUFFERVIEW_H
|
|
#define BUFFERVIEW_H
|
|
|
|
#include "Buffer.h"
|
|
#include "CharacterWidthDeterminer.h"
|
|
#include <functional>
|
|
#include "BufferLineWalker.h"
|
|
#include <vector>
|
|
|
|
/**
|
|
* 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:
|
|
enum class CursorMovement : uint8_t
|
|
{
|
|
LEFT,
|
|
RIGHT,
|
|
UP,
|
|
DOWN,
|
|
SOL,
|
|
EOL,
|
|
FIRST_LINE,
|
|
LAST_LINE,
|
|
SCREEN_ROW_UP,
|
|
SCREEN_ROW_DOWN,
|
|
};
|
|
|
|
class Iterator
|
|
{
|
|
public:
|
|
Iterator(BufferView & bv) : m_buffer_view(bv)
|
|
{
|
|
m_index = 0u;
|
|
}
|
|
void operator++()
|
|
{
|
|
(*this)++;
|
|
}
|
|
void operator++(int unused)
|
|
{
|
|
m_index++;
|
|
}
|
|
bool is_valid()
|
|
{
|
|
return m_index < m_buffer_view.m_lines.size();
|
|
}
|
|
int row_offset() const
|
|
{
|
|
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
|
|
{
|
|
return m_buffer_view.m_lines[m_index].line;
|
|
}
|
|
|
|
protected:
|
|
BufferView & m_buffer_view;
|
|
size_t m_index;
|
|
};
|
|
|
|
BufferView(std::shared_ptr<Buffer> buffer,
|
|
std::shared_ptr<Buffer::Iterator> iterator,
|
|
CharacterWidthDeterminer & character_width_determiner);
|
|
void resize(int width, int height);
|
|
void set_scroll_offset(int scroll_offset);
|
|
void update();
|
|
Iterator vert_iter();
|
|
BufferLineWalker horiz_iter(std::shared_ptr<Buffer::Iterator> start_of_line)
|
|
{
|
|
return BufferLineWalker(m_buffer, start_of_line, m_width, m_character_width_determiner);
|
|
}
|
|
bool cursor_move(CursorMovement which, bool allow_eol);
|
|
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; }
|
|
void set_cursor_screen_row(int cursor_screen_row)
|
|
{
|
|
m_cursor_screen_row = cursor_screen_row;
|
|
}
|
|
|
|
protected:
|
|
struct LineDescriptor
|
|
{
|
|
int row_offset;
|
|
int n_rows;
|
|
std::shared_ptr<Buffer::Iterator> line;
|
|
};
|
|
|
|
std::shared_ptr<Buffer> m_buffer;
|
|
std::shared_ptr<Buffer::Iterator> m_iterator;
|
|
std::vector<LineDescriptor> m_lines;
|
|
CharacterWidthDeterminer & m_character_width_determiner;
|
|
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;
|
|
int m_target_column;
|
|
bool m_update_target_column;
|
|
|
|
int effective_scroll_offset()
|
|
{
|
|
return std::min(m_scroll_offset, (m_height - 1) / 2);
|
|
}
|
|
void determine_new_cursor_screen_row();
|
|
int calculate_rows_in_line(std::shared_ptr<Buffer::Iterator> start_of_line);
|
|
int calculate_rows_in_cursor_line(std::shared_ptr<Buffer::Iterator> start_of_line);
|
|
int screen_rows_below_line(std::shared_ptr<Buffer::Iterator> line);
|
|
int screen_rows_above_line(
|
|
std::shared_ptr<Buffer::Iterator> line,
|
|
std::list<std::pair<int, std::shared_ptr<Buffer::Iterator>>> & backward_lines);
|
|
void move_forward_to_column(int to_column, bool allow_eol);
|
|
};
|
|
|
|
#endif
|