Keyboard captures
This commit is contained in:
parent
04df1078b4
commit
f15e895af5
@ -13,11 +13,14 @@ static KeyBinding
|
||||
keyUp,
|
||||
keyDown,
|
||||
keyOptions,
|
||||
keyToggleCursorMode;
|
||||
keyToggleCursorMode,
|
||||
keyExit;
|
||||
|
||||
static ButtonElement *options;
|
||||
|
||||
static void defaultInput(GLFWwindow *window, void *data) {
|
||||
if(Input::isKeyboardCaptured()) return;
|
||||
|
||||
if(Input::getKeyState(keyForward) == GLFW_PRESS) {
|
||||
kekData.activeCamera->translate(kekData.activeCamera->direction * KEK_NOCLIP_SPEED * kekData.lastFrameTime);
|
||||
}
|
||||
@ -46,6 +49,10 @@ static void defaultInput(GLFWwindow *window, void *data) {
|
||||
}
|
||||
|
||||
static void defaultKeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods, void *data) {
|
||||
if(key == Input::getKeyBinding(keyExit).key && action == GLFW_PRESS) {
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
}
|
||||
|
||||
if(key == Input::getKeyBinding(keyOptions).key && action == GLFW_PRESS) {
|
||||
options->visible = !options->visible;
|
||||
}
|
||||
@ -128,6 +135,7 @@ void init() {
|
||||
keyDown = Input::createKeyBinding("Down", GLFW_KEY_LEFT_CONTROL);
|
||||
keyOptions = Input::createKeyBinding("Options", GLFW_KEY_Q);
|
||||
keyToggleCursorMode = Input::createKeyBinding("Toggle Cursor Mode", GLFW_KEY_TAB);
|
||||
keyExit = Input::createKeyBinding("Exit", GLFW_KEY_ESCAPE);
|
||||
|
||||
Input::addPeriodicCallback(PeriodicCallback(defaultInput, nullptr));
|
||||
Input::addKeyListener(KeyCallback(defaultKeyCallback, nullptr));
|
||||
|
@ -50,11 +50,27 @@ static void onCursorPosCallback(GLFWwindow *window, double x, double y) {
|
||||
}
|
||||
|
||||
static void onKeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) {
|
||||
if(Input::isKeyboardCaptured()) {
|
||||
if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) Input::uncaptureKeyboardInput(kekData.activeKeyboardCapture.id);
|
||||
return;
|
||||
}
|
||||
|
||||
for(auto cb : kekData.keyCallbacks) {
|
||||
cb.second(window, key, scancode, action, mods);
|
||||
}
|
||||
}
|
||||
|
||||
static void onKeyCharCallback(GLFWwindow *window, unsigned int codepoint) {
|
||||
if(Input::isKeyboardCaptured()) {
|
||||
kekData.activeKeyboardCapture.callback(window, codepoint);
|
||||
return;
|
||||
}
|
||||
|
||||
for(auto cb : kekData.keyCharCallbacks) {
|
||||
cb.second(window, codepoint);
|
||||
}
|
||||
}
|
||||
|
||||
void onMouseButtonCallback(GLFWwindow* window, int button, int action, int mods) {
|
||||
for(auto cb : kekData.mouseButtonCallbacks) {
|
||||
cb.second(window, button, action, mods);
|
||||
@ -159,6 +175,7 @@ int init() {
|
||||
glfwSetCursorPosCallback(kekData.window, onCursorPosCallback);
|
||||
Input::setCursorMode(GLFWCursorMode::CAPTURE);
|
||||
glfwSetKeyCallback(kekData.window, onKeyCallback);
|
||||
glfwSetCharCallback(kekData.window, onKeyCharCallback);
|
||||
glfwSetMouseButtonCallback(kekData.window, onMouseButtonCallback);
|
||||
|
||||
glClearColor(0.1f, 0.3f, 0.1f, 0.0f);
|
||||
@ -195,10 +212,6 @@ int start() {
|
||||
cb.second(kekData.window);
|
||||
}
|
||||
|
||||
if(glfwGetKey(kekData.window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
|
||||
break;
|
||||
}
|
||||
|
||||
kekData.shader->use();
|
||||
|
||||
glm::mat4 view = kekData.activeCamera->transformationMatrix();
|
||||
|
@ -29,6 +29,16 @@ void removeKeyListener(InputListener listener) {
|
||||
kekData.keyCallbacks.erase(listener);
|
||||
}
|
||||
|
||||
InputListener addKeyCharListener(KeyCharCallback callback) {
|
||||
InputListener id = nextID++;
|
||||
kekData.keyCharCallbacks.emplace(id, callback);
|
||||
return id;
|
||||
}
|
||||
|
||||
void removeKeyCharListener(InputListener listener) {
|
||||
kekData.keyCharCallbacks.erase(listener);
|
||||
}
|
||||
|
||||
InputListener addMouseListener(MouseCallback callback) {
|
||||
InputListener id = nextID++;
|
||||
kekData.mouseCallbacks.emplace(id, callback);
|
||||
@ -50,7 +60,7 @@ void removeMouseButtonListener(InputListener listener) {
|
||||
}
|
||||
|
||||
KeyBinding createKeyBinding(std::string name, GLFWKey defaultKey) {
|
||||
if(name == KEK_INVALID_KEY_BINDING_NAME) return KEK_INVALID_KEY_BINDING;
|
||||
if(name == KEK_INVALID_KEY_BINDING_NAME) return KEK_INVALID_ID;
|
||||
KeyBinding id = nextID++;
|
||||
KeyBindingData d;
|
||||
d.name = name;
|
||||
@ -60,7 +70,7 @@ KeyBinding createKeyBinding(std::string name, GLFWKey defaultKey) {
|
||||
}
|
||||
|
||||
void reassignKeyBinding(KeyBinding binding, GLFWKey key) {
|
||||
if(binding == KEK_INVALID_KEY_BINDING) return;
|
||||
if(binding == KEK_INVALID_ID) return;
|
||||
auto it = kekData.keyBindings.find(binding);
|
||||
if(it == kekData.keyBindings.end()) return;
|
||||
KeyBindingData d = it->second;
|
||||
@ -89,4 +99,24 @@ GLFWCursorMode getCursorMode() {
|
||||
return kekData.uiCursorMode;
|
||||
}
|
||||
|
||||
KeyboardCapture captureKeyboardInput(KeyCharCallback callback, Callable uncaptureCallback) {
|
||||
KeyboardCapture id = nextID++;
|
||||
kekData.activeKeyboardCapture.id = id;
|
||||
kekData.activeKeyboardCapture.callback = callback;
|
||||
kekData.activeKeyboardCapture.uncaptureCallback = uncaptureCallback;
|
||||
return id;
|
||||
}
|
||||
|
||||
bool uncaptureKeyboardInput(KeyboardCapture capture) {
|
||||
if(capture == KEK_INVALID_ID || capture != kekData.activeKeyboardCapture.id) return false;
|
||||
kekData.activeKeyboardCapture.id = KEK_INVALID_ID;
|
||||
kekData.activeKeyboardCapture.callback = KeyCharCallback();
|
||||
kekData.activeKeyboardCapture.uncaptureCallback = Callable();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isKeyboardCaptured() {
|
||||
return kekData.activeKeyboardCapture.id != KEK_INVALID_ID;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -55,6 +55,10 @@ void TextElement::setText(std::string text) {
|
||||
this->text->setText(text);
|
||||
}
|
||||
|
||||
std::string TextElement::getText() {
|
||||
return text->getText();
|
||||
}
|
||||
|
||||
void TextElement::draw(UIPoint screenPos, glm::mat4 projection) {
|
||||
UIBounds offset = getBounds();
|
||||
|
||||
|
17
src/kekengine/cpp/unicode.cpp
Normal file
17
src/kekengine/cpp/unicode.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
#include "unicode.h"
|
||||
|
||||
#include <locale>
|
||||
|
||||
namespace kek::Unicode {
|
||||
|
||||
static std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> utf32cvt;
|
||||
|
||||
std::u32string convertStdToU32(std::string string) {
|
||||
return utf32cvt.from_bytes(string);
|
||||
}
|
||||
|
||||
std::string convertU32ToStd(std::u32string string) {
|
||||
return utf32cvt.to_bytes(string);
|
||||
}
|
||||
|
||||
}
|
@ -27,14 +27,14 @@
|
||||
#define KEK_LIGHT_MAX_DISTANCE_SQUARED (KEK_LIGHT_MAX_DISTANCE * KEK_LIGHT_MAX_DISTANCE)
|
||||
|
||||
#define KEK_INVALID_KEY_BINDING_NAME "INVALID"
|
||||
#define KEK_INVALID_KEY_BINDING -1u
|
||||
#define KEK_INVALID_ID -1u
|
||||
|
||||
#define KEK_FONT_RESOLUTION 64
|
||||
#define KEK_FONT_BITMAP_WIDTH_BLOCKS 16
|
||||
#define KEK_FONT_BITMAP_HEIGHT_BLOCKS 16
|
||||
#define KEK_FONT_BITMAP_WIDTH (KEK_FONT_BITMAP_WIDTH_BLOCKS * KEK_FONT_RESOLUTION)
|
||||
#define KEK_FONT_BITMAP_HEIGHT (KEK_FONT_BITMAP_HEIGHT_BLOCKS * KEK_FONT_RESOLUTION)
|
||||
#define KEK_FONT_BITMAP_CHAR_BITS 8 // = log2(KEK_FONT_BITMAP_WIDTH_BLOCKS * KEK_FONT_BITMAP_HEIGHT_BLOCKS)
|
||||
#define KEK_FONT_BITMAP_CHAR_BITS 8 // = ceil(log2(KEK_FONT_BITMAP_WIDTH_BLOCKS * KEK_FONT_BITMAP_HEIGHT_BLOCKS))
|
||||
#define KEK_FONT_BITMAP_CHAR_MASK 0xFF // = KEK_FONT_BITMAP_CHAR_BITS 1s in binary
|
||||
#define KEK_TEXT_BLOCK_SIZE 8
|
||||
|
||||
|
@ -9,6 +9,7 @@ namespace kek {
|
||||
|
||||
typedef GenericCallable<GLFWwindow *> PeriodicCallback; // periodicCallback(GLFWwindow *window)
|
||||
typedef GenericCallable<GLFWwindow *, int, int, int, int> KeyCallback; // keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
|
||||
typedef GenericCallable<GLFWwindow *, unsigned int> KeyCharCallback; // keyCharCallback(GLFWwindow *window, unsigned int codepoint)
|
||||
typedef GenericCallable<GLFWwindow *, double, double> MouseCallback; // mouseCallback(GLFWwindow *window, double x, double y)
|
||||
typedef GenericCallable<GLFWwindow *, int, int, int> MouseButtonCallback; // void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods)
|
||||
|
||||
@ -16,6 +17,7 @@ typedef unsigned int InputListener;
|
||||
typedef int GLFWKey;
|
||||
typedef int GLFWKeyState;
|
||||
typedef unsigned int KeyBinding;
|
||||
typedef unsigned int KeyboardCapture;
|
||||
|
||||
struct KeyBindingData {
|
||||
std::string name;
|
||||
@ -44,6 +46,9 @@ void removePeriodicCallback(InputListener listener);
|
||||
InputListener addKeyListener(KeyCallback callback);
|
||||
void removeKeyListener(InputListener listener);
|
||||
|
||||
InputListener addKeyCharListener(KeyCharCallback callback);
|
||||
void removeKeyCharListener(InputListener listener);
|
||||
|
||||
InputListener addMouseListener(MouseCallback callback);
|
||||
void removeMouseListener(InputListener listener);
|
||||
|
||||
@ -58,4 +63,8 @@ GLFWKeyState getKeyState(KeyBinding mapping);
|
||||
void setCursorMode(GLFWCursorMode mode);
|
||||
GLFWCursorMode getCursorMode();
|
||||
|
||||
KeyboardCapture captureKeyboardInput(KeyCharCallback callback, Callable uncaptureCallback);
|
||||
bool uncaptureKeyboardInput(KeyboardCapture capture);
|
||||
bool isKeyboardCaptured();
|
||||
|
||||
}
|
||||
|
@ -13,9 +13,16 @@
|
||||
|
||||
namespace kek {
|
||||
|
||||
struct ActiveKeyboardCapture {
|
||||
KeyboardCapture id = KEK_INVALID_ID;
|
||||
KeyCharCallback callback;
|
||||
Callable uncaptureCallback;
|
||||
};
|
||||
|
||||
struct KekData {
|
||||
std::map<InputListener, PeriodicCallback> periodicCallbacks;
|
||||
std::map<InputListener, KeyCallback> keyCallbacks;
|
||||
std::map<InputListener, KeyCharCallback> keyCharCallbacks;
|
||||
std::map<InputListener, MouseCallback> mouseCallbacks;
|
||||
std::map<InputListener, MouseButtonCallback> mouseButtonCallbacks;
|
||||
std::map<KeyBinding, KeyBindingData> keyBindings;
|
||||
@ -39,6 +46,7 @@ struct KekData {
|
||||
Font *uiDefaultFont;
|
||||
Shader *uiRectangleShader;
|
||||
GLFWCursorMode uiCursorMode;
|
||||
ActiveKeyboardCapture activeKeyboardCapture;
|
||||
};
|
||||
|
||||
extern KekData kekData;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "scene.h"
|
||||
#include "shader.h"
|
||||
#include "types.h"
|
||||
#include "utils.h"
|
||||
#include "ui.h"
|
||||
#include "unicode.h"
|
||||
#include "uielements.h"
|
||||
#include "utils.h"
|
||||
|
@ -51,6 +51,8 @@ public:
|
||||
|
||||
void setText(std::string text);
|
||||
|
||||
std::string getText();
|
||||
|
||||
virtual void draw(UIPoint screenPos, glm::mat4 projection);
|
||||
|
||||
};
|
||||
|
10
src/kekengine/include/unicode.h
Normal file
10
src/kekengine/include/unicode.h
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <codecvt>
|
||||
|
||||
namespace kek::Unicode {
|
||||
|
||||
std::u32string convertStdToU32(std::string string);
|
||||
std::string convertU32ToStd(std::u32string string);
|
||||
|
||||
}
|
@ -6,6 +6,8 @@
|
||||
|
||||
using namespace kek;
|
||||
|
||||
static ButtonElement *button;
|
||||
|
||||
void periodicCallback(GLFWwindow *window, void *data){
|
||||
|
||||
}
|
||||
@ -19,7 +21,11 @@ void mouseButtonCallback(GLFWwindow *window, int button, int action, int mods, v
|
||||
}
|
||||
|
||||
void onButtonClick(void *data) {
|
||||
std::cout << "Clicked!" << std::endl;
|
||||
Input::captureKeyboardInput(KeyCharCallback([](GLFWwindow *window, unsigned int codepoint, void *data) {
|
||||
std::u32string str = Unicode::convertStdToU32(button->text->getText());
|
||||
str.push_back(codepoint);
|
||||
button->text->setText(Unicode::convertU32ToStd(str));
|
||||
}, nullptr), Callable());
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
@ -58,13 +64,13 @@ int main(int argc, char **argv) {
|
||||
Input::addKeyListener(KeyCallback(keyCallback, nullptr));
|
||||
Input::addMouseButtonListener(MouseButtonCallback(mouseButtonCallback, nullptr));
|
||||
|
||||
ButtonElement *btn = new ButtonElement(px(10), px(100), px(200), px(50));
|
||||
btn->text->color = Colors::BLACK;
|
||||
btn->color = Colors::WHITE;
|
||||
btn->hoverColor = Colors::GRAY;
|
||||
btn->text->setText("Hello There!");
|
||||
btn->onClick = Callable(onButtonClick, nullptr);
|
||||
UI::addElement(btn);
|
||||
button = new ButtonElement(px(10), px(100), px(200), px(50));
|
||||
button->text->color = Colors::BLACK;
|
||||
button->color = Colors::WHITE;
|
||||
button->hoverColor = Colors::GRAY;
|
||||
button->text->setText("Hello There!");
|
||||
button->onClick = Callable(onButtonClick, nullptr);
|
||||
UI::addElement(button);
|
||||
|
||||
Engine::start();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user