Refactor UI code
This commit is contained in:
parent
26b532c926
commit
d9cfcba0ba
@ -1,11 +1,15 @@
|
||||
#include "constants.h"
|
||||
#include "defaultplayercontroller.h"
|
||||
#include "input.h"
|
||||
#include "internal.h"
|
||||
#include "internal/input.h"
|
||||
#include "internal/physics.h"
|
||||
#include "internal/ui.h"
|
||||
#include "noclipplayercontroller.h"
|
||||
#include "types.h"
|
||||
#include "ui.h"
|
||||
#include "uielements.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
namespace kek::Defaults {
|
||||
|
||||
@ -25,17 +29,10 @@ static void defaultPeriodic(PeriodicEvent event, void *data) {
|
||||
}
|
||||
|
||||
static void doUIMouseHover(double x, double y) {
|
||||
UIElement *hoveredElement = nullptr;
|
||||
if(Input::getMouseButtonState(GLFWMouseButton::LEFT) == GLFWMouseButtonState::PRESSED) return;
|
||||
|
||||
for(UIElement *element : kekData.ui->elements) {
|
||||
UIPoint childPos = element->getPosition();
|
||||
UIPoint hoveredAt = UIPoint((int) x - childPos.x, (int) y - childPos.y);
|
||||
|
||||
UIBounds bounds = element->getBounds();
|
||||
if(!bounds.containsOffset(hoveredAt)) continue;
|
||||
|
||||
hoveredElement = element;
|
||||
}
|
||||
IntPoint2 mousePosition = IntPoint2((int) x, (int) y);
|
||||
UIElement *hoveredElement = UI::findElementAt(mousePosition);
|
||||
|
||||
for(UIElement *element : kekData.ui->elements) {
|
||||
if(element->hovering && element != hoveredElement) {
|
||||
@ -44,36 +41,54 @@ static void doUIMouseHover(double x, double y) {
|
||||
}
|
||||
|
||||
if(hoveredElement) {
|
||||
UIPoint childPos = hoveredElement->getPosition();
|
||||
UIPoint hoveredAt = UIPoint((int) x - childPos.x, (int) y - childPos.y);
|
||||
hoveredElement->hoverAll(hoveredAt, UIPoint((int) x, (int) y));
|
||||
IntPoint2 childPos = hoveredElement->getPosition();
|
||||
hoveredElement->hoverAll(mousePosition - childPos, mousePosition);
|
||||
}
|
||||
}
|
||||
|
||||
static void doUIMouseDrag(double x, double y) {
|
||||
if(Input::getMouseButtonState(GLFWMouseButton::LEFT) != GLFWMouseButtonState::PRESSED) {
|
||||
kekData.input->mouseDown = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!kekData.input->mouseDown) {
|
||||
kekData.input->mouseDownPosition = IntPoint2((int) x, (int) y);
|
||||
}
|
||||
|
||||
int deltaX = (int) x - kekData.input->mouseDownPosition.x;
|
||||
int deltaY = (int) y - kekData.input->mouseDownPosition.y;
|
||||
if(deltaX * deltaX + deltaY * deltaY >= KEK_UI_MIN_DRAG_DISTANCE_SQUARED) {
|
||||
// Initiate drag
|
||||
IntPoint2 mousePosition = IntPoint2((int) x, (int) y);
|
||||
UIElement *draggedElement = UI::findElementAt(mousePosition);
|
||||
|
||||
if(draggedElement) {
|
||||
IntPoint2 childPos = draggedElement->getPosition();
|
||||
draggedElement->dragEnterAll(mousePosition - childPos, mousePosition);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: drag dragged element, exit drag
|
||||
|
||||
kekData.input->mouseDown = true;
|
||||
}
|
||||
|
||||
static void doUIMouseClick(double x, double y, GLFWMouseButton button) {
|
||||
UIElement *clickedElement = nullptr;
|
||||
|
||||
for(UIElement *element : kekData.ui->elements) {
|
||||
UIPoint childPos = element->getPosition();
|
||||
UIPoint clickedAt = UIPoint((int) x - childPos.x, (int) y - childPos.y);
|
||||
|
||||
UIBounds bounds = element->getBounds();
|
||||
if(!bounds.containsOffset(clickedAt)) continue;
|
||||
|
||||
clickedElement = element;
|
||||
}
|
||||
IntPoint2 mousePosition = IntPoint2((int) x, (int) y);
|
||||
UIElement *clickedElement = UI::findElementAt(mousePosition);
|
||||
|
||||
if(clickedElement) {
|
||||
UIPoint childPos = clickedElement->getPosition();
|
||||
UIPoint clickedAt = UIPoint((int) x - childPos.x, (int) y - childPos.y);
|
||||
IntPoint2 childPos = clickedElement->getPosition();
|
||||
IntPoint2 clickedAt = mousePosition - childPos;
|
||||
|
||||
if(button == GLFWMouseButton::LEFT) {
|
||||
if(!clickedElement->focusEnterAll(clickedAt, UIPoint((int) x, (int) y))) {
|
||||
if(!clickedElement->focusEnterAll(clickedAt, IntPoint2((int) x, (int) y))) {
|
||||
UI::unfocusElement(kekData.ui->focusedElement);
|
||||
}
|
||||
}
|
||||
|
||||
clickedElement->clickAll(clickedAt, UIPoint((int) x, (int) y), button);
|
||||
clickedElement->clickAll(clickedAt, IntPoint2((int) x, (int) y), button);
|
||||
} else {
|
||||
UI::unfocusElement(kekData.ui->focusedElement);
|
||||
}
|
||||
@ -94,6 +109,7 @@ static void defaultKeyCallback(KeyEvent event, void *data) {
|
||||
double x, y;
|
||||
glfwGetCursorPos(kekData.window, &x, &y);
|
||||
doUIMouseHover(x, y);
|
||||
doUIMouseDrag(x, y);
|
||||
} else {
|
||||
Input::setCursorMode(GLFWCursorMode::CAPTURE);
|
||||
|
||||
@ -138,6 +154,7 @@ static void defaultMouseCallback(MouseEvent event, void *data) {
|
||||
case GLFWCursorMode::FREE:
|
||||
case GLFWCursorMode::HIDDEN: {
|
||||
doUIMouseHover(event.x, event.y);
|
||||
doUIMouseDrag(event.x, event.y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -301,7 +301,7 @@ int start() {
|
||||
prevTime = time;
|
||||
|
||||
for(UIElement *uiEl : kekData.ui->elements) {
|
||||
UIPoint pos = uiEl->getScreenPosition();
|
||||
IntPoint2 pos = uiEl->getScreenPosition();
|
||||
uiEl->drawAll(pos, uiProjection);
|
||||
}
|
||||
|
||||
|
@ -147,8 +147,12 @@ KeyBindingData getKeyBinding(KeyBinding binding) {
|
||||
|
||||
GLFWKeyState getKeyState(KeyBinding binding) {
|
||||
auto it = kekData.input->keyBindings.find(binding);
|
||||
if(it == kekData.input->keyBindings.end()) return -1;
|
||||
return glfwGetKey(kekData.window, it->second.key);
|
||||
if(it == kekData.input->keyBindings.end()) return GLFWKeyState::ERROR_INVALID_KEY_BINDING;
|
||||
return (GLFWKeyState) glfwGetKey(kekData.window, it->second.key);
|
||||
}
|
||||
|
||||
GLFWMouseButtonState getMouseButtonState(GLFWMouseButton mouseButton) {
|
||||
return (GLFWMouseButtonState) glfwGetMouseButton(kekData.window, (int) mouseButton);
|
||||
}
|
||||
|
||||
void setCursorMode(GLFWCursorMode mode) {
|
||||
|
@ -105,23 +105,23 @@ void DefaultPlayerController::update() {
|
||||
glm::vec3 direction = glm::vec3(0);
|
||||
|
||||
if(!Input::isKeyboardCaptured()) {
|
||||
if(Input::getKeyState(keyForward) == GLFW_PRESS) {
|
||||
if(Input::getKeyState(keyForward) == GLFWKeyState::PRESSED) {
|
||||
direction += kekData.activeCamera->direction;
|
||||
}
|
||||
|
||||
if(Input::getKeyState(keyBackward) == GLFW_PRESS) {
|
||||
if(Input::getKeyState(keyBackward) == GLFWKeyState::PRESSED) {
|
||||
direction += -kekData.activeCamera->direction;
|
||||
}
|
||||
|
||||
if(Input::getKeyState(keyLeft) == GLFW_PRESS) {
|
||||
if(Input::getKeyState(keyLeft) == GLFWKeyState::PRESSED) {
|
||||
direction += -glm::normalize(glm::cross(kekData.activeCamera->direction, glm::vec3(0.0f, 1.0f, 0.0f)));
|
||||
}
|
||||
|
||||
if(Input::getKeyState(keyRight) == GLFW_PRESS) {
|
||||
if(Input::getKeyState(keyRight) == GLFWKeyState::PRESSED) {
|
||||
direction += glm::normalize(glm::cross(kekData.activeCamera->direction, glm::vec3(0.0f, 1.0f, 0.0f)));
|
||||
}
|
||||
|
||||
if(Input::getKeyState(keyJump) == GLFW_PRESS && kekData.player->onGround) {
|
||||
if(Input::getKeyState(keyJump) == GLFWKeyState::PRESSED && kekData.player->onGround) {
|
||||
velocity += glm::vec3(0, jumpVelocity, 0);
|
||||
}
|
||||
|
||||
|
@ -21,27 +21,27 @@ void NoclipPlayerController::update() {
|
||||
|
||||
glm::vec3 direction = glm::vec3(0);
|
||||
|
||||
if(Input::getKeyState(keyForward) == GLFW_PRESS) {
|
||||
if(Input::getKeyState(keyForward) == GLFWKeyState::PRESSED) {
|
||||
direction += kekData.activeCamera->direction;
|
||||
}
|
||||
|
||||
if(Input::getKeyState(keyBackward) == GLFW_PRESS) {
|
||||
if(Input::getKeyState(keyBackward) == GLFWKeyState::PRESSED) {
|
||||
direction += -kekData.activeCamera->direction;
|
||||
}
|
||||
|
||||
if(Input::getKeyState(keyLeft) == GLFW_PRESS) {
|
||||
if(Input::getKeyState(keyLeft) == GLFWKeyState::PRESSED) {
|
||||
direction += -glm::normalize(glm::cross(kekData.activeCamera->direction, glm::vec3(0.0f, 1.0f, 0.0f)));
|
||||
}
|
||||
|
||||
if(Input::getKeyState(keyRight) == GLFW_PRESS) {
|
||||
if(Input::getKeyState(keyRight) == GLFWKeyState::PRESSED) {
|
||||
direction += glm::normalize(glm::cross(kekData.activeCamera->direction, glm::vec3(0.0f, 1.0f, 0.0f)));
|
||||
}
|
||||
|
||||
if(Input::getKeyState(keyUp) == GLFW_PRESS) {
|
||||
if(Input::getKeyState(keyUp) == GLFWKeyState::PRESSED) {
|
||||
direction += glm::vec3(0, 1, 0);
|
||||
}
|
||||
|
||||
if(Input::getKeyState(keyDown) == GLFW_PRESS) {
|
||||
if(Input::getKeyState(keyDown) == GLFWKeyState::PRESSED) {
|
||||
direction += glm::vec3(0, -1, 0);
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "input.h"
|
||||
#include "internal.h"
|
||||
#include "internal/ui.h"
|
||||
#include "types.h"
|
||||
|
||||
namespace kek {
|
||||
|
||||
@ -21,21 +22,21 @@ UIElement::~UIElement() {
|
||||
}
|
||||
|
||||
// Returns the element's origin position relative to its parent in pixels (not offset by getBounds())
|
||||
UIPoint UIElement::getOriginPosition() {
|
||||
return UIPoint(uiToScreen(x), uiToScreen(y));
|
||||
IntPoint2 UIElement::getOriginPosition() {
|
||||
return IntPoint2(uiToScreen(x), uiToScreen(y));
|
||||
}
|
||||
|
||||
// Returns the element's position relative to its parent in pixels (offset by getBounds())
|
||||
UIPoint UIElement::getPosition() {
|
||||
// Returns the element's position relative to its parent in pixels (offset by getBounds(), aka. the position of the top-left of the element)
|
||||
IntPoint2 UIElement::getPosition() {
|
||||
UIBounds bounds = getBounds();
|
||||
return UIPoint(uiToScreen(x) + bounds.x, uiToScreen(y) + bounds.y);
|
||||
return IntPoint2(uiToScreen(x) + bounds.x, uiToScreen(y) + bounds.y);
|
||||
}
|
||||
|
||||
// Returns the element's origin position on the screen in pixels (not offset by getBounds())
|
||||
UIPoint UIElement::getScreenOriginPosition() {
|
||||
UIPoint pos = getOriginPosition();
|
||||
IntPoint2 UIElement::getScreenOriginPosition() {
|
||||
IntPoint2 pos = getOriginPosition();
|
||||
if(parent) {
|
||||
UIPoint parentPos = parent->getScreenPosition();
|
||||
IntPoint2 parentPos = parent->getScreenPosition();
|
||||
pos.x += parentPos.x;
|
||||
pos.y += parentPos.y;
|
||||
}
|
||||
@ -43,11 +44,18 @@ UIPoint UIElement::getScreenOriginPosition() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
// Returns the element's position on the screen in pixels (offset by getBounds())
|
||||
UIPoint UIElement::getScreenPosition() {
|
||||
UIPoint pos = getScreenOriginPosition();
|
||||
// Returns the element's position on the screen in pixels (offset by getBounds(), aka. the position of the top-left of the element)
|
||||
IntPoint2 UIElement::getScreenPosition() {
|
||||
IntPoint2 pos = getScreenOriginPosition();
|
||||
UIBounds bounds = getBounds();
|
||||
return UIPoint(pos.x + bounds.x, pos.y + bounds.y);
|
||||
return IntPoint2(pos.x + bounds.x, pos.y + bounds.y);
|
||||
}
|
||||
|
||||
// Returns the bounds of the element on the screen
|
||||
UIBounds UIElement::getScreenBounds() {
|
||||
IntPoint2 pos = getScreenOriginPosition();
|
||||
UIBounds bounds = getBounds();
|
||||
return UIBounds(pos.x + bounds.x, pos.y + bounds.y, bounds.w, bounds.h);
|
||||
}
|
||||
|
||||
std::vector<UIElement *> UIElement::getChildren() {
|
||||
@ -122,7 +130,7 @@ UIBounds UIElement::offsetUIBounds(int w, int h, Origin origin) {
|
||||
return UIBounds(offsetX(w, origin), offsetY(h, origin), w, h);
|
||||
}
|
||||
|
||||
void UIElement::drawAll(UIPoint screenPos, glm::mat4 projection) {
|
||||
void UIElement::drawAll(IntPoint2 screenPos, glm::mat4 projection) {
|
||||
if(!visible) return;
|
||||
|
||||
UIBounds bounds = getBounds();
|
||||
@ -135,8 +143,8 @@ void UIElement::drawAll(UIPoint screenPos, glm::mat4 projection) {
|
||||
draw(screenPos, projection);
|
||||
|
||||
for(UIElement *child : children) {
|
||||
UIPoint pos = child->getPosition();
|
||||
child->drawAll(UIPoint(screenPos.x + pos.x, screenPos.y + pos.y), projection);
|
||||
IntPoint2 pos = child->getPosition();
|
||||
child->drawAll(IntPoint2(screenPos.x + pos.x, screenPos.y + pos.y), projection);
|
||||
}
|
||||
|
||||
if(enableClipping) {
|
||||
@ -144,24 +152,30 @@ void UIElement::drawAll(UIPoint screenPos, glm::mat4 projection) {
|
||||
}
|
||||
}
|
||||
|
||||
void UIElement::hoverAll(UIPoint pos, UIPoint screenPos) {
|
||||
UIElement *hoveredChild = nullptr;
|
||||
for(UIElement *child : children) {
|
||||
UIPoint childPos = child->getPosition();
|
||||
int relX = pos.x - childPos.x;
|
||||
int relY = pos.y - childPos.y;
|
||||
static UIElement *findChildAtRelativePos(UIElement *element, IntPoint2 pos) {
|
||||
UIElement *foundChild = nullptr;
|
||||
|
||||
for(UIElement *child : element->getChildren()) {
|
||||
IntPoint2 childPos = child->getPosition();
|
||||
IntPoint2 relativeChildPos = pos - childPos;
|
||||
UIBounds b = child->getBounds();
|
||||
if(!b.containsOffset(UIPoint(relX, relY))) continue;
|
||||
hoveredChild = child;
|
||||
if(!b.containsOffset(relativeChildPos)) continue;
|
||||
foundChild = child;
|
||||
}
|
||||
|
||||
return foundChild;
|
||||
}
|
||||
|
||||
void UIElement::hoverAll(IntPoint2 pos, IntPoint2 screenPos) {
|
||||
UIElement *hoveredChild = findChildAtRelativePos(this, pos);
|
||||
|
||||
for(UIElement *child : children) {
|
||||
if(child != hoveredChild && child->hovering) child->hoverExitAll();
|
||||
}
|
||||
|
||||
if(hoveredChild) {
|
||||
UIPoint childPos = hoveredChild->getPosition();
|
||||
hoveredChild->hoverAll(UIPoint(pos.x - childPos.x, pos.y - childPos.y), screenPos);
|
||||
IntPoint2 childPos = hoveredChild->getPosition();
|
||||
hoveredChild->hoverAll(pos - childPos, screenPos);
|
||||
}
|
||||
|
||||
if(!hovering) hoverEnter(pos, screenPos);
|
||||
@ -178,20 +192,12 @@ void UIElement::hoverExitAll() {
|
||||
hoverExit();
|
||||
}
|
||||
|
||||
bool UIElement::clickAll(UIPoint pos, UIPoint screenPos, GLFWMouseButton button) {
|
||||
UIElement *clickedChild = nullptr;
|
||||
for(UIElement *child : children) {
|
||||
UIPoint childPos = child->getPosition();
|
||||
int relX = pos.x - childPos.x;
|
||||
int relY = pos.y - childPos.y;
|
||||
UIBounds b = child->getBounds();
|
||||
if(!b.containsOffset(UIPoint(relX, relY))) continue;
|
||||
clickedChild = child;
|
||||
}
|
||||
bool UIElement::clickAll(IntPoint2 pos, IntPoint2 screenPos, GLFWMouseButton button) {
|
||||
UIElement *clickedChild = findChildAtRelativePos(this, pos);
|
||||
|
||||
if(clickedChild != nullptr) {
|
||||
UIPoint childPos = clickedChild->getPosition();
|
||||
if(clickedChild->clickAll(UIPoint(pos.x - childPos.x, pos.y - childPos.y), screenPos, button)) return true;
|
||||
IntPoint2 childPos = clickedChild->getPosition();
|
||||
if(clickedChild->clickAll(pos - childPos, screenPos, button)) return true;
|
||||
}
|
||||
|
||||
if(clickable) {
|
||||
@ -202,20 +208,12 @@ bool UIElement::clickAll(UIPoint pos, UIPoint screenPos, GLFWMouseButton button)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UIElement::focusEnterAll(UIPoint pos, UIPoint screenPos) {
|
||||
UIElement *focusedChild = nullptr;
|
||||
for(UIElement *child : children) {
|
||||
UIPoint childPos = child->getPosition();
|
||||
int relX = pos.x - childPos.x;
|
||||
int relY = pos.y - childPos.y;
|
||||
UIBounds b = child->getBounds();
|
||||
if(!b.containsOffset(UIPoint(relX, relY))) continue;
|
||||
focusedChild = child;
|
||||
}
|
||||
bool UIElement::focusEnterAll(IntPoint2 pos, IntPoint2 screenPos) {
|
||||
UIElement *focusedChild = findChildAtRelativePos(this, pos);
|
||||
|
||||
if(focusedChild != nullptr) {
|
||||
UIPoint childPos = focusedChild->getPosition();
|
||||
if(focusedChild->focusEnterAll(UIPoint(pos.x - childPos.x, pos.y - childPos.y), screenPos)) return true;
|
||||
IntPoint2 childPos = focusedChild->getPosition();
|
||||
if(focusedChild->focusEnterAll(pos - childPos, screenPos)) return true;
|
||||
}
|
||||
|
||||
if(focusable) {
|
||||
@ -226,27 +224,19 @@ bool UIElement::focusEnterAll(UIPoint pos, UIPoint screenPos) {
|
||||
return false;
|
||||
}
|
||||
|
||||
UIElement *UIElement::dragEnterAll(UIPoint pos, UIPoint screenPos) {
|
||||
UIBounds bounds = getBounds();
|
||||
if(!bounds.contains(pos)) return nullptr; // Only used by topmost parent UIElement
|
||||
|
||||
UIElement *draggedChild = nullptr;
|
||||
for(UIElement *child : children) {
|
||||
UIPoint childPos = child->getPosition();
|
||||
int relX = pos.x - childPos.x;
|
||||
int relY = pos.y - childPos.y;
|
||||
UIBounds b = child->getBounds();
|
||||
if(!b.containsOffset(UIPoint(relX, relY))) continue;
|
||||
draggedChild = child;
|
||||
}
|
||||
UIElement *UIElement::dragEnterAll(IntPoint2 pos, IntPoint2 screenPos) {
|
||||
UIElement *draggedChild = findChildAtRelativePos(this, pos);
|
||||
|
||||
if(draggedChild) {
|
||||
UIPoint childPos = draggedChild->getPosition();
|
||||
UIElement *dragged = draggedChild->dragEnterAll(UIPoint(pos.x - childPos.x, pos.y - childPos.y), screenPos);
|
||||
IntPoint2 childPos = draggedChild->getPosition();
|
||||
UIElement *dragged = draggedChild->dragEnterAll(pos - childPos, screenPos);
|
||||
if(dragged) return dragged;
|
||||
}
|
||||
|
||||
if(draggable) return this;
|
||||
if(draggable) {
|
||||
// TODO: start drag
|
||||
return this;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@ -304,4 +294,17 @@ void UI::unfocusElement(UIElement *element) {
|
||||
oldFocus->focusExit();
|
||||
}
|
||||
|
||||
UIElement *UI::findElementAt(IntPoint2 screenPos) {
|
||||
UIElement *foundElement = nullptr;
|
||||
|
||||
for(UIElement *element : kekData.ui->elements) {
|
||||
UIBounds bounds = element->getScreenBounds();
|
||||
if(!bounds.contains(screenPos)) continue;
|
||||
|
||||
foundElement = element;
|
||||
}
|
||||
|
||||
return foundElement;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "input.h"
|
||||
#include "internal.h"
|
||||
#include "internal/ui.h"
|
||||
#include "pango/pango-engine.h"
|
||||
#include "ui.h"
|
||||
#include "unicode.h"
|
||||
#include "utils.h"
|
||||
@ -68,7 +69,7 @@ std::string TextElement::getText() {
|
||||
return text->getText();
|
||||
}
|
||||
|
||||
void TextElement::draw(UIPoint screenPos, glm::mat4 projection) {
|
||||
void TextElement::draw(IntPoint2 screenPos, glm::mat4 projection) {
|
||||
switch(textMode) {
|
||||
case TextMode::BASELINE:
|
||||
text->getFont()->drawText(text, projection, screenPos.x, screenPos.y, sizePixels, color);
|
||||
@ -136,7 +137,7 @@ UIBounds RectangleElement::getBounds() {
|
||||
return offsetUIBounds(uiToScreen(w), uiToScreen(h), origin);
|
||||
}
|
||||
|
||||
void RectangleElement::draw(UIPoint screenPos, glm::mat4 projection) {
|
||||
void RectangleElement::draw(IntPoint2 screenPos, glm::mat4 projection) {
|
||||
kekData.ui->rectangleShader->use();
|
||||
|
||||
UIBounds offset = getBounds();
|
||||
@ -170,11 +171,11 @@ UIElementType ButtonElement::getType() {
|
||||
return UIElementType::BUTTON;
|
||||
}
|
||||
|
||||
void ButtonElement::click(UIPoint pos, UIPoint screenPos, GLFWMouseButton button) {
|
||||
void ButtonElement::click(IntPoint2 pos, IntPoint2 screenPos, GLFWMouseButton button) {
|
||||
onClick();
|
||||
}
|
||||
|
||||
void ButtonElement::draw(UIPoint screenPos, glm::mat4 projection) {
|
||||
void ButtonElement::draw(IntPoint2 screenPos, glm::mat4 projection) {
|
||||
RectangleElement::color = hovering ? hoverColor : color;
|
||||
RectangleElement::draw(screenPos, projection);
|
||||
}
|
||||
@ -318,7 +319,7 @@ void TextFieldElement::focusExit() {
|
||||
updateText(Unicode::convertStdToU32(this->text));
|
||||
}
|
||||
|
||||
void TextFieldElement::draw(UIPoint screenPos, glm::mat4 projection) {
|
||||
void TextFieldElement::draw(IntPoint2 screenPos, glm::mat4 projection) {
|
||||
RectangleElement::color = focused ? focusColor : color;
|
||||
RectangleElement::draw(screenPos, projection);
|
||||
|
||||
@ -332,7 +333,8 @@ void TextFieldElement::setText(std::string text) {
|
||||
}
|
||||
|
||||
UIWindowTitleBar::UIWindowTitleBar(UIValue height)
|
||||
: RectangleElement(uiPx(0), uiPx(0), uiPw(1), height) {
|
||||
: RectangleElement(uiPx(0), uiPx(0), uiPw(1), height),
|
||||
dragDownPos(0, 0) {
|
||||
this->color = Colors::GRAY;
|
||||
this->draggable = true;
|
||||
|
||||
@ -354,15 +356,20 @@ UIWindowTitleBar::~UIWindowTitleBar() {
|
||||
delete closeButton;
|
||||
}
|
||||
|
||||
void UIWindowTitleBar::dragEnter(UIPoint pos, UIPoint screenPos) {
|
||||
void UIWindowTitleBar::dragEnter(IntPoint2 pos, IntPoint2 screenPos) {
|
||||
// TODO
|
||||
std::cout << "Drag start" << std::endl;
|
||||
this->dragDownPos = pos;
|
||||
}
|
||||
|
||||
void UIWindowTitleBar::drag(UIPoint pos, UIPoint screenPos) {
|
||||
void UIWindowTitleBar::drag(IntPoint2 pos, IntPoint2 screenPos) {
|
||||
// TODO
|
||||
std::cout << "Drag" << std::endl;
|
||||
this->x = uiPx(screenPos.x + dragDownPos.x);
|
||||
this->y = uiPx(screenPos.y + dragDownPos.y);
|
||||
}
|
||||
|
||||
void UIWindowTitleBar::dragExit(UIPoint pos, UIPoint screenPos) {
|
||||
void UIWindowTitleBar::dragExit(IntPoint2 pos, IntPoint2 screenPos) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@ -397,7 +404,7 @@ UIBounds UIWindow::getBounds() {
|
||||
return offsetUIBounds(uiToScreen(w), uiToScreen(h), origin);
|
||||
}
|
||||
|
||||
void UIWindow::draw(UIPoint screenPos, glm::mat4 projection) {
|
||||
void UIWindow::draw(IntPoint2 screenPos, glm::mat4 projection) {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
#define KEK_LIGHT_DEFAULT_SPECULAR_STRENGTH 0.1f
|
||||
|
||||
#define KEK_INVALID_KEY_BINDING_NAME "INVALID"
|
||||
#define KEK_INVALID_KEY_BINDING_ID -1
|
||||
#define KEK_INVALID_ID -1u
|
||||
|
||||
#define KEK_FONT_RESOLUTION 64
|
||||
@ -48,3 +49,6 @@
|
||||
#define KEK_PLAYER_HEIGHT 2
|
||||
#define KEK_PLAYER_RADIUS 0.5f
|
||||
#define KEK_PLAYER_EYE_OFFSET (KEK_PLAYER_HEIGHT / 2 - KEK_PLAYER_RADIUS)
|
||||
|
||||
#define KEK_UI_MIN_DRAG_DISTANCE 10
|
||||
#define KEK_UI_MIN_DRAG_DISTANCE_SQUARED (KEK_UI_MIN_DRAG_DISTANCE * KEK_UI_MIN_DRAG_DISTANCE)
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "constants.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace kek {
|
||||
@ -45,7 +46,6 @@ typedef GenericCallable<MouseButtonEvent> MouseButtonCallback; // void mouseButt
|
||||
|
||||
typedef unsigned int InputListener;
|
||||
typedef int GLFWKey;
|
||||
typedef int GLFWKeyState;
|
||||
typedef unsigned int KeyBinding;
|
||||
typedef unsigned int KeyboardCapture;
|
||||
|
||||
@ -66,6 +66,17 @@ enum class GLFWMouseButton {
|
||||
MIDDLE = GLFW_MOUSE_BUTTON_MIDDLE
|
||||
};
|
||||
|
||||
enum class GLFWKeyState {
|
||||
ERROR_INVALID_KEY_BINDING = KEK_INVALID_KEY_BINDING_ID,
|
||||
PRESSED = GLFW_PRESS,
|
||||
RELEASED = GLFW_RELEASE
|
||||
};
|
||||
|
||||
enum class GLFWMouseButtonState {
|
||||
PRESSED = GLFW_PRESS,
|
||||
RELEASED = GLFW_RELEASE
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace kek::Input {
|
||||
@ -93,6 +104,8 @@ void reassignKeyBinding(KeyBinding mapping, GLFWKey key);
|
||||
KeyBindingData getKeyBinding(KeyBinding mapping);
|
||||
GLFWKeyState getKeyState(KeyBinding mapping);
|
||||
|
||||
GLFWMouseButtonState getMouseButtonState(GLFWMouseButton mouseButton);
|
||||
|
||||
void setCursorMode(GLFWCursorMode mode);
|
||||
GLFWCursorMode getCursorMode();
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <map>
|
||||
|
||||
#include "../input.h"
|
||||
#include "ui.h"
|
||||
|
||||
namespace kek {
|
||||
|
||||
@ -23,6 +24,9 @@ struct InputData {
|
||||
|
||||
ActiveKeyboardCapture activeKeyboardCapture;
|
||||
GLFWCursorMode cursorMode;
|
||||
|
||||
bool mouseDown;
|
||||
IntPoint2 mouseDownPosition;
|
||||
};
|
||||
|
||||
namespace Input {
|
||||
|
@ -24,4 +24,34 @@ class MemoryBuffer: public std::streambuf {
|
||||
}
|
||||
};
|
||||
|
||||
struct IntPoint2 {
|
||||
int x, y;
|
||||
|
||||
IntPoint2(int x, int y)
|
||||
: x(x),
|
||||
y(y) {}
|
||||
|
||||
IntPoint2() = default;
|
||||
|
||||
constexpr IntPoint2 &operator+=(const IntPoint2 &rhs) {
|
||||
this->x += rhs.x;
|
||||
this->y += rhs.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr IntPoint2 &operator-=(const IntPoint2 &rhs) {
|
||||
this->x -= rhs.x;
|
||||
this->y -= rhs.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr friend IntPoint2 operator+(const IntPoint2 &lhs, const IntPoint2 &rhs) {
|
||||
return IntPoint2(lhs) += rhs;
|
||||
}
|
||||
|
||||
constexpr friend IntPoint2 operator-(const IntPoint2 &lhs, const IntPoint2 &rhs) {
|
||||
return IntPoint2(lhs) -= rhs;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "fonts.h"
|
||||
#include "input.h"
|
||||
#include "types.h"
|
||||
|
||||
#define uiPx(val) kek::UIValue(val, kek::UIUnit::PIXELS)
|
||||
#define uiPw(val) kek::UIValue(val, kek::UIUnit::PARENT_WIDTH)
|
||||
@ -14,14 +15,6 @@
|
||||
|
||||
namespace kek {
|
||||
|
||||
struct UIPoint {
|
||||
int x, y;
|
||||
|
||||
UIPoint(int x, int y)
|
||||
: x(x),
|
||||
y(y) {}
|
||||
};
|
||||
|
||||
struct UIBounds {
|
||||
int x, y, w, h;
|
||||
|
||||
@ -32,12 +25,12 @@ struct UIBounds {
|
||||
h(h) {}
|
||||
|
||||
// Checks if a point is contained in the bounds
|
||||
inline bool contains(UIPoint pos) {
|
||||
inline bool contains(IntPoint2 pos) {
|
||||
return pos.x > x && pos.y > y && pos.x < x + w && pos.y < y + h;
|
||||
}
|
||||
|
||||
// Checks if an already offset point is contained in the bounds
|
||||
inline bool containsOffset(UIPoint pos) {
|
||||
inline bool containsOffset(IntPoint2 pos) {
|
||||
return pos.x > 0 && pos.y > 0 && pos.x < w && pos.y < h;
|
||||
}
|
||||
};
|
||||
@ -156,16 +149,22 @@ class UIElement {
|
||||
virtual UIElementType getType() = 0;
|
||||
|
||||
// Returns the element's origin position relative to its parent in pixels (not offset by getBounds())
|
||||
UIPoint getOriginPosition();
|
||||
IntPoint2 getOriginPosition();
|
||||
|
||||
// Returns the element's position relative to its parent in pixels (offset by getBounds())
|
||||
UIPoint getPosition();
|
||||
IntPoint2 getPosition();
|
||||
|
||||
// Returns the element's origin position on the screen in pixels (not offset by getBounds())
|
||||
UIPoint getScreenOriginPosition();
|
||||
IntPoint2 getScreenOriginPosition();
|
||||
|
||||
// Returns the element's position on the screen in pixels (offset by getBounds())
|
||||
UIPoint getScreenPosition();
|
||||
IntPoint2 getScreenPosition();
|
||||
|
||||
// Returns the bounds of the element relative to its origin
|
||||
virtual UIBounds getBounds() = 0;
|
||||
|
||||
// Returns the bounds of the element on the screen
|
||||
UIBounds getScreenBounds();
|
||||
|
||||
std::vector<UIElement *> getChildren();
|
||||
void addChild(UIElement *child);
|
||||
@ -178,29 +177,26 @@ class UIElement {
|
||||
static UIBounds offsetUIBounds(int w, int h, Origin origin);
|
||||
|
||||
public:
|
||||
// Returns the bounds of the element relative to its origin
|
||||
virtual UIBounds getBounds() = 0;
|
||||
void drawAll(IntPoint2 screenPos, glm::mat4 projection);
|
||||
virtual void draw(IntPoint2 screenPos, glm::mat4 projection) = 0;
|
||||
|
||||
void drawAll(UIPoint screenPos, glm::mat4 projection);
|
||||
virtual void draw(UIPoint screenPos, glm::mat4 projection) = 0;
|
||||
|
||||
void hoverAll(UIPoint pos, UIPoint screenPos);
|
||||
void hoverAll(IntPoint2 pos, IntPoint2 screenPos);
|
||||
void hoverExitAll();
|
||||
virtual void hoverEnter(UIPoint pos, UIPoint screenPos){};
|
||||
virtual void hover(UIPoint pos, UIPoint screenPos){};
|
||||
virtual void hoverEnter(IntPoint2 pos, IntPoint2 screenPos){};
|
||||
virtual void hover(IntPoint2 pos, IntPoint2 screenPos){};
|
||||
virtual void hoverExit(){};
|
||||
|
||||
bool clickAll(UIPoint pos, UIPoint screenPos, GLFWMouseButton button);
|
||||
virtual void click(UIPoint pos, UIPoint screenPos, GLFWMouseButton button){};
|
||||
bool clickAll(IntPoint2 pos, IntPoint2 screenPos, GLFWMouseButton button);
|
||||
virtual void click(IntPoint2 pos, IntPoint2 screenPos, GLFWMouseButton button){};
|
||||
|
||||
bool focusEnterAll(UIPoint pos, UIPoint screenPos);
|
||||
bool focusEnterAll(IntPoint2 pos, IntPoint2 screenPos);
|
||||
virtual void focusEnter(){};
|
||||
virtual void focusExit(){};
|
||||
|
||||
UIElement *dragEnterAll(UIPoint pos, UIPoint screenPos);
|
||||
virtual void dragEnter(UIPoint pos, UIPoint screenPos){};
|
||||
virtual void drag(UIPoint pos, UIPoint screenPos){};
|
||||
virtual void dragExit(UIPoint pos, UIPoint screenPos){};
|
||||
UIElement *dragEnterAll(IntPoint2 pos, IntPoint2 screenPos);
|
||||
virtual void dragEnter(IntPoint2 pos, IntPoint2 screenPos){};
|
||||
virtual void drag(IntPoint2 pos, IntPoint2 screenPos){};
|
||||
virtual void dragExit(IntPoint2 pos, IntPoint2 screenPos){};
|
||||
};
|
||||
|
||||
namespace UI {
|
||||
@ -215,6 +211,9 @@ void removeElement(UIElement *element);
|
||||
void focusElement(UIElement *element);
|
||||
void unfocusElement(UIElement *element);
|
||||
|
||||
// Finds the first (topmost) element at the given screen position
|
||||
UIElement *findElementAt(IntPoint2 screenPos);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ class TextElement: public UIElement {
|
||||
|
||||
std::string getText();
|
||||
|
||||
virtual void draw(UIPoint screenPos, glm::mat4 projection);
|
||||
virtual void draw(IntPoint2 screenPos, glm::mat4 projection);
|
||||
};
|
||||
|
||||
class RectangleElement: public UIElement {
|
||||
@ -64,7 +64,7 @@ class RectangleElement: public UIElement {
|
||||
|
||||
virtual UIBounds getBounds();
|
||||
|
||||
virtual void draw(UIPoint screenPos, glm::mat4 projection);
|
||||
virtual void draw(IntPoint2 screenPos, glm::mat4 projection);
|
||||
};
|
||||
|
||||
class ButtonElement: public RectangleElement {
|
||||
@ -81,9 +81,9 @@ class ButtonElement: public RectangleElement {
|
||||
|
||||
virtual UIElementType getType();
|
||||
|
||||
virtual void click(UIPoint pos, UIPoint screenPos, GLFWMouseButton button);
|
||||
virtual void click(IntPoint2 pos, IntPoint2 screenPos, GLFWMouseButton button);
|
||||
|
||||
virtual void draw(UIPoint screenPos, glm::mat4 projection);
|
||||
virtual void draw(IntPoint2 screenPos, glm::mat4 projection);
|
||||
};
|
||||
|
||||
typedef GenericCallable<std::string> SubmitCallback;
|
||||
@ -119,13 +119,16 @@ class TextFieldElement: public RectangleElement {
|
||||
virtual void focusEnter();
|
||||
virtual void focusExit();
|
||||
|
||||
virtual void draw(UIPoint screenPos, glm::mat4 projection);
|
||||
virtual void draw(IntPoint2 screenPos, glm::mat4 projection);
|
||||
|
||||
void setText(std::string text);
|
||||
};
|
||||
|
||||
class UIWindowTitleBar: public RectangleElement {
|
||||
|
||||
protected:
|
||||
IntPoint2 dragDownPos;
|
||||
|
||||
public:
|
||||
TextElement *text;
|
||||
ButtonElement *closeButton;
|
||||
@ -134,9 +137,9 @@ class UIWindowTitleBar: public RectangleElement {
|
||||
|
||||
virtual ~UIWindowTitleBar();
|
||||
|
||||
virtual void dragEnter(UIPoint pos, UIPoint screenPos);
|
||||
virtual void drag(UIPoint pos, UIPoint screenPos);
|
||||
virtual void dragExit(UIPoint pos, UIPoint screenPos);
|
||||
virtual void dragEnter(IntPoint2 pos, IntPoint2 screenPos);
|
||||
virtual void drag(IntPoint2 pos, IntPoint2 screenPos);
|
||||
virtual void dragExit(IntPoint2 pos, IntPoint2 screenPos);
|
||||
};
|
||||
|
||||
class UIWindow: public UIElement {
|
||||
@ -155,7 +158,7 @@ class UIWindow: public UIElement {
|
||||
|
||||
virtual UIBounds getBounds();
|
||||
|
||||
virtual void draw(UIPoint screenPos, glm::mat4 projection);
|
||||
virtual void draw(IntPoint2 screenPos, glm::mat4 projection);
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user