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;
SDL_Cursor *SDL_MouseCursor = NULL;
struct Key {
SDL_Keycode code;
uint8_t shift;
uint8_t ctrl;
uint8_t alt;
uint8_t super;
struct Event {
SDL_Keycode key;
int16_t xmouse;
int16_t ymouse;
struct {
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 Ctrl(KEY) (key.code == KEY && key.ctrl)
#define Shift(KEY) (key.code == KEY && key.shift)
#define Alt(KEY) (key.code == KEY && key.alt)
#define CtrlShift(KEY) (key.code == KEY && key.ctrl && key.shift)
#define CtrlAlt(KEY) (key.code == KEY && key.ctrl && key.alt)
#define AltShift(KEY) (key.code == KEY && key.shift && key.alt)
#define Press(KEY) (event.key == KEY)
#define Ctrl(KEY) (event.key == KEY && event.ctrl)
#define Shift(KEY) (event.key == KEY && event.shift)
#define Alt(KEY) (event.key == KEY && event.alt)
#define CtrlShift(KEY) (event.key == KEY && event.ctrl && event.shift)
#define CtrlAlt(KEY) (event.key == KEY && event.ctrl && event.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)) {
AppIsRunning = false;
run_window_command = false;
}
if (Ctrl(SDLK_P)) {
@@ -68,6 +144,7 @@ void GlobalCommand(Key key) {
} else {
SetActiveWindow(command_window->id);
}
run_window_command = false;
}
if (Ctrl(SDLK_P)) {
@@ -77,20 +154,26 @@ void GlobalCommand(Key key) {
} else {
SetActiveWindow(search_window->id);
}
run_window_command = false;
}
if (Ctrl(SDLK_1)) {
SetActiveWindow({0});
run_window_command = false;
}
if (Ctrl(SDLK_2)) {
SetActiveWindow({1});
run_window_command = false;
}
if (Ctrl(SDLK_3)) {
SetActiveWindow({2});
}
run_window_command = false;
}
void WindowCommand(Key key, Window *window, View *view) {
return run_window_command;
}
void WindowCommand(Event event, Window *window, View *view) {
Buffer *buffer = GetBuffer(view->active_buffer);
if (Ctrl(SDLK_F2)) {
@@ -257,6 +340,18 @@ void WindowCommand(Key key, Window *window, View *view) {
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()) {
// // we interpret 2 byte sequences as 1 byte when rendering but we still
// // want to read them properly.
@@ -432,108 +527,63 @@ void WindowCommand(Key key, Window *window, View *view) {
// }
}
void ProcessSDLEvent(SDL_Event *event) {
switch (event->type) {
void ProcessSDLEvent(SDL_Event *input_event) {
Event event = {};
switch (input_event->type) {
case SDL_EVENT_QUIT: AppIsRunning = false; return;
case SDL_EVENT_KEY_DOWN: {
SDL_KeyboardEvent &key = event->key;
Key k = {key.key};
k.shift = key.mod & SDL_KMOD_SHIFT;
k.ctrl = key.mod & SDL_KMOD_CTRL;
k.alt = key.mod & SDL_KMOD_ALT;
k.super = key.mod & SDL_KMOD_GUI;
GlobalCommand(k);
Window *window = GetActiveWindow();
View *view = GetActiveView(window);
WindowCommand(k, window, view);
MergeCarets(view);
SDL_KeyboardEvent &key = input_event->key;
event.key = key.key;
event.shift = (key.mod & SDL_KMOD_SHIFT) != 0;
event.ctrl = (key.mod & SDL_KMOD_CTRL) != 0;
event.alt = (key.mod & SDL_KMOD_ALT) != 0;
event.super = (key.mod & SDL_KMOD_GUI) != 0;
} break;
case SDL_EVENT_KEY_UP: {
SDL_KeyboardEvent &key = event->key;
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;
return;
} break;
case SDL_EVENT_TEXT_INPUT: {
SDL_TextInputEvent &b = event->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;
SDL_TextInputEvent &b = input_event->text;
event.text = b.text;
} break;
case SDL_EVENT_MOUSE_MOTION: {
SDL_MouseMotionEvent &b = event->motion;
Vec2I mouse = {(Int)b.x, (Int)b.y};
Window *w = GetActiveWindow();
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);
}
SDL_MouseMotionEvent &b = input_event->motion;
event.xmouse = (int16_t)b.x;
event.ymouse = (int16_t)b.y;
event.mouse_move = 1;
} break;
case SDL_EVENT_MOUSE_BUTTON_DOWN: {
SDL_MouseButtonEvent &b = event->button;
Vec2I mouse = {(Int)b.x, (Int)b.y};
Scratch scratch;
Array<Int> order = GetWindowZOrder(scratch);
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);
}
}
SDL_MouseButtonEvent &b = input_event->button;
event.xmouse = (int16_t)b.x;
event.ymouse = (int16_t)b.y;
if (b.button == SDL_BUTTON_LEFT) {
event.mouse_left = 1;
if (b.clicks == 2) event.mouse_double_click = 1;
} else if (b.button == SDL_BUTTON_RIGHT) {
event.mouse_right = 1;
} else if (b.button == SDL_BUTTON_MIDDLE) {
event.mouse_middle = 1;
}
} break;
case SDL_EVENT_MOUSE_BUTTON_UP: {
SDL_MouseButtonEvent &b = event->button;
SDL_MouseButtonEvent &b = input_event->button;
return;
} break;
case SDL_EVENT_MOUSE_WHEEL: {
SDL_MouseWheelEvent &b = event->wheel;
Vec2 wheel = {b.x, b.y};
Vec2I mouse = {(Int)b.mouse_x, (Int)b.mouse_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;
}
}
SDL_MouseWheelEvent &b = input_event->wheel;
event.xmouse = (int16_t)b.mouse_x;
event.ymouse = (int16_t)b.mouse_y;
event.wheel = b.y;
} 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);
}
}