diff --git a/src/App.cpp b/src/App.cpp index 3619f31..a38e357 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -191,13 +191,13 @@ auto App::init_wayland() -> void bool meta = app->m_kbd.mod_active("Mod4"); if (!(ctrl || alt || meta)) { if (sym == XKB_KEY_Left) { - app->m_kbd.typing.push_back(0); - } else if (sym == XKB_KEY_Down) { app->m_kbd.typing.push_back(1); - } else if (sym == XKB_KEY_Up) { + } else if (sym == XKB_KEY_Down) { app->m_kbd.typing.push_back(2); - } else if (sym == XKB_KEY_Right) { + } else if (sym == XKB_KEY_Up) { app->m_kbd.typing.push_back(3); + } else if (sym == XKB_KEY_Right) { + app->m_kbd.typing.push_back(4); } else { u32 cp = xkb_keysym_to_utf32(sym); if (cp >= 0x20) { @@ -311,6 +311,7 @@ auto App::init_egl() -> void InitWindow(m_win_w, m_win_h, ""); m_tr = std::make_shared(); + m_gui = std::make_shared(m_tr); auto const font = find_font_path(); assert(font && "Could not find font"); std::vector fallback_paths; diff --git a/src/App.hpp b/src/App.hpp index 8e0a8f1..3353e46 100644 --- a/src/App.hpp +++ b/src/App.hpp @@ -17,6 +17,7 @@ extern "C" { #include #include +#include "ImGui.hpp" #include "TextRenderer.hpp" #include "Theme.hpp" #include "common.hpp" @@ -141,6 +142,7 @@ private: std::shared_ptr m_tr { nullptr }; FontHandle m_font; + std::shared_ptr m_gui { nullptr }; enum_array m_themes { make_default_themes() }; Theme m_active_theme { Theme::Light }; diff --git a/src/ImGui.cpp b/src/ImGui.cpp index 7ca903d..6ad0a62 100644 --- a/src/ImGui.cpp +++ b/src/ImGui.cpp @@ -1,14 +1,17 @@ #include "ImGui.hpp" +#include + +#include + ImGui::ImGui(std::shared_ptr text_renderer) : m_text_renderer(text_renderer) { } -void ImGui::begin( - std::pmr::vector const input_runes, bool ctrl, bool shift) +void ImGui::begin(u32 const rune, bool ctrl, bool shift) { - m_input_runes = input_runes; + m_rune = rune; m_ctrl = ctrl; m_shift = shift; } @@ -18,9 +21,30 @@ void ImGui::end() { } auto ImGui::text_input(std::size_t id, std::pmr::string &str, Rectangle rec, TextInputOptions options) -> std::bitset<2> { + assert(id != 0); + bool submitted { false }; bool changed { false }; + if (!m_ti_states.contains(id)) { + m_ti_states[id] = {}; + } + + assert(!options.multiline && "Multiline not yet implemented."); + + if (options.font_size > rec.height) { + TraceLog(LOG_WARNING, + std::format("Text size for text input {} is bigger than height ({} " + "> {}). Clipping will occur.", + id, options.font_size, rec.height) + .c_str()); + } + + BeginScissorMode(rec.x, rec.y, rec.width, rec.height); + { + } + EndScissorMode(); + return std::bitset<2> { static_cast( (submitted ? 1 : 0) | (changed ? 2 : 0)) }; } diff --git a/src/ImGui.hpp b/src/ImGui.hpp index fbaf8bf..d6bcb91 100644 --- a/src/ImGui.hpp +++ b/src/ImGui.hpp @@ -7,8 +7,11 @@ #include "TextRenderer.hpp" +constexpr float DEFAULT_FONT_SIZE { 16 }; + struct TextInputOptions { bool multiline { false }; + float font_size { DEFAULT_FONT_SIZE }; }; struct ImGui { @@ -19,7 +22,7 @@ struct ImGui { ImGui(ImGui &&) = default; auto operator=(ImGui &&) -> ImGui & = default; - void begin(std::pmr::vector const input_runes, bool ctrl, bool shift); + void begin(u32 const rune, bool ctrl, bool shift); void end(); // Bit 0 -> Submitted @@ -36,11 +39,13 @@ struct ImGui { private: struct TextInputState { int current_rune_idx { 0 }; + Vector2 scroll_offset; // y not used if multiline == false + Vector2 cursor_position; // y not used if multiline == false }; std::unordered_map m_ti_states; - std::size_t m_focused {}; - std::pmr::vector m_input_runes {}; // 0123 <-> hjkl arrow keys + std::size_t m_focused_id {}; + u32 m_rune {}; // 1234 <-> hjkl arrow keys bool m_ctrl {}; bool m_shift {}; @@ -48,14 +53,14 @@ private: }; struct ImGuiGuard { - ImGuiGuard(ImGui *imgui, std::pmr::vector const input_runes, bool ctrl, - bool shift) + ImGuiGuard(std::shared_ptr imgui, u32 const rune, bool const ctrl, + bool const shift) : m_imgui(imgui) { - m_imgui->begin(input_runes, ctrl, shift); + m_imgui->begin(rune, ctrl, shift); } ~ImGuiGuard() { m_imgui->end(); } private: - ImGui *m_imgui { nullptr }; + std::shared_ptr m_imgui { nullptr }; }; diff --git a/src/Tick.cpp b/src/Tick.cpp index 5c333fe..4be41f2 100644 --- a/src/Tick.cpp +++ b/src/Tick.cpp @@ -1,26 +1,23 @@ #include "App.hpp" +#include + #include #include -#include #include #include #include auto App::tick() -> void { + static std::pmr::string text_input_data; + if (!m_visible || m_gl.edpy == EGL_NO_DISPLAY || m_gl.esurf == EGL_NO_SURFACE) return; glViewport(0, 0, m_win_w, m_win_h); - for (auto const cp : m_kbd.typing) { - std::println("Char typed: {} ({}) shift={} ctrl={}", - rune_to_string(cp), cp, m_kbd.shift() ? 'y' : 'n', - m_kbd.ctrl() ? 'y' : 'n'); - } - if (m_kbd.is_sym_pressed(XKB_KEY_Escape)) { set_visible(!visible()); if (m_kbd.ctrl() && m_kbd.shift()) { @@ -33,12 +30,22 @@ auto App::tick() -> void ClearBackground(theme().window.background); DrawFPS(10, 10); - if (m_tr) { - Color const fg = theme().foreground; - Vector2 const pos { 40.0f, 60.0f }; - auto text = std::string_view("Hello from Waylight! 日本人ですか?"); - auto size = sin(GetTime()) * 12 + 32; - m_tr->draw_text(m_font, text, pos, size, fg); + { + assert(m_gui); + u32 rune { 0 }; + if (!m_kbd.typing.empty()) { + rune = m_kbd.typing.back(); + m_kbd.typing.clear(); + } + ImGuiGuard gui_scope(m_gui, rune, m_kbd.ctrl(), m_kbd.shift()); + + m_gui->text_input(1, text_input_data, + { + 0, + 0, + static_cast(GetScreenWidth()), + static_cast(GetScreenHeight()), + }); } EndDrawing();