Porting mouse related events and abstraction idea

This commit is contained in:
Krzosa Karol
2024-07-27 08:58:52 +02:00
parent 680c782a56
commit 1e0c5dac83

View File

@@ -40,25 +40,101 @@ bool AppIsRunning = true;
bool WaitForEvents = true; bool WaitForEvents = true;
SDL_Cursor *SDL_MouseCursor = NULL; SDL_Cursor *SDL_MouseCursor = NULL;
struct Key { struct Event {
SDL_Keycode code; SDL_Keycode key;
uint8_t shift; int16_t xmouse;
uint8_t ctrl; int16_t ymouse;
uint8_t alt; struct {
uint8_t super; uint8_t shift : 1;
uint8_t ctrl : 1;
uint8_t alt : 1;
uint8_t super : 1;
uint8_t mouse_move : 1;
uint8_t mouse_left : 1;
uint8_t mouse_right : 1;
uint8_t mouse_middle : 1;
uint8_t mouse_double_click : 1;
};
float wheel;
const char *text;
}; };
#define Press(KEY) (key.code == KEY) #define Press(KEY) (event.key == KEY)
#define Ctrl(KEY) (key.code == KEY && key.ctrl) #define Ctrl(KEY) (event.key == KEY && event.ctrl)
#define Shift(KEY) (key.code == KEY && key.shift) #define Shift(KEY) (event.key == KEY && event.shift)
#define Alt(KEY) (key.code == KEY && key.alt) #define Alt(KEY) (event.key == KEY && event.alt)
#define CtrlShift(KEY) (key.code == KEY && key.ctrl && key.shift) #define CtrlShift(KEY) (event.key == KEY && event.ctrl && event.shift)
#define CtrlAlt(KEY) (key.code == KEY && key.ctrl && key.alt) #define CtrlAlt(KEY) (event.key == KEY && event.ctrl && event.alt)
#define AltShift(KEY) (key.code == KEY && key.shift && key.alt) #define AltShift(KEY) (event.key == KEY && event.shift && event.alt)
#define MousePress() (event.mouse_left == 1 || event.mouse_right == 1 || event.mouse_middle == 1 || event.mouse_double_click == 1)
#define MouseVec2() \
Vec2 { (float)event.xmouse, (float)event.ymouse }
#define MouseVec2I() \
Vec2I { (Int) event.xmouse, (Int)event.ymouse }
bool GlobalCommand(Event event) {
bool run_window_command = true;
if (event.mouse_move) {
Vec2I mouse = MouseVec2I();
Window *window = GetActiveWindow();
bool mouse_in_document = CheckCollisionPointRec(mouse, window->document_rect);
bool mouse_in_scrollbar = CheckCollisionPointRec(mouse, window->scrollbar_rect);
bool mouse_in_total = CheckCollisionPointRec(mouse, window->total_rect);
if (SDL_MouseCursor) SDL_DestroyCursor(SDL_MouseCursor);
if (window->mouse_selecting || mouse_in_document) {
SDL_MouseCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_TEXT);
SDL_SetCursor(SDL_MouseCursor);
} else if (mouse_in_scrollbar || window->mouse_selecting_scrollbar) {
SDL_MouseCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_DEFAULT);
SDL_SetCursor(SDL_MouseCursor);
} else {
SDL_MouseCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_POINTER);
SDL_SetCursor(SDL_MouseCursor);
}
}
if (MousePress()) {
Scratch scratch;
Array<Int> order = GetWindowZOrder(scratch);
Vec2I mouse = MouseVec2I();
For(order) {
Window *window = &Windows[it];
if (!window->visible) continue;
bool mouse_in_window = CheckCollisionPointRec(mouse, window->total_rect);
if (mouse_in_window) {
Window *active_window = GetWindow(ActiveWindow);
if (active_window->z <= window->z) {
SetActiveWindow(window->id);
}
}
}
}
if (event.wheel) {
Scratch scratch;
Array<Int> order = GetWindowZOrder(scratch);
Vec2I mouse = MouseVec2I();
For(order) {
Window *window = &Windows[it];
if (!window->visible) continue;
bool mouse_in_window = CheckCollisionPointRec(mouse, window->total_rect);
if (mouse_in_window) {
View *view = GetView(window->active_view);
view->scroll.y -= (Int)(event.wheel * 48);
break;
}
}
}
void GlobalCommand(Key key) {
if (Press(SDLK_F5)) { if (Press(SDLK_F5)) {
AppIsRunning = false; AppIsRunning = false;
run_window_command = false;
} }
if (Ctrl(SDLK_P)) { if (Ctrl(SDLK_P)) {
@@ -68,6 +144,7 @@ void GlobalCommand(Key key) {
} else { } else {
SetActiveWindow(command_window->id); SetActiveWindow(command_window->id);
} }
run_window_command = false;
} }
if (Ctrl(SDLK_P)) { if (Ctrl(SDLK_P)) {
@@ -77,20 +154,26 @@ void GlobalCommand(Key key) {
} else { } else {
SetActiveWindow(search_window->id); SetActiveWindow(search_window->id);
} }
run_window_command = false;
} }
if (Ctrl(SDLK_1)) { if (Ctrl(SDLK_1)) {
SetActiveWindow({0}); SetActiveWindow({0});
run_window_command = false;
} }
if (Ctrl(SDLK_2)) { if (Ctrl(SDLK_2)) {
SetActiveWindow({1}); SetActiveWindow({1});
run_window_command = false;
} }
if (Ctrl(SDLK_3)) { if (Ctrl(SDLK_3)) {
SetActiveWindow({2}); SetActiveWindow({2});
run_window_command = false;
} }
return run_window_command;
} }
void WindowCommand(Key key, Window *window, View *view) { void WindowCommand(Event event, Window *window, View *view) {
Buffer *buffer = GetBuffer(view->active_buffer); Buffer *buffer = GetBuffer(view->active_buffer);
if (Ctrl(SDLK_F2)) { if (Ctrl(SDLK_F2)) {
@@ -257,6 +340,18 @@ void WindowCommand(Key key, Window *window, View *view) {
search = true; search = true;
} }
if (event.text) {
Scratch scratch;
String string = event.text;
String16 string16 = ToString16(scratch, string);
Window *window = GetActiveWindow();
View *view = GetActiveView(window);
Command_Replace(view, string16);
search = true;
}
// for (int c = GetCharPressed(); c; c = GetCharPressed()) { // for (int c = GetCharPressed(); c; c = GetCharPressed()) {
// // we interpret 2 byte sequences as 1 byte when rendering but we still // // we interpret 2 byte sequences as 1 byte when rendering but we still
// // want to read them properly. // // want to read them properly.
@@ -432,108 +527,63 @@ void WindowCommand(Key key, Window *window, View *view) {
// } // }
} }
void ProcessSDLEvent(SDL_Event *event) { void ProcessSDLEvent(SDL_Event *input_event) {
switch (event->type) { Event event = {};
switch (input_event->type) {
case SDL_EVENT_QUIT: AppIsRunning = false; return; case SDL_EVENT_QUIT: AppIsRunning = false; return;
case SDL_EVENT_KEY_DOWN: { case SDL_EVENT_KEY_DOWN: {
SDL_KeyboardEvent &key = event->key; SDL_KeyboardEvent &key = input_event->key;
event.key = key.key;
Key k = {key.key}; event.shift = (key.mod & SDL_KMOD_SHIFT) != 0;
k.shift = key.mod & SDL_KMOD_SHIFT; event.ctrl = (key.mod & SDL_KMOD_CTRL) != 0;
k.ctrl = key.mod & SDL_KMOD_CTRL; event.alt = (key.mod & SDL_KMOD_ALT) != 0;
k.alt = key.mod & SDL_KMOD_ALT; event.super = (key.mod & SDL_KMOD_GUI) != 0;
k.super = key.mod & SDL_KMOD_GUI;
GlobalCommand(k);
Window *window = GetActiveWindow();
View *view = GetActiveView(window);
WindowCommand(k, window, view);
MergeCarets(view);
} break; } break;
case SDL_EVENT_KEY_UP: { case SDL_EVENT_KEY_UP: {
SDL_KeyboardEvent &key = event->key; return;
bool shift = key.mod & SDL_KMOD_SHIFT;
bool ctrl = key.mod & SDL_KMOD_CTRL;
bool alt = key.mod & SDL_KMOD_ALT;
bool super = key.mod & SDL_KMOD_GUI;
} break; } break;
case SDL_EVENT_TEXT_INPUT: { case SDL_EVENT_TEXT_INPUT: {
SDL_TextInputEvent &b = event->text; SDL_TextInputEvent &b = input_event->text;
event.text = b.text;
Scratch scratch;
String string = b.text;
String16 string16 = ToString16(scratch, string);
Window *window = GetActiveWindow();
View *view = GetActiveView(window);
Command_Replace(view, string16);
// search = true;
} break; } break;
case SDL_EVENT_MOUSE_MOTION: { case SDL_EVENT_MOUSE_MOTION: {
SDL_MouseMotionEvent &b = event->motion; SDL_MouseMotionEvent &b = input_event->motion;
Vec2I mouse = {(Int)b.x, (Int)b.y}; event.xmouse = (int16_t)b.x;
event.ymouse = (int16_t)b.y;
Window *w = GetActiveWindow(); event.mouse_move = 1;
bool mouse_in_document = CheckCollisionPointRec(mouse, w->document_rect);
bool mouse_in_scrollbar = CheckCollisionPointRec(mouse, w->scrollbar_rect);
bool mouse_in_total = CheckCollisionPointRec(mouse, w->total_rect);
if (SDL_MouseCursor) SDL_DestroyCursor(SDL_MouseCursor);
if (w->mouse_selecting || mouse_in_document) {
SDL_MouseCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_TEXT);
SDL_SetCursor(SDL_MouseCursor);
} else if (mouse_in_scrollbar || w->mouse_selecting_scrollbar) {
SDL_MouseCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_DEFAULT);
SDL_SetCursor(SDL_MouseCursor);
} else {
SDL_MouseCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_POINTER);
SDL_SetCursor(SDL_MouseCursor);
}
} break; } break;
case SDL_EVENT_MOUSE_BUTTON_DOWN: { case SDL_EVENT_MOUSE_BUTTON_DOWN: {
SDL_MouseButtonEvent &b = event->button; SDL_MouseButtonEvent &b = input_event->button;
Vec2I mouse = {(Int)b.x, (Int)b.y}; event.xmouse = (int16_t)b.x;
Scratch scratch; event.ymouse = (int16_t)b.y;
Array<Int> order = GetWindowZOrder(scratch); if (b.button == SDL_BUTTON_LEFT) {
event.mouse_left = 1;
For(order) { if (b.clicks == 2) event.mouse_double_click = 1;
Window *window = &Windows[it]; } else if (b.button == SDL_BUTTON_RIGHT) {
if (!window->visible) continue; event.mouse_right = 1;
bool mouse_in_window = CheckCollisionPointRec(mouse, window->total_rect); } else if (b.button == SDL_BUTTON_MIDDLE) {
if (mouse_in_window) { event.mouse_middle = 1;
Window *active_window = GetWindow(ActiveWindow);
if (active_window->z <= window->z) {
SetActiveWindow(window->id);
}
}
} }
} break; } break;
case SDL_EVENT_MOUSE_BUTTON_UP: { case SDL_EVENT_MOUSE_BUTTON_UP: {
SDL_MouseButtonEvent &b = event->button; SDL_MouseButtonEvent &b = input_event->button;
return;
} break; } break;
case SDL_EVENT_MOUSE_WHEEL: { case SDL_EVENT_MOUSE_WHEEL: {
SDL_MouseWheelEvent &b = event->wheel; SDL_MouseWheelEvent &b = input_event->wheel;
Vec2 wheel = {b.x, b.y}; event.xmouse = (int16_t)b.mouse_x;
Vec2I mouse = {(Int)b.mouse_x, (Int)b.mouse_y}; event.ymouse = (int16_t)b.mouse_y;
event.wheel = b.y;
Scratch scratch;
Array<Int> order = GetWindowZOrder(scratch);
For(IterateInReverse(&order)) {
Window *window = &Windows[it];
if (!window->visible) continue;
bool mouse_in_window = CheckCollisionPointRec(mouse, window->total_rect);
if (mouse_in_window) {
View *view = GetView(window->active_view);
view->scroll.y -= (Int)(wheel.y * 48);
break;
}
}
} break; } break;
default: return;
}
bool run_window_command = GlobalCommand(event);
if (run_window_command) {
Window *window = GetActiveWindow();
View *view = GetActiveView(window);
WindowCommand(event, window, view);
MergeCarets(view);
} }
} }