171 lines
4.3 KiB
C
171 lines
4.3 KiB
C
#include "editor.h"
|
|
#include <SDL2/SDL_render.h>
|
|
#include <SDL2/SDL_ttf.h>
|
|
|
|
void render_text(
|
|
SDL_Renderer* renderer, const char* text, TTF_Font* font, int x, int y,
|
|
SDL_Color fg, SDL_Color bg);
|
|
|
|
void editor_init(
|
|
Editor* editor, int width, int height, AppRessources* ressources)
|
|
{
|
|
*editor = (Editor) {
|
|
.buffer = nullptr,
|
|
width,
|
|
height,
|
|
.cursor_idx = 0,
|
|
.cursor_line = 1,
|
|
.cursor_col = 1,
|
|
ressources,
|
|
};
|
|
}
|
|
|
|
void editor_open(Editor* editor, Buffer* buffer)
|
|
{
|
|
editor->buffer = buffer;
|
|
editor->cursor_idx = 0;
|
|
editor->cursor_line = 1;
|
|
editor->cursor_col = 1;
|
|
}
|
|
|
|
static int cols_at_idx(Editor* editor, size_t idx)
|
|
{
|
|
Buffer* buffer = editor->buffer;
|
|
|
|
int line_start = (int)idx;
|
|
while (line_start > 0 && buffer->text[line_start] != '\n') {
|
|
line_start -= 1;
|
|
}
|
|
int line_end = (int)idx + 1;
|
|
while (line_end < (int)buffer->text_length
|
|
&& buffer->text[line_end] != '\n') {
|
|
line_end += 1;
|
|
}
|
|
printf("idx = %ld, cols = %d\n", idx, line_end - line_start);
|
|
return line_end - line_start;
|
|
}
|
|
|
|
static void cursor_increment(Editor* editor)
|
|
{
|
|
if (editor->cursor_idx >= editor->buffer->text_length)
|
|
return;
|
|
if (editor->buffer->text[editor->cursor_idx] == '\n') {
|
|
editor->cursor_line += 1;
|
|
editor->cursor_col = 1;
|
|
} else {
|
|
editor->cursor_col += 1;
|
|
}
|
|
editor->cursor_idx += 1;
|
|
}
|
|
|
|
static void cursor_decrement(Editor* editor)
|
|
{
|
|
if (editor->cursor_idx <= 0)
|
|
return;
|
|
editor->cursor_idx -= 1;
|
|
if (editor->buffer->text[editor->cursor_idx] == '\n') {
|
|
editor->cursor_line -= 1;
|
|
editor->cursor_col = cols_at_idx(editor, editor->cursor_idx);
|
|
} else {
|
|
editor->cursor_col -= 1;
|
|
}
|
|
}
|
|
|
|
void editor_cursor_up(Editor* editor)
|
|
{
|
|
if (editor->cursor_line == 1)
|
|
return;
|
|
int originalLine = editor->cursor_line;
|
|
int originalCol = editor->cursor_col;
|
|
while (editor->cursor_line >= originalLine
|
|
|| editor->cursor_col > originalCol) {
|
|
cursor_decrement(editor);
|
|
}
|
|
}
|
|
|
|
void editor_cursor_down(Editor* editor)
|
|
{
|
|
int originalLine = editor->cursor_line;
|
|
int originalCol = editor->cursor_col;
|
|
while (editor->cursor_line <= originalLine
|
|
|| editor->cursor_col > originalCol) {
|
|
cursor_increment(editor);
|
|
}
|
|
}
|
|
|
|
void editor_cursor_left(Editor* editor)
|
|
{
|
|
}
|
|
|
|
void editor_cursor_right(Editor* editor)
|
|
{
|
|
}
|
|
|
|
void editor_render(Editor* editor, void* renderer, int x, int y)
|
|
{
|
|
Theme* theme = &editor->ressources->theme;
|
|
SDL_Color fg = *(SDL_Color*)&theme->foreground;
|
|
SDL_Color bg = *(SDL_Color*)&theme->background;
|
|
|
|
SDL_SetRenderDrawColor(renderer, bg.r, bg.g, bg.b, bg.a);
|
|
SDL_RenderFillRect(
|
|
renderer, &(SDL_Rect) { 0, 0, editor->width, editor->height });
|
|
|
|
TextSize char_size = editor->ressources->char_size;
|
|
|
|
Buffer* buffer = editor->buffer;
|
|
|
|
size_t i = 0;
|
|
int line = 1;
|
|
int offset_y = 0;
|
|
|
|
while (i < buffer->text_length) {
|
|
size_t line_start = i;
|
|
while (i < buffer->text_length && buffer->text[i] != '\n') {
|
|
i += 1;
|
|
}
|
|
|
|
char line_number[16] = "";
|
|
snprintf(line_number, 15, "%4d", line);
|
|
|
|
TextSize ln_size = text_size(line_number, editor->ressources->font);
|
|
render_text(
|
|
renderer,
|
|
line_number,
|
|
editor->ressources->font,
|
|
x,
|
|
y + offset_y,
|
|
*(SDL_Color*)&theme->linenumber,
|
|
bg);
|
|
|
|
char* line_text = strndup(&buffer->text[line_start], i - line_start);
|
|
TextSize line_size = text_size(line_text, editor->ressources->font);
|
|
render_text(
|
|
renderer,
|
|
line_text,
|
|
editor->ressources->font,
|
|
x + ln_size.width + 8,
|
|
y + offset_y,
|
|
fg,
|
|
bg);
|
|
free(line_text);
|
|
|
|
offset_y += line_size.height;
|
|
|
|
if (i < buffer->text_length && buffer->text[i] == '\n') {
|
|
i += 1;
|
|
}
|
|
line += 1;
|
|
}
|
|
|
|
SDL_SetRenderDrawColor(renderer, fg.r, fg.g, fg.b, fg.a);
|
|
SDL_RenderFillRect(
|
|
renderer,
|
|
&(SDL_Rect) {
|
|
x + char_size.width * (editor->cursor_col - 1 + 4) + 8 - 1,
|
|
y + char_size.height * (editor->cursor_line - 1),
|
|
2,
|
|
char_size.height,
|
|
});
|
|
}
|