#include "BufferPane.h" BufferPane::BufferPane(Window * window, std::shared_ptr buffer) : m_window(window), m_buffer(buffer) { m_cursor_row = 0; m_scroll_offset = 5; #if 0 m_cursor = buffer->add_cursor(); #endif } void BufferPane::resize(int width, int height) { Pane::resize(width, height); m_columns = std::max(1, m_width / m_window->font()->get_advance()); m_rows = std::max(1, (m_height + m_window->font()->get_line_height() - 1) / m_window->font()->get_line_height()); } #if 0 void BufferPane::update_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)); } int BufferPane::screen_rows_below_cursor(int stop_at) { Buffer::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 BufferPane::screen_rows_above_cursor(int stop_at) { Buffer::Cursor cursor = *m_cursor; int rows = cursor.column() / m_columns; while ((rows < stop_at) && cursor.go_up(0u)) { Buffer::Cursor cursor2 = cursor; cursor2.go_end_of_line(false); rows += (cursor2.column() / m_columns) + 1; } return rows; } #endif void BufferPane::draw() { #if 0 if (m_cursor->valid()) { update_cursor_row(); int screen_row = m_cursor_row - m_cursor->column() / m_columns; Buffer::Cursor iter_cursor = *m_cursor; iter_cursor.go_start_of_line(); while ((screen_row > 0) && iter_cursor.go_up(0u)) { Buffer::Cursor cursor2 = iter_cursor; cursor2.go_end_of_line(false); screen_row -= (1 + cursor2.column() / m_columns); } while (screen_row < m_rows) { draw_buffer_line(screen_row, iter_cursor); iter_cursor.go_end_of_line(false); screen_row += (1 + iter_cursor.column() / m_columns); if (!iter_cursor.go_down(0u)) { break; } } } else { draw_cursor(col_x(0), row_y(0), false); } #endif } #if 0 void BufferPane::draw_buffer_line(int screen_row, const Buffer::Cursor & cursor) { Buffer::Cursor iter_cursor = cursor; while (!iter_cursor.is_end_of_line(true)) { int draw_row = screen_row + (iter_cursor.column() / m_columns); if (draw_row < 0) continue; if (draw_row >= m_rows) break; int draw_column = iter_cursor.column() % m_columns; int x = col_x(draw_column); int y = row_y(draw_row); if (iter_cursor == *m_cursor) { draw_cursor(x, y, false); } uint32_t c = *iter_cursor; if ((c != '\t') && (c != ' ')) { m_window->gl()->draw_character(win_x(x), win_y(y), c, *m_window->font()); } iter_cursor.go_right(true); } } void BufferPane::draw_buffer_character(int screen_column, int screen_row, uint32_t character) { m_window->gl()->draw_character(win_x(col_x(screen_column)), win_y(row_y(screen_row)), character, *m_window->font()); } void BufferPane::draw_cursor(int x, int y, bool insert_mode) { int width = insert_mode ? 1 : m_window->font()->get_advance(); int height = m_window->font()->get_line_height(); m_window->gl()->draw_rect(win_x(x), win_y(y), width, height, 1.0, 0.2, 1.0, 1.0); } #endif void BufferPane::handle_key(uint32_t keyval) { #if 0 if (m_buffer->piece_table->in_insert_mode()) { if (keyval == '\033') { m_buffer->piece_table->end_insert(); } else if (keyval <= 0xFFu) { m_buffer->piece_table->insert_code_point(keyval); } redraw(); } else #endif { switch (keyval) { case '0': cursor_move(CursorMovement::SOL); break; case '$': cursor_move(CursorMovement::EOL); break; case 'h': cursor_move(CursorMovement::LEFT); break; case 'j': cursor_move(CursorMovement::DOWN); break; case 'k': cursor_move(CursorMovement::UP); break; case 'l': cursor_move(CursorMovement::RIGHT); break; } } } void BufferPane::cursor_move(CursorMovement which) { #if 0 bool moved = false; int current_row_offset = m_cursor->column / m_columns; int row_offset = 0; switch (which) { case CursorMovement::LEFT: moved = m_cursor->check_go_left(1); m_target_column = m_cursor->column; break; case CursorMovement::RIGHT: moved = m_cursor->check_go_right(1, false); m_target_column = m_cursor->column; break; case CursorMovement::UP: moved = m_cursor->check_go_up(1, m_target_column); break; case CursorMovement::DOWN: moved = m_cursor->check_go_down(1, m_target_column); break; case CursorMovement::SOL: moved = m_cursor->check_go_start_of_line(); m_target_column = 0u; break; case CursorMovement::EOL: moved = m_cursor->check_go_end_of_line(false); m_target_column = 0x7FFFFFFFu; break; } if (moved) { switch (which) { case CursorMovement::LEFT: case CursorMovement::RIGHT: row_offset = m_cursor->column / m_columns - current_row_offset; break; case CursorMovement::UP: { PieceTable::Cursor c = *m_cursor; c.go_end_of_line(false); row_offset = m_cursor->column / m_columns - c.column / m_columns - 1 - current_row_offset; } break; case CursorMovement::DOWN: { PieceTable::Cursor c = *m_cursor; c.go_up(1, 0u); c.go_end_of_line(false); row_offset = c.column / m_columns - current_row_offset + 1 + m_cursor->column / m_columns; } break; case CursorMovement::SOL: row_offset = -current_row_offset; break; case CursorMovement::EOL: { PieceTable::Cursor c = *m_cursor; c.go_end_of_line(false); row_offset = c.column / m_columns - current_row_offset; } break; } update_cursor_row(m_cursor_row + row_offset); redraw(); } #endif }