diff --git a/include/ignition/gui/Conversions.hh b/include/ignition/gui/Conversions.hh index c7e3a7cee..ecc1fa692 100644 --- a/include/ignition/gui/Conversions.hh +++ b/include/ignition/gui/Conversions.hh @@ -44,13 +44,13 @@ namespace ignition namespace gui { - /// \brief Return the equivalent qt color + /// \brief Return the equivalent Qt color /// \param[in] _color Ignition color to convert /// \return Qt color value IGNITION_GUI_VISIBLE QColor convert(const math::Color &_color); - /// \brief Return the equivalent ignition color + /// \brief Return the equivalent Ignition color /// \param[in] _color Qt color to convert /// \return Ignition color value IGNITION_GUI_VISIBLE @@ -62,25 +62,25 @@ namespace ignition IGNITION_GUI_VISIBLE QPointF convert(const math::Vector2d &_pt); - /// \brief Return the equivalent ignition vector. + /// \brief Return the equivalent Ignition vector. /// \param[in] _pt QPointF to convert /// \return Ignition Vector2d. IGNITION_GUI_VISIBLE math::Vector2d convert(const QPointF &_pt); - /// \brief Return the equivalent qt vector 3d. + /// \brief Return the equivalent Qt vector 3d. /// \param[in] _vec Ignition vector 3d to convert. /// \return Qt vector 3d value. IGNITION_GUI_VISIBLE QVector3D convert(const math::Vector3d &_vec); - /// \brief Return the equivalent ignition vector 3d. + /// \brief Return the equivalent Ignition vector 3d. /// \param[in] _vec Qt vector 3d to convert. /// \return Ignition vector 3d value IGNITION_GUI_VISIBLE math::Vector3d convert(const QVector3D &_vec); - /// \brief Return the equivalent ignition mouse event. + /// \brief Return the equivalent Ignition mouse event. /// /// Note that there isn't a 1-1 mapping between these types, so fields such /// as common::MouseEvent::PressPos need to be set afterwards. @@ -89,6 +89,14 @@ namespace ignition IGNITION_GUI_VISIBLE common::MouseEvent convert(const QMouseEvent &_e); + /// \brief Return the equivalent Ignition mouse event. + /// + /// Note that there isn't a 1-1 mapping between these types. + /// \param[in] _e Qt wheel event + /// \return Ignition mouse event + IGNITION_GUI_VISIBLE + common::MouseEvent convert(const QWheelEvent &_e); + /// \brief Return the equivalent ignition key event. /// /// \param[in] _e Qt key event diff --git a/include/ignition/gui/GuiEvents.hh b/include/ignition/gui/GuiEvents.hh index 2219e3acb..8b0c2f469 100644 --- a/include/ignition/gui/GuiEvents.hh +++ b/include/ignition/gui/GuiEvents.hh @@ -151,7 +151,7 @@ namespace ignition }; /// \brief Event which is called to broadcast the 3D coordinates of a - /// user's left click within the scene. + /// user's releasing the left button within the scene. /// \sa LeftClickOnScene class IGNITION_GUI_VISIBLE LeftClickToScene : public QEvent { @@ -173,7 +173,7 @@ namespace ignition }; /// \brief Event which is called to broadcast the 3D coordinates of a - /// user's right click within the scene. + /// user's releasing the right button within the scene. /// \sa RightClickOnScene class IGNITION_GUI_VISIBLE RightClickToScene : public QEvent { @@ -257,7 +257,7 @@ namespace ignition }; /// \brief Event which is called to broadcast information about left - /// mouse clicks on the scene. + /// mouse releases on the scene. /// For the 3D coordinates of that point on the scene, see /// `LeftClickToScene`. /// \sa LeftClickToScene @@ -280,7 +280,7 @@ namespace ignition }; /// \brief Event which is called to broadcast information about right - /// mouse clicks on the scene. + /// mouse releases on the scene. /// For the 3D coordinates of that point on the scene, see /// `RightClickToScene`. /// \sa RightClickToScene @@ -329,8 +329,7 @@ namespace ignition class IGNITION_GUI_VISIBLE HoverOnScene : public QEvent { /// \brief Constructor - /// \param[in] _point The point at which the mouse is hovering within - /// the scene + /// \param[in] _mouse The hover mouse event on the scene public: explicit HoverOnScene(const common::MouseEvent &_mouse); /// \brief Unique type for this event. @@ -390,6 +389,66 @@ namespace ignition /// \brief Private data pointer IGN_UTILS_IMPL_PTR(dataPtr) }; + + /// \brief Event which is called to broadcast information about mouse + /// scrolls on the scene. + class IGNITION_GUI_VISIBLE ScrollOnScene : public QEvent + { + /// \brief Constructor + /// \param[in] _mouse The scroll mouse event on the scene + public: explicit ScrollOnScene(const common::MouseEvent &_mouse); + + /// \brief Unique type for this event. + static const QEvent::Type kType = QEvent::Type(QEvent::MaxUser - 16); + + /// \brief Return the scroll mouse event + public: const common::MouseEvent &Mouse() const; + + /// \internal + /// \brief Private data pointer + IGN_UTILS_IMPL_PTR(dataPtr) + }; + + /// \brief Event which is called to broadcast information about mouse + /// drags on the scene. + class IGNITION_GUI_VISIBLE DragOnScene : public QEvent + { + /// \brief Constructor + /// \param[in] _mouse The drag mouse event on the scene + public: explicit DragOnScene(const common::MouseEvent &_mouse); + + /// \brief Unique type for this event. + static const QEvent::Type kType = QEvent::Type(QEvent::MaxUser - 17); + + /// \brief Get the point within the scene over which the user is + /// dragging. + /// \return The 2D point + public: common::MouseEvent Mouse() const; + + /// \internal + /// \brief Private data pointer + IGN_UTILS_IMPL_PTR(dataPtr) + }; + + /// \brief Event which is called to broadcast information about mouse + /// presses on the scene, with right, left or middle buttons. + class IGNITION_GUI_VISIBLE MousePressOnScene : public QEvent + { + /// \brief Constructor + /// \param[in] _mouse The mouse event on the scene + public: MousePressOnScene( + const common::MouseEvent &_mouse); + + /// \brief Unique type for this event. + static const QEvent::Type kType = QEvent::Type(QEvent::MaxUser - 18); + + /// \brief Return the button press mouse event + public: const common::MouseEvent &Mouse() const; + + /// \internal + /// \brief Private data pointer + IGN_UTILS_IMPL_PTR(dataPtr) + }; } } } diff --git a/src/Conversions.cc b/src/Conversions.cc index 089fa25a7..aa6869f81 100644 --- a/src/Conversions.cc +++ b/src/Conversions.cc @@ -114,6 +114,43 @@ ignition::common::MouseEvent ignition::gui::convert(const QMouseEvent &_e) return event; } +////////////////////////////////////////////////// +ignition::common::MouseEvent ignition::gui::convert(const QWheelEvent &_e) +{ + common::MouseEvent event; + + event.SetType(common::MouseEvent::SCROLL); +#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) + event.SetPos(_e.x(), _e.y()); +#else + event.SetPos(_e.position().x(), _e.position().y()); +#endif + double scroll = (_e.angleDelta().y() > 0) ? -1.0 : 1.0; + event.SetScroll(scroll, scroll); + + // Buttons + if (_e.buttons() & Qt::LeftButton) + event.SetButtons(event.Buttons() | common::MouseEvent::LEFT); + + if (_e.buttons() & Qt::RightButton) + event.SetButtons(event.Buttons() | common::MouseEvent::RIGHT); + + if (_e.buttons() & Qt::MiddleButton) + event.SetButtons(event.Buttons() | common::MouseEvent::MIDDLE); + + // Modifiers + if (_e.modifiers() & Qt::ShiftModifier) + event.SetShift(true); + + if (_e.modifiers() & Qt::ControlModifier) + event.SetControl(true); + + if (_e.modifiers() & Qt::AltModifier) + event.SetAlt(true); + + return event; +} + ////////////////////////////////////////////////// ignition::common::KeyEvent ignition::gui::convert(const QKeyEvent &_e) { diff --git a/src/Conversions_TEST.cc b/src/Conversions_TEST.cc index 065ab8ce8..266ca0709 100644 --- a/src/Conversions_TEST.cc +++ b/src/Conversions_TEST.cc @@ -146,6 +146,28 @@ TEST(ConversionsTest, MouseEvent) EXPECT_TRUE(ignEvent.Dragging()); EXPECT_TRUE(ignEvent.Alt()); } + + // Scroll + { +#if QT_VERSION < QT_VERSION_CHECK(5, 12, 0) + QWheelEvent qtEvent(QPointF(123, 456), QPointF(1000, 2000), QPoint(2, 3), + QPoint(1, 4), -1, Qt::Horizontal, Qt::MiddleButton, Qt::ShiftModifier, + Qt::ScrollUpdate, Qt::MouseEventNotSynthesized, false); +#else + QWheelEvent qtEvent(QPointF(123, 456), QPointF(1000, 2000), QPoint(2, 3), + QPoint(1, 4), Qt::MiddleButton, Qt::ShiftModifier, Qt::ScrollUpdate, + false); +#endif + + auto ignEvent = convert(qtEvent); + + EXPECT_EQ(ignEvent.Type(), common::MouseEvent::SCROLL); + EXPECT_EQ(ignEvent.Pos(), math::Vector2i(123, 456)); + EXPECT_EQ(ignEvent.Scroll(), math::Vector2i(-1, -1)); + EXPECT_EQ(ignEvent.Buttons(), common::MouseEvent::MIDDLE); + EXPECT_FALSE(ignEvent.Dragging()); + EXPECT_TRUE(ignEvent.Shift()); + } } ///////////////////////////////////////////////// diff --git a/src/GuiEvents.cc b/src/GuiEvents.cc index 4664d70e4..16cacc25b 100644 --- a/src/GuiEvents.cc +++ b/src/GuiEvents.cc @@ -118,6 +118,24 @@ class ignition::gui::events::DropOnScene::Implementation public: ignition::math::Vector2i mouse; }; +class ignition::gui::events::ScrollOnScene::Implementation +{ + /// \brief Mouse event with scroll information. + public: common::MouseEvent mouse; +}; + +class ignition::gui::events::DragOnScene::Implementation +{ + /// \brief Mouse event with drag information. + public: common::MouseEvent mouse; +}; + +class ignition::gui::events::MousePressOnScene::Implementation +{ + /// \brief Mouse event with press information. + public: common::MouseEvent mouse; +}; + using namespace ignition; using namespace gui; using namespace events; @@ -344,3 +362,42 @@ const ignition::math::Vector2i &DropOnScene::Mouse() const { return this->dataPtr->mouse; } + +///////////////////////////////////////////////// +ScrollOnScene::ScrollOnScene(const common::MouseEvent &_mouse) + : QEvent(kType), dataPtr(utils::MakeImpl()) +{ + this->dataPtr->mouse = _mouse; +} + +///////////////////////////////////////////////// +const common::MouseEvent &ScrollOnScene::Mouse() const +{ + return this->dataPtr->mouse; +} + +///////////////////////////////////////////////// +DragOnScene::DragOnScene(const common::MouseEvent &_mouse) + : QEvent(kType), dataPtr(utils::MakeImpl()) +{ + this->dataPtr->mouse = _mouse; +} + +///////////////////////////////////////////////// +common::MouseEvent DragOnScene::Mouse() const +{ + return this->dataPtr->mouse; +} + +///////////////////////////////////////////////// +MousePressOnScene::MousePressOnScene(const common::MouseEvent &_mouse) + : QEvent(kType), dataPtr(utils::MakeImpl()) +{ + this->dataPtr->mouse = _mouse; +} + +///////////////////////////////////////////////// +const common::MouseEvent &MousePressOnScene::Mouse() const +{ + return this->dataPtr->mouse; +} diff --git a/src/GuiEvents_TEST.cc b/src/GuiEvents_TEST.cc index 3342523ce..a72e23864 100644 --- a/src/GuiEvents_TEST.cc +++ b/src/GuiEvents_TEST.cc @@ -212,3 +212,45 @@ TEST(GuiEventsTest, DropOnScene) EXPECT_EQ(ignition::math::Vector2i(3, 100), dropOnScene.Mouse()); EXPECT_EQ("text", dropOnScene.DropText()); } + +///////////////////////////////////////////////// +TEST(GuiEventsTest, ScrollOnScene) +{ + ignition::common::MouseEvent mouse; + mouse.SetControl(true); + mouse.SetAlt(true); + events::ScrollOnScene event(mouse); + + EXPECT_LT(QEvent::User, event.type()); + EXPECT_TRUE(event.Mouse().Control()); + EXPECT_TRUE(event.Mouse().Alt()); + EXPECT_FALSE(event.Mouse().Shift()); +} + +///////////////////////////////////////////////// +TEST(GuiEventsTest, DragOnScene) +{ + ignition::common::MouseEvent mouse; + mouse.SetControl(true); + mouse.SetAlt(true); + events::DragOnScene event(mouse); + + EXPECT_LT(QEvent::User, event.type()); + EXPECT_TRUE(event.Mouse().Control()); + EXPECT_TRUE(event.Mouse().Alt()); + EXPECT_FALSE(event.Mouse().Shift()); +} + +///////////////////////////////////////////////// +TEST(GuiEventsTest, MousePressOnScene) +{ + ignition::common::MouseEvent mouse; + mouse.SetControl(true); + mouse.SetAlt(true); + events::MousePressOnScene event(mouse); + + EXPECT_LT(QEvent::User, event.type()); + EXPECT_TRUE(event.Mouse().Control()); + EXPECT_TRUE(event.Mouse().Alt()); + EXPECT_FALSE(event.Mouse().Shift()); +} diff --git a/src/plugins/interactive_view_control/InteractiveViewControl.cc b/src/plugins/interactive_view_control/InteractiveViewControl.cc index 134f5e6c8..f15a6a46d 100644 --- a/src/plugins/interactive_view_control/InteractiveViewControl.cc +++ b/src/plugins/interactive_view_control/InteractiveViewControl.cc @@ -31,6 +31,7 @@ #include #include #include +#include #include @@ -42,12 +43,6 @@ class ignition::gui::plugins::InteractiveViewControlPrivate /// \brief Perform rendering calls in the rendering thread. public: void OnRender(); - /// \brief Transform a position on screen to the first point that's hit on - /// the 3D scene - /// \param[in] _screenPos Position on 2D screen within the 3D scene - /// \return First point hit on the 3D scene. - public: math::Vector3d ScreenToScene(const math::Vector2i &_screenPos) const; - /// \brief Callback for camera view controller request /// \param[in] _msg Request message to set the camera view controller /// \param[in] _res Response data @@ -149,7 +144,7 @@ void InteractiveViewControlPrivate::OnRender() if (this->blockOrbit) { - this->drag = 0; + this->drag = {0, 0}; return; } @@ -180,21 +175,23 @@ void InteractiveViewControlPrivate::OnRender() if (this->mouseEvent.Type() == common::MouseEvent::SCROLL) { - this->target = this->ScreenToScene(this->mouseEvent.Pos()); + this->target = rendering::screenToScene( + this->mouseEvent.Pos(), this->camera, this->rayQuery); + this->viewControl->SetTarget(this->target); double distance = this->camera->WorldPosition().Distance( this->target); double amount = -this->drag.Y() * distance / 5.0; this->viewControl->Zoom(amount); } + else if (this->mouseEvent.Type() == common::MouseEvent::PRESS) + { + this->target = rendering::screenToScene( + this->mouseEvent.PressPos(), this->camera, this->rayQuery); + this->viewControl->SetTarget(this->target); + } else { - if (this->drag == math::Vector2d::Zero) - { - this->target = this->ScreenToScene(this->mouseEvent.PressPos()); - this->viewControl->SetTarget(this->target); - } - // Pan with left button if (this->mouseEvent.Buttons() & common::MouseEvent::LEFT) { @@ -224,30 +221,6 @@ void InteractiveViewControlPrivate::OnRender() this->mouseDirty = false; } -///////////////////////////////////////////////// -math::Vector3d InteractiveViewControlPrivate::ScreenToScene( - const math::Vector2i &_screenPos) const -{ - // Normalize point on the image - double width = this->camera->ImageWidth(); - double height = this->camera->ImageHeight(); - - double nx = 2.0 * _screenPos.X() / width - 1.0; - double ny = 1.0 - 2.0 * _screenPos.Y() / height; - - // Make a ray query - this->rayQuery->SetFromCamera( - this->camera, math::Vector2d(nx, ny)); - - auto result = this->rayQuery->ClosestPoint(); - if (result) - return result.point; - - // Set point to be 10m away if no intersection found - return this->rayQuery->Origin() + - this->rayQuery->Direction() * 10; -} - ///////////////////////////////////////////////// bool InteractiveViewControlPrivate::OnViewControl(const msgs::StringMsg &_msg, msgs::Boolean &_res) @@ -309,26 +282,43 @@ bool InteractiveViewControl::eventFilter(QObject *_obj, QEvent *_event) reinterpret_cast(_event); this->dataPtr->mouseDirty = true; - auto dragInt = - leftClickOnScene->Mouse().Pos() - this->dataPtr->mouseEvent.Pos(); + this->dataPtr->drag = math::Vector2d::Zero; + this->dataPtr->mouseEvent = leftClickOnScene->Mouse(); + } + else if (_event->type() == events::MousePressOnScene::kType) + { + auto pressOnScene = + reinterpret_cast(_event); + this->dataPtr->mouseDirty = true; + + this->dataPtr->drag = math::Vector2d::Zero; + this->dataPtr->mouseEvent = pressOnScene->Mouse(); + } + else if (_event->type() == events::DragOnScene::kType) + { + auto dragOnScene = + reinterpret_cast(_event); + this->dataPtr->mouseDirty = true; + + auto dragStart = this->dataPtr->mouseEvent.Pos(); + auto dragInt = dragOnScene->Mouse().Pos() - dragStart; auto dragDistance = math::Vector2d(dragInt.X(), dragInt.Y()); - if (leftClickOnScene->Mouse().Dragging()) { - this->dataPtr->drag += dragDistance; - } - else if (leftClickOnScene->Mouse().Type() == - ignition::common::MouseEvent::SCROLL) - { - this->dataPtr->drag += math::Vector2d( - leftClickOnScene->Mouse().Scroll().X(), - leftClickOnScene->Mouse().Scroll().Y()); - } - else - { - this->dataPtr->drag += 0; - } + this->dataPtr->drag += dragDistance; - this->dataPtr->mouseEvent = leftClickOnScene->Mouse(); + this->dataPtr->mouseEvent = dragOnScene->Mouse(); + } + else if (_event->type() == events::ScrollOnScene::kType) + { + auto scrollOnScene = + reinterpret_cast(_event); + this->dataPtr->mouseDirty = true; + + this->dataPtr->drag += math::Vector2d( + scrollOnScene->Mouse().Scroll().X(), + scrollOnScene->Mouse().Scroll().Y()); + + this->dataPtr->mouseEvent = scrollOnScene->Mouse(); } else if (_event->type() == ignition::gui::events::BlockOrbit::kType) { diff --git a/src/plugins/minimal_scene/MinimalScene.cc b/src/plugins/minimal_scene/MinimalScene.cc index c125d6733..3e7fe3174 100644 --- a/src/plugins/minimal_scene/MinimalScene.cc +++ b/src/plugins/minimal_scene/MinimalScene.cc @@ -318,29 +318,17 @@ void IgnRenderer::HandleMouseEvent() { std::lock_guard lock(this->dataPtr->mutex); this->BroadcastHoverPos(); + this->BroadcastDrag(); + this->BroadcastMousePress(); this->BroadcastLeftClick(); this->BroadcastRightClick(); + this->BroadcastScroll(); this->BroadcastKeyPress(); this->BroadcastKeyRelease(); this->BroadcastDrop(); - this->HandleMouseViewControl(); this->dataPtr->mouseDirty = false; } -///////////////////////////////////////////////// -void IgnRenderer::HandleMouseViewControl() -{ - if (!this->dataPtr->mouseDirty) - return; - - auto pos = this->ScreenToScene(this->dataPtr->mouseEvent.Pos()); - - events::LeftClickOnScene leftClickOnSceneEvent(this->dataPtr->mouseEvent); - events::LeftClickToScene leftClickToSceneEvent(pos); - App()->sendEvent(App()->findChild(), &leftClickOnSceneEvent); - App()->sendEvent(App()->findChild(), &leftClickToSceneEvent); -} - //////////////////////////////////////////////// void IgnRenderer::HandleKeyPress(const common::KeyEvent &_e) { @@ -393,15 +381,30 @@ void IgnRenderer::BroadcastHoverPos() hoverMouseEvent.SetType(common::MouseEvent::MOVE); events::HoverOnScene hoverOnSceneEvent(hoverMouseEvent); App()->sendEvent(App()->findChild(), &hoverOnSceneEvent); + + this->dataPtr->hoverDirty = false; } ///////////////////////////////////////////////// -void IgnRenderer::BroadcastLeftClick() +void IgnRenderer::BroadcastDrag() { if (!this->dataPtr->mouseDirty) return; - if (this->dataPtr->mouseEvent.Dragging()) + // Only broadcast drag if dragging + if (!this->dataPtr->mouseEvent.Dragging()) + return; + + events::DragOnScene dragEvent(this->dataPtr->mouseEvent); + App()->sendEvent(App()->findChild(), &dragEvent); + + this->dataPtr->mouseDirty = false; +} + +///////////////////////////////////////////////// +void IgnRenderer::BroadcastLeftClick() +{ + if (!this->dataPtr->mouseDirty) return; if (this->dataPtr->mouseEvent.Button() != common::MouseEvent::LEFT || @@ -412,6 +415,11 @@ void IgnRenderer::BroadcastLeftClick() events::LeftClickToScene leftClickToSceneEvent(pos); App()->sendEvent(App()->findChild(), &leftClickToSceneEvent); + + events::LeftClickOnScene leftClickOnSceneEvent(this->dataPtr->mouseEvent); + App()->sendEvent(App()->findChild(), &leftClickOnSceneEvent); + + this->dataPtr->mouseDirty = false; } ///////////////////////////////////////////////// @@ -420,9 +428,6 @@ void IgnRenderer::BroadcastRightClick() if (!this->dataPtr->mouseDirty) return; - if (this->dataPtr->mouseEvent.Dragging()) - return; - if (this->dataPtr->mouseEvent.Button() != common::MouseEvent::RIGHT || this->dataPtr->mouseEvent.Type() != common::MouseEvent::RELEASE) return; @@ -431,31 +436,65 @@ void IgnRenderer::BroadcastRightClick() events::RightClickToScene rightClickToSceneEvent(pos); App()->sendEvent(App()->findChild(), &rightClickToSceneEvent); + events::RightClickOnScene rightClickOnSceneEvent(this->dataPtr->mouseEvent); App()->sendEvent(App()->findChild(), &rightClickOnSceneEvent); + + this->dataPtr->mouseDirty = false; +} + +///////////////////////////////////////////////// +void IgnRenderer::BroadcastMousePress() +{ + if (!this->dataPtr->mouseDirty) + return; + + if (this->dataPtr->mouseEvent.Type() != common::MouseEvent::PRESS) + return; + + events::MousePressOnScene event(this->dataPtr->mouseEvent); + App()->sendEvent(App()->findChild(), &event); + + this->dataPtr->mouseDirty = false; } +///////////////////////////////////////////////// +void IgnRenderer::BroadcastScroll() +{ + if (!this->dataPtr->mouseDirty) + return; + + if (this->dataPtr->mouseEvent.Type() != common::MouseEvent::SCROLL) + return; + + events::ScrollOnScene scrollOnSceneEvent(this->dataPtr->mouseEvent); + App()->sendEvent(App()->findChild(), &scrollOnSceneEvent); + + this->dataPtr->mouseDirty = false; +} ///////////////////////////////////////////////// void IgnRenderer::BroadcastKeyRelease() { - if (this->dataPtr->keyEvent.Type() == common::KeyEvent::RELEASE) - { - events::KeyReleaseOnScene keyRelease(this->dataPtr->keyEvent); - App()->sendEvent(App()->findChild(), &keyRelease); - this->dataPtr->keyEvent.SetType(common::KeyEvent::NO_EVENT); - } + if (this->dataPtr->keyEvent.Type() != common::KeyEvent::RELEASE) + return; + + events::KeyReleaseOnScene keyRelease(this->dataPtr->keyEvent); + App()->sendEvent(App()->findChild(), &keyRelease); + + this->dataPtr->keyEvent.SetType(common::KeyEvent::NO_EVENT); } ///////////////////////////////////////////////// void IgnRenderer::BroadcastKeyPress() { - if (this->dataPtr->keyEvent.Type() == common::KeyEvent::PRESS) - { - events::KeyPressOnScene keyPress(this->dataPtr->keyEvent); - App()->sendEvent(App()->findChild(), &keyPress); - this->dataPtr->keyEvent.SetType(common::KeyEvent::NO_EVENT); - } + if (this->dataPtr->keyEvent.Type() != common::KeyEvent::PRESS) + return; + + events::KeyPressOnScene keyPress(this->dataPtr->keyEvent); + App()->sendEvent(App()->findChild(), &keyPress); + + this->dataPtr->keyEvent.SetType(common::KeyEvent::NO_EVENT); } ///////////////////////////////////////////////// @@ -1056,9 +1095,8 @@ void RenderWindowItem::OnDropped(const QString &_drop, ///////////////////////////////////////////////// void RenderWindowItem::mousePressEvent(QMouseEvent *_e) { - auto pressPos = this->dataPtr->mouseEvent.PressPos(); this->dataPtr->mouseEvent = convert(*_e); - this->dataPtr->mouseEvent.SetPressPos(pressPos); + this->dataPtr->mouseEvent.SetPressPos(this->dataPtr->mouseEvent.Pos()); this->dataPtr->renderThread->ignRenderer.NewMouseEvent( this->dataPtr->mouseEvent); @@ -1087,8 +1125,13 @@ void RenderWindowItem::keyReleaseEvent(QKeyEvent *_e) //////////////////////////////////////////////// void RenderWindowItem::mouseReleaseEvent(QMouseEvent *_e) { + // Store values that depend on previous events + auto pressPos = this->dataPtr->mouseEvent.PressPos(); + auto dragging = this->dataPtr->mouseEvent.Dragging(); + this->dataPtr->mouseEvent = convert(*_e); - this->dataPtr->mouseEvent.SetPressPos(_e->pos().x(), _e->pos().y()); + this->dataPtr->mouseEvent.SetPressPos(pressPos); + this->dataPtr->mouseEvent.SetDragging(dragging); this->dataPtr->renderThread->ignRenderer.NewMouseEvent( this->dataPtr->mouseEvent); @@ -1097,29 +1140,26 @@ void RenderWindowItem::mouseReleaseEvent(QMouseEvent *_e) //////////////////////////////////////////////// void RenderWindowItem::mouseMoveEvent(QMouseEvent *_e) { - auto event = convert(*_e); - event.SetPressPos(this->dataPtr->mouseEvent.PressPos()); + // Store values that depend on previous events + auto pressPos = this->dataPtr->mouseEvent.PressPos(); - if (!event.Dragging()) - return; + this->dataPtr->mouseEvent = convert(*_e); + + if (this->dataPtr->mouseEvent.Dragging()) + this->dataPtr->mouseEvent.SetPressPos(pressPos); - this->dataPtr->renderThread->ignRenderer.NewMouseEvent(event); - this->dataPtr->mouseEvent = event; + this->dataPtr->renderThread->ignRenderer.NewMouseEvent( + this->dataPtr->mouseEvent); } //////////////////////////////////////////////// void RenderWindowItem::wheelEvent(QWheelEvent *_e) { - this->dataPtr->mouseEvent.SetType(common::MouseEvent::SCROLL); -#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) - this->dataPtr->mouseEvent.SetPos(_e->x(), _e->y()); -#else - this->dataPtr->mouseEvent.SetPos(_e->position().x(), _e->position().y()); -#endif - double scroll = (_e->angleDelta().y() > 0) ? -1.0 : 1.0; + this->forceActiveFocus(); + + this->dataPtr->mouseEvent = convert(*_e); this->dataPtr->renderThread->ignRenderer.NewMouseEvent( this->dataPtr->mouseEvent); - this->dataPtr->mouseEvent.SetScroll(scroll, scroll); } //////////////////////////////////////////////// diff --git a/src/plugins/minimal_scene/MinimalScene.hh b/src/plugins/minimal_scene/MinimalScene.hh index f56ae2095..c1c02a6f9 100644 --- a/src/plugins/minimal_scene/MinimalScene.hh +++ b/src/plugins/minimal_scene/MinimalScene.hh @@ -133,18 +133,24 @@ namespace plugins /// \brief Handle mouse event for view control private: void HandleMouseEvent(); - /// \brief Handle mouse event for view control - private: void HandleMouseViewControl(); - /// \brief Broadcasts the currently hovered 3d scene location. private: void BroadcastHoverPos(); - /// \brief Broadcasts a left click within the scene + /// \brief Broadcasts drag events. + private: void BroadcastDrag(); + + /// \brief Broadcasts a left click (release) within the scene private: void BroadcastLeftClick(); - /// \brief Broadcasts a right click within the scene + /// \brief Broadcasts a right click (release) within the scene private: void BroadcastRightClick(); + /// \brief Broadcasts a mouse press within the scene + private: void BroadcastMousePress(); + + /// \brief Broadcasts a scroll event within the scene. + private: void BroadcastScroll(); + /// \brief Broadcasts a key release event within the scene private: void BroadcastKeyRelease();