Fix UI click/hover

This commit is contained in:
MrLetsplay 2023-09-12 17:53:56 +02:00
parent 6a5fb84553
commit 8ce8f8a0dd
Signed by: mr
SSH Key Fingerprint: SHA256:92jBH80vpXyaZHjaIl47pjRq+Yt7XGTArqQg1V7hSqg
4 changed files with 57 additions and 24 deletions

View File

@ -27,10 +27,49 @@ static void defaultInput(GLFWwindow *window, void *data) {
kekData.player->controller->update(); kekData.player->controller->update();
} }
static void doUIMouse(double x, double y) { static void doUIMouseHover(double x, double y) {
UIElement *hoveredElement = nullptr;
for(UIElement *element : kekData.ui->elements) { for(UIElement *element : kekData.ui->elements) {
UIPoint childPos = element->getPosition(); UIPoint childPos = element->getPosition();
if(element->hoverAll(UIPoint((int) x - childPos.x, (int) y - childPos.y), UIPoint((int) x, (int) y))) break; UIPoint hoveredAt = UIPoint((int) x - childPos.x, (int) y - childPos.y);
UIBounds bounds = element->getBounds();
if(!bounds.contains(hoveredAt)) continue;
hoveredElement = element;
}
for(UIElement *element : kekData.ui->elements) {
if(element->hovering && element != hoveredElement) {
element->hoverExitAll();
}
}
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));
}
}
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.contains(clickedAt)) continue;
clickedElement = element;
}
if(clickedElement) {
UIPoint childPos = clickedElement->getPosition();
UIPoint clickedAt = UIPoint((int) x - childPos.x, (int) y - childPos.y);
clickedElement->clickAll(clickedAt, UIPoint((int) x, (int) y), button);
} }
} }
@ -48,7 +87,7 @@ static void defaultKeyCallback(GLFWwindow *window, int key, int scancode, int ac
Input::setCursorMode(GLFWCursorMode::FREE); Input::setCursorMode(GLFWCursorMode::FREE);
double x, y; double x, y;
glfwGetCursorPos(kekData.window, &x, &y); glfwGetCursorPos(kekData.window, &x, &y);
doUIMouse(x, y); doUIMouseHover(x, y);
}else { }else {
Input::setCursorMode(GLFWCursorMode::CAPTURE); Input::setCursorMode(GLFWCursorMode::CAPTURE);
@ -96,7 +135,7 @@ static void defaultMouseCallback(GLFWwindow *window, double x, double y, void *d
case GLFWCursorMode::FREE: case GLFWCursorMode::FREE:
case GLFWCursorMode::HIDDEN: case GLFWCursorMode::HIDDEN:
{ {
doUIMouse(x, y); doUIMouseHover(x, y);
break; break;
} }
} }
@ -119,10 +158,7 @@ static void defaultMouseButtonCallback(GLFWwindow* window, int button, int actio
{ {
double x, y; double x, y;
glfwGetCursorPos(window, &x, &y); glfwGetCursorPos(window, &x, &y);
for(UIElement *element : kekData.ui->elements) { doUIMouseClick(x, y, (GLFWMouseButton) button);
UIPoint childPos = element->getPosition();
if(element->clickAll(UIPoint((int) x - childPos.x, (int) y - childPos.y), UIPoint((int) x, (int) y), (GLFWMouseButton) button)) break;
}
} }
} }

View File

