WidgetPtr Gui::GetWidgetAt(int x, int y) { // If the widget's parent has no child then we have found the widget.. WidgetPtr parent = mTop; WidgetPtr child = mTop; while (child != NULL) { WidgetPtr swap = child; int parentX, parentY; parent->getAbsolutePosition(parentX, parentY); child = parent->GetWidgetAt(x - parentX, y - parentY); parent = swap; } return parent; }
void Gui::handleMouseReleased(const MouseInput& mouseInput) { WidgetPtr sourceWidget = GetMouseEventSource(mouseInput.getX(), mouseInput.getY()); if (mFocusHandler->GetDraggedWidget()) { if (sourceWidget != mFocusHandler->GetLastWidgetPressed()) { mFocusHandler->SetLastWidgetPressed(WidgetPtr()); } sourceWidget = mFocusHandler->GetDraggedWidget(); } int sourceWidgetX, sourceWidgetY; sourceWidget->getAbsolutePosition(sourceWidgetX, sourceWidgetY); distributeMouseEvent(sourceWidget, MouseEvent::RELEASED, mouseInput.getButton(), mouseInput.getX(), mouseInput.getY()); if (mouseInput.getButton() == mLastMousePressButton && mFocusHandler->GetLastWidgetPressed() == sourceWidget) { distributeMouseEvent(sourceWidget, MouseEvent::CLICKED, mouseInput.getButton(), mouseInput.getX(), mouseInput.getY()); mFocusHandler->SetLastWidgetPressed(WidgetPtr()); } else { mLastMousePressButton = 0; mClickCount = 0; } if (mFocusHandler->GetDraggedWidget()) { mFocusHandler->SetDraggedWidget(WidgetPtr()); } }
void Gui::handleMouseWheelMovedUp(const MouseInput& mouseInput) { WidgetPtr sourceWidget = GetMouseEventSource(mouseInput.getX(), mouseInput.getY()); if (mFocusHandler->GetDraggedWidget() != NULL) { sourceWidget = mFocusHandler->GetDraggedWidget(); } int sourceWidgetX, sourceWidgetY; sourceWidget->getAbsolutePosition(sourceWidgetX, sourceWidgetY); distributeMouseEvent(sourceWidget, MouseEvent::WHEEL_MOVED_UP, mouseInput.getButton(), mouseInput.getX(), mouseInput.getY()); }
void Gui::handleMousePressed(const MouseInput& mouseInput) { WidgetPtr sourceWidget = GetMouseEventSource(mouseInput.getX(), mouseInput.getY()); if (mFocusHandler->GetDraggedWidget()) { sourceWidget = mFocusHandler->GetDraggedWidget(); } int sourceWidgetX, sourceWidgetY; sourceWidget->getAbsolutePosition(sourceWidgetX, sourceWidgetY); if ((mFocusHandler->GetModalFocused() != NULL && sourceWidget->isModalFocused()) || mFocusHandler->GetModalFocused() == NULL) { sourceWidget->requestFocus(); } if (mouseInput.getTimeStamp() - mLastMousePressTimeStamp < 250 && mLastMousePressButton == mouseInput.getButton()) { mClickCount++; } else { mClickCount = 1; } distributeMouseEvent(sourceWidget, MouseEvent::PRESSED, mouseInput.getButton(), mouseInput.getX(), mouseInput.getY()); mFocusHandler->SetLastWidgetPressed(sourceWidget); mFocusHandler->SetDraggedWidget(sourceWidget); mLastMouseDragButton = mouseInput.getButton(); mLastMousePressButton = mouseInput.getButton(); mLastMousePressTimeStamp = mouseInput.getTimeStamp(); }
void Gui::distributeMouseEvent(WidgetPtr source, int type, int button, int x, int y, bool force, bool toSourceOnly) { WidgetPtr parent = source; WidgetPtr widget = source; if (mFocusHandler->GetModalFocused() && !widget->isModalFocused() && !force) { return; } if (mFocusHandler->GetModalMouseInputFocused() && !widget->isModalMouseInputFocused() && !force) { return; } MouseEvent mouseEvent(source, mShiftPressed, mControlPressed, mAltPressed, mMetaPressed, type, button, x, y, mClickCount); while (parent != NULL) { // If the widget has been removed due to input // cancel the distribution. if (!Widget::widgetExists(widget)) { break; } parent = (WidgetPtr)widget->GetParent(); if (widget->IsEnabled() || force) { int widgetX, widgetY; widget->getAbsolutePosition(widgetX, widgetY); mouseEvent.mX = x - widgetX; mouseEvent.mY = y - widgetY; std::list<MouseListener*> mouseListeners = widget->_getMouseListeners(); // Send the event to all mouse listeners of the widget. for (std::list<MouseListener*>::iterator it = mouseListeners.begin(); it != mouseListeners.end(); ++it) { switch (mouseEvent.getType()) { case MouseEvent::ENTERED: (*it)->MouseEntered(mouseEvent); break; case MouseEvent::EXITED: (*it)->MouseExited(mouseEvent); break; case MouseEvent::MOVED: (*it)->mouseMoved(mouseEvent); break; case MouseEvent::PRESSED: (*it)->mousePressed(mouseEvent); break; case MouseEvent::RELEASED: (*it)->mouseReleased(mouseEvent); break; case MouseEvent::WHEEL_MOVED_UP: (*it)->mouseWheelMovedUp(mouseEvent); break; case MouseEvent::WHEEL_MOVED_DOWN: (*it)->mouseWheelMovedDown(mouseEvent); break; case MouseEvent::DRAGGED: (*it)->mouseDragged(mouseEvent); break; case MouseEvent::CLICKED: (*it)->mouseClicked(mouseEvent); break; default: throw GCN_EXCEPTION("Unknown mouse event type."); } } if (toSourceOnly) { break; } } WidgetPtr swap = widget; widget = parent; parent = (WidgetPtr)swap->GetParent(); // If a non modal focused widget has been reach // and we have modal focus cancel the distribution. if (mFocusHandler->GetModalFocused() != NULL && !widget->isModalFocused()) { break; } // If a non modal mouse input focused widget has been reach // and we have modal mouse input focus cancel the distribution. if (mFocusHandler->GetModalMouseInputFocused() != NULL && !widget->isModalMouseInputFocused()) { break; } } }
void Gui::handleMouseMoved(const MouseInput& mouseInput) { // Check if the mouse leaves the application window. if (!mWidgetWithMouseQueue.empty() && (mouseInput.getX() < 0 || mouseInput.getY() < 0 || !mTop->GetDimension().isPointInRect(mouseInput.getX(), mouseInput.getY())) ) { // Distribute an event to all widgets in the "widget with mouse" queue. while (!mWidgetWithMouseQueue.empty()) { WidgetPtr widget = mWidgetWithMouseQueue.front(); if (Widget::widgetExists(widget)) { distributeMouseEvent(widget, MouseEvent::EXITED, mouseInput.getButton(), mouseInput.getX(), mouseInput.getY(), true, true); } mWidgetWithMouseQueue.pop_front(); } return; } // Check if there is a need to send mouse exited events by // traversing the "widget with mouse" queue. bool widgetWithMouseQueueCheckDone = mWidgetWithMouseQueue.empty(); while (!widgetWithMouseQueueCheckDone) { unsigned int iterations = 0; std::deque<WidgetPtr>::iterator iter; for (iter = mWidgetWithMouseQueue.begin(); iter != mWidgetWithMouseQueue.end(); iter++) { WidgetPtr widget = *iter; // If a widget in the "widget with mouse queue" doesn't // exists anymore it should be removed from the queue. if (!Widget::widgetExists(widget)) { mWidgetWithMouseQueue.erase(iter); break; } else { int x, y; widget->getAbsolutePosition(x, y); if (x > mouseInput.getX() || y > mouseInput.getY() || x + widget->GetWidth() <= mouseInput.getX() || y + widget->GetHeight() <= mouseInput.getY() || !widget->IsVisible()) { distributeMouseEvent(widget, MouseEvent::EXITED, mouseInput.getButton(), mouseInput.getX(), mouseInput.getY(), true, true); mClickCount = 1; mLastMousePressTimeStamp = 0; mWidgetWithMouseQueue.erase(iter); break; } } iterations++; } widgetWithMouseQueueCheckDone = iterations == mWidgetWithMouseQueue.size(); } // Check all widgets below the mouse to see if they are // present in the "widget with mouse" queue. If a widget // is not then it should be added and an entered event should // be sent to it. WidgetPtr parent = GetMouseEventSource(mouseInput.getX(), mouseInput.getY()); WidgetPtr widget = parent; // If a widget has modal mouse input focus then it will // always be returned from getMouseEventSource, but we only wan't to send // mouse entered events if the mouse has actually entered the widget with // modal mouse input focus, hence we need to check if that's the case. If // it's not we should simply ignore to send any mouse entered events. if (mFocusHandler->GetModalMouseInputFocused() && widget == mFocusHandler->GetModalMouseInputFocused() && Widget::widgetExists(widget)) { int x, y; widget->getAbsolutePosition(x, y); if (x > mouseInput.getX() || y > mouseInput.getY() || x + widget->GetWidth() <= mouseInput.getX() || y + widget->GetHeight() <= mouseInput.getY()) { parent.reset(); } } while (parent) { parent = widget->GetParent(); // Check if the widget is present in the "widget with mouse" queue. bool widgetIsPresentInQueue = false; std::deque<WidgetPtr>::iterator iter; for (iter = mWidgetWithMouseQueue.begin(); iter != mWidgetWithMouseQueue.end(); iter++) { if (*iter == widget) { widgetIsPresentInQueue = true; break; } } // Widget is not present, send an entered event and add // it to the "widget with mouse" queue. if (!widgetIsPresentInQueue && Widget::widgetExists(widget)) { distributeMouseEvent(widget, MouseEvent::ENTERED, mouseInput.getButton(), mouseInput.getX(), mouseInput.getY(), true, true); mWidgetWithMouseQueue.push_front(widget); } WidgetPtr swap = widget; widget = parent; parent = (WidgetPtr)swap->GetParent(); } if (mFocusHandler->GetDraggedWidget()) { distributeMouseEvent(mFocusHandler->GetDraggedWidget(), MouseEvent::DRAGGED, mLastMouseDragButton, mouseInput.getX(), mouseInput.getY()); } else { WidgetPtr sourceWidget = GetMouseEventSource(mouseInput.getX(), mouseInput.getY()); distributeMouseEvent(sourceWidget, MouseEvent::MOVED, mouseInput.getButton(), mouseInput.getX(), mouseInput.getY()); } }