Draw text based on new cursor movement system
The cursor row still locked to the first row for now
This commit is contained in:
1 parent
01bf455e68
commit
86246385d4
4 files changed
+135
-50
No files matched your search
+105
-41
@@ -133,6 +133,7 @@ bool Window::create(std::shared_ptr<Buffer> buffer)
|
||||
m_buffer = buffer;
|
||||
m_cursor = m_buffer->piece_table->add_cursor();
|
||||
m_start_piece = m_buffer->piece_table->start_piece->next;
|
||||
m_cursor_row = 0;
|
||||
|
||||
resize();
|
||||
|
||||
@@ -232,15 +233,45 @@ void Window::handle_key(uint32_t scancode, uint32_t mod)
|
||||
case SDL_SCANCODE_ESCAPE:
|
||||
m_exit_requested = true;
|
||||
break;
|
||||
case SDL_SCANCODE_H:
|
||||
cursor_left();
|
||||
break;
|
||||
case SDL_SCANCODE_J:
|
||||
scroll_down();
|
||||
cursor_down();
|
||||
break;
|
||||
case SDL_SCANCODE_K:
|
||||
scroll_up();
|
||||
cursor_up();
|
||||
break;
|
||||
case SDL_SCANCODE_L:
|
||||
cursor_right();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Window::cursor_left()
|
||||
{
|
||||
m_cursor->go_left(1);
|
||||
redraw();
|
||||
}
|
||||
|
||||
void Window::cursor_right()
|
||||
{
|
||||
m_cursor->go_right(1);
|
||||
redraw();
|
||||
}
|
||||
|
||||
void Window::cursor_up()
|
||||
{
|
||||
m_cursor->go_up(1, m_cursor->column);
|
||||
redraw();
|
||||
}
|
||||
|
||||
void Window::cursor_down()
|
||||
{
|
||||
m_cursor->go_down(1, m_cursor->column);
|
||||
redraw();
|
||||
}
|
||||
|
||||
void Window::scroll_down()
|
||||
{
|
||||
if ((m_start_piece != m_buffer->piece_table->end_piece) &&
|
||||
@@ -261,6 +292,71 @@ void Window::scroll_up()
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<int, PieceTable::Cursor> Window::calculate_start_position()
|
||||
{
|
||||
m_cursor_row = std::min(m_cursor_row, m_rows - 1);
|
||||
int row = m_cursor_row - m_cursor->column / m_columns;
|
||||
PieceTable::Cursor cursor = *m_cursor;
|
||||
cursor.go_start_of_line();
|
||||
while (row > 0)
|
||||
{
|
||||
if (cursor.go_up(1, 0u))
|
||||
{
|
||||
PieceTable::Cursor c = cursor;
|
||||
c.go_end_of_line();
|
||||
row -= c.column / m_columns + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cursor_row -= row;
|
||||
row = 0;
|
||||
}
|
||||
}
|
||||
return std::pair<int, PieceTable::Cursor>(row, cursor);
|
||||
}
|
||||
|
||||
void Window::draw_text()
|
||||
{
|
||||
auto start_position = calculate_start_position();
|
||||
int row = start_position.first;
|
||||
PieceTable::Cursor cursor = start_position.second;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int row_offset = cursor.column / m_columns;
|
||||
int screen_row = row + row_offset;
|
||||
if (screen_row >= m_rows)
|
||||
break;
|
||||
int screen_column = cursor.column % m_columns;
|
||||
if (cursor == *m_cursor)
|
||||
draw_cursor(screen_column, screen_row);
|
||||
if (screen_row >= 0)
|
||||
{
|
||||
uint32_t character = *cursor;
|
||||
if (character != 0xFFFFFFFFu)
|
||||
draw_character(screen_column, screen_row, character);
|
||||
}
|
||||
if (!cursor.go_right(1))
|
||||
{
|
||||
if (!cursor.go_down(1, 0))
|
||||
break;
|
||||
row = screen_row + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Window::draw_character(int screen_column, int screen_row, uint32_t character)
|
||||
{
|
||||
m_shaders.text->use();
|
||||
int advance = m_font.get_advance();
|
||||
int line_height = m_font.get_line_height();
|
||||
int x = screen_column * advance;
|
||||
int y = m_height - (screen_row + 1) * line_height;
|
||||
auto g = m_font.get_glyph(character);
|
||||
m_shaders.text->set_position(x, y + m_font.get_baseline_offset());
|
||||
g->render();
|
||||
}
|
||||
|
||||
void Window::resize()
|
||||
{
|
||||
SDL_GetWindowSize(m_window, &m_width, &m_height);
|
||||
@@ -280,52 +376,20 @@ void Window::redraw()
|
||||
glClearColor (0.0, 0.0, 0.0, 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
draw_cursor();
|
||||
m_shaders.text->use();
|
||||
|
||||
int advance = m_font.get_advance();
|
||||
int line_height = m_font.get_line_height();
|
||||
int x = 0;
|
||||
int y = m_height - line_height;
|
||||
for (PieceTable::Piece * piece = m_start_piece;
|
||||
piece != m_buffer->piece_table->end_piece;
|
||||
piece = piece->next)
|
||||
{
|
||||
for (int i = 0, len = piece->length; i < len; i++)
|
||||
{
|
||||
uint8_t c = piece->start[i];
|
||||
auto g = m_font.get_glyph(c);
|
||||
m_shaders.text->set_position(x, y + m_font.get_baseline_offset());
|
||||
g->render();
|
||||
if ((i + 1) % m_columns == 0)
|
||||
{
|
||||
y -= line_height;
|
||||
x = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
x += advance;
|
||||
}
|
||||
}
|
||||
if (piece->eol())
|
||||
{
|
||||
y -= line_height;
|
||||
x = 0;
|
||||
}
|
||||
if (y + line_height < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
draw_text();
|
||||
|
||||
SDL_GL_SwapWindow(m_window);
|
||||
}
|
||||
|
||||
void Window::draw_cursor()
|
||||
void Window::draw_cursor(int screen_column, int screen_row)
|
||||
{
|
||||
int advance = m_font.get_advance();
|
||||
int line_height = m_font.get_line_height();
|
||||
int x = screen_column * advance;
|
||||
int y = m_height - (screen_row + 1) * line_height;
|
||||
m_cursor_array->bind();
|
||||
m_shaders.flat->use();
|
||||
m_shaders.flat->set_color(1.0, 0.2, 1.0, 1.0);
|
||||
m_shaders.flat->set_position(0, m_height - m_font.get_line_height());
|
||||
m_shaders.flat->set_position(x, y);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
}
|
||||
+10
-1
@@ -1,6 +1,7 @@
|
||||
#ifndef WINDOW_H
|
||||
#define WINDOW_H
|
||||
|
||||
#include <utility>
|
||||
#include <SDL.h>
|
||||
#include "TextShader.h"
|
||||
#include "FlatShader.h"
|
||||
@@ -17,11 +18,18 @@ public:
|
||||
protected:
|
||||
void resize();
|
||||
void redraw();
|
||||
void draw_cursor();
|
||||
void draw_cursor(int screen_column, int screen_row);
|
||||
void handle_event(SDL_Event & event);
|
||||
void handle_key(uint32_t scancode, uint32_t mod);
|
||||
void cursor_left();
|
||||
void cursor_right();
|
||||
void cursor_up();
|
||||
void cursor_down();
|
||||
void scroll_down();
|
||||
void scroll_up();
|
||||
std::pair<int, PieceTable::Cursor> calculate_start_position();
|
||||
void draw_text();
|
||||
void draw_character(int screen_column, int screen_row, uint32_t character);
|
||||
|
||||
SDL_Window * m_window;
|
||||
bool m_exit_requested;
|
||||
@@ -36,6 +44,7 @@ protected:
|
||||
Font m_font;
|
||||
int m_columns;
|
||||
int m_rows;
|
||||
int m_cursor_row;
|
||||
|
||||
std::shared_ptr<Buffer> m_buffer;
|
||||
|
||||
|
||||
Reference in new issue
Block a user