jes/src/core/BufferView.h

103 lines
3.1 KiB
C++

#ifndef BUFFERVIEW_H
#define BUFFERVIEW_H
#include "Buffer.h"
#include "CharacterWidthDeterminer.h"
#include <functional>
#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<Buffer::Iterator>(*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<Buffer::Iterator> iterator() const
{
return m_iterator;
}
protected:
BufferView & m_buffer_view;
std::shared_ptr<Buffer::Iterator> m_iterator;
int m_row_offset;
};
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);
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);
}
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<Buffer> m_buffer;
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_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<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);
};
#endif