Line highlights

This commit is contained in:
Krzosa Karol
2024-07-04 07:20:45 +02:00
parent a77a149664
commit e7f53d2c07
3 changed files with 126 additions and 78 deletions

View File

@@ -28,6 +28,11 @@ struct History {
int debug_edit_phase;
};
struct ColoredString {
Range range;
Color color;
};
struct Window {
Font font;
float font_size;
@@ -46,8 +51,9 @@ struct Window {
Buffer buffer;
History history;
Arena layout_arena;
Layout layout;
Array<ColoredString> colored_strings;
Arena layout_arena;
Layout layout;
};
template <class T1, class T2>

View File

@@ -5,9 +5,11 @@
// @todo: highlight all occurences of selected word
// @todo: systematic way of coloring words
// @todo: line wrapping
// @todo: search for word
// @todo: context menu
// @todo: toy around with acme ideas
// @todo: undo tree
// @todo: resize font, reload font
// @todo: add clipboard history?
#include "rect2.cpp"
#include "buffer.cpp"
@@ -85,6 +87,7 @@ int main() {
window.font = font;
window.font_size = font_size;
window.font_spacing;
window.colored_strings.allocator = FrameArena;
InitArena(&window.layout_arena);
InitBuffer(GetSystemAllocator(), &window.buffer);
@@ -294,6 +297,18 @@ int main() {
it.range.min = it.range.max = line.max_without_new_line;
}
}
if (IsKeyPressed(KEY_PAGE_UP) || IsKeyPressedRepeat(KEY_PAGE_UP)) {
if (IsKeyDown(KEY_LEFT_SHIFT)) {
} else {
}
}
if (IsKeyPressed(KEY_PAGE_DOWN) || IsKeyPressedRepeat(KEY_PAGE_DOWN)) {
if (IsKeyDown(KEY_LEFT_SHIFT)) {
} else {
}
}
}
if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_C)) {
@@ -411,6 +426,16 @@ int main() {
ApplyEdits(focused_window, edits);
AfterEdit(focused_window, edits);
}
{
int64_t index = 0;
String buffer_string = GetString(focused_window->buffer);
if (Seek(buffer_string, "number", &index)) {
Range range = {index, index + 6};
focused_window->colored_strings.add({range, RED});
}
}
EventRecording_SimulateGetCharPressed(focused_window);
}
@@ -427,7 +452,9 @@ int main() {
// Draw and layout window overlay
Vec2 mouse = GetMousePosition();
{
// @todo: why are we drawing this here??
DrawRectangleRec(ToRectangle(window.rect), WHITE);
DrawRectangleRec(ToRectangle(line_number_rect), WHITE);
Vec2 size = GetSize(window.rect);
Vec2 min = window.scroll / (window.layout.buffer_world_pixel_size + size);
@@ -613,34 +640,34 @@ int main() {
Vec2 window_rect_size = GetSize(window.rect);
BeginScissorMode((int)window.rect.min.x, (int)window.rect.min.y, (int)window_rect_size.x, (int)window_rect_size.y);
Range visible_line_range = CalculateVisibleLineRange(window);
for (int64_t line = visible_line_range.min; line < visible_line_range.max; line += 1) {
LayoutRow &row = window.layout.rows[line];
Array<LayoutColumn> visible_columns = CalculateVisibleColumns(&FrameArena, window);
Range visible_line_range = CalculateVisibleLineRange(window);
ForItem(col, row.columns) {
Rect2 rect = {col.rect.min + window.rect.min - window.scroll, col.rect.max + window.rect.min - window.scroll};
if (!CheckCollisionRecs(ToRectangle(rect), ToRectangle(window.rect))) {
continue; // Clip everything that is outside the window and screen
}
if (col.codepoint == '\n') {
DrawTextEx(font, "\\n", rect.min, font_size, font_spacing, GRAY);
} else if (col.codepoint == '\0') {
DrawTextEx(font, "\\0", rect.min, font_size, font_spacing, {255, 0, 0, 150});
} else if ((col.codepoint != ' ') && (col.codepoint != '\t')) {
DrawTextCodepoint(font, col.codepoint, rect.min, font_size, BLACK);
}
ForItem(col, visible_columns) {
Rect2 rect = {col.rect.min + window.rect.min - window.scroll, col.rect.max + window.rect.min - window.scroll};
if (col.codepoint == '\n') {
DrawTextEx(font, "\\n", rect.min, font_size, font_spacing, GRAY);
} else if (col.codepoint == '\0') {
DrawTextEx(font, "\\0", rect.min, font_size, font_spacing, {255, 0, 0, 150});
} else if ((col.codepoint != ' ') && (col.codepoint != '\t')) {
DrawTextCodepoint(font, col.codepoint, rect.min, font_size, BLACK);
}
}
Array<LayoutColumn> visible_columns = CalculateVisibleColumns(&FrameArena, window);
// Draw cursor stuff
Array<LayoutRow *> lines_to_highlight = {FrameArena};
ForItem(cursor, window.cursors) {
auto front = GetRowCol(window, GetFront(cursor));
auto back = GetRowCol(window, GetBack(cursor));
Tuple<LayoutRow *, LayoutColumn *> front = GetRowCol(window, GetFront(cursor));
Tuple<LayoutRow *, LayoutColumn *> back = GetRowCol(window, GetBack(cursor));
// Line highlight
lines_to_highlight.add(front.a);
if (GetRangeSize(cursor.range) == 0) {
Rect2 rect = front.a->rect + window.rect.min - window.scroll;
DrawRectangleRec(ToRectangle(rect), {0, 0, 0, 30});
}
// Selection
For(visible_columns) {
if (it.pos >= cursor.range.min && it.pos < cursor.range.max) {
Rect2 rect = it.rect + window.rect.min - window.scroll;
@@ -648,6 +675,7 @@ int main() {
}
}
// Cursor blocks
if (front.b) {
Rect2 rect = front.b->rect + window.rect.min - window.scroll;
rect = CutLeft(&rect, 4);
@@ -664,12 +692,19 @@ int main() {
// Draw line numbers
{
Rect2 rect = line_number_rect;
BeginScissorMode((int)rect.min.x, (int)rect.min.y, (int)(rect.max.x - rect.min.x), (int)(rect.max.y - rect.min.y));
BeginScissorMode((int)line_number_rect.min.x, (int)line_number_rect.min.y, (int)(line_number_rect.max.x - line_number_rect.min.x), (int)(line_number_rect.max.y - line_number_rect.min.y));
for (int64_t line = visible_line_range.min; line < visible_line_range.max; line += 1) {
LayoutRow &row = window.layout.rows[line];
Vec2 pos = {rect.min.x, row.rect.min.y + rect.min.y - window.scroll.y};
Vec2 pos = {line_number_rect.min.x, row.rect.min.y + line_number_rect.min.y - window.scroll.y};
For(lines_to_highlight) {
if (it == &row) {
Rect2 r = {pos, pos};
r.max.x = line_number_rect.max.x;
r.max.y += GetSize(row.rect).y;
DrawRectangleRec(ToRectangle(r), {0, 0, 0, 30});
break;
}
}
String line_num_string = Format(FrameArena, "%lld", (long long)line);
DrawTextEx(font, line_num_string.data, pos, font_size, font_spacing, LIGHTGRAY);

View File

@@ -14,6 +14,63 @@ Rectangle ToRectangle(Rect2 r) {
return result;
}
// clang-format off
Rect2 operator-(Rect2 r, Rect2 value) { return { r.min.x - value.min.x, r.min.y - value.min.y, r.max.x - value.max.x, r.max.y - value.max.y }; }
Rect2 operator+(Rect2 r, Rect2 value) { return { r.min.x + value.min.x, r.min.y + value.min.y, r.max.x + value.max.x, r.max.y + value.max.y }; }
Rect2 operator*(Rect2 r, Rect2 value) { return { r.min.x * value.min.x, r.min.y * value.min.y, r.max.x * value.max.x, r.max.y * value.max.y }; }
Rect2 operator/(Rect2 r, Rect2 value) { return { r.min.x / value.min.x, r.min.y / value.min.y, r.max.x / value.max.x, r.max.y / value.max.y }; }
Rect2 operator-(Rect2 r, Vec2 value) { return { r.min.x - value.x, r.min.y - value.y, r.max.x - value.x, r.max.y - value.y }; }
Rect2 operator+(Rect2 r, Vec2 value) { return { r.min.x + value.x, r.min.y + value.y, r.max.x + value.x, r.max.y + value.y }; }
Rect2 operator*(Rect2 r, Vec2 value) { return { r.min.x * value.x, r.min.y * value.y, r.max.x * value.x, r.max.y * value.y }; }
Rect2 operator/(Rect2 r, Vec2 value) { return { r.min.x / value.x, r.min.y / value.y, r.max.x / value.x, r.max.y / value.y }; }
Rect2 operator-(Rect2 r, float value) { return { r.min.x - value, r.min.y - value, r.max.x - value, r.max.y - value }; }
Rect2 operator+(Rect2 r, float value) { return { r.min.x + value, r.min.y + value, r.max.x + value, r.max.y + value }; }
Rect2 operator*(Rect2 r, float value) { return { r.min.x * value, r.min.y * value, r.max.x * value, r.max.y * value }; }
Rect2 operator/(Rect2 r, float value) { return { r.min.x / value, r.min.y / value, r.max.x / value, r.max.y / value }; }
Rect2 operator-=(Rect2 &r, Rect2 value) { r = r - value; return r; }
Rect2 operator+=(Rect2 &r, Rect2 value) { r = r + value; return r; }
Rect2 operator*=(Rect2 &r, Rect2 value) { r = r * value; return r; }
Rect2 operator/=(Rect2 &r, Rect2 value) { r = r / value; return r; }
Rect2 operator-=(Rect2 &r, Vec2 value) { r = r - value; return r; }
Rect2 operator+=(Rect2 &r, Vec2 value) { r = r + value; return r; }
Rect2 operator*=(Rect2 &r, Vec2 value) { r = r * value; return r; }
Rect2 operator/=(Rect2 &r, Vec2 value) { r = r / value; return r; }
Rect2 operator-=(Rect2 &r, float value) { r = r - value; return r; }
Rect2 operator+=(Rect2 &r, float value) { r = r + value; return r; }
Rect2 operator*=(Rect2 &r, float value) { r = r * value; return r; }
Rect2 operator/=(Rect2 &r, float value) { r = r / value; return r; }
Vec2 operator-(Vec2 a, Vec2 b) { return {a.x - b.x, a.y - b.y}; }
Vec2 operator+(Vec2 a, Vec2 b) { return {a.x + b.x, a.y + b.y}; }
Vec2 operator*(Vec2 a, Vec2 b) { return {a.x * b.x, a.y * b.y}; }
Vec2 operator/(Vec2 a, Vec2 b) { return {a.x / b.x, a.y / b.y}; }
Vec2 operator-(Vec2 a, float b) { return {a.x - b, a.y - b}; }
Vec2 operator+(Vec2 a, float b) { return {a.x + b, a.y + b}; }
Vec2 operator*(Vec2 a, float b) { return {a.x * b, a.y * b}; }
Vec2 operator/(Vec2 a, float b) { return {a.x / b, a.y / b}; }
Vec2 operator-=(Vec2 &a, Vec2 b) { a = a - b; return a; }
Vec2 operator+=(Vec2 &a, Vec2 b) { a = a + b; return a; }
Vec2 operator*=(Vec2 &a, Vec2 b) { a = a * b; return a; }
Vec2 operator/=(Vec2 &a, Vec2 b) { a = a / b; return a; }
Vec2 operator-=(Vec2 &a, float b) { a = a - b; return a; }
Vec2 operator+=(Vec2 &a, float b) { a = a + b; return a; }
Vec2 operator*=(Vec2 &a, float b) { a = a * b; return a; }
Vec2 operator/=(Vec2 &a, float b) { a = a / b; return a; }
// clang-format on
Rect2 Rect2FromSize(Vec2 pos, Vec2 size) {
Rect2 result = {};
result.min = pos;
result.max = pos + size;
return result;
}
Rect2 Shrink(Rect2 result, float v) {
result.min.x += v;
result.max.x -= v;
@@ -71,53 +128,3 @@ Rect2 CutTop(Rect2 *r, float value) {
};
return result;
}
// clang-format off
Rect2 operator-(Rect2 r, Rect2 value) { return { r.min.x - value.min.x, r.min.y - value.min.y, r.max.x - value.max.x, r.max.y - value.max.y }; }
Rect2 operator+(Rect2 r, Rect2 value) { return { r.min.x + value.min.x, r.min.y + value.min.y, r.max.x + value.max.x, r.max.y + value.max.y }; }
Rect2 operator*(Rect2 r, Rect2 value) { return { r.min.x * value.min.x, r.min.y * value.min.y, r.max.x * value.max.x, r.max.y * value.max.y }; }
Rect2 operator/(Rect2 r, Rect2 value) { return { r.min.x / value.min.x, r.min.y / value.min.y, r.max.x / value.max.x, r.max.y / value.max.y }; }
Rect2 operator-(Rect2 r, Vec2 value) { return { r.min.x - value.x, r.min.y - value.y, r.max.x - value.x, r.max.y - value.y }; }
Rect2 operator+(Rect2 r, Vec2 value) { return { r.min.x + value.x, r.min.y + value.y, r.max.x + value.x, r.max.y + value.y }; }
Rect2 operator*(Rect2 r, Vec2 value) { return { r.min.x * value.x, r.min.y * value.y, r.max.x * value.x, r.max.y * value.y }; }
Rect2 operator/(Rect2 r, Vec2 value) { return { r.min.x / value.x, r.min.y / value.y, r.max.x / value.x, r.max.y / value.y }; }
Rect2 operator-(Rect2 r, float value) { return { r.min.x - value, r.min.y - value, r.max.x - value, r.max.y - value }; }
Rect2 operator+(Rect2 r, float value) { return { r.min.x + value, r.min.y + value, r.max.x + value, r.max.y + value }; }
Rect2 operator*(Rect2 r, float value) { return { r.min.x * value, r.min.y * value, r.max.x * value, r.max.y * value }; }
Rect2 operator/(Rect2 r, float value) { return { r.min.x / value, r.min.y / value, r.max.x / value, r.max.y / value }; }
Rect2 operator-=(Rect2 &r, Rect2 value) { r = r - value; return r; }
Rect2 operator+=(Rect2 &r, Rect2 value) { r = r + value; return r; }
Rect2 operator*=(Rect2 &r, Rect2 value) { r = r * value; return r; }
Rect2 operator/=(Rect2 &r, Rect2 value) { r = r / value; return r; }
Rect2 operator-=(Rect2 &r, Vec2 value) { r = r - value; return r; }
Rect2 operator+=(Rect2 &r, Vec2 value) { r = r + value; return r; }
Rect2 operator*=(Rect2 &r, Vec2 value) { r = r * value; return r; }
Rect2 operator/=(Rect2 &r, Vec2 value) { r = r / value; return r; }
Rect2 operator-=(Rect2 &r, float value) { r = r - value; return r; }
Rect2 operator+=(Rect2 &r, float value) { r = r + value; return r; }
Rect2 operator*=(Rect2 &r, float value) { r = r * value; return r; }
Rect2 operator/=(Rect2 &r, float value) { r = r / value; return r; }
Vec2 operator-(Vec2 a, Vec2 b) { return {a.x - b.x, a.y - b.y}; }
Vec2 operator+(Vec2 a, Vec2 b) { return {a.x + b.x, a.y + b.y}; }
Vec2 operator*(Vec2 a, Vec2 b) { return {a.x * b.x, a.y * b.y}; }
Vec2 operator/(Vec2 a, Vec2 b) { return {a.x / b.x, a.y / b.y}; }
Vec2 operator-(Vec2 a, float b) { return {a.x - b, a.y - b}; }
Vec2 operator+(Vec2 a, float b) { return {a.x + b, a.y + b}; }
Vec2 operator*(Vec2 a, float b) { return {a.x * b, a.y * b}; }
Vec2 operator/(Vec2 a, float b) { return {a.x / b, a.y / b}; }
Vec2 operator-=(Vec2 &a, Vec2 b) { a = a - b; return a; }
Vec2 operator+=(Vec2 &a, Vec2 b) { a = a + b; return a; }
Vec2 operator*=(Vec2 &a, Vec2 b) { a = a * b; return a; }
Vec2 operator/=(Vec2 &a, Vec2 b) { a = a / b; return a; }
Vec2 operator-=(Vec2 &a, float b) { a = a - b; return a; }
Vec2 operator+=(Vec2 &a, float b) { a = a + b; return a; }
Vec2 operator*=(Vec2 &a, float b) { a = a * b; return a; }
Vec2 operator/=(Vec2 &a, float b) { a = a / b; return a; }
// clang-format on