Update UI, more fonts & configs, Use C++20
This commit is contained in:
parent
f9041ffc28
commit
3b03637cd4
29
.clang-format
Normal file
29
.clang-format
Normal file
@ -0,0 +1,29 @@
|
||||
Language: Cpp
|
||||
BasedOnStyle: LLVM
|
||||
IndentWidth: 4
|
||||
UseTab: Always
|
||||
TabWidth: 4
|
||||
ColumnLimit: 0
|
||||
IndentCaseLabels: true
|
||||
AllowShortIfStatementsOnASingleLine: true
|
||||
FixNamespaceComments: false
|
||||
SpaceBeforeParens: Never
|
||||
SpaceAfterCStyleCast: true
|
||||
SeparateDefinitionBlocks: Always
|
||||
PackConstructorInitializers: Never
|
||||
IncludeBlocks: Preserve
|
||||
SpaceBeforeInheritanceColon: false
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignTrailingComments: false
|
||||
AlignOperands: false
|
||||
AlignEscapedNewlines: false
|
||||
AlignConsecutiveMacros: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
SpaceBeforeCtorInitializerColon: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
AllowShortLoopsOnASingleLine: true
|
||||
AlignAfterOpenBracket: DontAlign
|
||||
LambdaBodyIndentation: Signature
|
||||
LineEnding: LF
|
||||
ContinuationIndentWidth: 4
|
@ -37,9 +37,9 @@ file(GLOB_RECURSE KEKGAME_RELATIVE_RESOURCE_FILES RELATIVE ${KEKGAME_RESOURCE_DI
|
||||
add_compile_definitions(FT_CONFIG_OPTION_ERROR_STRINGS) # Freetype error strings
|
||||
|
||||
if(${KEKENGINE_DEBUG})
|
||||
add_compile_options(-Wall -g)
|
||||
add_compile_options(-Wall -std=c++20 -g)
|
||||
else()
|
||||
add_compile_options(-Wall -O3)
|
||||
add_compile_options(-Wall -std=c++20 -O3)
|
||||
endif()
|
||||
|
||||
block()
|
||||
|
@ -20,10 +20,7 @@ static KeyBinding
|
||||
|
||||
static ButtonElement *options;
|
||||
|
||||
static void defaultInput(GLFWwindow *window, void *data) {
|
||||
if(Input::isKeyboardCaptured()) return;
|
||||
|
||||
// TODO: move input handling to controller class, add NoclipController
|
||||
static void defaultPeriodic(PeriodicEvent event, void *data) {
|
||||
kekData.player->controller->update();
|
||||
}
|
||||
|
||||
@ -55,6 +52,7 @@ static void doUIMouseHover(double x, double y) {
|
||||
|
||||
static void doUIMouseClick(double x, double y, GLFWMouseButton button) {
|
||||
UIElement *clickedElement = nullptr;
|
||||
UIElement *focusedElement = nullptr;
|
||||
|
||||
for(UIElement *element : kekData.ui->elements) {
|
||||
UIPoint childPos = element->getPosition();
|
||||
@ -63,34 +61,41 @@ static void doUIMouseClick(double x, double y, GLFWMouseButton button) {
|
||||
UIBounds bounds = element->getBounds();
|
||||
if(!bounds.contains(clickedAt)) continue;
|
||||
|
||||
clickedElement = element;
|
||||
if(element->clickable) clickedElement = element;
|
||||
if(element->focusable) focusedElement = element;
|
||||
}
|
||||
|
||||
if(clickedElement) {
|
||||
/*if(clickedElement != kekData.ui->focusedElement) { // TODO: check for focusable on children etc
|
||||
if(kekData.ui->focusedElement != nullptr) {
|
||||
kekData.ui->focusedElement->focusExit();
|
||||
}
|
||||
|
||||
clickedElement->focusEnter();
|
||||
}*/
|
||||
|
||||
UIPoint childPos = clickedElement->getPosition();
|
||||
UIPoint clickedAt = UIPoint((int) x - childPos.x, (int) y - childPos.y);
|
||||
clickedElement->clickAll(clickedAt, UIPoint((int) x, (int) y), button);
|
||||
}
|
||||
|
||||
if(button == GLFWMouseButton::LEFT && focusedElement != kekData.ui->focusedElement) {
|
||||
if(kekData.ui->focusedElement != nullptr) {
|
||||
kekData.ui->focusedElement->focusExit();
|
||||
}
|
||||
|
||||
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(focusedElement) {
|
||||
UIPoint childPos = focusedElement->getPosition();
|
||||
UIPoint clickedAt = UIPoint((int) x - childPos.x, (int) y - childPos.y);
|
||||
focusedElement->focusEnterAll(clickedAt, UIPoint((int) x, (int) y));
|
||||
}
|
||||
|
||||
if(key == Input::getKeyBinding(keyOptions).key && action == GLFW_PRESS) {
|
||||
kekData.ui->focusedElement = focusedElement;
|
||||
}
|
||||
}
|
||||
|
||||
static void defaultKeyCallback(KeyEvent event, void *data) {
|
||||
if(event.key == Input::getKeyBinding(keyExit).key && event.action == GLFW_PRESS) {
|
||||
glfwSetWindowShouldClose(event.window, true);
|
||||
}
|
||||
|
||||
if(event.key == Input::getKeyBinding(keyOptions).key && event.action == GLFW_PRESS) {
|
||||
options->visible = !options->visible;
|
||||
}
|
||||
|
||||
if(key == Input::getKeyBinding(keyToggleCursorMode).key && action == GLFW_PRESS) {
|
||||
if(event.key == Input::getKeyBinding(keyToggleCursorMode).key && event.action == GLFW_PRESS) {
|
||||
if(Input::getCursorMode() == GLFWCursorMode::CAPTURE) {
|
||||
Input::setCursorMode(GLFWCursorMode::FREE);
|
||||
double x, y;
|
||||
@ -105,7 +110,7 @@ static void defaultKeyCallback(GLFWwindow *window, int key, int scancode, int ac
|
||||
}
|
||||
}
|
||||
|
||||
if(key == Input::getKeyBinding(keyToggleNoclip).key && action == GLFW_PRESS) {
|
||||
if(event.key == Input::getKeyBinding(keyToggleNoclip).key && event.action == GLFW_PRESS) {
|
||||
kekData.player->noclip = !kekData.player->noclip;
|
||||
kekData.player->controller = kekData.player->noclip ? (PlayerController *) noclipController : (PlayerController *) defaultController;
|
||||
if(kekData.player->noclip) {
|
||||
@ -116,19 +121,19 @@ static void defaultKeyCallback(GLFWwindow *window, int key, int scancode, int ac
|
||||
}
|
||||
}
|
||||
|
||||
static void defaultMouseCallback(GLFWwindow *window, double x, double y, void *data) {
|
||||
static void defaultMouseCallback(MouseEvent event, void *data) {
|
||||
static bool firstMouse = true;
|
||||
static double lastX = 0, lastY = 0;
|
||||
if(firstMouse) {
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
lastX = event.x;
|
||||
lastY = event.y;
|
||||
firstMouse = false;
|
||||
}
|
||||
|
||||
switch(Input::getCursorMode()) {
|
||||
case GLFWCursorMode::CAPTURE: {
|
||||
float xoff = lastX - x;
|
||||
float yoff = lastY - y;
|
||||
float xoff = lastX - event.x;
|
||||
float yoff = lastY - event.y;
|
||||
|
||||
xoff *= 0.1f;
|
||||
yoff *= 0.1f;
|
||||
@ -139,16 +144,16 @@ static void defaultMouseCallback(GLFWwindow *window, double x, double y, void *d
|
||||
}
|
||||
case GLFWCursorMode::FREE:
|
||||
case GLFWCursorMode::HIDDEN: {
|
||||
doUIMouseHover(x, y);
|
||||
doUIMouseHover(event.x, event.y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
lastX = event.x;
|
||||
lastY = event.y;
|
||||
}
|
||||
|
||||
static void defaultMouseButtonCallback(GLFWwindow *window, int button, int action, int mods, void *data) {
|
||||
static void defaultMouseButtonCallback(MouseButtonEvent event, void *data) {
|
||||
switch(Input::getCursorMode()) {
|
||||
case GLFWCursorMode::CAPTURE: {
|
||||
// TODO
|
||||
@ -156,13 +161,13 @@ static void defaultMouseButtonCallback(GLFWwindow *window, int button, int actio
|
||||
}
|
||||
case GLFWCursorMode::FREE:
|
||||
case GLFWCursorMode::HIDDEN: {
|
||||
switch(action) {
|
||||
switch(event.action) {
|
||||
case GLFW_PRESS:
|
||||
break;
|
||||
case GLFW_RELEASE: {
|
||||
double x, y;
|
||||
glfwGetCursorPos(window, &x, &y);
|
||||
doUIMouseClick(x, y, (GLFWMouseButton) button);
|
||||
glfwGetCursorPos(event.window, &x, &y);
|
||||
doUIMouseClick(x, y, (GLFWMouseButton) event.button);
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,7 +190,7 @@ void init() {
|
||||
keyToggleNoclip = Input::createKeyBinding("Toggle Noclip", GLFW_KEY_N);
|
||||
keyExit = Input::createKeyBinding("Exit", GLFW_KEY_ESCAPE);
|
||||
|
||||
Input::addPeriodicCallback(PeriodicCallback(defaultInput, nullptr));
|
||||
Input::addPeriodicCallback(PeriodicCallback(defaultPeriodic, nullptr));
|
||||
Input::addKeyListener(KeyCallback(defaultKeyCallback, nullptr));
|
||||
Input::addMouseListener(MouseCallback(defaultMouseCallback, nullptr));
|
||||
Input::addMouseButtonListener(MouseButtonCallback(defaultMouseButtonCallback, nullptr));
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "engine.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
@ -183,7 +184,7 @@ int start() {
|
||||
Physics::step(kekData.lastFrameTime);
|
||||
|
||||
for(auto cb : kekData.input->periodicCallbacks) {
|
||||
cb.second(kekData.window);
|
||||
cb.second(PeriodicEvent{kekData.window});
|
||||
}
|
||||
|
||||
if(kekData.activeScene) {
|
||||
|
@ -20,7 +20,7 @@ void destroy() {
|
||||
|
||||
void onCursorPosCallback(GLFWwindow *window, double x, double y) {
|
||||
for(auto cb : kekData.input->mouseCallbacks) {
|
||||
cb.second(window, x, y);
|
||||
cb.second(MouseEvent{window, x, y});
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,32 +32,32 @@ void onKeyCallback(GLFWwindow *window, int key, int scancode, int action, int mo
|
||||
}
|
||||
|
||||
if(key == GLFW_KEY_BACKSPACE && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
|
||||
kekData.input->activeKeyboardCapture.charCallback(window, KEK_INPUT_DELETE);
|
||||
kekData.input->activeKeyboardCapture.charCallback(KeyCharEvent{window, KEK_INPUT_DELETE});
|
||||
}
|
||||
|
||||
kekData.input->activeKeyboardCapture.keyCallback(window, key, scancode, action, mods);
|
||||
kekData.input->activeKeyboardCapture.keyCallback(KeyEvent{window, key, scancode, action, mods});
|
||||
return;
|
||||
}
|
||||
|
||||
for(auto cb : kekData.input->keyCallbacks) {
|
||||
cb.second(window, key, scancode, action, mods);
|
||||
cb.second(KeyEvent{window, key, scancode, action, mods});
|
||||
}
|
||||
}
|
||||
|
||||
void onKeyCharCallback(GLFWwindow *window, unsigned int codepoint) {
|
||||
if(Input::isKeyboardCaptured()) {
|
||||
kekData.input->activeKeyboardCapture.charCallback(window, codepoint);
|
||||
kekData.input->activeKeyboardCapture.charCallback(KeyCharEvent{window, codepoint});
|
||||
return;
|
||||
}
|
||||
|
||||
for(auto cb : kekData.input->keyCharCallbacks) {
|
||||
cb.second(window, codepoint);
|
||||
cb.second(KeyCharEvent{window, codepoint});
|
||||
}
|
||||
}
|
||||
|
||||
void onMouseButtonCallback(GLFWwindow *window, int button, int action, int mods) {
|
||||
for(auto cb : kekData.input->mouseButtonCallbacks) {
|
||||
cb.second(window, button, action, mods);
|
||||
cb.second(MouseButtonEvent{window, button, action, mods});
|
||||
}
|
||||
}
|
||||
|
||||
@ -163,12 +163,13 @@ KeyboardCapture captureKeyboardInput(KeyCharCallback charCallback, KeyCallback k
|
||||
|
||||
bool uncaptureKeyboardInput(KeyboardCapture capture) {
|
||||
if(capture == KEK_INVALID_ID || capture != kekData.input->activeKeyboardCapture.id) return false;
|
||||
kekData.input->activeKeyboardCapture.uncaptureCallback();
|
||||
ActiveKeyboardCapture oldCapture = kekData.input->activeKeyboardCapture;
|
||||
kekData.input->activeKeyboardCapture = {
|
||||
KEK_INVALID_ID,
|
||||
KeyCharCallback(),
|
||||
KeyCallback(),
|
||||
Callable()};
|
||||
oldCapture.uncaptureCallback();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -176,4 +177,8 @@ bool isKeyboardCaptured() {
|
||||
return kekData.input->activeKeyboardCapture.id != KEK_INVALID_ID;
|
||||
}
|
||||
|
||||
KeyboardCapture getActiveKeyboardCapture() {
|
||||
return kekData.input->activeKeyboardCapture.id;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "defaultplayercontroller.h"
|
||||
|
||||
#include "input.h"
|
||||
#include "internal.h"
|
||||
#include "internal/physics.h"
|
||||
|
||||
@ -100,6 +101,7 @@ void DefaultPlayerController::update() {
|
||||
|
||||
glm::vec3 direction = glm::vec3(0);
|
||||
|
||||
if(!Input::isKeyboardCaptured()) {
|
||||
if(Input::getKeyState(keyForward) == GLFW_PRESS) {
|
||||
direction += kekData.activeCamera->direction;
|
||||
}
|
||||
@ -126,6 +128,7 @@ void DefaultPlayerController::update() {
|
||||
// Project movement onto ground
|
||||
direction = glm::normalize(glm::cross(groundNormal, glm::cross(direction, groundNormal)));
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 move = velocity;
|
||||
if(glm::length2(direction) > 0) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "noclipplayercontroller.h"
|
||||
|
||||
#include "input.h"
|
||||
#include "internal.h"
|
||||
|
||||
namespace kek {
|
||||
@ -16,6 +17,8 @@ glm::vec3 NoclipPlayerController::move(glm::vec3 movement) {
|
||||
}
|
||||
|
||||
void NoclipPlayerController::update() {
|
||||
if(Input::isKeyboardCaptured()) return;
|
||||
|
||||
glm::vec3 direction = glm::vec3(0);
|
||||
|
||||
if(Input::getKeyState(keyForward) == GLFW_PRESS) {
|
||||
|
@ -1,7 +1,11 @@
|
||||
#include "ui.h"
|
||||
|
||||
#include <bits/stdc++.h>
|
||||
#include <iostream>
|
||||
#include <numeric>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "input.h"
|
||||
#include "internal.h"
|
||||
#include "internal/ui.h"
|
||||
|
||||
@ -13,6 +17,7 @@ UIElement::UIElement(UIValue x, UIValue y)
|
||||
}
|
||||
|
||||
UIElement::~UIElement() {
|
||||
UI::unfocusElement(this);
|
||||
}
|
||||
|
||||
// Returns the element's position relative to its parent in pixels
|
||||
@ -50,7 +55,7 @@ void UIElement::addChild(UIElement *child) {
|
||||
|
||||
void UIElement::removeChild(UIElement *child) {
|
||||
child->parent = nullptr;
|
||||
std::remove(children.begin(), children.end(), child);
|
||||
std::erase(children, child);
|
||||
}
|
||||
|
||||
int UIElement::uiToScreen(UIValue val) {
|
||||
@ -188,9 +193,6 @@ void UIElement::clickAll(UIPoint pos, UIPoint screenPos, GLFWMouseButton button)
|
||||
}
|
||||
|
||||
bool UIElement::focusEnterAll(UIPoint pos, UIPoint screenPos) {
|
||||
UIBounds bounds = getBounds();
|
||||
if(!bounds.contains(pos)) return false;
|
||||
|
||||
UIElement *focusedChild = nullptr;
|
||||
for(UIElement *child : children) {
|
||||
UIPoint childPos = child->getPosition();
|
||||
@ -271,21 +273,26 @@ std::vector<UIElement *> UI::getElements() {
|
||||
}
|
||||
|
||||
void UI::focusElement(UIElement *element) {
|
||||
if(kekData.ui->focusedElement != element) {
|
||||
if(kekData.ui->focusedElement != nullptr) {
|
||||
unfocusElement();
|
||||
unfocusElement(kekData.ui->focusedElement);
|
||||
}
|
||||
|
||||
kekData.ui->focusedElement = element;
|
||||
if(element != nullptr) {
|
||||
element->focused = true;
|
||||
element->focusEnter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UI::unfocusElement() {
|
||||
if(kekData.ui->focusedElement == nullptr) return;
|
||||
void UI::unfocusElement(UIElement *element) {
|
||||
if(kekData.ui->focusedElement == nullptr || element != kekData.ui->focusedElement) return;
|
||||
|
||||
kekData.ui->focusedElement->focusExit();
|
||||
UIElement *oldFocus = kekData.ui->focusedElement;
|
||||
kekData.ui->focusedElement = nullptr;
|
||||
oldFocus->focused = false;
|
||||
oldFocus->focusExit();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,10 +1,15 @@
|
||||
#include "uielements.h"
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include "constants.h"
|
||||
#include "input.h"
|
||||
#include "internal.h"
|
||||
#include "internal/ui.h"
|
||||
#include "ui.h"
|
||||
#include "unicode.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace kek {
|
||||
|
||||
@ -195,17 +200,25 @@ TextFieldElement::TextFieldElement(UIValue x, UIValue y, UIValue w, Font *font)
|
||||
this->enableClipping = true;
|
||||
this->focusable = true;
|
||||
this->color = Colors::WHITE;
|
||||
this->text = "Hello World";
|
||||
this->focusColor = Colors::GRAY;
|
||||
this->text = "";
|
||||
|
||||
RectangleElement::color = color;
|
||||
|
||||
this->textElement = new TextElement(uiPx(0), uiPx(0));
|
||||
textElement->textBounds = TextBounds::LINE;
|
||||
textElement->color = Colors::RED;
|
||||
textElement->color = Colors::BLACK;
|
||||
textElement->setText(text);
|
||||
addChild(textElement);
|
||||
|
||||
int textH = textElement->getBounds().h;
|
||||
std::cout << "TEXTH" << textH << std::endl;
|
||||
h = uiPx(textH);
|
||||
|
||||
this->cursor = new RectangleElement(uiPx(0), uiPx(2), uiPx(1), uiPx(textH - 4));
|
||||
cursor->color = Colors::BLACK;
|
||||
addChild(cursor);
|
||||
|
||||
this->capture = KEK_INVALID_ID;
|
||||
}
|
||||
|
||||
TextFieldElement::TextFieldElement(UIValue x, UIValue y, UIValue w)
|
||||
@ -213,15 +226,72 @@ TextFieldElement::TextFieldElement(UIValue x, UIValue y, UIValue w)
|
||||
}
|
||||
|
||||
TextFieldElement::~TextFieldElement() {
|
||||
Input::uncaptureKeyboardInput(capture);
|
||||
capture = KEK_INVALID_ID;
|
||||
|
||||
delete textElement;
|
||||
delete cursor;
|
||||
}
|
||||
|
||||
UIElementType TextFieldElement::getType() {
|
||||
return UIElementType::TEXT_FIELD;
|
||||
}
|
||||
|
||||
void TextFieldElement::focusEnter() {
|
||||
RectangleElement::color = focusColor;
|
||||
cursor->visible = true;
|
||||
|
||||
capture = Input::captureKeyboardInput(
|
||||
KeyCharCallback([](KeyCharEvent event, void *data) {
|
||||
TextFieldElement *_this = (TextFieldElement *) data;
|
||||
|
||||
std::u32string str = Unicode::convertStdToU32(_this->text);
|
||||
if(event.codepoint == KEK_INPUT_DELETE) {
|
||||
if(str.length() == 0) return;
|
||||
str = str.substr(0, str.length() - 1);
|
||||
} else {
|
||||
str.push_back(event.codepoint);
|
||||
}
|
||||
|
||||
_this->text = Unicode::convertU32ToStd(str);
|
||||
_this->textElement->setText(_this->text);
|
||||
|
||||
_this->lastCharTyped = glfwGetTime();
|
||||
_this->cursor->x = uiPx(_this->textElement->getBounds().w);
|
||||
},
|
||||
this),
|
||||
KeyCallback([](KeyEvent event, void *data) {
|
||||
TextFieldElement *_this = (TextFieldElement *) data;
|
||||
if(event.key == GLFW_KEY_ENTER && event.action == GLFW_PRESS) {
|
||||
Input::uncaptureKeyboardInput(_this->capture);
|
||||
}
|
||||
},
|
||||
this),
|
||||
Callable([](void *data) {
|
||||
TextFieldElement *_this = (TextFieldElement *) data;
|
||||
UI::unfocusElement(_this);
|
||||
},
|
||||
this));
|
||||
}
|
||||
|
||||
void TextFieldElement::focusExit() {
|
||||
RectangleElement::color = color;
|
||||
cursor->visible = false;
|
||||
|
||||
Input::uncaptureKeyboardInput(capture);
|
||||
capture = KEK_INVALID_ID;
|
||||
}
|
||||
|
||||
void TextFieldElement::draw(UIPoint screenPos, glm::mat4 projection) {
|
||||
RectangleElement::draw(screenPos, projection);
|
||||
|
||||
double time = glfwGetTime();
|
||||
cursor->visible = focused ? (time - lastCharTyped < 0.5 || (int) time % 2 == 0) : false;
|
||||
}
|
||||
|
||||
void TextFieldElement::setText(std::string text) {
|
||||
this->text = text;
|
||||
this->textElement->setText(text);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -28,6 +28,10 @@ struct Color {
|
||||
constexpr Color brighter(float factor = 0.7) const {
|
||||
return Color(r / factor, g / factor, b / factor, a);
|
||||
}
|
||||
|
||||
constexpr bool operator==(const Color &other) {
|
||||
return r == other.r && g == other.g && b == other.g;
|
||||
}
|
||||
};
|
||||
|
||||
class Colors {
|
||||
|
@ -38,7 +38,7 @@
|
||||
#define KEK_FONT_BITMAP_CHAR_MASK 0xFF // = KEK_FONT_BITMAP_CHAR_BITS 1s in binary
|
||||
#define KEK_TEXT_BLOCK_SIZE 8
|
||||
|
||||
#define KEK_DEFAULT_FONT "font/MaredivRegular-yeg3.ttf"
|
||||
#define KEK_DEFAULT_FONT "font/JupiteroidRegular.ttf"
|
||||
#define KEK_DEFAULT_FONT_SIZE_PIXELS 24
|
||||
|
||||
#define KEK_INPUT_DELETE -1u
|
||||
|
@ -7,11 +7,41 @@
|
||||
|
||||
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)
|
||||
typedef struct {
|
||||
GLFWwindow *window;
|
||||
} PeriodicEvent;
|
||||
|
||||
typedef struct {
|
||||
GLFWwindow *window;
|
||||
int key;
|
||||
int scancode;
|
||||
int action;
|
||||
int mods;
|
||||
} KeyEvent;
|
||||
|
||||
typedef struct {
|
||||
GLFWwindow *window;
|
||||
unsigned int codepoint;
|
||||
} KeyCharEvent;
|
||||
|
||||
typedef struct {
|
||||
GLFWwindow *window;
|
||||
double x;
|
||||
double y;
|
||||
} MouseEvent;
|
||||
|
||||
typedef struct {
|
||||
GLFWwindow *window;
|
||||
int button;
|
||||
int action;
|
||||
int mods;
|
||||
} MouseButtonEvent;
|
||||
|
||||
typedef GenericCallable<PeriodicEvent> PeriodicCallback; // periodicCallback(GLFWwindow *window)
|
||||
typedef GenericCallable<KeyEvent> KeyCallback; // keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
|
||||
typedef GenericCallable<KeyCharEvent> KeyCharCallback; // keyCharCallback(GLFWwindow *window, unsigned int codepoint)
|
||||
typedef GenericCallable<MouseEvent> MouseCallback; // mouseCallback(GLFWwindow *window, double x, double y)
|
||||
typedef GenericCallable<MouseButtonEvent> MouseButtonCallback; // void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods)
|
||||
|
||||
typedef unsigned int InputListener;
|
||||
typedef int GLFWKey;
|
||||
@ -69,5 +99,6 @@ GLFWCursorMode getCursorMode();
|
||||
KeyboardCapture captureKeyboardInput(KeyCharCallback charCallback, KeyCallback keyCallback, Callable uncaptureCallback);
|
||||
bool uncaptureKeyboardInput(KeyboardCapture capture);
|
||||
bool isKeyboardCaptured();
|
||||
KeyboardCapture getActiveKeyboardCapture();
|
||||
|
||||
}
|
||||
|
@ -136,11 +136,13 @@ class UIElement {
|
||||
bool enableClipping = false;
|
||||
|
||||
bool clickable = false;
|
||||
bool hovering = false;
|
||||
bool visible = true;
|
||||
bool focusable = false;
|
||||
bool draggable = false;
|
||||
|
||||
bool hovering = false;
|
||||
bool focused = false;
|
||||
|
||||
UIElement(UIValue x, UIValue y);
|
||||
|
||||
virtual ~UIElement();
|
||||
@ -202,7 +204,7 @@ void addElement(UIElement *element);
|
||||
void removeElement(UIElement *element);
|
||||
|
||||
void focusElement(UIElement *element);
|
||||
void unfocusElement();
|
||||
void unfocusElement(UIElement *element);
|
||||
|
||||
};
|
||||
|
||||
|
@ -101,7 +101,14 @@ class TextFieldElement: public RectangleElement {
|
||||
|
||||
protected:
|
||||
std::string text;
|
||||
Color color;
|
||||
Color focusColor;
|
||||
|
||||
TextElement *textElement;
|
||||
RectangleElement *cursor;
|
||||
|
||||
KeyboardCapture capture;
|
||||
float lastCharTyped = 0;
|
||||
|
||||
public:
|
||||
TextFieldElement(UIValue x, UIValue y, UIValue w, Font *font);
|
||||
@ -112,7 +119,12 @@ class TextFieldElement: public RectangleElement {
|
||||
|
||||
virtual UIElementType getType();
|
||||
|
||||
virtual void focusEnter();
|
||||
virtual void focusExit();
|
||||
|
||||
virtual void draw(UIPoint screenPos, glm::mat4 projection);
|
||||
|
||||
void setText(std::string text);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -20,9 +20,8 @@ struct GenericCallable {
|
||||
: function(nullptr),
|
||||
data(nullptr) {}
|
||||
|
||||
GenericCallable(GenericFunction<Args..., void *> function)
|
||||
: function(function),
|
||||
data(nullptr){};
|
||||
GenericCallable(GenericFunction<Args...> function)
|
||||
: GenericCallable([](void *f) { ((GenericFunction<Args...>) f)(); }, (void *) function) {}
|
||||
|
||||
GenericCallable(GenericFunction<Args..., void *> function, void *data)
|
||||
: function(function),
|
||||
|
BIN
src/kekengine/res/font/JupiteroidBold.ttf
Normal file
BIN
src/kekengine/res/font/JupiteroidBold.ttf
Normal file
Binary file not shown.
BIN
src/kekengine/res/font/JupiteroidBoldItalic.ttf
Normal file
BIN
src/kekengine/res/font/JupiteroidBoldItalic.ttf
Normal file
Binary file not shown.
BIN
src/kekengine/res/font/JupiteroidItalic.ttf
Normal file
BIN
src/kekengine/res/font/JupiteroidItalic.ttf
Normal file
Binary file not shown.
BIN
src/kekengine/res/font/JupiteroidLight.ttf
Normal file
BIN
src/kekengine/res/font/JupiteroidLight.ttf
Normal file
Binary file not shown.
BIN
src/kekengine/res/font/JupiteroidLightItalic.ttf
Normal file
BIN
src/kekengine/res/font/JupiteroidLightItalic.ttf
Normal file
Binary file not shown.
BIN
src/kekengine/res/font/JupiteroidRegular.ttf
Normal file
BIN
src/kekengine/res/font/JupiteroidRegular.ttf
Normal file
Binary file not shown.
@ -1,5 +1,6 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "input.h"
|
||||
#include "kekengine.h"
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
@ -16,42 +17,24 @@
|
||||
using namespace kek;
|
||||
|
||||
static ButtonElement *button;
|
||||
static KeyboardCapture capture = KEK_INVALID_ID;
|
||||
|
||||
void periodicCallback(GLFWwindow *window, void *data) {
|
||||
void periodicCallback(PeriodicEvent event, void *data) {
|
||||
}
|
||||
|
||||
void keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods, void *data) {
|
||||
void keyCallback(KeyEvent event, void *data) {
|
||||
}
|
||||
|
||||
void mouseButtonCallback(GLFWwindow *window, int button, int action, int mods, void *data) {
|
||||
void mouseButtonCallback(MouseButtonEvent event, void *data) {
|
||||
}
|
||||
|
||||
void onButtonClick(void *data) {
|
||||
button->color = Colors::RED;
|
||||
button->hoverColor = Colors::ORANGE;
|
||||
capture = Input::captureKeyboardInput(
|
||||
KeyCharCallback([](GLFWwindow *window, unsigned int codepoint, void *data) {
|
||||
std::u32string str = Unicode::convertStdToU32(button->text->getText());
|
||||
if(codepoint == KEK_INPUT_DELETE) {
|
||||
str = str.substr(0, str.length() - 1);
|
||||
if(button->color == Colors::RED) {
|
||||
button->color = Colors::GREEN;
|
||||
button->hoverColor = Colors::GREEN.darker();
|
||||
} else {
|
||||
str.push_back(codepoint);
|
||||
button->color = Colors::RED;
|
||||
button->hoverColor = Colors::RED.darker();
|
||||
}
|
||||
button->text->setText(Unicode::convertU32ToStd(str));
|
||||
},
|
||||
nullptr),
|
||||
KeyCallback([](GLFWwindow *window, int key, int scancode, int action, int mods, void *data) {
|
||||
if(key == GLFW_KEY_ENTER && action == GLFW_PRESS) {
|
||||
Input::uncaptureKeyboardInput(capture);
|
||||
}
|
||||
},
|
||||
nullptr),
|
||||
Callable([](void *data) {
|
||||
button->color = Colors::WHITE;
|
||||
button->hoverColor = Colors::GRAY;
|
||||
},
|
||||
nullptr));
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
@ -142,7 +125,7 @@ int main(int argc, char **argv) {
|
||||
button3->addChild(rect);
|
||||
UI::addElement(button3);
|
||||
|
||||
TextFieldElement *textField = new TextFieldElement(uiPx(10), uiPx(200), uiPx(50));
|
||||
TextFieldElement *textField = new TextFieldElement(uiPx(10), uiPx(200), uiPx(500));
|
||||
UI::addElement(textField);
|
||||
|
||||
if(Engine::start() != KEK_SUCCESS) return 1;
|
||||
|
Loading…
Reference in New Issue
Block a user