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