Experimenting with key bindings

This commit is contained in:
Krzosa Karol
2024-07-21 15:10:54 +02:00
parent fc928da75b
commit 9554160edc
5 changed files with 220 additions and 15 deletions

View File

@@ -249,7 +249,7 @@ struct Slice {
template <class T>
Slice<T> Copy(Allocator alo, Slice<T> array) {
Slice<T> result = {alo};
Slice<T> result = {};
result.data = AllocArray(alo, T, array.len);
memcpy(result.data, array.data, sizeof(T) * array.len);
result.len = array.len;
@@ -824,7 +824,7 @@ struct Table {
size_t old_cap = cap;
values = (Entry *)AllocSize(allocator, sizeof(Entry) * size);
for (int64_t i = 0; i < size; i += 1) values[i] = {};
for (size_t i = 0; i < size; i += 1) values[i] = {};
cap = size;
Assert(!(old_values == 0 && len != 0));

View File

@@ -38,7 +38,7 @@ Color GruvboxFadedOrange = {0xaf, 0x3a, 0x03, 0xff};
Color ColorText = GruvboxDark0Hard;
Color ColorBackground = GruvboxLight0Hard;
Color ColorSelection = GruvboxLight3;
Color ColorLineHighlight = GruvboxLight2;
Color ColorSelection = GruvboxLight1;
Color ColorLineHighlight = GruvboxLight1;
Color ColorMainCaret = GruvboxBrightRed;
Color ColorSubCaret = GruvboxGray245;

View File

@@ -28,8 +28,6 @@
- Ctrl + Alt + Down - duplicate line down
- Shify + Alt + Down - make a cursor below
- Mouse anchor point and double click
- Mouse cursor changes
- Color new lines and end of buffer
- Scrollbars
- Line numbers
- Colored strings

View File

@@ -163,12 +163,171 @@ void MultiCursorReplace(View *view, String16 string) {
AfterEdit(view, edits);
}
union KeyEncode {
struct {
U32 key;
U8 ctrl : 1;
U8 alt : 1;
U8 shift : 1;
};
U64 u64;
};
typedef void CommandProc(View *view);
Table<CommandProc *> RegisteredBindings;
KeyEncode Key(int key) {
KeyEncode result = {};
result.key = key;
return result;
}
KeyEncode KeyControl(int key) {
KeyEncode result = {};
result.key = key;
result.ctrl = true;
return result;
}
KeyEncode KeyShiftControl(int key) {
KeyEncode result = {};
result.key = key;
result.ctrl = true;
result.shift = true;
return result;
}
KeyEncode KeyControlAlt(int key) {
KeyEncode result = {};
result.key = key;
result.ctrl = true;
result.alt = true;
return result;
}
KeyEncode KeyShiftAlt(int key) {
KeyEncode result = {};
result.key = key;
result.shift = true;
result.alt = true;
return result;
}
void RegisterBinding(CommandProc *proc, KeyEncode key) {
RegisteredBindings.insert(key.u64, proc);
}
void CommandClearCarets(View *view) {
view->carets.len = 1;
}
void HandleKeybindings(View *_view) {
ProfileFunction();
View &view = *_view;
Buffer &buf = *view.buffer;
Caret main_caret_on_begin_frame = view.carets[0];
if (RegisteredBindings.cap == 0) {
RegisterBinding(CommandClearCarets, Key(KEY_ESCAPE));
}
{
KeyEncode key = {};
key.ctrl = IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_CONTROL);
key.alt = IsKeyDown(KEY_LEFT_ALT) || IsKeyDown(KEY_RIGHT_ALT);
key.shift = IsKeyDown(KEY_LEFT_SHIFT) || IsKeyDown(KEY_RIGHT_SHIFT);
int keys[] = {
KEY_APOSTROPHE,
KEY_COMMA,
KEY_MINUS,
KEY_PERIOD,
KEY_SLASH,
KEY_ZERO,
KEY_ONE,
KEY_TWO,
KEY_THREE,
KEY_FOUR,
KEY_FIVE,
KEY_SIX,
KEY_SEVEN,
KEY_EIGHT,
KEY_NINE,
KEY_SEMICOLON,
KEY_EQUAL,
KEY_A,
KEY_B,
KEY_C,
KEY_D,
KEY_E,
KEY_F,
KEY_G,
KEY_H,
KEY_I,
KEY_J,
KEY_K,
KEY_L,
KEY_M,
KEY_N,
KEY_O,
KEY_P,
KEY_Q,
KEY_R,
KEY_S,
KEY_T,
KEY_U,
KEY_V,
KEY_W,
KEY_X,
KEY_Y,
KEY_Z,
KEY_LEFT_BRACKET,
KEY_BACKSLASH,
KEY_RIGHT_BRACKET,
KEY_GRAVE,
KEY_SPACE,
KEY_ESCAPE,
KEY_ENTER,
KEY_TAB,
KEY_BACKSPACE,
KEY_INSERT,
KEY_DELETE,
KEY_RIGHT,
KEY_LEFT,
KEY_DOWN,
KEY_UP,
KEY_PAGE_UP,
KEY_PAGE_DOWN,
KEY_HOME,
KEY_END,
KEY_CAPS_LOCK,
KEY_SCROLL_LOCK,
KEY_NUM_LOCK,
KEY_PRINT_SCREEN,
KEY_PAUSE,
KEY_F1,
KEY_F2,
KEY_F3,
KEY_F4,
KEY_F5,
KEY_F6,
KEY_F7,
KEY_F8,
KEY_F9,
KEY_F10,
KEY_F11,
KEY_F12,
};
for (int i = 0; i < sizeof(keys); i += 1) {
bool press = IsKeyPressed(keys[i]) || IsKeyPressedRepeat(keys[i]);
if (!press) continue;
key.key = keys[i];
CommandProc *proc = RegisteredBindings.get(key.u64, NULL);
if (proc) proc(&view);
}
}
if (IsKeyDown(KEY_F1)) {
view.scroll.x -= (Int)(GetMouseWheelMove() * 48);
} else {
@@ -183,11 +342,43 @@ void HandleKeybindings(View *_view) {
}
}
if (IsKeyDown(KEY_ESCAPE)) {
if (IsKeyPressed(KEY_ESCAPE) || IsKeyPressedRepeat(KEY_ESCAPE)) {
view.carets.len = 1;
}
{
if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyDown(KEY_LEFT_ALT) && (IsKeyPressed(KEY_DOWN) || IsKeyPressedRepeat(KEY_DOWN))) {
For(view.carets) it = MakeCaret(GetFront(it));
MergeCarets(&view.carets);
Scratch scratch;
Array<Edit> edits = {scratch};
For(view.carets) {
Int line = PosToLine(buf, it.range.min);
Range range = GetLineRange(buf, line);
String16 string = Copy(scratch, GetString(buf, range));
AddEdit(&edits, {range.max, range.max}, string);
}
ApplyEdits(&buf, edits);
AfterEdit(&view, edits);
For(view.carets) it = MakeCaret(MoveCaret(buf, it.range.min, 2, false));
} else if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyDown(KEY_LEFT_ALT) && (IsKeyPressed(KEY_UP) || IsKeyPressedRepeat(KEY_UP))) {
For(view.carets) it = MakeCaret(GetFront(it));
MergeCarets(&view.carets);
Scratch scratch;
Array<Edit> edits = {scratch};
For(view.carets) {
Int line = PosToLine(buf, it.range.min);
Range range = GetLineRange(buf, line);
String16 string = Copy(scratch, GetString(buf, range));
AddEdit(&edits, {range.min, range.min}, string);
}
ApplyEdits(&buf, edits);
AfterEdit(&view, edits);
For(view.carets) it = MakeCaret(MoveCaret(buf, it.range.min, 3, false));
} else {
int keys[4] = {KEY_RIGHT, KEY_LEFT, KEY_DOWN, KEY_UP};
for (int i = 0; i < 4; i += 1) {
if (IsKeyPressed(keys[i]) || IsKeyPressedRepeat(keys[i])) {
@@ -277,10 +468,19 @@ void HandleKeybindings(View *_view) {
{
ProfileScope(mouse);
Vec2 _mouse = GetMousePosition();
bool mouse_in_view = CheckCollisionPointRec(_mouse, ToRectangle(view.rect));
Vec2I mouse = ToVec2I(_mouse);
if (!view.mouse_selecting) {
if (mouse_in_view) {
SetMouseCursor(MOUSE_CURSOR_IBEAM);
} else {
SetMouseCursor(MOUSE_CURSOR_DEFAULT);
}
}
Vec2I mworld = mouse - view.rect.min + view.scroll;
Vec2I pos = mworld / Vec2I{view.char_spacing, view.line_spacing};
XY xy = {(Int)(pos.x), (Int)(pos.y)};

View File

@@ -19,10 +19,12 @@ Rect2I GetVisibleCells(const View &view) {
return result;
}
void DrawVisibleCells(const View &view) {
void DrawVisibleText(const View &view) {
ProfileFunction();
Color tint = ColorText;
Rect2I visible = GetVisibleCells(view);
Color tint = ColorText;
Color space_color = tint;
space_color.a = 50;
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) {
Range line_range = GetLineRange(*view.buffer, line_index);
String16 line_string = GetString(*view.buffer, line_range);
@@ -37,7 +39,9 @@ void DrawVisibleCells(const View &view) {
if (codepoint == '\n') {
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 != ' ') && (codepoint != '\t')) {
} 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);
} else if (codepoint != '\t') {
DrawTextCodepoint(view.font, codepoint, {(float)pos.x + text_offset_x, (float)pos.y}, (float)view.font_size, tint);
}
@@ -118,11 +122,14 @@ void DrawView(View &view) {
Int back = GetBack(it);
XY bxy = PosToXY(buf, back);
DrawLineHighlight(view, fxy, ColorLineHighlight);
DrawSelection(view, it);
if (GetSize(it.range)) {
DrawSelection(view, it);
} else {
DrawLineHighlight(view, fxy, ColorLineHighlight);
}
}
DrawVisibleCells(view);
DrawVisibleText(view);
For(view.carets) {
Int front = GetFront(it);