diff --git a/src/renderedtarget.cpp b/src/renderedtarget.cpp index 9bad239..38c7147 100644 --- a/src/renderedtarget.cpp +++ b/src/renderedtarget.cpp @@ -180,6 +180,15 @@ void RenderedTarget::beforeRedraw() m_oldTexture = m_texture; update(); } + + // Update drag position + if (m_spriteModel) { + Sprite *sprite = m_spriteModel->sprite(); + Q_ASSERT(sprite); + + if (sprite->dragging()) + sprite->dragToPosition(m_dragX, m_dragY); + } } void RenderedTarget::deinitClone() @@ -486,9 +495,11 @@ void RenderedTarget::mouseReleaseEvent(QMouseEvent *event) Q_ASSERT(m_mouseArea); // Stop dragging - if (m_mouseArea->draggedSprite() == this) + if (m_mouseArea->draggedSprite() == this) { + Sprite *sprite = m_spriteModel->sprite(); + sprite->stopDragging(); m_mouseArea->setDraggedSprite(nullptr); - else if (m_engine && m_spriteModel && m_spriteModel->sprite()->draggable()) { + } else if (m_engine && m_spriteModel && m_spriteModel->sprite()->draggable()) { // Notify libscratchcpp about the click m_engine->clickTarget(scratchTarget()); } @@ -503,6 +514,7 @@ void RenderedTarget::mouseMoveEvent(QMouseEvent *event) if (m_clicked && !m_mouseArea->draggedSprite() && m_spriteModel && m_spriteModel->sprite()->draggable()) { Q_ASSERT(m_engine); Sprite *sprite = m_spriteModel->sprite(); + sprite->startDragging(); m_dragDeltaX = m_engine->mouseX() - sprite->x(); m_dragDeltaY = m_engine->mouseY() - sprite->y(); m_mouseArea->setDraggedSprite(this); @@ -755,11 +767,9 @@ void RenderedTarget::handleSceneMouseMove(qreal x, qreal y) Q_ASSERT(m_mouseArea); if (m_mouseArea->draggedSprite() == this) { - Q_ASSERT(m_spriteModel && m_spriteModel->sprite()); Q_ASSERT(m_engine); - Sprite *sprite = m_spriteModel->sprite(); - sprite->setX(x / m_stageScale - m_engine->stageWidth() / 2.0 - m_dragDeltaX); - sprite->setY(-y / m_stageScale + m_engine->stageHeight() / 2.0 - m_dragDeltaY); + m_dragX = x / m_stageScale - m_engine->stageWidth() / 2.0 - m_dragDeltaX; + m_dragY = -y / m_stageScale + m_engine->stageHeight() / 2.0 - m_dragDeltaY; } } diff --git a/src/renderedtarget.h b/src/renderedtarget.h index 7c5ed0e..7d5d1c8 100644 --- a/src/renderedtarget.h +++ b/src/renderedtarget.h @@ -168,6 +168,8 @@ class RenderedTarget : public IRenderedTarget bool m_convexHullDirty = true; std::vector m_hullPoints; bool m_clicked = false; // left mouse button only! + double m_dragX = 0; + double m_dragY = 0; double m_dragDeltaX = 0; double m_dragDeltaY = 0; }; diff --git a/test/renderedtarget/renderedtarget_test.cpp b/test/renderedtarget/renderedtarget_test.cpp index dd9feb9..77018c8 100644 --- a/test/renderedtarget/renderedtarget_test.cpp +++ b/test/renderedtarget/renderedtarget_test.cpp @@ -440,9 +440,11 @@ TEST_F(RenderedTargetTest, SpriteDragging) target.setMouseArea(&mouseArea); emit mouseArea.mouseMoved(1064, 651); + target.beforeRedraw(); ASSERT_EQ(sprite.x(), 64.08); ASSERT_EQ(sprite.y(), -6.86); ASSERT_EQ(mouseArea.draggedSprite(), nullptr); + ASSERT_FALSE(sprite.dragging()); // Try right mouse button (should not work) QMouseEvent moveEventRightButton(QEvent::MouseMove, QPointF(), QPointF(), Qt::RightButton, Qt::RightButton, Qt::NoModifier); @@ -454,14 +456,18 @@ TEST_F(RenderedTargetTest, SpriteDragging) ASSERT_EQ(sprite.x(), 64.08); ASSERT_EQ(sprite.y(), -6.86); ASSERT_EQ(mouseArea.draggedSprite(), nullptr); + ASSERT_FALSE(sprite.dragging()); EXPECT_CALL(engine, clickTarget).Times(0); QCoreApplication::sendEvent(&target, &releaseEventRightButton); ASSERT_EQ(mouseArea.draggedSprite(), nullptr); + ASSERT_FALSE(sprite.dragging()); emit mouseArea.mouseMoved(1064, 651); + target.beforeRedraw(); ASSERT_EQ(sprite.x(), 64.08); ASSERT_EQ(sprite.y(), -6.86); ASSERT_EQ(mouseArea.draggedSprite(), nullptr); + ASSERT_FALSE(sprite.dragging()); // Try right mouse button with "draggable" set to true (should not work) sprite.setDraggable(true); @@ -471,14 +477,18 @@ TEST_F(RenderedTargetTest, SpriteDragging) ASSERT_EQ(sprite.x(), 64.08); ASSERT_EQ(sprite.y(), -6.86); ASSERT_EQ(mouseArea.draggedSprite(), nullptr); + ASSERT_FALSE(sprite.dragging()); EXPECT_CALL(engine, clickTarget(&sprite)); QCoreApplication::sendEvent(&target, &releaseEventRightButton); ASSERT_EQ(mouseArea.draggedSprite(), nullptr); + ASSERT_FALSE(sprite.dragging()); emit mouseArea.mouseMoved(1064, 651); + target.beforeRedraw(); ASSERT_EQ(sprite.x(), 64.08); ASSERT_EQ(sprite.y(), -6.86); ASSERT_EQ(mouseArea.draggedSprite(), nullptr); + ASSERT_FALSE(sprite.dragging()); // Try left mouse button (should not work with "draggable" set to false) sprite.setDraggable(false); @@ -491,11 +501,14 @@ TEST_F(RenderedTargetTest, SpriteDragging) ASSERT_EQ(sprite.x(), 64.08); ASSERT_EQ(sprite.y(), -6.86); ASSERT_EQ(mouseArea.draggedSprite(), nullptr); + ASSERT_FALSE(sprite.dragging()); emit mouseArea.mouseMoved(1064, 651); + target.beforeRedraw(); ASSERT_EQ(sprite.x(), 64.08); ASSERT_EQ(sprite.y(), -6.86); ASSERT_EQ(mouseArea.draggedSprite(), nullptr); + ASSERT_FALSE(sprite.dragging()); EXPECT_CALL(engine, clickTarget).Times(0); QCoreApplication::sendEvent(&target, &releaseEvent); @@ -510,21 +523,26 @@ TEST_F(RenderedTargetTest, SpriteDragging) ASSERT_EQ(sprite.x(), 64.08); ASSERT_EQ(sprite.y(), -6.86); ASSERT_EQ(mouseArea.draggedSprite(), &target); + ASSERT_TRUE(sprite.dragging()); // Drag EXPECT_CALL(engine, stageWidth()).WillOnce(Return(480)); EXPECT_CALL(engine, stageHeight()).WillOnce(Return(360)); emit mouseArea.mouseMoved(1067.8, 649.06); + target.beforeRedraw(); ASSERT_EQ(std::round(sprite.x() * 100) / 100, 61.22); ASSERT_EQ(std::round(sprite.y() * 100) / 100, -14.41); ASSERT_EQ(mouseArea.draggedSprite(), &target); + ASSERT_TRUE(sprite.dragging()); EXPECT_CALL(engine, stageWidth()).WillOnce(Return(480)); EXPECT_CALL(engine, stageHeight()).WillOnce(Return(360)); emit mouseArea.mouseMoved(1092.47, 605.46); + target.beforeRedraw(); ASSERT_EQ(std::round(sprite.x() * 100) / 100, 68.26); ASSERT_EQ(std::round(sprite.y() * 100) / 100, -1.95); ASSERT_EQ(mouseArea.draggedSprite(), &target); + ASSERT_TRUE(sprite.dragging()); // Create another sprite RenderedTarget anotherTarget; @@ -536,17 +554,21 @@ TEST_F(RenderedTargetTest, SpriteDragging) anotherSprite.setY(-6.86); anotherSprite.setDraggable(true); anotherModel.init(&anotherSprite); - anotherTarget.setSpriteModel(&model); + anotherTarget.setSpriteModel(&anotherModel); anotherTarget.setStageScale(3.5); anotherTarget.setMouseArea(&mouseArea); + ASSERT_FALSE(anotherSprite.dragging()); + // Try to drag the second sprite while the first is being dragged sprite.setDraggable(true); EXPECT_CALL(engine, clickTarget).Times(0); QCoreApplication::sendEvent(&anotherTarget, &pressEvent); QCoreApplication::sendEvent(&anotherTarget, &moveEvent); ASSERT_EQ(mouseArea.draggedSprite(), &target); - EXPECT_CALL(engine, clickTarget(&sprite)); + ASSERT_TRUE(sprite.dragging()); + ASSERT_FALSE(anotherSprite.dragging()); + EXPECT_CALL(engine, clickTarget(&anotherSprite)); QCoreApplication::sendEvent(&anotherTarget, &releaseEvent); // Stop dragging @@ -555,6 +577,8 @@ TEST_F(RenderedTargetTest, SpriteDragging) ASSERT_EQ(std::round(sprite.x() * 100) / 100, 68.26); ASSERT_EQ(std::round(sprite.y() * 100) / 100, -1.95); ASSERT_EQ(mouseArea.draggedSprite(), nullptr); + ASSERT_FALSE(sprite.dragging()); + ASSERT_FALSE(anotherSprite.dragging()); } TEST_F(RenderedTargetTest, Engine)