Implement UI drag
This commit is contained in:
parent
d9cfcba0ba
commit
bc0cab870b
@ -41,35 +41,54 @@ static void doUIMouseHover(double x, double y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(hoveredElement) {
|
if(hoveredElement) {
|
||||||
IntPoint2 childPos = hoveredElement->getPosition();
|
IntPoint2 childPos = hoveredElement->getScreenPosition();
|
||||||
hoveredElement->hoverAll(mousePosition - childPos, mousePosition);
|
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) {
|
static void doUIMouseDrag(double x, double y) {
|
||||||
|
IntPoint2 mousePosition = IntPoint2((int) x, (int) y);
|
||||||
|
|
||||||
if(Input::getMouseButtonState(GLFWMouseButton::LEFT) != GLFWMouseButtonState::PRESSED) {
|
if(Input::getMouseButtonState(GLFWMouseButton::LEFT) != GLFWMouseButtonState::PRESSED) {
|
||||||
kekData.input->mouseDown = false;
|
kekData.input->mouseDown = false;
|
||||||
|
stopUIMouseDrag();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!kekData.input->mouseDown) {
|
if(!kekData.input->mouseDown) {
|
||||||
kekData.input->mouseDownPosition = IntPoint2((int) x, (int) y);
|
kekData.input->mouseDownPosition = mousePosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
int deltaX = (int) x - kekData.input->mouseDownPosition.x;
|
if(!kekData.ui->draggedElement) {
|
||||||
int deltaY = (int) y - kekData.input->mouseDownPosition.y;
|
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) {
|
if(deltaX * deltaX + deltaY * deltaY >= KEK_UI_MIN_DRAG_DISTANCE_SQUARED) {
|
||||||
// Initiate drag
|
// Initiate drag
|
||||||
IntPoint2 mousePosition = IntPoint2((int) x, (int) y);
|
|
||||||
UIElement *draggedElement = UI::findElementAt(mousePosition);
|
UIElement *draggedElement = UI::findElementAt(mousePosition);
|
||||||
|
|
||||||
if(draggedElement) {
|
if(draggedElement) {
|
||||||
IntPoint2 childPos = draggedElement->getPosition();
|
IntPoint2 childPos = draggedElement->getScreenPosition();
|
||||||
draggedElement->dragEnterAll(mousePosition - childPos, mousePosition);
|
draggedElement->dragEnterAll(mouseDownPosition - childPos, mouseDownPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
// TODO: drag dragged element, exit drag
|
// Element is being dragged
|
||||||
|
IntPoint2 childPos = kekData.ui->draggedElement->getScreenPosition();
|
||||||
|
kekData.ui->draggedElement->drag(mousePosition - childPos, mousePosition);
|
||||||
|
}
|
||||||
|
|
||||||
kekData.input->mouseDown = true;
|
kekData.input->mouseDown = true;
|
||||||
}
|
}
|
||||||
@ -79,7 +98,7 @@ static void doUIMouseClick(double x, double y, GLFWMouseButton button) {
|
|||||||
UIElement *clickedElement = UI::findElementAt(mousePosition);
|
UIElement *clickedElement = UI::findElementAt(mousePosition);
|
||||||
|
|
||||||
if(clickedElement) {
|
if(clickedElement) {
|
||||||
IntPoint2 childPos = clickedElement->getPosition();
|
IntPoint2 childPos = clickedElement->getScreenPosition();
|
||||||
IntPoint2 clickedAt = mousePosition - childPos;
|
IntPoint2 clickedAt = mousePosition - childPos;
|
||||||
|
|
||||||
if(button == GLFWMouseButton::LEFT) {
|
if(button == GLFWMouseButton::LEFT) {
|
||||||
@ -175,6 +194,9 @@ static void defaultMouseButtonCallback(MouseButtonEvent event, void *data) {
|
|||||||
case GLFW_PRESS:
|
case GLFW_PRESS:
|
||||||
break;
|
break;
|
||||||
case GLFW_RELEASE: {
|
case GLFW_RELEASE: {
|
||||||
|
kekData.input->mouseDown = false;
|
||||||
|
stopUIMouseDrag();
|
||||||
|
|
||||||
double x, y;
|
double x, y;
|
||||||
glfwGetCursorPos(event.window, &x, &y);
|
glfwGetCursorPos(event.window, &x, &y);
|
||||||
doUIMouseClick(x, y, (GLFWMouseButton) event.button);
|
doUIMouseClick(x, y, (GLFWMouseButton) event.button);
|
||||||
|
@ -224,21 +224,21 @@ bool UIElement::focusEnterAll(IntPoint2 pos, IntPoint2 screenPos) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
UIElement *UIElement::dragEnterAll(IntPoint2 pos, IntPoint2 screenPos) {
|
bool UIElement::dragEnterAll(IntPoint2 pos, IntPoint2 screenPos) {
|
||||||
UIElement *draggedChild = findChildAtRelativePos(this, pos);
|
UIElement *draggedChild = findChildAtRelativePos(this, pos);
|
||||||
|
|
||||||
if(draggedChild) {
|
if(draggedChild) {
|
||||||
IntPoint2 childPos = draggedChild->getPosition();
|
IntPoint2 childPos = draggedChild->getPosition();
|
||||||
UIElement *dragged = draggedChild->dragEnterAll(pos - childPos, screenPos);
|
if(draggedChild->dragEnterAll(pos - childPos, screenPos)) return true;
|
||||||
if(dragged) return dragged;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(draggable) {
|
if(draggable) {
|
||||||
// TODO: start drag
|
dragEnter(pos, screenPos);
|
||||||
return this;
|
kekData.ui->draggedElement = this;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UI::init() {
|
void UI::init() {
|
||||||
@ -272,7 +272,9 @@ std::vector<UIElement *> UI::getElements() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UI::focusElement(UIElement *element) {
|
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) {
|
if(kekData.ui->focusedElement != nullptr) {
|
||||||
unfocusElement(kekData.ui->focusedElement);
|
unfocusElement(kekData.ui->focusedElement);
|
||||||
}
|
}
|
||||||
@ -282,7 +284,6 @@ void UI::focusElement(UIElement *element) {
|
|||||||
element->focused = true;
|
element->focused = true;
|
||||||
element->focusEnter();
|
element->focusEnter();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UI::unfocusElement(UIElement *element) {
|
void UI::unfocusElement(UIElement *element) {
|
||||||
|
@ -357,20 +357,16 @@ UIWindowTitleBar::~UIWindowTitleBar() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UIWindowTitleBar::dragEnter(IntPoint2 pos, IntPoint2 screenPos) {
|
void UIWindowTitleBar::dragEnter(IntPoint2 pos, IntPoint2 screenPos) {
|
||||||
// TODO
|
|
||||||
std::cout << "Drag start" << std::endl;
|
|
||||||
this->dragDownPos = pos;
|
this->dragDownPos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIWindowTitleBar::drag(IntPoint2 pos, IntPoint2 screenPos) {
|
void UIWindowTitleBar::drag(IntPoint2 pos, IntPoint2 screenPos) {
|
||||||
// TODO
|
if(!this->parent) return;
|
||||||
std::cout << "Drag" << std::endl;
|
this->parent->x = uiPx(screenPos.x - dragDownPos.x);
|
||||||
this->x = uiPx(screenPos.x + dragDownPos.x);
|
this->parent->y = uiPx(screenPos.y - dragDownPos.y);
|
||||||
this->y = uiPx(screenPos.y + dragDownPos.y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIWindowTitleBar::dragExit(IntPoint2 pos, IntPoint2 screenPos) {
|
void UIWindowTitleBar::dragExit(IntPoint2 pos, IntPoint2 screenPos) {
|
||||||
// TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UIWindow::UIWindow(UIValue x, UIValue y, UIValue w, UIValue h)
|
UIWindow::UIWindow(UIValue x, UIValue y, UIValue w, UIValue h)
|
||||||
|
@ -7,6 +7,7 @@ namespace kek {
|
|||||||
struct UIData {
|
struct UIData {
|
||||||
std::vector<UIElement *> elements;
|
std::vector<UIElement *> elements;
|
||||||
UIElement *focusedElement;
|
UIElement *focusedElement;
|
||||||
|
UIElement *draggedElement;
|
||||||
std::shared_ptr<Font> defaultFont;
|
std::shared_ptr<Font> defaultFont;
|
||||||
Shader *rectangleShader;
|
Shader *rectangleShader;
|
||||||
};
|
};
|
||||||
|
@ -193,7 +193,7 @@ class UIElement {
|
|||||||
virtual void focusEnter(){};
|
virtual void focusEnter(){};
|
||||||
virtual void focusExit(){};
|
virtual void focusExit(){};
|
||||||
|
|
||||||
UIElement *dragEnterAll(IntPoint2 pos, IntPoint2 screenPos);
|
bool dragEnterAll(IntPoint2 pos, IntPoint2 screenPos);
|
||||||
virtual void dragEnter(IntPoint2 pos, IntPoint2 screenPos){};
|
virtual void dragEnter(IntPoint2 pos, IntPoint2 screenPos){};
|
||||||
virtual void drag(IntPoint2 pos, IntPoint2 screenPos){};
|
virtual void drag(IntPoint2 pos, IntPoint2 screenPos){};
|
||||||
virtual void dragExit(IntPoint2 pos, IntPoint2 screenPos){};
|
virtual void dragExit(IntPoint2 pos, IntPoint2 screenPos){};
|
||||||
|
Loading…
Reference in New Issue
Block a user