Create cursor above, double click, render whitespace when selecting

This commit is contained in:
Krzosa Karol
2024-07-22 07:30:40 +02:00
parent 4c9366d495
commit 91d2db6116
5 changed files with 76 additions and 30 deletions

View File

@@ -18,7 +18,7 @@ void LoadBigTextAndBigLine(Buffer *buffer, int size = 2500000) {
void LoadTextA(Buffer *buffer) { void LoadTextA(Buffer *buffer) {
Scratch scratch; Scratch scratch;
for (int i = 0; i < 1000; i += 1) { 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); 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\r\n", i, i, i, i, i, i, i, i, i, i, i, i);
String16 s16 = ToString16(scratch, s); String16 s16 = ToString16(scratch, s);
ReplaceText(buffer, GetEndAsRange(*buffer), s16); ReplaceText(buffer, GetEndAsRange(*buffer), s16);
} }
@@ -26,12 +26,12 @@ void LoadTextA(Buffer *buffer) {
void LoadLine(Buffer *buffer) { void LoadLine(Buffer *buffer) {
Scratch scratch; Scratch scratch;
String s = "Line number and so on óźćż"; String s = "Line number and so on óźćż";
ReplaceText(buffer, {}, ToString16(scratch, s)); ReplaceText(buffer, {}, ToString16(scratch, s));
} }
void LoadUnicode(Buffer *buffer) { void LoadUnicode(Buffer *buffer) {
String text = R"===( String text = R"===(
This page contains characters from each of the Unicode character blocks. This page contains characters from each of the Unicode character blocks.
See also Unicode 3.2 test page. See also Unicode 3.2 test page.

View File

@@ -36,9 +36,11 @@ Color GruvboxFadedPurple = {0x8f, 0x3f, 0x71, 0xff};
Color GruvboxFadedAqua = {0x42, 0x7b, 0x58, 0xff}; Color GruvboxFadedAqua = {0x42, 0x7b, 0x58, 0xff};
Color GruvboxFadedOrange = {0xaf, 0x3a, 0x03, 0xff}; Color GruvboxFadedOrange = {0xaf, 0x3a, 0x03, 0xff};
Color ColorText = GruvboxDark0Hard; Color ColorText = GruvboxDark0Hard;
Color ColorBackground = GruvboxLight0Hard; Color ColorBackground = GruvboxLight0Hard;
Color ColorSelection = GruvboxLight1;
Color ColorLineHighlight = GruvboxLight1; Color ColorLineHighlight = GruvboxLight1;
Color ColorMainCaret = GruvboxBrightRed; Color ColorMainCaret = GruvboxBrightRed;
Color ColorSubCaret = GruvboxGray245; Color ColorSubCaret = GruvboxGray245;
Color ColorSelection = GruvboxLight1;
Color ColorWhitespaceDuringSelection = GruvboxLight2;

View File

@@ -38,6 +38,11 @@ inline bool CtrlAltPress(int key) {
return result; return result;
} }
inline bool AltShiftPress(int key) {
bool result = Press(key) && Shift() && Alt();
return result;
}
bool IsDoubleClick() { bool IsDoubleClick() {
static double last_click_time; static double last_click_time;
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) { if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
@@ -150,7 +155,9 @@ const int DIR_LEFT = 1;
const int DIR_DOWN = 2; const int DIR_DOWN = 2;
const int DIR_UP = 3; const int DIR_UP = 3;
Int MovePos(Buffer &buffer, Int pos, int direction, bool ctrl_pressed) { const bool CTRL_PRESSED = true;
Int MovePos(Buffer &buffer, Int pos, int direction, bool ctrl_pressed = false) {
ProfileFunction(); ProfileFunction();
Assert(direction >= 0 && direction <= 3); Assert(direction >= 0 && direction <= 3);
if (ctrl_pressed) { if (ctrl_pressed) {
@@ -171,3 +178,10 @@ Int MovePos(Buffer &buffer, Int pos, int direction, bool ctrl_pressed) {
} }
} }
} }
Range EncloseWord(Buffer &buffer, Int pos) {
Range result = {};
result.min = MoveOnWhitespaceBoundaryBackward(buffer, pos);
result.max = MoveOnWhitespaceBoundaryForward(buffer, pos);
return result;
}

View File

@@ -98,7 +98,6 @@ void Command_MoveCursorsToSide(View *_view, int direction, bool shift = false) {
} }
} }
bool CTRL_PRESSED = true;
void Command_Delete(View *_view, int direction, bool ctrl = false) { void Command_Delete(View *_view, int direction, bool ctrl = false) {
Assert(direction == DIR_LEFT || direction == DIR_RIGHT); Assert(direction == DIR_LEFT || direction == DIR_RIGHT);
View &view = *_view; View &view = *_view;
@@ -114,6 +113,28 @@ void Command_Delete(View *_view, int direction, bool ctrl = false) {
Command_Replace(&view, {}); Command_Replace(&view, {});
} }
void Command_CreateCursorVertical(View *_view, int direction) {
Assert(direction == DIR_UP || direction == DIR_DOWN);
View &view = *_view;
Buffer &buf = *view.buffer;
Scratch scratch;
Array<Caret> arr = {scratch};
For(view.carets) {
if (PosToLine(buf, it.range.min) == PosToLine(buf, it.range.max)) {
Int f = MovePos(buf, GetFront(it), direction);
Int b = MovePos(buf, GetBack(it), direction);
Add(&arr, MakeCaret(f, b));
} else {
Int pos = direction == DIR_UP ? it.range.min : it.range.max;
Int min = MovePos(buf, pos, direction);
Add(&arr, MakeCaret(min));
}
}
For(arr) Add(&view.carets, it);
MergeCarets(&view.carets);
}
void HandleKeybindings(View *_view) { void HandleKeybindings(View *_view) {
ProfileFunction(); ProfileFunction();
View &view = *_view; View &view = *_view;
@@ -138,6 +159,8 @@ void HandleKeybindings(View *_view) {
if (CtrlAltPress(KEY_DOWN)) { if (CtrlAltPress(KEY_DOWN)) {
Command_DuplicateLine(&view, DIR_DOWN); Command_DuplicateLine(&view, DIR_DOWN);
} else if (AltShiftPress(KEY_DOWN)) {
Command_CreateCursorVertical(&view, DIR_DOWN);
} else if (CtrlShiftPress(KEY_DOWN)) { } else if (CtrlShiftPress(KEY_DOWN)) {
For(view.carets) it = ChangeFront(it, MovePos(buf, GetFront(it), DIR_DOWN, true)); For(view.carets) it = ChangeFront(it, MovePos(buf, GetFront(it), DIR_DOWN, true));
} else if (CtrlPress(KEY_DOWN)) { } else if (CtrlPress(KEY_DOWN)) {
@@ -156,16 +179,18 @@ void HandleKeybindings(View *_view) {
if (CtrlAltPress(KEY_UP)) { if (CtrlAltPress(KEY_UP)) {
Command_DuplicateLine(&view, DIR_UP); Command_DuplicateLine(&view, DIR_UP);
} else if (AltShiftPress(KEY_UP)) {
Command_CreateCursorVertical(&view, DIR_UP);
} else if (CtrlShiftPress(KEY_UP)) { } else if (CtrlShiftPress(KEY_UP)) {
For(view.carets) it = ChangeFront(it, MovePos(buf, GetFront(it), DIR_UP, true)); For(view.carets) it = ChangeFront(it, MovePos(buf, GetFront(it), DIR_UP, CTRL_PRESSED));
} else if (CtrlPress(KEY_UP)) { } else if (CtrlPress(KEY_UP)) {
For(view.carets) it = MakeCaret(MovePos(buf, it.range.min, DIR_UP, true)); For(view.carets) it = MakeCaret(MovePos(buf, it.range.min, DIR_UP, CTRL_PRESSED));
} else if (ShiftPress(KEY_UP)) { } else if (ShiftPress(KEY_UP)) {
For(view.carets) it = ChangeFront(it, MovePos(buf, GetFront(it), DIR_UP, false)); For(view.carets) it = ChangeFront(it, MovePos(buf, GetFront(it), DIR_UP));
} else if (Press(KEY_UP)) { } else if (Press(KEY_UP)) {
For(view.carets) { For(view.carets) {
if (GetSize(it.range) == 0) { if (GetSize(it.range) == 0) {
it = MakeCaret(MovePos(buf, it.range.min, DIR_UP, false)); it = MakeCaret(MovePos(buf, it.range.min, DIR_UP));
} else { } else {
it = MakeCaret(it.range.min); it = MakeCaret(it.range.min);
} }
@@ -297,9 +322,9 @@ void HandleKeybindings(View *_view) {
Add(&view.carets, MakeCaret(p, p)); Add(&view.carets, MakeCaret(p, p));
view.selection_anchor = GetLast(view.carets)->range; view.selection_anchor = GetLast(view.carets)->range;
if (IsDoubleClick()) { if (IsDoubleClick()) {
// Cursor *c = window.cursors.last(); Caret *c = GetLast(view.carets);
// c->range = EncloseWord(window.buffer, col->pos); c->range = EncloseWord(buf, p);
// window.selection_anchor_point = c->range; view.selection_anchor = c->range;
} }
MergeCarets(&view.carets); MergeCarets(&view.carets);

View File

@@ -21,10 +21,9 @@ Rect2I GetVisibleCells(const View &view) {
void DrawVisibleText(const View &view) { void DrawVisibleText(const View &view) {
ProfileFunction(); ProfileFunction();
Color tint = ColorText; Color tint = ColorText;
Color space_color = tint;
space_color.a = 50; Rect2I visible = GetVisibleCells(view);
Rect2I visible = GetVisibleCells(view);
for (Int line_index = visible.min.y; line_index < visible.max.y && line_index >= 0 && line_index < view.buffer->line_starts.len; line_index += 1) { for (Int line_index = visible.min.y; line_index < visible.max.y && line_index >= 0 && line_index < view.buffer->line_starts.len; line_index += 1) {
Range line_range = GetLineRange(*view.buffer, line_index); Range line_range = GetLineRange(*view.buffer, line_index);
String16 line_string = GetString(*view.buffer, line_range); String16 line_string = GetString(*view.buffer, line_range);
@@ -37,10 +36,10 @@ void DrawVisibleText(const View &view) {
int codepoint = line_string[col_index]; int codepoint = line_string[col_index];
int index = GetGlyphIndex(view.font, codepoint); int index = GetGlyphIndex(view.font, codepoint);
if (codepoint == '\n') { if (codepoint == '\n' || codepoint == '\r') {
DrawCircle((int)pos.x + (int)text_offset_x + (int)view.char_spacing / 2, (int)pos.y + (int)view.line_spacing / 2, (float)view.font_size / 10.f, tint); // DrawCircle((int)pos.x + (int)text_offset_x + (int)view.char_spacing / 2, (int)pos.y + (int)view.line_spacing / 2, (float)view.font_size / 10.f, tint);
} else if (codepoint == ' ') { } else if (codepoint == ' ') {
DrawCircle((int)pos.x + (int)text_offset_x + (int)view.char_spacing / 2, (int)pos.y + (int)view.line_spacing / 2, (float)view.font_size / 10.f, space_color); // DrawCircle((int)pos.x + (int)text_offset_x + (int)view.char_spacing / 2, (int)pos.y + (int)view.line_spacing / 2, (float)view.font_size / 10.f, space_color);
} else if (codepoint != '\t') { } else if (codepoint != '\t') {
DrawTextCodepoint(view.font, codepoint, {(float)pos.x + text_offset_x, (float)pos.y}, (float)view.font_size, tint); DrawTextCodepoint(view.font, codepoint, {(float)pos.x + text_offset_x, (float)pos.y}, (float)view.font_size, tint);
} }
@@ -88,12 +87,10 @@ void DrawSelection(const View &view, Caret &it) {
Color color = ColorSelection; Color color = ColorSelection;
Rect2I vlines = GetVisibleCells(view); Rect2I vlines = GetVisibleCells(view);
for (Int line = vlines.min.y; line <= vlines.max.y && line >= 0 && line < view.buffer->line_starts.len; line += 1) { for (Int line = vlines.min.y; line <= vlines.max.y && line >= 0 && line < view.buffer->line_starts.len; line += 1) {
Range range = GetLineRange(buf, line); Range range = GetLineRange(buf, line);
range -= range.min; String16 line_string = GetString(buf, range);
range.min = Clamp(range.min, vlines.min.x, vlines.max.x);
range.max = Clamp(range.max, vlines.min.x, vlines.max.x);
for (Int col = range.min; col < range.max; col += 1) { for (Int col = vlines.min.x; col < vlines.max.x && col >= 0 && col < line_string.len; col += 1) {
bool a = line > min.line && line < max.line; bool a = line > min.line && line < max.line;
bool b = min.line != max.line && (line == min.line && col >= min.col); bool b = min.line != max.line && (line == min.line && col >= min.col);
bool c = min.line != max.line && (line == max.line && col < max.col); bool c = min.line != max.line && (line == max.line && col < max.col);
@@ -105,6 +102,14 @@ void DrawSelection(const View &view, Caret &it) {
Rectangle rectangle = {(float)pos.x, (float)pos.y, (float)view.char_spacing, (float)view.line_spacing}; Rectangle rectangle = {(float)pos.x, (float)pos.y, (float)view.char_spacing, (float)view.line_spacing};
DrawRectangleRec(rectangle, color); DrawRectangleRec(rectangle, color);
if (line_string[col] == ' ' || line_string[col] == '\t') {
DrawCircle((int)pos.x + (int)view.char_spacing / 2, (int)pos.y + (int)view.line_spacing / 2, (float)view.font_size / 10.f, ColorWhitespaceDuringSelection);
} else if (line_string[col] == '\n') {
DrawEllipse((int)pos.x + (int)view.char_spacing / 2, (int)pos.y + (int)view.line_spacing / 2, (float)view.font_size / 4.f, (float)view.font_size / 15.f, ColorWhitespaceDuringSelection);
} else if (line_string[col] == '\r') {
DrawEllipse((int)pos.x + (int)view.char_spacing / 2, (int)pos.y + (int)view.line_spacing / 2, (float)view.font_size / 10.f, (float)view.font_size / 4.f, ColorWhitespaceDuringSelection);
}
} }
} }
} }