Drawing selection and overlapping selections
This commit is contained in:
@@ -493,6 +493,14 @@ struct Array {
|
|||||||
|
|
||||||
// @copy_paste array slice
|
// @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() {
|
T pop() {
|
||||||
Assert(len > 0);
|
Assert(len > 0);
|
||||||
return data[--len];
|
return data[--len];
|
||||||
|
|||||||
@@ -349,6 +349,7 @@ LineAndColumn FindLineAndColumn(Buffer &buffer, int64_t pos) {
|
|||||||
result.column = 1;
|
result.column = 1;
|
||||||
result.line = FindLine(buffer, pos);
|
result.line = FindLine(buffer, pos);
|
||||||
for (BufferIter iter = Iterate(buffer, result.line.range); IsValid(iter); Advance(&iter)) {
|
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) {
|
if (iter.pos == pos) {
|
||||||
result.column = iter.codepoint_index;
|
result.column = iter.codepoint_index;
|
||||||
break;
|
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_whitespace = standing_on_whitespace == false;
|
||||||
bool seek_word = standing_on_whitespace;
|
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);
|
BufferIter iter = Iterate(buffer, {min, max}, direction);
|
||||||
int64_t prev_pos = iter.pos;
|
int64_t prev_pos = iter.pos;
|
||||||
for (; IsValid(iter); Advance(&iter)) {
|
for (; IsValid(iter); Advance(&iter)) {
|
||||||
|
|||||||
@@ -178,18 +178,30 @@ int main() {
|
|||||||
|
|
||||||
if (IsKeyPressed(KEY_LEFT) || IsKeyPressedRepeat(KEY_LEFT)) {
|
if (IsKeyPressed(KEY_LEFT) || IsKeyPressedRepeat(KEY_LEFT)) {
|
||||||
For(focused_window->cursors) {
|
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);
|
it.max = it.min = MoveLeft(focused_window->buffer, it.min);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (IsKeyPressed(KEY_RIGHT) || IsKeyPressedRepeat(KEY_RIGHT)) {
|
if (IsKeyPressed(KEY_RIGHT) || IsKeyPressedRepeat(KEY_RIGHT)) {
|
||||||
For(focused_window->cursors) {
|
For(focused_window->cursors) {
|
||||||
if (IsKeyDown(KEY_LEFT_CONTROL)) {
|
if (IsKeyDown(KEY_LEFT_CONTROL)) {
|
||||||
it.max = it.min = Seek(focused_window->buffer, it.min, ITERATE_FORWARD);
|
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 {
|
} else {
|
||||||
it.max = it.min = MoveRight(focused_window->buffer, it.min);
|
it.max = it.min = MoveRight(focused_window->buffer, it.min);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (IsKeyPressed(KEY_DOWN) || IsKeyPressedRepeat(KEY_DOWN)) {
|
if (IsKeyPressed(KEY_DOWN) || IsKeyPressedRepeat(KEY_DOWN)) {
|
||||||
For(focused_window->cursors) {
|
For(focused_window->cursors) {
|
||||||
it.max = it.min = MoveDown(focused_window->buffer, it.min);
|
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) {
|
IterRemove(focused_window->cursors) {
|
||||||
IterRemovePrepare(focused_window->cursors);
|
IterRemovePrepare(focused_window->cursors);
|
||||||
|
|
||||||
ForItem(cursor, focused_window->cursors) {
|
|
||||||
if (&cursor == &it) continue;
|
if (&cursor == &it) continue;
|
||||||
|
|
||||||
if (cursor.min == it.min) {
|
if (cursor.max > it.min && cursor.max <= it.max) {
|
||||||
remove_item = true;
|
remove_item = true;
|
||||||
|
cursor.max = it.max;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -285,6 +299,7 @@ int main() {
|
|||||||
struct Cell {
|
struct Cell {
|
||||||
Rect2 rect;
|
Rect2 rect;
|
||||||
int codepoint;
|
int codepoint;
|
||||||
|
int64_t column;
|
||||||
int64_t pos;
|
int64_t pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -352,7 +367,7 @@ int main() {
|
|||||||
|
|
||||||
// Clip everything that is outside the window and screen
|
// Clip everything that is outside the window and screen
|
||||||
if (CheckCollisionRecs(cell_rectangle, ToRectangle(window_text_rect_in_render_units_clamped_to_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;
|
row.rect.max = cell_rect.max;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -388,18 +403,40 @@ int main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the cursor
|
// Draw cursor stuff
|
||||||
ForItem(cursor, window.cursors) {
|
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) {
|
ForItem(row, rows) {
|
||||||
Range line_range = window.buffer.lines[row.line];
|
// Draw line highlights
|
||||||
if (cursor.min >= line_range.min && cursor.min <= line_range.max) {
|
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) {
|
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;
|
Rect2 rect = cell.rect;
|
||||||
rect = CutLeft(&rect, 4);
|
rect = CutLeft(&rect, 4);
|
||||||
DrawRectangleRec(ToRectangle(rect), RED);
|
DrawRectangleRec(ToRectangle(rect), RED);
|
||||||
}
|
}
|
||||||
|
if (cell.pos == cursor.max) {
|
||||||
|
Rect2 rect = cell.rect;
|
||||||
|
rect = CutLeft(&rect, 2);
|
||||||
|
DrawRectangleRec(ToRectangle(rect), GREEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user