Skip to content

Commit

Permalink
Merge pull request #153 from s4my/feat/UICodeSelection
Browse files Browse the repository at this point in the history
feat: added keyboard shortcuts for making selections in `UICode` elements.
  • Loading branch information
nakst authored Oct 27, 2023
2 parents b54a7c8 + 170f857 commit 6073595
Showing 1 changed file with 75 additions and 14 deletions.
89 changes: 75 additions & 14 deletions luigi2.h
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,7 @@ void UICodeFocusLine(UICode *code, int index); // Line numbers are 1-indexed!!
int UICodeHitTest(UICode *code, int x, int y); // Returns line number; negates if in margin. Returns 0 if not on a line.
void UICodePositionToByte(UICode *code, int x, int y, int *line, int *byte);
void UICodeInsertContent(UICode *code, const char *content, ptrdiff_t byteCount, bool replace);
void UICodeMoveCaret(UICode *code, bool backward, bool word);

void UIDrawBlock(UIPainter *painter, UIRectangle rectangle, uint32_t color);
void UIDrawCircle(UIPainter *painter, int centerX, int centerY, int radius, uint32_t fillColor, uint32_t outlineColor, bool hollow);
Expand Down Expand Up @@ -2857,7 +2858,7 @@ int _UICodeMessage(UIElement *element, UIMessage message, int di, void *dp) {

UIFont *previousFont = UIFontActivate(code->font);

if (element->window->cursorX < element->bounds.l + ((element->flags & UI_CODE_NO_MARGIN)
if (element->window->cursorX < element->bounds.l + ((element->flags & UI_CODE_NO_MARGIN)
? UI_SIZE_CODE_MARGIN_GAP : (UI_SIZE_CODE_MARGIN + UI_SIZE_CODE_MARGIN_GAP * 2))) {
code->hScroll->position -= delta;
} else if (element->window->cursorX >= code->vScroll->e.bounds.l - UI_SIZE_CODE_MARGIN_GAP) {
Expand Down Expand Up @@ -2905,23 +2906,52 @@ int _UICodeMessage(UIElement *element, UIMessage message, int di, void *dp) {
for (int i = from; i < to; i++) pasteText[i - from] = code->content[i];
_UIClipboardWriteText(element->window, pasteText);
}

return 1;
} else if ((m->code == UI_KEYCODE_UP || m->code == UI_KEYCODE_DOWN || m->code == UI_KEYCODE_PAGE_UP || m->code == UI_KEYCODE_PAGE_DOWN
|| m->code == UI_KEYCODE_HOME || m->code == UI_KEYCODE_END)
&& !element->window->ctrl && !element->window->alt && !element->window->shift) {
|| m->code == UI_KEYCODE_HOME || m->code == UI_KEYCODE_END) && !element->window->ctrl && !element->window->alt) {
UIFont *previousFont = UIFontActivate(code->font);
int lineHeight = UIMeasureStringHeight();
UIFontActivate(previousFont);
code->moveScrollToFocusNextLayout = false;
_UI_KEY_INPUT_VSCROLL(code, lineHeight, (element->bounds.t - code->hScroll->e.bounds.t) * 4 / 5 /* leave a few lines for context */);
return 1;
} else if ((m->code == UI_KEYCODE_LEFT || m->code == UI_KEYCODE_RIGHT)
&& !element->window->ctrl && !element->window->alt && !element->window->shift) {
code->hScroll->position += m->code == UI_KEYCODE_LEFT ? -ui.activeFont->glyphWidth : ui.activeFont->glyphWidth;
UIElementRefresh(&code->e);
return 1;

if (element->window->shift) {
if (m->code == UI_KEYCODE_UP) {
if (code->selection[0].line - 1 >= 0) {
code->selection[0].line--;
} else {
code->selection[0].offset = 0;
}
} else if (m->code == UI_KEYCODE_DOWN) {
if (code->selection[0].line + 1 < code->lineCount) {
code->selection[0].line++;
} else {
code->selection[0].offset = code->lines[code->selection[0].line].bytes;
}
} else if (m->code == UI_KEYCODE_HOME) {
code->selection[0].offset = 0;
} else if (m->code == UI_KEYCODE_END) {
code->selection[0].offset = code->lines[code->selection[0].line].bytes;
} else if (m->code == UI_KEYCODE_PAGE_UP || m->code == UI_KEYCODE_PAGE_DOWN) {
int pageHeight = (element->bounds.t - code->hScroll->e.bounds.t) / lineHeight * 4 / 5;

code->selection[0].line += m->code == UI_KEYCODE_PAGE_UP ? pageHeight : -pageHeight;
}

UIFontActivate(previousFont);
UIElementRepaint(&code->e, NULL);
} else {
UIFontActivate(previousFont);
code->moveScrollToFocusNextLayout = false;
_UI_KEY_INPUT_VSCROLL(code, lineHeight, (element->bounds.t - code->hScroll->e.bounds.t) * 4 / 5 /* leave a few lines for context */);
}
} else if ((m->code == UI_KEYCODE_LEFT || m->code == UI_KEYCODE_RIGHT) && !element->window->alt) {
if (element->window->shift) {
UICodeMoveCaret(code, m->code == UI_KEYCODE_LEFT, element->window->ctrl);
} else {
if (!element->window->ctrl) {
code->hScroll->position += m->code == UI_KEYCODE_LEFT ? -ui.activeFont->glyphWidth : ui.activeFont->glyphWidth;
UIElementRefresh(&code->e);
}
}
}
return 1;
} else if (message == UI_MSG_UPDATE) {
UIElementRepaint(element, NULL);
} else if (message == UI_MSG_DEALLOCATE) {
Expand All @@ -2932,6 +2962,37 @@ int _UICodeMessage(UIElement *element, UIMessage message, int di, void *dp) {
return 0;
}

void UICodeMoveCaret(UICode *code, bool backward, bool word) {
while (true) {
if (backward) {
if (code->selection[0].offset - 1 < 0) {
if (code->selection[0].line > 0) {
code->selection[0].line--;
code->selection[0].offset = code->lines[code->selection[0].line].bytes;
} else break;
} else code->selection[0].offset--;
} else {
if (code->selection[0].offset + 1 > code->lines[code->selection[0].line].bytes) {
if (code->selection[0].line + 1 < code->lineCount) {
code->selection[0].line++;
code->selection[0].offset = 0;
} else break;
} else code->selection[0].offset++;
}

if (!word) break;

if (code->selection[0].offset != 0 && code->selection[0].offset != code->lines[code->selection[0].line].bytes) {
char c1 = *(code->content + code->lines[code->selection[0].line].offset + code->selection[0].offset - 1);
char c2 = *(code->content + code->lines[code->selection[0].line].offset + code->selection[0].offset);

if (_UICharIsAlphaOrDigitOrUnderscore(c1) != _UICharIsAlphaOrDigitOrUnderscore(c2)) break;
}
}

UIElementRepaint(&code->e, NULL);
}

void UICodeFocusLine(UICode *code, int index) {
code->focused = index - 1;
code->moveScrollToFocusNextLayout = true;
Expand Down

0 comments on commit 6073595

Please sign in to comment.