#pragma once #include #include #include #include #include #include #include "TextRenderer.hpp" constexpr float DEFAULT_FONT_SIZE { 24 }; struct TextInputOptions { bool multiline { false }; float font_size { DEFAULT_FONT_SIZE }; }; struct ImGui { ImGui(std::shared_ptr text_renderer); ImGui(ImGui const &) = delete; auto operator=(ImGui const &) -> ImGui & = delete; ImGui(ImGui &&) = default; auto operator=(ImGui &&) -> ImGui & = default; void begin(u32 const rune, bool ctrl, bool shift); void end(); // Bit 0 -> Submitted // Bit 1 -> String changed auto text_input(std::size_t id, std::pmr::string &str, Rectangle rec, TextInputOptions options = {}) -> std::bitset<2>; struct TextInputSurrounding { std::string text; int cursor { 0 }; int anchor { 0 }; std::size_t caret_byte { 0 }; }; struct TextInputCursor { Rectangle rect {}; bool visible { true }; }; auto focused_text_input() const -> std::optional; auto text_input_surrounding( std::size_t id, std::pmr::string const &str) const -> std::optional; auto text_input_cursor(std::size_t id) const -> std::optional; void ime_commit_text(std::pmr::string &str, std::string_view text); void ime_delete_surrounding( std::pmr::string &str, std::size_t before, std::size_t after); void ime_set_preedit(std::string text, int cursor_begin, int cursor_end); void ime_clear_preedit(); void set_font(FontHandle font); [[nodiscard]] inline auto id(std::string_view const str) -> std::size_t { std::hash hasher; return hasher(str); } 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 bool caret_visible { true }; double caret_timer { 0.0 }; std::string preedit_text; int preedit_cursor_begin { 0 }; int preedit_cursor_end { 0 }; bool preedit_active { false }; bool preedit_cursor_hidden { false }; std::size_t caret_byte { 0 }; Rectangle caret_rect {}; bool external_change { false }; }; std::unordered_map m_ti_states; std::size_t m_focused_id {}; u32 m_rune {}; // 1234 <-> hjkl arrow keys bool m_ctrl {}; bool m_shift {}; std::optional m_font {}; std::shared_ptr m_text_renderer {}; }; struct ImGuiGuard { ImGuiGuard(std::shared_ptr imgui, u32 const rune, bool const ctrl, bool const shift) : m_imgui(imgui) { m_imgui->begin(rune, ctrl, shift); } ~ImGuiGuard() { m_imgui->end(); } private: std::shared_ptr m_imgui { nullptr }; };