From afd584566ce46a05f3f379f64cbfabdc22e73723 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 9 Nov 2016 22:43:04 -0500 Subject: [PATCH] avoid empty screen rows if there is buffer content to fill them --- src/gui/Window.cc | 38 +++++++++++++++++++++++++++++++++++--- src/gui/Window.h | 8 +++++++- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/gui/Window.cc b/src/gui/Window.cc index 3bb3d84..5cda39a 100644 --- a/src/gui/Window.cc +++ b/src/gui/Window.cc @@ -365,13 +365,19 @@ void Window::cursor_move(int which) #endif } -void Window::update_cursor_row(int cursor_row) +void Window::update_cursor_row() { - m_cursor_row = std::max(m_scroll_offset, std::min(m_rows - m_scroll_offset - 1, cursor_row)); + int so = effective_scroll_offset(); + int rows_above = screen_rows_above_cursor(std::max(so, m_cursor_row)); + int rows_below = screen_rows_below_cursor(std::max(so, m_rows - m_cursor_row - 1)); + int min_rows_to_leave_above = std::min(rows_above, so); + int min_rows_to_leave_below = std::min(rows_below, so); + m_cursor_row = std::max(min_rows_to_leave_above, std::min(m_rows - min_rows_to_leave_below - 1, m_cursor_row)); } void Window::draw_buffer() { + update_cursor_row(); } void Window::draw_buffer_character(int screen_column, int screen_row, uint32_t character) @@ -403,7 +409,6 @@ void Window::resize() if (m_columns < 1) m_columns = 1; m_rows = (m_height - 2) / m_font.get_line_height(); - update_cursor_row(m_cursor_row); } void Window::redraw() @@ -533,3 +538,30 @@ uint32_t Window::get_shifted(uint32_t keysym) return keysym; } + +int Window::screen_rows_below_cursor(int stop_at) +{ + GapBuffer::Cursor cursor = *m_cursor; + size_t column = cursor.column(); + cursor.go_end_of_line(false); + int rows = (cursor.column() / m_columns) - (column / m_columns); + while ((rows < stop_at) && cursor.go_down(0u)) + { + cursor.go_end_of_line(false); + rows += (cursor.column() / m_columns) + 1; + } + return rows; +} + +int Window::screen_rows_above_cursor(int stop_at) +{ + GapBuffer::Cursor cursor = *m_cursor; + int rows = cursor.column() / m_columns; + while ((rows < stop_at) && cursor.go_up(0u)) + { + GapBuffer::Cursor cursor2 = cursor; + cursor2.go_end_of_line(false); + rows += (cursor2.column() / m_columns) + 1; + } + return rows; +} diff --git a/src/gui/Window.h b/src/gui/Window.h index ecf5a0e..7e9341b 100644 --- a/src/gui/Window.h +++ b/src/gui/Window.h @@ -47,11 +47,17 @@ protected: void draw_buffer(); void draw_buffer_character(int screen_column, int screen_row, uint32_t character); void draw_character(int x, int y, uint32_t character); - void update_cursor_row(int cursor_row); + void update_cursor_row(); void draw_rect(int x, int y, int width, int height, float r, float g, float b, float a); void draw_status_bar(); uint32_t get_keyval(SDL_Keycode keysym); uint32_t get_shifted(uint32_t keysym); + int screen_rows_below_cursor(int stop_at); + int screen_rows_above_cursor(int stop_at); + int effective_scroll_offset() + { + return std::min(m_scroll_offset, (m_rows - 1) / 2); + } SDL_Window * m_window; bool m_exit_requested;