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 "BufferPane.h"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
int BufferPane::Cwd::operator()(uint32_t character)
|
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->set_scroll_offset(5);
|
||||||
m_buffer_view->update();
|
m_buffer_view->update();
|
||||||
m_show_status_bar = true;
|
m_show_status_bar = true;
|
||||||
|
m_show_line_number_gutter = true;
|
||||||
m_command_mode = false;
|
m_command_mode = false;
|
||||||
m_focused = false;
|
m_focused = false;
|
||||||
|
m_rows = 0;
|
||||||
|
m_columns = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BufferPane::resize(int width, int height)
|
void BufferPane::resize(int width, int height)
|
||||||
{
|
{
|
||||||
Pane::resize(width, 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;
|
int height_subtract = 0;
|
||||||
if (m_show_status_bar)
|
if (m_show_status_bar)
|
||||||
{
|
{
|
||||||
height_subtract = m_window->font()->get_line_height() + 1;
|
height_subtract = m_window->font()->get_line_height() + 1;
|
||||||
}
|
}
|
||||||
m_rows = std::max(1, (m_height - height_subtract) / m_window->font()->get_line_height());
|
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->resize(m_columns, m_rows);
|
||||||
m_buffer_view->update();
|
m_buffer_view->update();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BufferPane::draw()
|
void BufferPane::draw()
|
||||||
{
|
{
|
||||||
|
resize_buffer_view();
|
||||||
if (m_iterator->valid())
|
if (m_iterator->valid())
|
||||||
{
|
{
|
||||||
for (auto line_iterator = m_buffer_view->vert_iter();
|
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);
|
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)
|
if (m_show_status_bar)
|
||||||
{
|
{
|
||||||
draw_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)
|
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;
|
int last_drawn_crosshair_row = -1;
|
||||||
for (auto it = m_buffer_view->horiz_iter(start_of_line);
|
for (auto it = m_buffer_view->horiz_iter(start_of_line);
|
||||||
it.is_valid();
|
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) &&
|
if ((draw_row > last_drawn_crosshair_row) &&
|
||||||
((!it.is_eol()) || (it.row_offset() == 0)))
|
((!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;
|
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
|
* did not do this then the draw_crosshair for the next
|
||||||
* character on the new row would overwrite the wrapped
|
* character on the new row would overwrite the wrapped
|
||||||
* part of the cursor. */
|
* 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;
|
last_drawn_crosshair_row = row;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,12 +182,12 @@ void BufferPane::draw_buffer_line(int screen_row, std::shared_ptr<Buffer::Iterat
|
|||||||
}
|
}
|
||||||
else
|
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 != ' ') &&
|
if ((character != ' ') &&
|
||||||
(character != '\t') &&
|
(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()
|
void BufferPane::exit_insert_mode()
|
||||||
{
|
{
|
||||||
if (insert_mode())
|
if (insert_mode())
|
||||||
@ -408,6 +471,7 @@ void BufferPane::set_command_mode()
|
|||||||
{
|
{
|
||||||
m_command_mode = true;
|
m_command_mode = true;
|
||||||
set_show_status_bar(false);
|
set_show_status_bar(false);
|
||||||
|
set_show_line_number_gutter(false);
|
||||||
enter_insert_mode(Window::EnterInsertModeMode::START_OF_CHAR);
|
enter_insert_mode(Window::EnterInsertModeMode::START_OF_CHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +45,10 @@ public:
|
|||||||
{
|
{
|
||||||
m_show_status_bar = show_status_bar;
|
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_command_mode();
|
||||||
void set_focused(bool focused)
|
void set_focused(bool focused)
|
||||||
{
|
{
|
||||||
@ -55,12 +59,13 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void draw_buffer_line(int screen_row, std::shared_ptr<Buffer::Iterator> start_of_line);
|
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_cursor(int x, int y, int i, int columns);
|
||||||
void draw_crosshair(int x, int y, int width = -1, int height = -1);
|
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)
|
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)
|
int row_y(int row)
|
||||||
{
|
{
|
||||||
@ -70,6 +75,7 @@ protected:
|
|||||||
size_t display_column() const;
|
size_t display_column() const;
|
||||||
void draw_status_bar();
|
void draw_status_bar();
|
||||||
int calculate_lines_to_scroll(Window::ScrollMode scroll_mode);
|
int calculate_lines_to_scroll(Window::ScrollMode scroll_mode);
|
||||||
|
void resize_buffer_view();
|
||||||
|
|
||||||
Window * m_window;
|
Window * m_window;
|
||||||
std::shared_ptr<Buffer> m_buffer;
|
std::shared_ptr<Buffer> m_buffer;
|
||||||
@ -77,9 +83,11 @@ protected:
|
|||||||
std::shared_ptr<BufferView> m_buffer_view;
|
std::shared_ptr<BufferView> m_buffer_view;
|
||||||
int m_rows;
|
int m_rows;
|
||||||
int m_columns;
|
int m_columns;
|
||||||
|
int m_line_number_gutter_width;
|
||||||
std::shared_ptr<Buffer::Iterator> m_iterator;
|
std::shared_ptr<Buffer::Iterator> m_iterator;
|
||||||
std::list<std::pair<int, Buffer::Iterator>> m_screen_lines;
|
std::list<std::pair<int, Buffer::Iterator>> m_screen_lines;
|
||||||
bool m_show_status_bar;
|
bool m_show_status_bar;
|
||||||
|
bool m_show_line_number_gutter;
|
||||||
bool m_command_mode;
|
bool m_command_mode;
|
||||||
bool m_focused;
|
bool m_focused;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user