Drawing selection and overlapping selections

This commit is contained in:
Krzosa Karol
2024-06-23 10:05:54 +02:00
parent 10afbd3e4f
commit b76d825f55
3 changed files with 64 additions and 18 deletions

View File

@@ -493,6 +493,14 @@ struct Array {
// @copy_paste array slice
T get_or_default(int64_t i, T default_value = {}) {
T result = default_value;
if (i >= 0 && i < len) {
result = data[i];
}
return result;
}
T pop() {
Assert(len > 0);
return data[--len];

View File

@@ -349,6 +349,7 @@ LineAndColumn FindLineAndColumn(Buffer &buffer, int64_t pos) {
result.column = 1;
result.line = FindLine(buffer, pos);
for (BufferIter iter = Iterate(buffer, result.line.range); IsValid(iter); Advance(&iter)) {
// @todo: make sure we handle when there is invalid unicode in the stream
if (iter.pos == pos) {
result.column = iter.codepoint_index;
break;
@@ -395,7 +396,7 @@ int64_t Seek(Buffer &buffer, int64_t pos, int64_t direction = ITERATE_FORWARD) {
bool seek_whitespace = standing_on_whitespace == false;
bool seek_word = standing_on_whitespace;
int64_t result = max;
int64_t result = direction == ITERATE_BACKWARD ? 0 : buffer.len;
BufferIter iter = Iterate(buffer, {min, max}, direction);
int64_t prev_pos = iter.pos;
for (; IsValid(iter); Advance(&iter)) {

View File

@@ -178,18 +178,30 @@ int main() {
if (IsKeyPressed(KEY_LEFT) || IsKeyPressedRepeat(KEY_LEFT)) {
For(focused_window->cursors) {
if (IsKeyDown(KEY_LEFT_CONTROL)) {
it.max = it.min = Seek(focused_window->buffer, it.min, ITERATE_BACKWARD);
} else {
if (IsKeyDown(KEY_LEFT_SHIFT)) {
it.min = MoveLeft(focused_window->buffer, it.min);
} else {
it.max = it.min = MoveLeft(focused_window->buffer, it.min);
}
}
}
}
if (IsKeyPressed(KEY_RIGHT) || IsKeyPressedRepeat(KEY_RIGHT)) {
For(focused_window->cursors) {
if (IsKeyDown(KEY_LEFT_CONTROL)) {
it.max = it.min = Seek(focused_window->buffer, it.min, ITERATE_FORWARD);
} else {
if (IsKeyDown(KEY_LEFT_SHIFT)) {
it.max = MoveRight(focused_window->buffer, it.max);
} else {
it.max = it.min = MoveRight(focused_window->buffer, it.min);
}
}
}
}
if (IsKeyPressed(KEY_DOWN) || IsKeyPressedRepeat(KEY_DOWN)) {
For(focused_window->cursors) {
it.max = it.min = MoveDown(focused_window->buffer, it.min);
@@ -201,15 +213,17 @@ int main() {
}
}
// Merge cursors that overlap
// Merge cursors that overlap, this needs to be handled before any edits to
// make sure overlapping edits won't happen.
for (int64_t cursor_i = 0; cursor_i < focused_window->cursors.len; cursor_i += 1) {
Range &cursor = focused_window->cursors[cursor_i];
IterRemove(focused_window->cursors) {
IterRemovePrepare(focused_window->cursors);
ForItem(cursor, focused_window->cursors) {
if (&cursor == &it) continue;
if (cursor.min == it.min) {
if (cursor.max > it.min && cursor.max <= it.max) {
remove_item = true;
cursor.max = it.max;
break;
}
}
@@ -285,6 +299,7 @@ int main() {
struct Cell {
Rect2 rect;
int codepoint;
int64_t column;
int64_t pos;
};
@@ -352,7 +367,7 @@ int main() {
// Clip everything that is outside the window and screen
if (CheckCollisionRecs(cell_rectangle, ToRectangle(window_text_rect_in_render_units_clamped_to_screen))) {
row.cells.add({cell_rect, codepoint, iter.pos});
row.cells.add({cell_rect, codepoint, iter.codepoint_index, iter.pos});
row.rect.max = cell_rect.max;
}
@@ -388,18 +403,40 @@ int main() {
}
}
// Draw the cursor
// Draw cursor stuff
ForItem(cursor, window.cursors) {
Line min_line = FindLine(window.buffer, cursor.min);
Line max_line = FindLine(window.buffer, cursor.max);
bool selecting = cursor.min != cursor.max;
ForItem(row, rows) {
Range line_range = window.buffer.lines[row.line];
if (cursor.min >= line_range.min && cursor.min <= line_range.max) {
// Draw line highlights
if (row.line == min_line.number) {
DrawRectangleRec(ToRectangle(row.rect), {255, 0, 0, 30});
}
// if (row.line == max_line.number) {
// DrawRectangleRec(ToRectangle(row.rect), {0, 255, 0, 30});
// }
ForItem(cell, row.cells) {
if (cursor.min == cell.pos) {
// Draw selection
if (selecting) {
if (row.line >= min_line.number && row.line <= max_line.number) {
if (cell.pos >= cursor.min && cell.pos < cursor.max) {
DrawRectangleRec(ToRectangle(cell.rect), BLUE);
}
}
}
// Draw cursors
if (cell.pos == cursor.min) {
Rect2 rect = cell.rect;
rect = CutLeft(&rect, 4);
DrawRectangleRec(ToRectangle(rect), RED);
}
if (cell.pos == cursor.max) {
Rect2 rect = cell.rect;
rect = CutLeft(&rect, 2);
DrawRectangleRec(ToRectangle(rect), GREEN);
}
}
}