@@ -191,13 +191,13 @@ auto App::init_wayland() -> void
|
|||||||
bool meta = app->m_kbd.mod_active("Mod4");
|
bool meta = app->m_kbd.mod_active("Mod4");
|
||||||
if (!(ctrl || alt || meta)) {
|
if (!(ctrl || alt || meta)) {
|
||||||
if (sym == XKB_KEY_Left) {
|
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);
|
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);
|
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);
|
app->m_kbd.typing.push_back(3);
|
||||||
|
} else if (sym == XKB_KEY_Right) {
|
||||||
|
app->m_kbd.typing.push_back(4);
|
||||||
} else {
|
} else {
|
||||||
u32 cp = xkb_keysym_to_utf32(sym);
|
u32 cp = xkb_keysym_to_utf32(sym);
|
||||||
if (cp >= 0x20) {
|
if (cp >= 0x20) {
|
||||||
@@ -311,6 +311,7 @@ auto App::init_egl() -> void
|
|||||||
InitWindow(m_win_w, m_win_h, "");
|
InitWindow(m_win_w, m_win_h, "");
|
||||||
|
|
||||||
m_tr = std::make_shared<TextRenderer>();
|
m_tr = std::make_shared<TextRenderer>();
|
||||||
|
m_gui = std::make_shared<ImGui>(m_tr);
|
||||||
auto const font = find_font_path();
|
auto const font = find_font_path();
|
||||||
assert(font && "Could not find font");
|
assert(font && "Could not find font");
|
||||||
std::vector<std::filesystem::path> fallback_paths;
|
std::vector<std::filesystem::path> fallback_paths;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ extern "C" {
|
|||||||
#include <wayland-egl.h>
|
#include <wayland-egl.h>
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
|
||||||
|
#include "ImGui.hpp"
|
||||||
#include "TextRenderer.hpp"
|
#include "TextRenderer.hpp"
|
||||||
#include "Theme.hpp"
|
#include "Theme.hpp"
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
@@ -141,6 +142,7 @@ private:
|
|||||||
|
|
||||||
std::shared_ptr<TextRenderer> m_tr { nullptr };
|
std::shared_ptr<TextRenderer> m_tr { nullptr };
|
||||||
FontHandle m_font;
|
FontHandle m_font;
|
||||||
|
std::shared_ptr<ImGui> m_gui { nullptr };
|
||||||
|
|
||||||
enum_array<Theme, ColorScheme> m_themes { make_default_themes() };
|
enum_array<Theme, ColorScheme> m_themes { make_default_themes() };
|
||||||
Theme m_active_theme { Theme::Light };
|
Theme m_active_theme { Theme::Light };
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
#include "ImGui.hpp"
|
#include "ImGui.hpp"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include <raylib.h>
|
||||||
|
|
||||||
ImGui::ImGui(std::shared_ptr<TextRenderer> text_renderer)
|
ImGui::ImGui(std::shared_ptr<TextRenderer> text_renderer)
|
||||||
: m_text_renderer(text_renderer)
|
: m_text_renderer(text_renderer)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::begin(
|
void ImGui::begin(u32 const rune, bool ctrl, bool shift)
|
||||||
std::pmr::vector<u32> const input_runes, bool ctrl, bool shift)
|
|
||||||
{
|
{
|
||||||
m_input_runes = input_runes;
|
m_rune = rune;
|
||||||
m_ctrl = ctrl;
|
m_ctrl = ctrl;
|
||||||
m_shift = shift;
|
m_shift = shift;
|
||||||
}
|
}
|
||||||
@@ -18,9 +21,30 @@ void ImGui::end() { }
|
|||||||
auto ImGui::text_input(std::size_t id, std::pmr::string &str, Rectangle rec,
|
auto ImGui::text_input(std::size_t id, std::pmr::string &str, Rectangle rec,
|
||||||
TextInputOptions options) -> std::bitset<2>
|
TextInputOptions options) -> std::bitset<2>
|
||||||
{
|
{
|
||||||
|
assert(id != 0);
|
||||||
|
|
||||||
bool submitted { false };
|
bool submitted { false };
|
||||||
bool changed { 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<unsigned long long>(
|
return std::bitset<2> { static_cast<unsigned long long>(
|
||||||
(submitted ? 1 : 0) | (changed ? 2 : 0)) };
|
(submitted ? 1 : 0) | (changed ? 2 : 0)) };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,11 @@
|
|||||||
|
|
||||||
#include "TextRenderer.hpp"
|
#include "TextRenderer.hpp"
|
||||||
|
|
||||||
|
constexpr float DEFAULT_FONT_SIZE { 16 };
|
||||||
|
|
||||||
struct TextInputOptions {
|
struct TextInputOptions {
|
||||||
bool multiline { false };
|
bool multiline { false };
|
||||||
|
float font_size { DEFAULT_FONT_SIZE };
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ImGui {
|
struct ImGui {
|
||||||
@@ -19,7 +22,7 @@ struct ImGui {
|
|||||||
ImGui(ImGui &&) = default;
|
ImGui(ImGui &&) = default;
|
||||||
auto operator=(ImGui &&) -> ImGui & = default;
|
auto operator=(ImGui &&) -> ImGui & = default;
|
||||||
|
|
||||||
void begin(std::pmr::vector<u32> const input_runes, bool ctrl, bool shift);
|
void begin(u32 const rune, bool ctrl, bool shift);
|
||||||
void end();
|
void end();
|
||||||
|
|
||||||
// Bit 0 -> Submitted
|
// Bit 0 -> Submitted
|
||||||
@@ -36,11 +39,13 @@ struct ImGui {
|
|||||||
private:
|
private:
|
||||||
struct TextInputState {
|
struct TextInputState {
|
||||||
int current_rune_idx { 0 };
|
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<std::size_t, TextInputState> m_ti_states;
|
std::unordered_map<std::size_t, TextInputState> m_ti_states;
|
||||||
std::size_t m_focused {};
|
std::size_t m_focused_id {};
|
||||||
std::pmr::vector<u32> m_input_runes {}; // 0123 <-> hjkl arrow keys
|
u32 m_rune {}; // 1234 <-> hjkl arrow keys
|
||||||
bool m_ctrl {};
|
bool m_ctrl {};
|
||||||
bool m_shift {};
|
bool m_shift {};
|
||||||
|
|
||||||
@@ -48,14 +53,14 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ImGuiGuard {
|
struct ImGuiGuard {
|
||||||
ImGuiGuard(ImGui *imgui, std::pmr::vector<u32> const input_runes, bool ctrl,
|
ImGuiGuard(std::shared_ptr<ImGui> imgui, u32 const rune, bool const ctrl,
|
||||||
bool shift)
|
bool const shift)
|
||||||
: m_imgui(imgui)
|
: m_imgui(imgui)
|
||||||
{
|
{
|
||||||
m_imgui->begin(input_runes, ctrl, shift);
|
m_imgui->begin(rune, ctrl, shift);
|
||||||
}
|
}
|
||||||
~ImGuiGuard() { m_imgui->end(); }
|
~ImGuiGuard() { m_imgui->end(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ImGui *m_imgui { nullptr };
|
std::shared_ptr<ImGui> m_imgui { nullptr };
|
||||||
};
|
};
|
||||||
|
|||||||
33
src/Tick.cpp
33
src/Tick.cpp
@@ -1,26 +1,23 @@
|
|||||||
#include "App.hpp"
|
#include "App.hpp"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
#include <GLES3/gl3.h>
|
#include <GLES3/gl3.h>
|
||||||
#include <print>
|
|
||||||
#include <raylib.h>
|
#include <raylib.h>
|
||||||
#include <rlgl.h>
|
#include <rlgl.h>
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
|
||||||
auto App::tick() -> void
|
auto App::tick() -> void
|
||||||
{
|
{
|
||||||
|
static std::pmr::string text_input_data;
|
||||||
|
|
||||||
if (!m_visible || m_gl.edpy == EGL_NO_DISPLAY
|
if (!m_visible || m_gl.edpy == EGL_NO_DISPLAY
|
||||||
|| m_gl.esurf == EGL_NO_SURFACE)
|
|| m_gl.esurf == EGL_NO_SURFACE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
glViewport(0, 0, m_win_w, m_win_h);
|
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)) {
|
if (m_kbd.is_sym_pressed(XKB_KEY_Escape)) {
|
||||||
set_visible(!visible());
|
set_visible(!visible());
|
||||||
if (m_kbd.ctrl() && m_kbd.shift()) {
|
if (m_kbd.ctrl() && m_kbd.shift()) {
|
||||||
@@ -33,12 +30,22 @@ auto App::tick() -> void
|
|||||||
ClearBackground(theme().window.background);
|
ClearBackground(theme().window.background);
|
||||||
|
|
||||||
DrawFPS(10, 10);
|
DrawFPS(10, 10);
|
||||||
if (m_tr) {
|
{
|
||||||
Color const fg = theme().foreground;
|
assert(m_gui);
|
||||||
Vector2 const pos { 40.0f, 60.0f };
|
u32 rune { 0 };
|
||||||
auto text = std::string_view("Hello from Waylight! 日本人ですか?");
|
if (!m_kbd.typing.empty()) {
|
||||||
auto size = sin(GetTime()) * 12 + 32;
|
rune = m_kbd.typing.back();
|
||||||
m_tr->draw_text(m_font, text, pos, size, fg);
|
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<float>(GetScreenWidth()),
|
||||||
|
static_cast<float>(GetScreenHeight()),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
|
|||||||
Reference in New Issue
Block a user