Implement UI drag
This commit is contained in:
parent
d9cfcba0ba
commit
bc0cab870b
@ -41,36 +41,55 @@ 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(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(!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
|
||||
UIElement *draggedElement = UI::findElementAt(mousePosition);
|
||||
|
||||
if(draggedElement) {
|
||||
IntPoint2 childPos = draggedElement->getPosition();
|
||||
draggedElement->dragEnterAll(mousePosition - childPos, mousePosition);
|
||||
if(draggedElement) {
|
||||
IntPoint2 childPos = draggedElement->getScreenPosition();
|
||||
draggedElement->dragEnterAll(mouseDownPosition - childPos, mouseDownPosition);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Element is being dragged
|
||||
IntPoint2 childPos = kekData.ui->draggedElement->getScreenPosition();
|
||||
kekData.ui->draggedElement->drag(mousePosition - childPos, mousePosition);
|
||||
}
|
||||
|
||||
// TODO: drag dragged element, exit drag
|
||||
|
||||
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);
|
||||
|
@ -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,16 +272,17 @@ std::vector<UIElement *> UI::getElements() {
|
||||
}
|
||||
|
||||
void UI::focusElement(UIElement *element) {
|
||||
if(kekData.ui->focusedElement != element) {
|
||||
if(kekData.ui->focusedElement != nullptr) {
|
||||
unfocusElement(kekData.ui->focusedElement);
|
||||
}
|
||||
if(!element->focusable) return;
|
||||
if(kekData.ui->focusedElement == element) return;
|
||||
|
||||
kekData.ui->focusedElement = element;
|
||||
if(element != nullptr) {
|
||||
element->focused = true;
|
||||
element->focusEnter();
|
||||
}
|
||||
if(kekData.ui->focusedElement != nullptr) {
|
||||
unfocusElement(kekData.ui->focusedElement);
|
||||
}
|
||||
|
||||
kekData.ui->focusedElement = element;
|
||||
if(element != nullptr) {
|
||||
element->focused = true;
|
||||
element->focusEnter();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -7,6 +7,7 @@ namespace kek {
|
||||
struct UIData {
|
||||
std::vector<UIElement *> elements;
|
||||
UIElement *focusedElement;
|
||||
UIElement *draggedElement;
|
||||
std::shared_ptr<Font> defaultFont;
|
||||
Shader *rectangleShader;
|
||||
};
|
||||
|
@ -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){};
|
||||
|
Loading…
Reference in New Issue
Block a user