Line highlight improvements and misc
This commit is contained in:
@@ -54,33 +54,6 @@ Range GetLineRange(Buffer &buffer, Int line) {
|
||||
return result;
|
||||
}
|
||||
|
||||
Int CalculateLongestLine(Buffer &buffer) {
|
||||
// @optimize: this is the bottleneck
|
||||
if (buffer.change_id == buffer.longest_line_id) {
|
||||
return buffer.index_of_longest_line;
|
||||
}
|
||||
Int index_max = 0;
|
||||
Int size_max = 0;
|
||||
for (Int i = 0; i < buffer.line_starts.len; i += 1) {
|
||||
Range range = GetLineRange(buffer, i);
|
||||
Int size = GetSize(range);
|
||||
if (size > size_max) {
|
||||
index_max = i;
|
||||
size_max = size;
|
||||
}
|
||||
}
|
||||
buffer.longest_line_id = buffer.change_id;
|
||||
buffer.index_of_longest_line = index_max;
|
||||
return index_max;
|
||||
}
|
||||
|
||||
Int GetCharCountOfLongestLine(Buffer &buffer) {
|
||||
Int line = CalculateLongestLine(buffer);
|
||||
Range range = GetLineRange(buffer, line);
|
||||
Int result = GetSize(range);
|
||||
return result;
|
||||
}
|
||||
|
||||
Int PosToLine(Buffer &buffer, Int pos) {
|
||||
Add(&buffer.line_starts, buffer.len + 1);
|
||||
|
||||
@@ -131,6 +104,7 @@ Int XYToPosWithoutNL(Buffer &buffer, XY xy) {
|
||||
}
|
||||
|
||||
void UpdateLines(Buffer *buffer, Range range, String16 string) {
|
||||
ProfileFunction();
|
||||
Array<Int> &ls = buffer->line_starts;
|
||||
Int min_line_number = PosToLine(*buffer, range.min);
|
||||
Assert(min_line_number < ls.len);
|
||||
@@ -181,6 +155,7 @@ void ValidateLineStarts(Buffer *buffer) {
|
||||
}
|
||||
|
||||
void ReplaceText(Buffer *buffer, Range range, String16 string) {
|
||||
ProfileFunction();
|
||||
Assert(range.max >= range.min);
|
||||
Assert(range.max >= 0 && range.max <= buffer->len);
|
||||
Assert(range.min >= 0 && range.min <= buffer->len);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @todo: gap buffer to improve speed of inserting on big files with only one cursor?
|
||||
struct Buffer {
|
||||
union {
|
||||
U16 *data;
|
||||
@@ -7,9 +8,6 @@ struct Buffer {
|
||||
Int cap;
|
||||
Array<Int> line_starts;
|
||||
Int change_id;
|
||||
|
||||
Int longest_line_id;
|
||||
Int index_of_longest_line;
|
||||
};
|
||||
|
||||
union Range {
|
||||
|
||||
@@ -65,6 +65,12 @@ Caret MakeCaret(Int pos) {
|
||||
return result;
|
||||
}
|
||||
|
||||
XY XYLine(Int line) {
|
||||
XY result = {};
|
||||
result.line = line;
|
||||
return result;
|
||||
}
|
||||
|
||||
Caret MakeCaret(Int front, Int back) {
|
||||
Caret result = {};
|
||||
if (front >= back) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
void MergeCarets(Array<Caret> *carets) {
|
||||
ProfileFunction();
|
||||
Scratch scratch;
|
||||
// Merge carets that overlap, this needs to be handled before any edits to
|
||||
// make sure overlapping edits won't happen.
|
||||
@@ -34,6 +35,7 @@ void MergeCarets(Array<Caret> *carets) {
|
||||
}
|
||||
|
||||
void MergeSort(int64_t Count, Edit *First, Edit *Temp) {
|
||||
ProfileFunction();
|
||||
// SortKey = range.min
|
||||
if (Count == 1) {
|
||||
// NOTE(casey): No work to do.
|
||||
@@ -88,6 +90,7 @@ void MergeSort(int64_t Count, Edit *First, Edit *Temp) {
|
||||
}
|
||||
|
||||
void ApplyEdits(Buffer *buffer, Array<Edit> edits) {
|
||||
ProfileFunction();
|
||||
#if BUFFER_DEBUG
|
||||
Assert(buffer->line_starts.len);
|
||||
Assert(edits.len);
|
||||
|
||||
14
src/text_editor/buffer_test_load.cpp
Normal file
14
src/text_editor/buffer_test_load.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
void LoadBigText(Buffer *buffer) {
|
||||
for (int i = 0; i < 5000000; i += 1) {
|
||||
ReplaceText(buffer, GetEndAsRange(*buffer), L"Line number and another meme or something of the sort which is here or there frankly somewhere\n");
|
||||
}
|
||||
}
|
||||
|
||||
void LoadTextA(Buffer *buffer) {
|
||||
Scratch scratch;
|
||||
for (int i = 0; i < 1000; i += 1) {
|
||||
String s = Format(scratch, "line1: %d line2: %d line3: %d line4: %d line5: %d line6: %d line1: %d line2: %d line3: %d line4: %d line5: %d line6: %d\n", i, i, i, i, i, i, i, i, i, i, i, i);
|
||||
String16 s16 = ToString16(scratch, s);
|
||||
ReplaceText(buffer, GetEndAsRange(*buffer), s16);
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "buffer.cpp"
|
||||
#include "buffer_multi_cursor.cpp"
|
||||
#include "buffer_history.cpp"
|
||||
#include "buffer_test_load.cpp"
|
||||
|
||||
#include "raylib.h"
|
||||
#include "raylib_utils.cpp"
|
||||
@@ -27,11 +28,9 @@
|
||||
- Backspace, Delete, Enter
|
||||
- Mouse anchor point and double click
|
||||
- Mouse cursor changes
|
||||
- Line highlight
|
||||
- Color new lines and end of buffer
|
||||
- Scrollbars
|
||||
- Line numbers
|
||||
- Test big files!!
|
||||
- Colored strings
|
||||
|
||||
- multiple windows
|
||||
@@ -73,16 +72,7 @@ int main(void) {
|
||||
view.char_spacing = GetCharSpacing(font, font_size, font_spacing);
|
||||
Add(&view.carets, {0, 0});
|
||||
view.buffer = CreateBuffer(Perm);
|
||||
{
|
||||
Scratch scratch;
|
||||
for (int i = 0; i < 1500000; i += 1) {
|
||||
String s = Format(scratch, "line1: %d line2: %d line3: %d line4: %d line5: %d line6: %d line1: %d line2: %d line3: %d line4: %d line5: %d line6: %d\n", i, i, i, i, i, i, i, i, i, i, i, i);
|
||||
// String s = Format(scratch, "line %d\n", i);
|
||||
String16 s16 = ToString16(scratch, s);
|
||||
ReplaceText(view.buffer, GetEndAsRange(*view.buffer), s16);
|
||||
// ReplaceText(view.buffer, GetEndAsRange(*view.buffer), L" \n");
|
||||
}
|
||||
}
|
||||
LoadTextA(view.buffer);
|
||||
}
|
||||
|
||||
while (!WindowShouldClose()) {
|
||||
|
||||
@@ -166,6 +166,10 @@ void HandleKeybindings(View *_view) {
|
||||
view.scroll.y -= GetMouseWheelMove() * 48;
|
||||
}
|
||||
|
||||
if (IsKeyDown(KEY_F2)) {
|
||||
LoadBigText(view.buffer);
|
||||
}
|
||||
|
||||
{
|
||||
int keys[4] = {KEY_RIGHT, KEY_LEFT, KEY_DOWN, KEY_UP};
|
||||
for (int i = 0; i < 4; i += 1) {
|
||||
@@ -308,8 +312,11 @@ void HandleKeybindings(View *_view) {
|
||||
Int last_line = LastLine(view.buffer[0]);
|
||||
view.scroll.y = Clamp(view.scroll.y, 0.f, Max(0.f, (last_line - 1) * view.line_spacing));
|
||||
|
||||
// Int line_chars = GetCharCountOfLongestLine(view.buffer[0]);
|
||||
// @note:
|
||||
// GetCharCountOfLongestLine is a bottleneck, there is probably an algorithm for
|
||||
// calculating this value incrementally but do we even need X scrollbar or x clipping?
|
||||
view.scroll.x = ClampBottom(view.scroll.x, 0.f);
|
||||
// Int line_chars = GetCharCountOfLongestLine(view.buffer[0]);
|
||||
// view.scroll.x = Clamp(view.scroll.x, 0.f, Max(0.f, (line_chars - 2) * view.char_spacing));
|
||||
}
|
||||
}
|
||||
@@ -28,14 +28,38 @@ void DrawVisibleCells(const View &view) {
|
||||
}
|
||||
}
|
||||
|
||||
Vec2 GetCellSize(const View &view) {
|
||||
Vec2 result = {view.char_spacing, view.line_spacing};
|
||||
return result;
|
||||
}
|
||||
|
||||
Vec2 XYToWorldPos(const View &view, XY xy) {
|
||||
Vec2 result = {(float)xy.col * view.char_spacing, (float)xy.line * view.line_spacing};
|
||||
return result;
|
||||
}
|
||||
|
||||
Rect2 XYToRect(const View &view, XY xy) {
|
||||
Rect2 result = Rect2FromSize(XYToWorldPos(view, xy), GetCellSize(view));
|
||||
return result;
|
||||
}
|
||||
|
||||
void DrawCaret(const View &view, XY xy, float size, Color color) {
|
||||
Rect2 _rect = Rect2FromSize({(float)xy.col * view.char_spacing, (float)xy.line * view.line_spacing}, {view.char_spacing, view.line_spacing});
|
||||
Rect2 _rect = XYToRect(view, xy);
|
||||
Rect2 rect = CutLeft(&_rect, size * view.char_spacing);
|
||||
rect -= view.scroll;
|
||||
DrawRectangleRec(ToRectangle(rect), color);
|
||||
}
|
||||
|
||||
void DrawCaret(const View &view, Caret it) {
|
||||
void DrawLineHighlight(const View &view, XY fxy, Color color) {
|
||||
Vec2 w = XYToWorldPos(view, XYLine(fxy.line));
|
||||
w -= view.scroll;
|
||||
Range range = GetLineRange(*view.buffer, fxy.line);
|
||||
float xsize = view.char_spacing * (float)GetSize(range);
|
||||
Rect2 rect = Rect2FromSize(w, {xsize, view.line_spacing});
|
||||
DrawRectangleRec(ToRectangle(rect), color);
|
||||
}
|
||||
|
||||
void DrawCaret(const View &view, Caret &it) {
|
||||
ProfileFunction();
|
||||
Buffer &buf = *view.buffer;
|
||||
Int front = GetFront(it);
|
||||
@@ -46,6 +70,12 @@ void DrawCaret(const View &view, Caret it) {
|
||||
XY bxy = PosToXY(buf, back);
|
||||
DrawCaret(view, bxy, 0.15f, GREEN);
|
||||
|
||||
// Line highlight
|
||||
bool main_caret = &it == &view.carets.data[0];
|
||||
unsigned char red = main_caret ? 0 : 120;
|
||||
DrawLineHighlight(view, fxy, {0, red, red, 30});
|
||||
DrawLineHighlight(view, fxy, {0, red, red, 10});
|
||||
|
||||
// Draw selection
|
||||
if (front != back) {
|
||||
XY min = PosToXY(buf, it.range.min);
|
||||
|
||||
Reference in New Issue
Block a user