Skip to content

Commit 7c9103f

Browse files
committed
Implement stage scaling
1 parent 3f6e062 commit 7c9103f

File tree

5 files changed

+45
-32
lines changed

5 files changed

+45
-32
lines changed

ScratchCPPGui/ProjectPlayer.qml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import ScratchCPPGui
77

88
ProjectScene {
99
property string fileName
10+
property int stageWidth: 480
11+
property int stageHeight: 360
1012
property alias fps: loader.fps
1113
property alias turboMode: loader.turboMode
1214
property alias cloneLimit: loader.cloneLimit
@@ -21,6 +23,7 @@ ProjectScene {
2123
id: root
2224
clip: true
2325
engine: loader.engine
26+
stageScale: (stageWidth == 0 || stageHeight == 0) ? 1 : Math.min(width / stageWidth, height / stageHeight)
2427
onFileNameChanged: priv.loading = true;
2528

2629
QtObject {
@@ -31,8 +34,8 @@ ProjectScene {
3134
ProjectLoader {
3235
id: loader
3336
fileName: root.fileName
34-
stageWidth: parent.width
35-
stageHeight: parent.height
37+
stageWidth: root.stageWidth
38+
stageHeight: root.stageHeight
3639
onLoadingFinished: {
3740
priv.loading = false;
3841

@@ -48,6 +51,7 @@ ProjectScene {
4851
engine: loader.engine
4952
stageModel: loader.stage
5053
mouseArea: sceneMouseArea
54+
stageScale: root.stageScale
5155
onStageModelChanged: stageModel.renderedTarget = this
5256
}
5357

@@ -68,6 +72,7 @@ ProjectScene {
6872
engine: loader.engine
6973
spriteModel: modelData
7074
mouseArea: sceneMouseArea
75+
stageScale: root.stageScale
7176
transform: Scale { xScale: mirrorHorizontally ? -1 : 1 }
7277
Component.onCompleted: modelData.renderedTarget = this
7378
}

ScratchCPPGui/projectscene.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ void ProjectScene::setStageScale(double newStageScale)
5555
void ProjectScene::handleMouseMove(qreal x, qreal y)
5656
{
5757
if (m_engine) {
58-
m_engine->setMouseX(x - m_engine->stageWidth() / 2.0);
59-
m_engine->setMouseY(-y + m_engine->stageHeight() / 2.0);
58+
m_engine->setMouseX(x / m_stageScale - m_engine->stageWidth() / 2.0);
59+
m_engine->setMouseY(-y / m_stageScale + m_engine->stageHeight() / 2.0);
6060
}
6161
}
6262

ScratchCPPGui/renderedtarget.cpp

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,12 @@ void RenderedTarget::loadProperties()
8080

8181
// Coordinates
8282
double clampedSize = std::min(m_size, m_maxSize);
83-
m_x = static_cast<double>(m_engine->stageWidth()) / 2 + sprite->x() - m_costume->rotationCenterX() * clampedSize / m_costume->bitmapResolution() * (m_newMirrorHorizontally ? -1 : 1);
84-
m_y = static_cast<double>(m_engine->stageHeight()) / 2 - sprite->y() - m_costume->rotationCenterY() * clampedSize / m_costume->bitmapResolution();
85-
m_originX = m_costume->rotationCenterX() * clampedSize / m_costume->bitmapResolution();
86-
m_originY = m_costume->rotationCenterY() * clampedSize / m_costume->bitmapResolution();
83+
double stageWidth = m_engine->stageWidth();
84+
double stageHeight = m_engine->stageHeight();
85+
m_x = m_stageScale * (stageWidth / 2 + sprite->x() - m_costume->rotationCenterX() * clampedSize / m_costume->bitmapResolution() * (m_newMirrorHorizontally ? -1 : 1));
86+
m_y = m_stageScale * (stageHeight / 2 - sprite->y() - m_costume->rotationCenterY() * clampedSize / m_costume->bitmapResolution());
87+
m_originX = m_costume->rotationCenterX() * clampedSize * m_stageScale / m_costume->bitmapResolution();
88+
m_originY = m_costume->rotationCenterY() * clampedSize * m_stageScale / m_costume->bitmapResolution();
8789

8890
// Layer
8991
m_z = sprite->layerOrder();
@@ -92,8 +94,10 @@ void RenderedTarget::loadProperties()
9294
mutex.unlock();
9395
} else if (m_stageModel) {
9496
updateCostumeData();
95-
m_x = static_cast<double>(m_engine->stageWidth()) / 2 - m_costume->rotationCenterX() / m_costume->bitmapResolution();
96-
m_y = static_cast<double>(m_engine->stageHeight()) / 2 - m_costume->rotationCenterY() / m_costume->bitmapResolution();
97+
double stageWidth = m_engine->stageWidth();
98+
double stageHeight = m_engine->stageHeight();
99+
m_x = m_stageScale * (stageWidth / 2 - m_costume->rotationCenterX() / m_costume->bitmapResolution());
100+
m_y = m_stageScale * (stageHeight / 2 - m_costume->rotationCenterY() / m_costume->bitmapResolution());
97101
m_originX = m_costume->rotationCenterX() / m_costume->bitmapResolution();
98102
m_originY = m_costume->rotationCenterY() / m_costume->bitmapResolution();
99103
}
@@ -451,16 +455,16 @@ void RenderedTarget::calculateSize(Target *target, double costumeWidth, double c
451455
{
452456
if (m_costume) {
453457
double bitmapRes = m_costume->bitmapResolution();
454-
m_maxSize = std::min(m_maximumWidth / costumeWidth, m_maximumHeight / costumeHeight);
458+
m_maxSize = std::min(m_maximumWidth / (costumeWidth * m_stageScale), m_maximumHeight / (costumeHeight * m_stageScale));
455459
Sprite *sprite = dynamic_cast<Sprite *>(target);
456460

457461
if (sprite) {
458462
double clampedSize = std::min(m_size, m_maxSize);
459-
m_width = costumeWidth * clampedSize / bitmapRes;
460-
m_height = costumeHeight * clampedSize / bitmapRes;
463+
m_width = costumeWidth * clampedSize * m_stageScale / bitmapRes;
464+
m_height = costumeHeight * clampedSize * m_stageScale / bitmapRes;
461465
} else {
462-
m_width = costumeWidth / bitmapRes;
463-
m_height = costumeHeight / bitmapRes;
466+
m_width = costumeWidth * m_stageScale / bitmapRes;
467+
m_height = costumeHeight * m_stageScale / bitmapRes;
464468
}
465469
}
466470
}
@@ -473,8 +477,8 @@ void RenderedTarget::handleSceneMouseMove(qreal x, qreal y)
473477
Q_ASSERT(m_spriteModel && m_spriteModel->sprite());
474478
Q_ASSERT(m_engine);
475479
Sprite *sprite = m_spriteModel->sprite();
476-
sprite->setX(x - m_engine->stageWidth() / 2.0 - m_dragDeltaX);
477-
sprite->setY(-y + m_engine->stageHeight() / 2.0 - m_dragDeltaY);
480+
sprite->setX(x / m_stageScale - m_engine->stageWidth() / 2.0 - m_dragDeltaX);
481+
sprite->setY(-y / m_stageScale + m_engine->stageHeight() / 2.0 - m_dragDeltaY);
478482
}
479483
}
480484

test/projectscene/projectscene_test.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,12 @@ TEST(ProjectSceneTest, HandleMouseMove)
3232
ProjectScene scene;
3333
EngineMock engine;
3434
scene.setEngine(&engine);
35+
scene.setStageScale(2.5);
3536

3637
EXPECT_CALL(engine, stageWidth()).WillOnce(Return(600));
3738
EXPECT_CALL(engine, stageHeight()).WillOnce(Return(400));
38-
EXPECT_CALL(engine, setMouseX(-253.1));
39-
EXPECT_CALL(engine, setMouseY(216.7));
39+
EXPECT_CALL(engine, setMouseX(-281.24));
40+
EXPECT_CALL(engine, setMouseY(206.68));
4041
scene.handleMouseMove(46.9, -16.7);
4142
}
4243

test/renderedtarget/renderedtarget_test.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ TEST_F(RenderedTargetTest, LoadAndUpdateProperties)
7474
target.setZ(2.5);
7575
target.setRotation(-78.05);
7676
target.setTransformOriginPoint(QPointF(3.4, 9.7));
77+
target.setStageScale(3.5);
7778

7879
EXPECT_CALL(engine, stageWidth()).WillOnce(Return(544));
7980
EXPECT_CALL(engine, stageHeight()).WillOnce(Return(249));
@@ -87,10 +88,10 @@ TEST_F(RenderedTargetTest, LoadAndUpdateProperties)
8788
ASSERT_EQ(target.transformOriginPoint(), QPointF(3.4, 9.7));
8889

8990
target.updateProperties();
90-
ASSERT_EQ(target.width(), 4);
91-
ASSERT_EQ(target.height(), 6);
92-
ASSERT_EQ(target.x(), 295);
93-
ASSERT_EQ(target.y(), 52.5);
91+
ASSERT_EQ(target.width(), 14);
92+
ASSERT_EQ(target.height(), 21);
93+
ASSERT_EQ(target.x(), 1032.5);
94+
ASSERT_EQ(target.y(), 183.75);
9495
ASSERT_EQ(target.z(), 0);
9596
ASSERT_EQ(target.rotation(), 0);
9697
ASSERT_EQ(target.transformOriginPoint(), QPointF(-23, 72));
@@ -118,6 +119,7 @@ TEST_F(RenderedTargetTest, LoadAndUpdateProperties)
118119
target.setZ(2.5);
119120
target.setRotation(-78.05);
120121
target.setTransformOriginPoint(QPointF(3.4, 9.7));
122+
target.setStageScale(5.23);
121123

122124
EXPECT_CALL(engine, stageWidth()).WillOnce(Return(544));
123125
EXPECT_CALL(engine, stageHeight()).WillOnce(Return(249));
@@ -131,14 +133,14 @@ TEST_F(RenderedTargetTest, LoadAndUpdateProperties)
131133
ASSERT_EQ(target.transformOriginPoint(), QPointF(3.4, 9.7));
132134

133135
target.updateProperties();
134-
ASSERT_EQ(target.width(), 5.7592);
135-
ASSERT_EQ(target.height(), 8.6388);
136-
ASSERT_EQ(std::round(target.x() * 100) / 100, 237.18);
137-
ASSERT_EQ(std::round(target.y() * 100) / 100, -100.93);
136+
ASSERT_EQ(std::round(target.width() * 100) / 100, 30.12);
137+
ASSERT_EQ(std::round(target.height() * 100) / 100, 45.18);
138+
ASSERT_EQ(std::round(target.x() * 100) / 100, 1240.43);
139+
ASSERT_EQ(std::round(target.y() * 100) / 100, -527.84);
138140
ASSERT_EQ(target.z(), 3);
139141
ASSERT_EQ(target.rotation(), -157.16);
140-
ASSERT_EQ(target.transformOriginPoint().x(), -33.1154);
141-
ASSERT_EQ(std::round(target.transformOriginPoint().y() * 100) / 100, 103.67);
142+
ASSERT_EQ(std::round(target.transformOriginPoint().x() * 100) / 100, -173.19);
143+
ASSERT_EQ(std::round(target.transformOriginPoint().y() * 100) / 100, 542.17);
142144
ASSERT_TRUE(mirrorHorizontallySpy.empty());
143145

144146
EXPECT_CALL(engine, stageWidth()).WillOnce(Return(544));
@@ -377,6 +379,7 @@ TEST_F(RenderedTargetTest, LoadSvgCostume)
377379

378380
// Test scale limit
379381
sprite.setSize(maxSize * 250);
382+
target.setStageScale(3.89);
380383

381384
target.loadCostume(costume.get());
382385
ASSERT_TRUE(target.isSvg());
@@ -406,9 +409,9 @@ TEST_F(RenderedTargetTest, LoadSvgCostume)
406409

407410
ASSERT_EQ(std::round(target.width() * 100) / 100, maxWidth);
408411
ASSERT_EQ(std::round(target.height() * 100) / 100, maxHeight);
409-
ASSERT_EQ(std::round(target.scale() * 100) / 100, 2.5);
410-
ASSERT_EQ(std::round(target.x() * 100) / 100, 11126.36);
411-
ASSERT_EQ(std::round(target.y() * 100) / 100, -6593.27);
412+
ASSERT_EQ(std::round(target.scale() * 100) / 100, 9.73);
413+
ASSERT_EQ(std::round(target.x() * 100) / 100, 11963.59);
414+
ASSERT_EQ(std::round(target.y() * 100) / 100, -5887.67);
412415
ASSERT_EQ(std::round(target.transformOriginPoint().x() * 100) / 100, -10836.66);
413416
ASSERT_EQ(std::round(target.transformOriginPoint().y() * 100) / 100, 6837.42);
414417
}

0 commit comments

Comments
 (0)