BufferPane: add ability to draw line number gutter
This commit is contained in:
parent
6d310f0f14
commit
1c673817d2
@ -1,4 +1,5 @@
|
||||
#include "BufferPane.h"
|
||||
#include <cmath>
|
||||
|
||||
int BufferPane::Cwd::operator()(uint32_t character)
|
||||
{
|
||||
@ -24,26 +25,53 @@ BufferPane::BufferPane(Window * window, std::shared_ptr<Buffer> buffer)
|
||||
m_buffer_view->set_scroll_offset(5);
|
||||
m_buffer_view->update();
|
||||
m_show_status_bar = true;
|
||||
m_show_line_number_gutter = true;
|
||||
m_command_mode = false;
|
||||
m_focused = false;
|
||||
m_rows = 0;
|
||||
m_columns = 0;
|
||||
}
|
||||
|
||||
void BufferPane::resize(int width, int height)
|
||||
{
|
||||
Pane::resize(width, height);
|
||||
m_columns = std::max(1, m_width / m_window->font()->get_advance());
|
||||
resize_buffer_view();
|
||||
}
|
||||
|
||||
void BufferPane::resize_buffer_view()
|
||||
{
|
||||
if (m_show_line_number_gutter)
|
||||
{
|
||||
int max_line_possible = 1;
|
||||
if (m_iterator->valid())
|
||||
{
|
||||
max_line_possible = std::min(m_iterator->line() + m_rows - m_buffer_view->cursor_screen_row(), m_buffer->end().line());
|
||||
}
|
||||
m_line_number_gutter_width = log10(max_line_possible) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_line_number_gutter_width = 0;
|
||||
}
|
||||
int columns = std::max(1, (m_width - col_x(0)) / m_window->font()->get_advance());
|
||||
int height_subtract = 0;
|
||||
if (m_show_status_bar)
|
||||
{
|
||||
height_subtract = m_window->font()->get_line_height() + 1;
|
||||
}
|
||||
m_rows = std::max(1, (m_height - height_subtract) / m_window->font()->get_line_height());
|
||||
m_buffer_view->resize(m_columns, m_rows);
|
||||
m_buffer_view->update();
|
||||
int rows = std::max(1, (m_height - height_subtract) / m_window->font()->get_line_height());
|
||||
if ((rows != m_rows) || (columns != m_columns))
|
||||
{
|
||||
m_rows = rows;
|
||||
m_columns = columns;
|
||||
m_buffer_view->resize(m_columns, m_rows);
|
||||
m_buffer_view->update();
|
||||
}
|
||||
}
|
||||
|
||||
void BufferPane::draw()
|
||||
{
|
||||
resize_buffer_view();
|
||||
if (m_iterator->valid())
|
||||
{
|
||||
for (auto line_iterator = m_buffer_view->vert_iter();
|
||||
@ -57,6 +85,10 @@ void BufferPane::draw()
|
||||
{
|
||||
draw_cursor(col_x(0), row_y(0), 0, 1);
|
||||
}
|
||||
if (m_show_line_number_gutter)
|
||||
{
|
||||
m_window->gl()->draw_rect(win_x(m_line_number_gutter_width * m_window->font()->get_advance() + 1), win_y(0), 1, m_height, 0.5, 0.5, 0.5, 1.0);
|
||||
}
|
||||
if (m_show_status_bar)
|
||||
{
|
||||
draw_status_bar();
|
||||
@ -82,6 +114,10 @@ void BufferPane::scroll_window_down(Window::ScrollMode scroll_mode)
|
||||
|
||||
void BufferPane::draw_buffer_line(int screen_row, std::shared_ptr<Buffer::Iterator> start_of_line)
|
||||
{
|
||||
if (m_show_line_number_gutter)
|
||||
{
|
||||
draw_line_number(screen_row, start_of_line->line());
|
||||
}
|
||||
int last_drawn_crosshair_row = -1;
|
||||
for (auto it = m_buffer_view->horiz_iter(start_of_line);
|
||||
it.is_valid();
|
||||
@ -96,7 +132,7 @@ void BufferPane::draw_buffer_line(int screen_row, std::shared_ptr<Buffer::Iterat
|
||||
if ((draw_row > last_drawn_crosshair_row) &&
|
||||
((!it.is_eol()) || (it.row_offset() == 0)))
|
||||
{
|
||||
draw_crosshair(0, row_y(draw_row), col_x(m_columns));
|
||||
draw_crosshair(col_x(0), row_y(draw_row), col_x(m_columns));
|
||||
last_drawn_crosshair_row = draw_row;
|
||||
}
|
||||
}
|
||||
@ -130,7 +166,7 @@ void BufferPane::draw_buffer_line(int screen_row, std::shared_ptr<Buffer::Iterat
|
||||
* did not do this then the draw_crosshair for the next
|
||||
* character on the new row would overwrite the wrapped
|
||||
* part of the cursor. */
|
||||
draw_crosshair(0, row_y(row), col_x(m_columns));
|
||||
draw_crosshair(col_x(0), row_y(row), col_x(m_columns));
|
||||
last_drawn_crosshair_row = row;
|
||||
}
|
||||
}
|
||||
@ -146,12 +182,12 @@ void BufferPane::draw_buffer_line(int screen_row, std::shared_ptr<Buffer::Iterat
|
||||
}
|
||||
else
|
||||
{
|
||||
draw_character(it.code_point(), draw_row, it.screen_column());
|
||||
draw_buffer_character(it.code_point(), draw_row, it.screen_column());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BufferPane::draw_character(uint32_t character, int screen_row, int screen_column)
|
||||
void BufferPane::draw_buffer_character(uint32_t character, int screen_row, int screen_column)
|
||||
{
|
||||
if ((character != ' ') &&
|
||||
(character != '\t') &&
|
||||
@ -221,6 +257,33 @@ void BufferPane::draw_crosshair(int x, int y, int width, int height)
|
||||
}
|
||||
}
|
||||
|
||||
void BufferPane::draw_line_number(int screen_row, size_t line_number)
|
||||
{
|
||||
if (screen_row >= 0)
|
||||
{
|
||||
char line_number_string[20];
|
||||
int length = snprintf(line_number_string, sizeof(line_number_string), "%lu", line_number + 1u);
|
||||
int x = (m_line_number_gutter_width - length) * m_window->font()->get_advance();
|
||||
int y = row_y(screen_row);
|
||||
float r, g;
|
||||
if (line_number == m_iterator->line())
|
||||
{
|
||||
r = 1.0;
|
||||
g = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = 0.6;
|
||||
g = 0.6;
|
||||
}
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
m_window->gl()->draw_character(win_x(x), win_y(y), line_number_string[i], *m_window->font(), r, g, 0.0, 1.0);
|
||||
x += m_window->font()->get_advance();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BufferPane::exit_insert_mode()
|
||||
{
|
||||
if (insert_mode())
|
||||
@ -408,6 +471,7 @@ void BufferPane::set_command_mode()
|
||||
{
|
||||
m_command_mode = true;
|
||||
set_show_status_bar(false);
|
||||
set_show_line_number_gutter(false);
|
||||
enter_insert_mode(Window::EnterInsertModeMode::START_OF_CHAR);
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,10 @@ public:
|
||||
{
|
||||
m_show_status_bar = show_status_bar;
|
||||
}
|
||||
void set_show_line_number_gutter(bool show_line_number_gutter)
|
||||
{
|
||||
m_show_line_number_gutter = show_line_number_gutter;
|
||||
}
|
||||
void set_command_mode();
|
||||
void set_focused(bool focused)
|
||||
{
|
||||
@ -55,12 +59,13 @@ public:
|
||||
|
||||
protected:
|
||||
void draw_buffer_line(int screen_row, std::shared_ptr<Buffer::Iterator> start_of_line);
|
||||
void draw_character(uint32_t character, int screen_row, int screen_column);
|
||||
void draw_buffer_character(uint32_t character, int screen_row, int screen_column);
|
||||
void draw_cursor(int x, int y, int i, int columns);
|
||||
void draw_crosshair(int x, int y, int width = -1, int height = -1);
|
||||
void draw_line_number(int screen_row, size_t line_number);
|
||||
int col_x(int col)
|
||||
{
|
||||
return col * m_window->font()->get_advance();
|
||||
return (m_line_number_gutter_width + col) * m_window->font()->get_advance() + (m_show_line_number_gutter ? 3 : 0);
|
||||
}
|
||||
int row_y(int row)
|
||||
{
|
||||
@ -70,6 +75,7 @@ protected:
|
||||
size_t display_column() const;
|
||||
void draw_status_bar();
|
||||
int calculate_lines_to_scroll(Window::ScrollMode scroll_mode);
|
||||
void resize_buffer_view();
|
||||
|
||||
Window * m_window;
|
||||
std::shared_ptr<Buffer> m_buffer;
|
||||
@ -77,9 +83,11 @@ protected:
|
||||
std::shared_ptr<BufferView> m_buffer_view;
|
||||
int m_rows;
|
||||
int m_columns;
|
||||
int m_line_number_gutter_width;
|
||||
std::shared_ptr<Buffer::Iterator> m_iterator;
|
||||
std::list<std::pair<int, Buffer::Iterator>> m_screen_lines;
|
||||
bool m_show_status_bar;
|
||||
bool m_show_line_number_gutter;
|
||||
bool m_command_mode;
|
||||
bool m_focused;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user