@ -139,13 +139,7 @@ void UIElement::drawAll(UIPoint screenPos, glm::mat4 projection) {
} }
} }
bool UIElement::hoverAll(UIPoint pos, UIPoint screenPos) { void UIElement::hoverAll(UIPoint pos, UIPoint screenPos) {
UIBounds bounds = getBounds();
if(!bounds.contains(pos)) { // Only used by topmost parent UIElement
if(hovering) hoverExitAll();
return false;
}
UIElement *hoveredChild = nullptr; UIElement *hoveredChild = nullptr;
for(UIElement *child : children) { for(UIElement *child : children) {
UIPoint childPos = child->getPosition(); UIPoint childPos = child->getPosition();
@ -168,7 +162,6 @@ bool UIElement::hoverAll(UIPoint pos, UIPoint screenPos) {
if(!hovering) hoverEnter(pos, screenPos); if(!hovering) hoverEnter(pos, screenPos);
hovering = true; hovering = true;
hover(pos, screenPos); hover(pos, screenPos);
return true;
} }
void UIElement::hoverExitAll() { void UIElement::hoverExitAll() {
@ -180,10 +173,7 @@ void UIElement::hoverExitAll() {
hoverExit(); hoverExit();
} }
bool UIElement::clickAll(UIPoint pos, UIPoint screenPos, GLFWMouseButton button) { void UIElement::clickAll(UIPoint pos, UIPoint screenPos, GLFWMouseButton button) {
UIBounds bounds = getBounds();
if(!bounds.contains(pos)) return false; // Only used by topmost parent UIElement
UIElement *clickedChild = nullptr; UIElement *clickedChild = nullptr;
for(UIElement *child : children) { for(UIElement *child : children) {
if(!child->clickable) continue; if(!child->clickable) continue;
@ -201,8 +191,6 @@ bool UIElement::clickAll(UIPoint pos, UIPoint screenPos, GLFWMouseButton button)
}else { }else {
click(pos, screenPos, button); click(pos, screenPos, button);
} }
return true;
} }
bool UIElement::focusEnterAll(UIPoint pos, UIPoint screenPos) { bool UIElement::focusEnterAll(UIPoint pos, UIPoint screenPos) {

View File

@ -144,13 +144,13 @@ public:
void drawAll(UIPoint screenPos, glm::mat4 projection); void drawAll(UIPoint screenPos, glm::mat4 projection);
virtual void draw(UIPoint screenPos, glm::mat4 projection) = 0; virtual void draw(UIPoint screenPos, glm::mat4 projection) = 0;
bool hoverAll(UIPoint pos, UIPoint screenPos); void hoverAll(UIPoint pos, UIPoint screenPos);
void hoverExitAll(); void hoverExitAll();
virtual void hoverEnter(UIPoint pos, UIPoint screenPos) {}; virtual void hoverEnter(UIPoint pos, UIPoint screenPos) {};
virtual void hover(UIPoint pos, UIPoint screenPos) {}; virtual void hover(UIPoint pos, UIPoint screenPos) {};
virtual void hoverExit() {}; virtual void hoverExit() {};
bool clickAll(UIPoint pos, UIPoint screenPos, GLFWMouseButton button); void clickAll(UIPoint pos, UIPoint screenPos, GLFWMouseButton button);
virtual void click(UIPoint pos, UIPoint screenPos, GLFWMouseButton button) {}; virtual void click(UIPoint pos, UIPoint screenPos, GLFWMouseButton button) {};
bool focusEnterAll(UIPoint pos, UIPoint screenPos); bool focusEnterAll(UIPoint pos, UIPoint screenPos);

View File

@ -30,6 +30,7 @@ void mouseButtonCallback(GLFWwindow *window, int button, int action, int mods, v
void onButtonClick(void *data) { void onButtonClick(void *data) {
button->color = Colors::RED; button->color = Colors::RED;
button->hoverColor = Colors::ORANGE;
capture = Input::captureKeyboardInput(KeyCharCallback([](GLFWwindow *window, unsigned int codepoint, void *data) { capture = Input::captureKeyboardInput(KeyCharCallback([](GLFWwindow *window, unsigned int codepoint, void *data) {
std::u32string str = Unicode::convertStdToU32(button->text->getText()); std::u32string str = Unicode::convertStdToU32(button->text->getText());
if(codepoint == KEK_INPUT_DELETE) { if(codepoint == KEK_INPUT_DELETE) {
@ -44,6 +45,7 @@ void onButtonClick(void *data) {
} }
}, nullptr), Callable([](void *data) { }, nullptr), Callable([](void *data) {
button->color = Colors::WHITE; button->color = Colors::WHITE;
button->hoverColor = Colors::GRAY;
}, nullptr)); }, nullptr));
} }
@ -122,6 +124,13 @@ int main(int argc, char **argv) {
button->onClick = Callable(onButtonClick, nullptr); button->onClick = Callable(onButtonClick, nullptr);
UI::addElement(button); UI::addElement(button);
ButtonElement *button2 = new ButtonElement(uiPx(10), uiPx(125), uiPx(200), uiPx(50));
button2->text->color = Colors::WHITE;
button2->color = Colors::ORANGE;
button2->hoverColor = Colors::RED;
button2->text->setText("Hi there!");
UI::addElement(button2);
if(Engine::start() != KEK_SUCCESS) return 1; if(Engine::start() != KEK_SUCCESS) return 1;
return 0; return 0;
} }