diff --git a/lib/ugui_sdl3.c3l/input.c3 b/lib/ugui_sdl3.c3l/input.c3 new file mode 100644 index 0000000..121c0c0 --- /dev/null +++ b/lib/ugui_sdl3.c3l/input.c3 @@ -0,0 +1,97 @@ +module ugui::sdl::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; + sdl::Event e; + + while (sdl::poll_event(&e)) { + switch (e.type) { + case EVENT_QUIT: + quit = true; + case EVENT_KEY_UP: + ctx.input_key_release(); + nextcase; + case EVENT_KEY_DOWN: + ctx.input_key_press(); + if (e.key.repeat) ctx.input_key_repeat(); + + bool down = e.type == EVENT_KEY_DOWN; + switch (e.key.key) { + case K_RCTRL: mod_set.rctrl = down; mod_reset.rctrl = !down; + case K_LCTRL: mod_set.lctrl = down; mod_reset.lctrl = !down; + case K_RSHIFT: mod_set.rshift = down; mod_reset.rshift = !down; + case K_LSHIFT: mod_set.lshift = down; mod_reset.lshift = !down; + case K_BACKSPACE: mod_set.bkspc = down; mod_reset.bkspc = !down; + case K_DELETE: mod_set.del = down; mod_reset.del = !down; + case K_HOME: mod_set.home = down; mod_reset.home = !down; + case K_END: mod_set.end = down; mod_reset.end = !down; + case K_UP: mod_set.up = down; mod_reset.up = !down; + case K_DOWN: mod_set.down = down; mod_reset.down = !down; + case K_LEFT: mod_set.left = down; mod_reset.left = !down; + case K_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 == EVENT_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 == EVENT_KEY_DOWN && e.key.key == K_RETURN) ctx.input_char('\n'); + + case EVENT_TEXT_INPUT: + ctx.input_text_utf8(e.text.text.str_view()); + case EVENT_WINDOW_RESIZED: + ctx.input_window_size((short)e.window.data1, (short)e.window.data2)!; + case EVENT_WINDOW_FOCUS_GAINED: + ctx.input_changefocus(true); + case EVENT_WINDOW_FOCUS_LOST: + ctx.input_changefocus(false); + case EVENT_MOUSE_MOTION: + ctx.input_mouse_abs((short)e.motion.x, (short)e.motion.y); + case EVENT_MOUSE_WHEEL: + ctx.input_mouse_wheel((short)e.wheel.integer_x, (short)e.wheel.integer_y); + case EVENT_MOUSE_BUTTON_DOWN: nextcase; + case EVENT_MOUSE_BUTTON_UP: + sdl::MouseButtonFlags mb = sdl::get_mouse_state(null, null); + btn = { + .btn_left = !!(mb & BUTTON_LMASK), + .btn_right = !!(mb & BUTTON_RMASK), + .btn_middle = !!(mb & BUTTON_MMASK), + .btn_4 = !!(mb & BUTTON_X1MASK), + .btn_5 = !!(mb & BUTTON_X2MASK), + }; + ctx.input_mouse_button(btn); + case EVENT_POLL_SENTINEL: break; + default: + io::eprintfn("unhandled event: %s", e.type); + } + } + + return quit; +} + +fn void pre(sdl::Window* win) => sdl::start_text_input(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) +{ + sdl::wait_event_timeout(null, timeout_ms); +} \ No newline at end of file diff --git a/lib/ugui_sdl3.c3l/manifest.json b/lib/ugui_sdl3.c3l/manifest.json new file mode 100644 index 0000000..2200db1 --- /dev/null +++ b/lib/ugui_sdl3.c3l/manifest.json @@ -0,0 +1,10 @@ +{ + "provides" : "ugui_sdl3", + "targets" : { + "linux-x64" : { + "link-args" : [], + "dependencies" : ["sdl3", "ugui"], + "linked-libraries" : [] + } + } +} diff --git a/src/renderer.c3 b/lib/ugui_sdl3.c3l/renderer.c3 similarity index 99% rename from src/renderer.c3 rename to lib/ugui_sdl3.c3l/renderer.c3 index 2794c36..d0e448c 100644 --- a/src/renderer.c3 +++ b/lib/ugui_sdl3.c3l/renderer.c3 @@ -7,11 +7,16 @@ import std::collections::list; alias IdList = List{Type}; +<* +@param [&in] self +@param [in] name +*> macro Type* IdList.get_from_name(&self, String name) { return self.get_from_id(name.hash()); } +<* @param [&in] self *> macro Type* IdList.get_from_id(&self, id) { foreach(&s: self) { @@ -24,10 +29,11 @@ macro Type* IdList.get_from_id(&self, id) // 2D renderer for ugui, based on SDL3 using the new GPU API -module sdlrenderer::ren; +module ugui::sdl::ren; + import std::io; -import std::core::mem; import sdl3::sdl; +import std::core::mem; import idlist; import ugui; @@ -1026,7 +1032,6 @@ fn void Renderer.render_ugui(&self, CmdQueue* queue) self.draw_quads(off, count); off += count; calls++; -// self.draw_quads(off++, 1); } } self.end_render_pass(); diff --git a/project.json b/project.json index 13bcb34..0440f28 100644 --- a/project.json +++ b/project.json @@ -2,7 +2,7 @@ "langrev": "1", "warnings": ["no-unused"], "dependency-search-paths": ["lib", "lib/vendor/libraries"], - "dependencies": ["sdl3", "ugui"], + "dependencies": ["sdl3", "ugui", "ugui_sdl3"], "features": ["DEBUG_POINTER"], "authors": ["Alessandro Mauri "], "version": "0.1.0", diff --git a/src/main.c3 b/src/main.c3 index ce62be5..7489ef5 100644 --- a/src/main.c3 +++ b/src/main.c3 @@ -1,13 +1,11 @@ import std::io; -import cache; import ugui; import std::time; import std::collections::ringbuffer; import std::core::string; -import std::ascii; import std::core::mem::allocator; -import sdlrenderer::ren; -import sdl3::sdl; +import ugui::sdl::ren; + alias Times = ringbuffer::RingBuffer{time::NanoDuration[128]}; @@ -127,81 +125,15 @@ fn int main(String[] args) // ========================================================================================== // // MAIN LOOP // // ========================================================================================== // - sdl::start_text_input(ren.win); - - sdl::Event e; - bool quit = false; - ugui::ModKeys mod; - ugui::MouseButtons btn; + ren::pre(ren.win); + + bool quit; while (!quit) { clock.mark(); fps_clock.mark(); sleep_clock.mark(); - do { - switch (e.type) { - case EVENT_QUIT: - quit = true; - case EVENT_KEY_UP: - ui.input_key_release(); - nextcase; - case EVENT_KEY_DOWN: - ui.input_key_press(); - if (e.key.repeat) ui.input_key_repeat(); - - mod.rctrl = e.key.key == K_RCTRL ? !!(e.type == EVENT_KEY_DOWN) : mod.rctrl; - mod.lctrl = e.key.key == K_LCTRL ? !!(e.type == EVENT_KEY_DOWN) : mod.lctrl; - mod.rshift = e.key.key == K_RSHIFT ? !!(e.type == EVENT_KEY_DOWN) : mod.rshift; - mod.lshift = e.key.key == K_LSHIFT ? !!(e.type == EVENT_KEY_DOWN) : mod.lshift; - mod.bkspc = e.key.key == K_BACKSPACE ? !!(e.type == EVENT_KEY_DOWN) : mod.bkspc; - mod.del = e.key.key == K_DELETE ? !!(e.type == EVENT_KEY_DOWN) : mod.del; - mod.home = e.key.key == K_HOME ? !!(e.type == EVENT_KEY_DOWN) : mod.home; - mod.end = e.key.key == K_END ? !!(e.type == EVENT_KEY_DOWN) : mod.end; - mod.up = e.key.key == K_UP ? !!(e.type == EVENT_KEY_DOWN) : mod.up; - mod.down = e.key.key == K_DOWN ? !!(e.type == EVENT_KEY_DOWN) : mod.down; - mod.left = e.key.key == K_LEFT ? !!(e.type == EVENT_KEY_DOWN) : mod.left; - mod.right = e.key.key == K_RIGHT ? !!(e.type == EVENT_KEY_DOWN) : mod.right; - - // 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 - if (e.type == EVENT_KEY_DOWN && (mod.lctrl || mod.rctrl)) { - if (ascii::is_alnum_m((uint)e.key.key)) { - ui.input_char((char)e.key.key); - } - } - - if (e.type == EVENT_KEY_DOWN && e.key.key == K_RETURN) ui.input_char('\n'); - - case EVENT_TEXT_INPUT: - ui.input_text_utf8(e.text.text.str_view()); - case EVENT_WINDOW_RESIZED: - ui.input_window_size((short)e.window.data1, (short)e.window.data2)!!; - case EVENT_WINDOW_FOCUS_GAINED: - ui.input_changefocus(true); - case EVENT_WINDOW_FOCUS_LOST: - ui.input_changefocus(false); - case EVENT_MOUSE_MOTION: - ui.input_mouse_abs((short)e.motion.x, (short)e.motion.y); - case EVENT_MOUSE_WHEEL: - ui.input_mouse_wheel((short)e.wheel.integer_x, (short)e.wheel.integer_y); - case EVENT_MOUSE_BUTTON_DOWN: nextcase; - case EVENT_MOUSE_BUTTON_UP: - sdl::MouseButtonFlags mb = sdl::get_mouse_state(null, null); - btn = { - .btn_left = !!(mb & BUTTON_LMASK), - .btn_right = !!(mb & BUTTON_RMASK), - .btn_middle = !!(mb & BUTTON_MMASK), - .btn_4 = !!(mb & BUTTON_X1MASK), - .btn_5 = !!(mb & BUTTON_X2MASK), - }; - case EVENT_POLL_SENTINEL: break; - default: - io::eprintfn("unhandled event: %s", e.type); - } - } while(sdl::poll_event(&e)); - ui.input_mod_keys(mod); - ui.input_mouse_button(btn); + quit = ui.handle_events()!!; /* End Input Handling */ @@ -248,7 +180,7 @@ $endswitch // wait for the next event, timeout after 100ms int timeout = LIMIT_FPS ? (int)(100.0-sleep_clock.mark().to_ms()-0.5) : 0; if (ui.skip_frame) timeout = 0; - sdl::wait_event_timeout(&e, timeout); + ren::wait_events(timeout); fps = 1.0 / fps_clock.mark().to_sec(); frame++; @@ -453,7 +385,7 @@ fn void calculator(ugui::Ctx* ui, TextEdit* te) ui.@div(ugui::@grow(), ugui::@fit(), anchor: CENTER) { static bool state; ui.checkbox("boolean", &state, "tick")!!; - ui.sprite("tux")!!; + ui.sprite("tux", 32)!!; ui.toggle("lmao", &state)!!; }!!; ui.@div(ugui::@grow(), ugui::@exact(50), anchor: CENTER, scroll_y: true) {