107 lines
2.7 KiB
C++
107 lines
2.7 KiB
C++
#pragma once
|
|
|
|
#include <bitset>
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
|
|
#include <raylib.h>
|
|
|
|
#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<TextRenderer> 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<std::size_t>;
|
|
auto text_input_surrounding(
|
|
std::size_t id, std::pmr::string const &str) const
|
|
-> std::optional<TextInputSurrounding>;
|
|
auto text_input_cursor(std::size_t id) const
|
|
-> std::optional<TextInputCursor>;
|
|
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<std::string_view> 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<std::size_t, TextInputState> m_ti_states;
|
|
std::size_t m_focused_id {};
|
|
u32 m_rune {}; // 1234 <-> hjkl arrow keys
|
|
bool m_ctrl {};
|
|
bool m_shift {};
|
|
|
|
std::optional<FontHandle> m_font {};
|
|
std::shared_ptr<TextRenderer> m_text_renderer {};
|
|
};
|
|
|
|
struct ImGuiGuard {
|
|
ImGuiGuard(std::shared_ptr<ImGui> 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<ImGui> m_imgui { nullptr };
|
|
};
|