diff --git a/src/gui/BufferPane.cc b/src/gui/BufferPane.cc index c17bcfb..e83f655 100644 --- a/src/gui/BufferPane.cc +++ b/src/gui/BufferPane.cc @@ -1,4 +1,5 @@ #include "BufferPane.h" +#include int BufferPane::Cwd::operator()(uint32_t character) { @@ -24,26 +25,53 @@ BufferPane::BufferPane(Window * window, std::shared_ptr 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 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 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= 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); } diff --git a/src/gui/BufferPane.h b/src/gui/BufferPane.h index e539542..ba2b41f 100644 --- a/src/gui/BufferPane.h +++ b/src/gui/BufferPane.h @@ -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 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 m_buffer; @@ -77,9 +83,11 @@ protected: std::shared_ptr m_buffer_view; int m_rows; int m_columns; + int m_line_number_gutter_width; std::shared_ptr m_iterator; std::list> m_screen_lines; bool m_show_status_bar; + bool m_show_line_number_gutter; bool m_command_mode; bool m_focused; };