Implement UI drag

This commit is contained in:
MrLetsplay 2024-08-25 21:41:54 +02:00
parent d9cfcba0ba
commit bc0cab870b
Signed by: mr
SSH Key Fingerprint: SHA256:92jBH80vpXyaZHjaIl47pjRq+Yt7XGTArqQg1V7hSqg
5 changed files with 57 additions and 37 deletions

View File

@ -41,35 +41,54 @@ static void doUIMouseHover(double x, double y) {
}
if(hoveredElement) {
IntPoint2 childPos = hoveredElement->getPosition();
IntPoint2 childPos = hoveredElement->getScreenPosition();
hoveredElement->hoverAll(mousePosition - childPos, mousePosition);
}
}
static void stopUIMouseDrag() {
if(!kekData.ui->draggedElement) return;
double x, y;
glfwGetCursorPos(kekData.window, &x, &y);
IntPoint2 mousePosition = IntPoint2((int) x, (int) y);
IntPoint2 childPos = kekData.ui->draggedElement->getScreenPosition();
kekData.ui->draggedElement->dragExit(mousePosition - childPos, mousePosition);
kekData.ui->draggedElement = nullptr;
}
static void doUIMouseDrag(double x, double y) {
IntPoint2 mousePosition = IntPoint2((int) x, (int) y);
if(Input::getMouseButtonState(GLFWMouseButton::LEFT) != GLFWMouseButtonState::PRESSED) {
kekData.input->mouseDown = false;
stopUIMouseDrag();
return;
}
if(!kekData.input->mouseDown) {
kekData.input->mouseDownPosition = IntPoint2((int) x, (int) y);
kekData.input->mouseDownPosition = mousePosition;
}
int deltaX = (int) x - kekData.input->mouseDownPosition.x;
int deltaY = (int) y - kekData.input->mouseDownPosition.y;
if(!kekData.ui->draggedElement) {
IntPoint2 mouseDownPosition = kekData.input->mouseDownPosition;
int deltaX = (int) x - mouseDownPosition.x;
int deltaY = (int) y - 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);
IntPoint2 childPos = draggedElement->getScreenPosition();
draggedElement->dragEnterAll(mouseDownPosition - childPos, mouseDownPosition);
}
}
// TODO: drag dragged element, exit drag
} else {
// Element is being dragged
IntPoint2 childPos = kekData.ui->draggedElement->getScreenPosition();
kekData.ui->draggedElement->drag(mousePosition - childPos, mousePosition);
}
kekData.input->mouseDown = true;
}
@ -79,7 +98,7 @@ static void doUIMouseClick(double x, double y, GLFWMouseButton button) {
UIElement *clickedElement = UI::findElementAt(mousePosition);
if(clickedElement) {
IntPoint2 childPos = clickedElement->getPosition();
IntPoint2 childPos = clickedElement->getScreenPosition();
IntPoint2 clickedAt = mousePosition - childPos;
if(button == GLFWMouseButton::LEFT) {
@ -175,6 +194,9 @@ static void defaultMouseButtonCallback(MouseButtonEvent event, void *data) {
case GLFW_PRESS:
break;
case GLFW_RELEASE: {
kekData.input->mouseDown = false;
stopUIMouseDrag();
double x, y;
glfwGetCursorPos(event.window, &x, &y);
doUIMouseClick(x, y, (GLFWMouseButton) event.button);

View File

@ -224,21 +224,21 @@ bool UIElement::focusEnterAll(IntPoint2 pos, IntPoint2 screenPos) {
return false;
}
UIElement *UIElement::dragEnterAll(IntPoint2 pos, IntPoint2 screenPos) {
bool UIElement::dragEnterAll(IntPoint2 pos, IntPoint2 screenPos) {
UIElement *draggedChild = findChildAtRelativePos(this, pos);
if(draggedChild) {
IntPoint2 childPos = draggedChild->getPosition();
UIElement *dragged = draggedChild->dragEnterAll(pos - childPos, screenPos);
if(dragged) return dragged;
if(draggedChild->dragEnterAll(pos - childPos, screenPos)) return true;
}
if(draggable) {
// TODO: start drag
return this;
dragEnter(pos, screenPos);
kekData.ui->draggedElement = this;
return true;
}
return nullptr;
return false;
}
void UI::init() {
@ -272,7 +272,9 @@ std::vector<UIElement *> UI::getElements() {
}
void UI::focusElement(UIElement *element) {
if(kekData.ui->focusedElement != element) {
if(!element->focusable) return;
if(kekData.ui->focusedElement == element) return;
if(kekData.ui->focusedElement != nullptr) {
unfocusElement(kekData.ui->focusedElement);
}
@ -283,7 +285,6 @@ void UI::focusElement(UIElement *element) {
element->focusEnter();
}
}
}
void UI::unfocusElement(UIElement *element) {
if(kekData.ui->focusedElement == nullptr || element != kekData.ui->focusedElement) return;

View File

@ -357,20 +357,16 @@ UIWindowTitleBar::~UIWindowTitleBar() {
}
void UIWindowTitleBar::dragEnter(IntPoint2 pos, IntPoint2 screenPos) {
// TODO
std::cout << "Drag start" << std::endl;
this->dragDownPos = pos;
}
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);
if(!this->parent) return;
this->parent->x = uiPx(screenPos.x - dragDownPos.x);
this->parent->y = uiPx(screenPos.y - dragDownPos.y);
}
void UIWindowTitleBar::dragExit(IntPoint2 pos, IntPoint2 screenPos) {
// TODO
}
UIWindow::UIWindow(UIValue x, UIValue y, UIValue w, UIValue h)

View File

@ -7,6 +7,7 @@ namespace kek {
struct UIData {
std::vector<UIElement *> elements;
UIElement *focusedElement;
UIElement *draggedElement;
std::shared_ptr<Font> defaultFont;
Shader *rectangleShader;
};

View File

@ -193,7 +193,7 @@ class UIElement {
virtual void focusEnter(){};
virtual void focusExit(){};
UIElement *dragEnterAll(IntPoint2 pos, IntPoint2 screenPos);
bool 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){};