Skip to content

Commit fa5135c

Browse files
authored
Merge pull request #68 from scratchcpp/monitors
Implement monitors
2 parents 2e636b2 + 13c9d7d commit fa5135c

25 files changed

+1892
-13
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ qputenv("QSG_RENDER_LOOP", "basic");
143143
- [ ] Touching sprite block
144144
- [ ] Touching color blocks
145145
- [ ] Pen blocks
146-
- [ ] Monitors
146+
- [x] Monitors
147147
- [ ] Graphics effects (maybe using shaders)
148148
- [ ] Speech and thought bubbles
149149
- [ ] Question text box ("ask and wait" block)

src/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ qt_add_qml_module(scratchcpp-render
88
OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ScratchCPP/Render
99
QML_FILES
1010
ProjectPlayer.qml
11+
RESOURCES
12+
internal/ValueMonitor.qml
13+
internal/MonitorSlider.qml
14+
internal/ListMonitor.qml
1115
SOURCES
1216
global.h
1317
projectloader.cpp
@@ -18,6 +22,14 @@ qt_add_qml_module(scratchcpp-render
1822
stagemodel.h
1923
spritemodel.cpp
2024
spritemodel.h
25+
monitormodel.cpp
26+
monitormodel.h
27+
valuemonitormodel.cpp
28+
valuemonitormodel.h
29+
listmonitormodel.cpp
30+
listmonitormodel.h
31+
listmonitorlistmodel.cpp
32+
listmonitorlistmodel.h
2133
irenderedtarget.h
2234
renderedtarget.cpp
2335
renderedtarget.h

src/ProjectPlayer.qml

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import QtQuick.Layouts
55
import QtQuick.Controls
66
import ScratchCPP.Render
77

8+
import "internal"
9+
810
ProjectScene {
911
property string fileName
1012
property int stageWidth: 480
@@ -64,6 +66,21 @@ ProjectScene {
6466
else
6567
clones.model.remove(i);
6668
}
69+
70+
onMonitorAdded: (monitorModel)=> monitors.model.append({"monitorModel": monitorModel})
71+
72+
onMonitorRemoved: (monitorModel)=> {
73+
// TODO: Removing the monitor from C++ would probably be faster
74+
let i;
75+
76+
for(i = 0; i < monitors.model.count; i++) {
77+
if(monitors.model.get(i).monitorModel === monitorModel)
78+
break;
79+
}
80+
81+
if(i !== monitors.model.count)
82+
monitors.model.remove(i);
83+
}
6784
}
6885

6986
function start() {
@@ -120,6 +137,57 @@ ProjectScene {
120137
delegate: renderedSprite
121138
}
122139

140+
SceneMouseArea {
141+
id: sceneMouseArea
142+
anchors.fill: parent
143+
stage: stageTarget
144+
projectLoader: loader
145+
onMouseMoved: (x, y)=> root.handleMouseMove(x, y)
146+
onMousePressed: root.handleMousePress()
147+
onMouseReleased: root.handleMouseRelease()
148+
}
149+
150+
Component {
151+
id: renderedValueMonitor
152+
153+
ValueMonitor {
154+
model: parent.model
155+
scale: root.stageScale
156+
transformOrigin: Item.TopLeft
157+
x: model.x * scale
158+
y: model.y * scale
159+
}
160+
}
161+
162+
Component {
163+
id: renderedListMonitor
164+
165+
ListMonitor {
166+
model: parent.model
167+
scale: root.stageScale
168+
transformOrigin: Item.TopLeft
169+
x: model.x * scale
170+
y: model.y * scale
171+
}
172+
}
173+
174+
Component {
175+
id: renderedMonitor
176+
177+
Loader {
178+
readonly property MonitorModel model: monitorModel
179+
sourceComponent: monitorModel ? (monitorModel.type === MonitorModel.Value ? renderedValueMonitor : renderedListMonitor) : null
180+
active: sourceComponent != null
181+
z: loader.sprites.length + loader.clones.length + 1 // above all sprites
182+
}
183+
}
184+
185+
Repeater {
186+
id: monitors
187+
model: ListModel {}
188+
delegate: renderedMonitor
189+
}
190+
123191
Loader {
124192
anchors.fill: parent
125193
active: showLoadingProgress && loading
@@ -159,15 +227,5 @@ ProjectScene {
159227
Item { Layout.fillHeight: true }
160228
}
161229
}
162-
163-
SceneMouseArea {
164-
id: sceneMouseArea
165-
anchors.fill: parent
166-
stage: stageTarget
167-
projectLoader: loader
168-
onMouseMoved: (x, y)=> root.handleMouseMove(x, y)
169-
onMousePressed: root.handleMousePress()
170-
onMouseReleased: root.handleMouseRelease()
171-
}
172230
}
173231
}

src/internal/ListMonitor.qml

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
// SPDX-License-Identifier: LGPL-3.0-or-later
2+
3+
import QtQuick
4+
import QtQuick.Layouts
5+
import QtQuick.Controls
6+
import ScratchCPP.Render
7+
8+
// NOTE: All the values here make list monitors look
9+
// like on Scratch, so be careful when doing any changes.
10+
Rectangle {
11+
id: root
12+
property ListMonitorModel model: null
13+
14+
width: model ? (model.width > 0 ? model.width : priv.defaultWidth) : priv.defaultWidth
15+
height: model ? (model.height > 0 ? model.height : priv.defaultHeight) : priv.defaultHeight
16+
color: Qt.rgba(0.9, 0.94, 1, 1)
17+
border.color: Qt.rgba(0.765, 0.8, 0.85, 1)
18+
radius: 5
19+
visible: model ? model.visible : true
20+
21+
QtObject {
22+
id: priv
23+
readonly property int defaultWidth: 102
24+
readonly property int defaultHeight: 203
25+
readonly property color textColor: Qt.rgba(0.34, 0.37, 0.46, 1)
26+
}
27+
28+
Text {
29+
id: header
30+
anchors.left: parent.left
31+
anchors.top: parent.top
32+
width: parent.width
33+
color: priv.textColor
34+
text: model ? model.name : ""
35+
textFormat: Text.PlainText
36+
font.pointSize: 9
37+
font.bold: true
38+
font.family: "Helvetica"
39+
horizontalAlignment: Qt.AlignHCenter
40+
wrapMode: Text.WordWrap
41+
clip: true
42+
padding: 3
43+
44+
Rectangle {
45+
anchors.left: parent.left
46+
anchors.right: parent.right
47+
anchors.top: parent.top
48+
anchors.leftMargin: 1
49+
anchors.topMargin: 1
50+
anchors.rightMargin: 1
51+
height: root.height
52+
color: "white"
53+
radius: root.radius
54+
z: -1
55+
}
56+
}
57+
58+
Text {
59+
id: emptyText
60+
anchors.left: parent.left
61+
anchors.right: parent.right
62+
anchors.top: header.bottom
63+
visible: listView.count <= 0
64+
color: priv.textColor
65+
text: qsTr("(empty)")
66+
textFormat: Text.PlainText
67+
font.pointSize: 9
68+
font.family: "Helvetica"
69+
horizontalAlignment: Qt.AlignHCenter
70+
wrapMode: Text.WordWrap
71+
clip: true
72+
padding: 3
73+
}
74+
75+
ListView {
76+
property real oldContentY
77+
readonly property int scrollBarWidth: 15
78+
79+
id: listView
80+
anchors.left: parent.left
81+
anchors.right: parent.right
82+
anchors.top: header.bottom
83+
anchors.bottom: footer.top
84+
anchors.topMargin: 1
85+
clip: true
86+
model: root.model ? root.model.listModel : null
87+
boundsBehavior: Flickable.StopAtBounds
88+
89+
ScrollBar.vertical: ScrollBar {
90+
id: scrollBar
91+
anchors.right: listView.right
92+
anchors.rightMargin: 2
93+
width: 13
94+
visible: scrollBar.size < 1
95+
policy: ScrollBar.AlwaysOn
96+
97+
contentItem: Rectangle {
98+
color: scrollBar.pressed ? Qt.rgba(0.47, 0.47, 0.47, 1) : (hoverHandler.hovered ? Qt.rgba(0.66, 0.66, 0.66, 1) : Qt.rgba(0.76, 0.76, 0.76, 1))
99+
100+
HoverHandler {
101+
id: hoverHandler
102+
}
103+
}
104+
105+
background: null // background is a separate component because contentItem width can't be changed
106+
}
107+
108+
Rectangle {
109+
// Scroll bar background
110+
id: scrollBarBg
111+
anchors.right: parent.right
112+
anchors.top: parent.top
113+
anchors.bottom: parent.bottom
114+
anchors.rightMargin: 1
115+
visible: scrollBar.visible
116+
width: listView.scrollBarWidth
117+
color: Qt.rgba(0.95, 0.95, 0.95, 1)
118+
}
119+
120+
delegate: RowLayout {
121+
width: scrollBar.visible ? listView.width - listView.scrollBarWidth - 6 : listView.width - 6
122+
height: implicitHeight + 2
123+
spacing: 6
124+
125+
Text {
126+
color: priv.textColor
127+
text: index + 1
128+
font.pointSize: 9
129+
font.bold: true
130+
font.family: "Helvetica"
131+
Layout.leftMargin: 6
132+
}
133+
134+
Item {
135+
height: 22
136+
Layout.fillWidth: true
137+
138+
TextEdit {
139+
// TextEdit instead of Text for mouse selection
140+
id: itemText
141+
anchors.left: parent.left
142+
anchors.leftMargin: 3
143+
color: "white"
144+
text: value
145+
textFormat: TextEdit.PlainText
146+
font.pointSize: 9
147+
font.family: "Helvetica"
148+
selectByMouse: true
149+
padding: 2
150+
Layout.rightMargin: 6
151+
}
152+
153+
Rectangle {
154+
anchors.fill: parent
155+
color: root.model ? root.model.color : "green"
156+
border.color: color.darker(1.2)
157+
radius: root.radius
158+
z: -1
159+
}
160+
}
161+
}
162+
}
163+
164+
Text {
165+
id: footer
166+
anchors.left: parent.left
167+
anchors.right: parent.right
168+
anchors.bottom: parent.bottom
169+
color: priv.textColor
170+
text: qsTr("length %1").arg(listView.count)
171+
textFormat: Text.PlainText
172+
font.pointSize: 9
173+
font.bold: true
174+
font.family: "Helvetica"
175+
horizontalAlignment: Qt.AlignHCenter
176+
wrapMode: Text.WordWrap
177+
clip: true
178+
padding: 3
179+
180+
Rectangle {
181+
anchors.fill: parent
182+
anchors.leftMargin: 1
183+
anchors.bottomMargin: 1
184+
anchors.rightMargin: 1
185+
anchors.topMargin: -5
186+
color: "white"
187+
radius: root.radius
188+
z: -1
189+
}
190+
}
191+
192+
Rectangle {
193+
// for header and footer borders
194+
anchors.left: parent.left
195+
anchors.right: parent.right
196+
anchors.top: header.bottom
197+
anchors.bottom: footer.top
198+
color: "transparent"
199+
border.color: root.border.color
200+
}
201+
}

0 commit comments

Comments
 (0)