diff --git a/src/text_editor/main.cpp b/src/text_editor/main.cpp index d89f465..1642969 100644 --- a/src/text_editor/main.cpp +++ b/src/text_editor/main.cpp @@ -3,6 +3,8 @@ #include "raylib.h" #include "raymath.h" +// @todo: add history (undo, redo) +// @todo: add clipboard history? #include "buffer.cpp" #include "rect2.cpp" @@ -78,6 +80,46 @@ void DrawString(Font font, String text, Vector2 position, float fontSize, float } } +Vector2 MeasureString(Font font, String text, float fontSize, float spacing) { + Vector2 textSize = {0}; + if ((font.texture.id == 0) || (text.data == NULL)) return textSize; // Security check + + int size = (int)text.len; // Get size in bytes of text + int tempByteCounter = 0; // Used to count longer text line num chars + int byteCounter = 0; + + float textWidth = 0.0f; + float tempTextWidth = 0.0f; // Used to count longer text line width + + float textHeight = fontSize; + float scaleFactor = fontSize / (float)font.baseSize; + + int letter = 0; // Current character + int index = 0; // Index position in sprite font + + for (int i = 0; i < size;) { + byteCounter++; + + int next = 0; + letter = GetCodepointNext(&text.data[i], &next); + index = GetGlyphIndex(font, letter); + + i += next; + + if (font.glyphs[index].advanceX != 0) textWidth += font.glyphs[index].advanceX; + else textWidth += (font.recs[index].width + font.glyphs[index].offsetX); + + if (tempByteCounter < byteCounter) tempByteCounter = byteCounter; + } + + if (tempTextWidth < textWidth) tempTextWidth = textWidth; + + textSize.x = tempTextWidth * scaleFactor + (float)((tempByteCounter - 1) * spacing); + textSize.y = textHeight; + + return textSize; +} + int64_t MoveRight(Buffer &buffer, int64_t pos) { pos = pos + 1; pos = AdjustUTF8Pos(buffer, pos); @@ -182,7 +224,7 @@ int main() { if (1) { for (int i = 0; i < 50; i += 1) { Array edits = {FrameArena}; - AddEdit(&edits, GetEnd(window.buffer), Format(FrameArena, "line number: %d\n", i)); + AddEdit(&edits, GetEnd(window.buffer), Format(FrameArena, "line number sddddddddddddssssssssss faasda s: %d\n", i)); ApplyEdits(&window.buffer, edits); } } @@ -559,27 +601,45 @@ int main() { if (row.cells.len) rows.add(row); } } - Assert(rows.len); - // @todo: x axis // Update the scroll based on first cursor if (!AreEqual(window.main_cursor_begin_frame, window.cursors[0])) { Vec2 rect_in_render_units = GetSize(window_text_rect_in_render_units_clamped_to_screen); float visible_cells_in_render_units = font_size * (float)rows.len; float cut_off_in_render_units = visible_cells_in_render_units - rect_in_render_units.y; - Cursor cursor = window.cursors[0]; - int64_t front = GetFront(cursor); - Line line = FindLine(window.buffer, front); + Cursor cursor = window.cursors[0]; + int64_t front = GetFront(cursor); + Line line = FindLine(window.buffer, front); + + // Scroll Y int64_t min_line = rows[0].line; int64_t max_line = rows[rows.len - 1].line; - if (line.number < min_line) { window.scroll.y = line.number * font_size; } else if (line.number >= max_line) { int64_t diff = line.number - max_line; window.scroll.y = (min_line + diff) * font_size + cut_off_in_render_units; } + + // Scroll X + Range x_distance = {line.range.min, front}; + String x_distance_string = GetString(window.buffer, x_distance); + Vec2 size = MeasureString(font, x_distance_string, font_size, font_spacing); + if (x_distance_string.len <= 0) size.x = 0; + float x_cursor_position_in_window_buffer_world_units = size.x; + + GlyphInfo info = GetGlyphInfo(font, ' '); + float right_scroll_zone = (float)(info.image.width + info.advanceX) * 3; + float window_buffer_world_right_edge = (rect_in_render_units.x + window.scroll.x) - right_scroll_zone; + float window_buffer_world_left_edge = window.scroll.x; + if (x_cursor_position_in_window_buffer_world_units >= window_buffer_world_right_edge) { + float diff = x_cursor_position_in_window_buffer_world_units - window_buffer_world_right_edge; + window.scroll.x += diff; + } else if (x_cursor_position_in_window_buffer_world_units <= window_buffer_world_left_edge) { + float diff = x_cursor_position_in_window_buffer_world_units - window_buffer_world_left_edge; + window.scroll.x += diff; + } } // Draw debug markers