[Add] Line numbers to the editor.
This commit is contained in:
		
							parent
							
								
									404f65867d
								
							
						
					
					
						commit
						9fa0b4b097
					
				@ -13,7 +13,7 @@
 | 
			
		||||
Terminal::Terminal(GameState* game_state)
 | 
			
		||||
    : _game_state(game_state), _should_close(false), _scroll_offset(0),
 | 
			
		||||
      _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) {}
 | 
			
		||||
@ -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. */
 | 
			
		||||
  float input_x_pos = x + padding + (prompt_str.length() * 8.5f); /* Estimate width */
 | 
			
		||||
  float input_width = width - (input_x_pos-x);
 | 
			
		||||
  _input_view->render(context.ui_renderer, input_x_pos, prompt_line_y, input_width, 
 | 
			
		||||
                      line_height, context.show_cursor);
 | 
			
		||||
  _input_view->render_text_content(context.ui_renderer, input_x_pos, prompt_line_y, input_width, line_height);
 | 
			
		||||
 | 
			
		||||
  context.ui_renderer->flush_text();
 | 
			
		||||
 | 
			
		||||
  /* Disable 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)
 | 
			
		||||
    : _should_close(false), _pending_action({ActionType::NONE}),
 | 
			
		||||
      _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->add_menu("File");
 | 
			
		||||
  _menu_bar->add_menu_item("File", "Save", [this]() {
 | 
			
		||||
@ -17,7 +17,7 @@ Editor::Editor(void)
 | 
			
		||||
Editor::Editor(const std::string& filename)
 | 
			
		||||
    : _should_close(false), _pending_action({ActionType::NONE}),
 | 
			
		||||
      _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->add_menu("File");
 | 
			
		||||
  _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();
 | 
			
		||||
 | 
			
		||||
  /* 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();
 | 
			
		||||
  _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();
 | 
			
		||||
 | 
			
		||||
  /* 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();
 | 
			
		||||
  _menu_bar->render_bar_text(context.ui_renderer, x, y_screen, width);
 | 
			
		||||
  _menu_bar->render_dropdown(context.ui_renderer, x, y_screen, width);
 | 
			
		||||
  context.ui_renderer->flush_text();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,16 @@
 | 
			
		||||
#include <SDL3/SDL_events.h>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "text_view.h"
 | 
			
		||||
#include "gfx/txt_renderer.h"
 | 
			
		||||
#include "gfx/types.h"
 | 
			
		||||
#include "ui/text_buffer.h"
 | 
			
		||||
#include "ui/ui_renderer.h"
 | 
			
		||||
 | 
			
		||||
TextView::TextView(TextBuffer* buffer, bool handle_ret) : _buffer(buffer),
 | 
			
		||||
    _scroll_offset(0), _handle_ret(handle_ret) {}
 | 
			
		||||
TextView::TextView(TextBuffer* buffer, bool handle_ret, bool show_line_numbers) :
 | 
			
		||||
      _buffer(buffer),
 | 
			
		||||
      _scroll_offset(0),
 | 
			
		||||
      _handle_ret(handle_ret),
 | 
			
		||||
      _show_line_numbers(show_line_numbers) {}
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
                      bool show_cursor) {
 | 
			
		||||
void TextView::render_text_content(UIRenderer* ui_renderer, int x, int y, int width, int height) {
 | 
			
		||||
  if(!_buffer) return;
 | 
			
		||||
 | 
			
		||||
  const Color text_color = { 1.0f, 1.0f, 1.0f };
 | 
			
		||||
  float line_height = 20.0f; /* TODO: Get font metrics? */
 | 
			
		||||
  float padding = 5.0f;
 | 
			
		||||
  const Color text_color      = { 1.0f, 1.0f, 1.0f };
 | 
			
		||||
  const Color line_num_color  = { 0.5f, 0.6f, 0.7f };
 | 
			
		||||
 | 
			
		||||
  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;
 | 
			
		||||
 | 
			
		||||
  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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string line = _buffer->get_line(i);
 | 
			
		||||
 | 
			
		||||
    if(show_cursor && (int)i == cursor_pos.row) {
 | 
			
		||||
      /*
 | 
			
		||||
      * This hacky. we should calculate the text width
 | 
			
		||||
      * 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, '_');
 | 
			
		||||
      }
 | 
			
		||||
    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);
 | 
			
		||||
    }
 | 
			
		||||
    /* Add 18 to get baseline from top of the line. */
 | 
			
		||||
    ui_renderer->render_text(line.c_str(), x+padding, current_y + 18, text_color);
 | 
			
		||||
 | 
			
		||||
    /* Render line content. */
 | 
			
		||||
    std::string line = _buffer->get_line(i);
 | 
			
		||||
    ui_renderer->render_text(line.c_str(), x+padding+gutter_width, current_y+18, text_color);
 | 
			
		||||
    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 {
 | 
			
		||||
public:
 | 
			
		||||
  TextView(TextBuffer* buffer, bool handle_ret);
 | 
			
		||||
  TextView(TextBuffer* buffer, bool handle_ret, bool show_line_numbers);
 | 
			
		||||
  ~TextView(void);
 | 
			
		||||
 | 
			
		||||
  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 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:
 | 
			
		||||
  TextBuffer* _buffer;
 | 
			
		||||
  int _scroll_offset;
 | 
			
		||||
  bool _handle_ret;
 | 
			
		||||
  bool _show_line_numbers;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user