[Add] Line numbers to the editor.
This commit is contained in:
parent
404f65867d
commit
9fa0b4b097
@ -13,7 +13,7 @@
|
|||||||
Terminal::Terminal(GameState* game_state)
|
Terminal::Terminal(GameState* game_state)
|
||||||
: _game_state(game_state), _should_close(false), _scroll_offset(0),
|
: _game_state(game_state), _should_close(false), _scroll_offset(0),
|
||||||
_prompt(""), _pending_action({ActionType::NONE}) {
|
_prompt(""), _pending_action({ActionType::NONE}) {
|
||||||
_input_view = std::make_unique<TextView>(&_input_buffer, false);
|
_input_view = std::make_unique<TextView>(&_input_buffer, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Terminal::~Terminal(void) {}
|
Terminal::~Terminal(void) {}
|
||||||
@ -141,11 +141,16 @@ void Terminal::render(const RenderContext& context, int x, int y_screen, int y_g
|
|||||||
/* Render text view for the input right after prompt. */
|
/* Render text view for the input right after prompt. */
|
||||||
float input_x_pos = x + padding + (prompt_str.length() * 8.5f); /* Estimate width */
|
float input_x_pos = x + padding + (prompt_str.length() * 8.5f); /* Estimate width */
|
||||||
float input_width = width - (input_x_pos-x);
|
float input_width = width - (input_x_pos-x);
|
||||||
_input_view->render(context.ui_renderer, input_x_pos, prompt_line_y, input_width,
|
_input_view->render_text_content(context.ui_renderer, input_x_pos, prompt_line_y, input_width, line_height);
|
||||||
line_height, context.show_cursor);
|
|
||||||
|
|
||||||
context.ui_renderer->flush_text();
|
context.ui_renderer->flush_text();
|
||||||
|
|
||||||
/* Disable scissor test. */
|
/* Disable scissor test. */
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
|
if(context.show_cursor) {
|
||||||
|
context.ui_renderer->begin_shapes();
|
||||||
|
_input_view->render_cursor(context.ui_renderer, input_x_pos, prompt_line_y, input_width, line_height);
|
||||||
|
context.ui_renderer->flush_shapes();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
Editor::Editor(void)
|
Editor::Editor(void)
|
||||||
: _should_close(false), _pending_action({ActionType::NONE}),
|
: _should_close(false), _pending_action({ActionType::NONE}),
|
||||||
_filename("untitled.txt") {
|
_filename("untitled.txt") {
|
||||||
_view = std::make_unique<TextView>(&_buffer, true);
|
_view = std::make_unique<TextView>(&_buffer, true, true);
|
||||||
_menu_bar = std::make_unique<MenuBar>(25);
|
_menu_bar = std::make_unique<MenuBar>(25);
|
||||||
_menu_bar->add_menu("File");
|
_menu_bar->add_menu("File");
|
||||||
_menu_bar->add_menu_item("File", "Save", [this]() {
|
_menu_bar->add_menu_item("File", "Save", [this]() {
|
||||||
@ -17,7 +17,7 @@ Editor::Editor(void)
|
|||||||
Editor::Editor(const std::string& filename)
|
Editor::Editor(const std::string& filename)
|
||||||
: _should_close(false), _pending_action({ActionType::NONE}),
|
: _should_close(false), _pending_action({ActionType::NONE}),
|
||||||
_filename(filename) {
|
_filename(filename) {
|
||||||
_view = std::make_unique<TextView>(&_buffer, true);
|
_view = std::make_unique<TextView>(&_buffer, true, true);
|
||||||
_menu_bar = std::make_unique<MenuBar>(25);
|
_menu_bar = std::make_unique<MenuBar>(25);
|
||||||
_menu_bar->add_menu("File");
|
_menu_bar->add_menu("File");
|
||||||
_menu_bar->add_menu_item("File", "Save", [this]() {
|
_menu_bar->add_menu_item("File", "Save", [this]() {
|
||||||
@ -58,15 +58,20 @@ void Editor::render(const RenderContext& context, int x, int y_screen, int y_gl,
|
|||||||
context.ui_renderer->flush_shapes();
|
context.ui_renderer->flush_shapes();
|
||||||
|
|
||||||
/* Pass 2: Main text view. */
|
/* Pass 2: Main text view. */
|
||||||
_view->render(context.ui_renderer, x, content_y, width, content_height, context.show_cursor);
|
|
||||||
|
|
||||||
/* Pass 3: Menu bar text and dropdown. */
|
|
||||||
context.ui_renderer->begin_text();
|
context.ui_renderer->begin_text();
|
||||||
_menu_bar->render_bar_text(context.ui_renderer, x, y_screen, width);
|
_view->render_text_content(context.ui_renderer, x, content_y, width, content_height);
|
||||||
context.ui_renderer->flush_text();
|
context.ui_renderer->flush_text();
|
||||||
|
|
||||||
/* Pass 4: Dropdown menu. */
|
/* Pass 3: Editor cursor. */
|
||||||
|
if(context.show_cursor) {
|
||||||
|
context.ui_renderer->begin_shapes();
|
||||||
|
_view->render_cursor(context.ui_renderer, x, content_y, width, content_height);
|
||||||
|
context.ui_renderer->flush_shapes();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pass 4: Menu bar text and dropdown. */
|
||||||
context.ui_renderer->begin_text();
|
context.ui_renderer->begin_text();
|
||||||
|
_menu_bar->render_bar_text(context.ui_renderer, x, y_screen, width);
|
||||||
_menu_bar->render_dropdown(context.ui_renderer, x, y_screen, width);
|
_menu_bar->render_dropdown(context.ui_renderer, x, y_screen, width);
|
||||||
context.ui_renderer->flush_text();
|
context.ui_renderer->flush_text();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,16 @@
|
|||||||
#include <SDL3/SDL_events.h>
|
#include <SDL3/SDL_events.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "text_view.h"
|
#include "text_view.h"
|
||||||
#include "gfx/txt_renderer.h"
|
|
||||||
#include "gfx/types.h"
|
#include "gfx/types.h"
|
||||||
#include "ui/text_buffer.h"
|
#include "ui/text_buffer.h"
|
||||||
|
#include "ui/ui_renderer.h"
|
||||||
|
|
||||||
TextView::TextView(TextBuffer* buffer, bool handle_ret) : _buffer(buffer),
|
TextView::TextView(TextBuffer* buffer, bool handle_ret, bool show_line_numbers) :
|
||||||
_scroll_offset(0), _handle_ret(handle_ret) {}
|
_buffer(buffer),
|
||||||
|
_scroll_offset(0),
|
||||||
|
_handle_ret(handle_ret),
|
||||||
|
_show_line_numbers(show_line_numbers) {}
|
||||||
|
|
||||||
TextView::~TextView(void) {}
|
TextView::~TextView(void) {}
|
||||||
|
|
||||||
@ -70,15 +75,16 @@ void TextView::scroll(int amount, int content_height) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextView::render(UIRenderer* ui_renderer, int x, int y, int width, int height,
|
void TextView::render_text_content(UIRenderer* ui_renderer, int x, int y, int width, int height) {
|
||||||
bool show_cursor) {
|
|
||||||
if(!_buffer) return;
|
if(!_buffer) return;
|
||||||
|
|
||||||
const Color text_color = { 1.0f, 1.0f, 1.0f };
|
const Color text_color = { 1.0f, 1.0f, 1.0f };
|
||||||
float line_height = 20.0f; /* TODO: Get font metrics? */
|
const Color line_num_color = { 0.5f, 0.6f, 0.7f };
|
||||||
float padding = 5.0f;
|
|
||||||
|
const float line_height = 20.0f; /* TODO: Get font metrics? */
|
||||||
|
const float padding = 5.0f;
|
||||||
|
const float gutter_width = _show_line_numbers ? 40.0f : 0.0f;
|
||||||
|
|
||||||
Point cursor_pos = _buffer->get_cursor_pos();
|
|
||||||
float current_y = y;
|
float current_y = y;
|
||||||
|
|
||||||
for(size_t i = _scroll_offset; i < _buffer->get_line_count(); ++i) {
|
for(size_t i = _scroll_offset; i < _buffer->get_line_count(); ++i) {
|
||||||
@ -90,22 +96,34 @@ void TextView::render(UIRenderer* ui_renderer, int x, int y, int width, int heig
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string line = _buffer->get_line(i);
|
if(_show_line_numbers) {
|
||||||
|
/* Render line number. */
|
||||||
|
std::string line_num_str = std::to_string(i+1);
|
||||||
|
float line_num_text_width =
|
||||||
|
ui_renderer->get_text_renderer()->get_text_width(line_num_str.c_str(), 1.0f);
|
||||||
|
ui_renderer->render_text(line_num_str.c_str(), x+padding+(gutter_width-line_num_text_width-10),
|
||||||
|
current_y+18, line_num_color);
|
||||||
|
}
|
||||||
|
|
||||||
if(show_cursor && (int)i == cursor_pos.row) {
|
/* Render line content. */
|
||||||
/*
|
std::string line = _buffer->get_line(i);
|
||||||
* This hacky. we should calculate the text width
|
ui_renderer->render_text(line.c_str(), x+padding+gutter_width, current_y+18, text_color);
|
||||||
* up to the cursor pos to draw correctly.
|
|
||||||
* For now, just append an underscore.
|
|
||||||
*/
|
|
||||||
if(cursor_pos.col == line.length()) {
|
|
||||||
line += "_";
|
|
||||||
} else {
|
|
||||||
line.insert(cursor_pos.col, 1, '_');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Add 18 to get baseline from top of the line. */
|
|
||||||
ui_renderer->render_text(line.c_str(), x+padding, current_y + 18, text_color);
|
|
||||||
current_y += line_height;
|
current_y += line_height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextView::render_cursor(UIRenderer* ui_renderer, int x, int y, int width, int height) {
|
||||||
|
const Color text_color = { 1.0f, 1.0f, 1.0f };
|
||||||
|
const float line_height = 20.0f; /* TODO: Get font metrics? */
|
||||||
|
const float padding = 5.0f;
|
||||||
|
const float gutter_width = _show_line_numbers ? 40.0f : 0.0f;
|
||||||
|
Point cursor_pos = _buffer->get_cursor_pos();
|
||||||
|
std::string line_before_cursor = _buffer->get_line(cursor_pos.row).substr(0, cursor_pos.col);
|
||||||
|
float text_width =
|
||||||
|
ui_renderer->get_text_renderer()->get_text_width(line_before_cursor.c_str(), 1.0f);
|
||||||
|
float cursor_x = x + padding + gutter_width + text_width;
|
||||||
|
float cursor_y = y + (cursor_pos.row - _scroll_offset) * line_height;
|
||||||
|
if(cursor_y >= y && cursor_y < y + height) {
|
||||||
|
ui_renderer->draw_rect(cursor_x, cursor_y, 2, line_height, text_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -9,16 +9,17 @@ class TextRenderer;
|
|||||||
|
|
||||||
class TextView {
|
class TextView {
|
||||||
public:
|
public:
|
||||||
TextView(TextBuffer* buffer, bool handle_ret);
|
TextView(TextBuffer* buffer, bool handle_ret, bool show_line_numbers);
|
||||||
~TextView(void);
|
~TextView(void);
|
||||||
|
|
||||||
bool handle_event(SDL_Event* event);
|
bool handle_event(SDL_Event* event);
|
||||||
void render(UIRenderer* ui_renderer, int x, int y, int width, int height,
|
|
||||||
bool show_cursor);
|
|
||||||
void scroll(int amount, int content_height);
|
void scroll(int amount, int content_height);
|
||||||
|
void render_text_content(UIRenderer* ui_renderer, int x, int y, int width, int height);
|
||||||
|
void render_cursor(UIRenderer* ui_renderer, int x, int y, int width, int height);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextBuffer* _buffer;
|
TextBuffer* _buffer;
|
||||||
int _scroll_offset;
|
int _scroll_offset;
|
||||||
bool _handle_ret;
|
bool _handle_ret;
|
||||||
|
bool _show_line_numbers;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user