module ugui::sdl3::ren; import std::io; import std::ascii; import ugui; import sdl3; <* @param [&inout] ctx *> fn bool? Ctx.handle_events(&ctx) { bool quit = false; ugui::ModKeys mod_set, mod_reset; ugui::MouseButtons btn; sdl3::Event e; while (sdl3::pollEvent(&e)) { switch (e.type) { case QUIT: quit = true; case KEY_UP: ctx.input_key_release(); nextcase; case KEY_DOWN: ctx.input_key_press(); if (e.key.repeat) ctx.input_key_repeat(); bool down = e.type == KEY_DOWN; switch (e.key.key) { case sdl3::KEY_RCTRL: mod_set.rctrl = down; mod_reset.rctrl = !down; case sdl3::KEY_LCTRL: mod_set.lctrl = down; mod_reset.lctrl = !down; case sdl3::KEY_RSHIFT: mod_set.rshift = down; mod_reset.rshift = !down; case sdl3::KEY_LSHIFT: mod_set.lshift = down; mod_reset.lshift = !down; case sdl3::KEY_BACKSPACE: mod_set.bkspc = down; mod_reset.bkspc = !down; case sdl3::KEY_DELETE: mod_set.del = down; mod_reset.del = !down; case sdl3::KEY_HOME: mod_set.home = down; mod_reset.home = !down; case sdl3::KEY_END: mod_set.end = down; mod_reset.end = !down; case sdl3::KEY_UP: mod_set.up = down; mod_reset.up = !down; case sdl3::KEY_DOWN: mod_set.down = down; mod_reset.down = !down; case sdl3::KEY_LEFT: mod_set.left = down; mod_reset.left = !down; case sdl3::KEY_RIGHT: mod_set.right = down; mod_reset.right = !down; } ctx.input_mod_keys(mod_set, true); ctx.input_mod_keys(mod_reset, false); // pressing ctrl+key or alt+key does not generate a character as such no // TEXT_INPUT event is generated. When those keys are pressed we have to // do manual text input, bummer ModKeys mod = ctx.get_mod(); if (e.type == KEY_DOWN && (mod.lctrl || mod.rctrl)) { if (ascii::is_alnum_m((uint)e.key.key)) { ctx.input_char((char)e.key.key); } } if (e.type == KEY_DOWN && e.key.key == sdl3::KEY_RETURN) ctx.input_char('\n'); case TEXT_INPUT: ctx.input_text_utf8(((ZString)e.text.text).str_view()); case WINDOW_RESIZED: ctx.input_window_size((short)e.window.data1, (short)e.window.data2)!; case WINDOW_FOCUS_GAINED: ctx.input_changefocus(true); case WINDOW_FOCUS_LOST: ctx.input_changefocus(false); case MOUSE_MOTION: ctx.input_mouse_abs((short)e.motion.x, (short)e.motion.y); case MOUSE_WHEEL: ctx.input_mouse_wheel((short)e.wheel.integer_x, (short)e.wheel.integer_y); case MOUSE_BUTTON_DOWN: nextcase; case MOUSE_BUTTON_UP: sdl3::MouseButtonFlags mb = sdl3::getMouseState(null, null); btn = { .btn_left = !!(mb & sdl3::BUTTON_LMASK), .btn_right = !!(mb & sdl3::BUTTON_RMASK), .btn_middle = !!(mb & sdl3::BUTTON_MMASK), .btn_4 = !!(mb & sdl3::BUTTON_X1MASK), .btn_5 = !!(mb & sdl3::BUTTON_X2MASK), }; ctx.input_mouse_button(btn); //case POLL_SENTINEL: break; default: io::eprintfn("unhandled event: %s", e.type); } } return quit; } fn void pre(sdl3::Window* win) => sdl3::startTextInput(win); // TODO: this has to be a function of Ctx if we want to set the fps internally fn void wait_events(uint timeout_ms = 0) { sdl3::waitEventTimeout(null, timeout_ms); }