Skip to content

Commit 45a3127

Browse files
committed
feat(QML): all widgets are now QML components
All audio widgets are now QML components. This required migrating the delay estimator, the generator, and refactoring the Pitch tracker. The benefit is that now the creation of the visual part of the audio widget is centralized in dock.py, instead of being copied over in every widget. Also, it promotes a clearer separation between viewmodel and view. This will allow to continue the conversion of Friture to be a full QML app. We choose the Fusion style for Qt Quick Controls, used in the Generator view. The Fusion style is appropriate for Desktop apps, and works fine with Dark or White themes as set in the system.
1 parent 59da39e commit 45a3127

40 files changed

+977
-795
lines changed

friture.spec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ if platform.system() == "Windows":
8282
a = Analysis(['main.py'],
8383
pathex=pathex,
8484
binaries=[],
85-
datas= [('friture/*.qml', '.' ), ('friture/playback/*.qml', 'playback' ), ('friture/*.js', '.' )],
85+
datas= [('friture/*.qml', '.' ), ('friture/playback/*.qml', 'playback' ), ('friture/generators/*.qml', 'generators' ), ('friture/*.js', '.' )],
8686
hiddenimports=[],
8787
hookspath=["installer/pyinstaller-hooks"], # our custom hooks for python-sounddevice
8888
runtime_hooks=[],

friture/DelayEstimator.qml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import QtQuick 2.15
2+
import QtQuick.Controls 2.15
3+
4+
Rectangle {
5+
id: root
6+
required property var viewModel
7+
required property string fixedFont
8+
9+
SystemPalette { id: systemPalette; colorGroup: SystemPalette.Active }
10+
color: systemPalette.window
11+
anchors.fill: parent
12+
13+
Column {
14+
spacing: 8
15+
anchors.fill: parent
16+
anchors.margins: 12
17+
18+
Row {
19+
spacing: 8
20+
Label {
21+
text: qsTr("Delay:")
22+
font.pointSize: 14
23+
color: systemPalette.windowText
24+
}
25+
Label {
26+
text: viewModel.delay
27+
font.pointSize: 14
28+
font.bold: true
29+
color: systemPalette.windowText
30+
}
31+
}
32+
Row {
33+
spacing: 8
34+
Label {
35+
text: qsTr("Confidence:")
36+
color: systemPalette.windowText
37+
}
38+
Label {
39+
id: correlationLabel
40+
text: viewModel.correlation
41+
color: systemPalette.windowText
42+
}
43+
}
44+
Row {
45+
spacing: 8
46+
Label {
47+
text: qsTr("Polarity:")
48+
color: systemPalette.windowText
49+
}
50+
Label {
51+
text: viewModel.polarity
52+
font.pointSize: 14
53+
font.bold: true
54+
color: systemPalette.windowText
55+
}
56+
}
57+
Label {
58+
text: viewModel.channel_info
59+
wrapMode: Text.WordWrap
60+
color: systemPalette.windowText
61+
}
62+
}
63+
}

friture/Generator.qml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import QtQuick 2.15
2+
import QtQuick.Controls 2.15
3+
import QtQuick.Layouts 1.15
4+
import QtQuick.Dialogs 1.3
5+
import QtQml 2.15
6+
import "./generators"
7+
8+
Rectangle {
9+
id: generatorRoot
10+
required property var viewModel
11+
required property string fixedFont
12+
13+
SystemPalette { id: systemPalette; colorGroup: SystemPalette.Active }
14+
color: systemPalette.window
15+
anchors.fill: parent
16+
17+
ColumnLayout {
18+
anchors.top: parent.top
19+
anchors.left: parent.left
20+
spacing: 12
21+
22+
ComboBox {
23+
model: viewModel.generatorNames
24+
currentIndex: viewModel.generatorIndex
25+
onCurrentIndexChanged: viewModel.generatorIndex = currentIndex
26+
}
27+
28+
Button {
29+
id: startStopButton
30+
text: viewModel.isPlaying ? qsTr("Stop") : qsTr("Start")
31+
checkable: true
32+
checked: viewModel.isPlaying
33+
onCheckedChanged: viewModel.isPlaying = checked
34+
icon.source: viewModel.isPlaying ? "qrc:/images-src/stop.svg" : "qrc:/images-src/start.svg"
35+
}
36+
37+
SineSettings {
38+
viewModel: generatorRoot.viewModel.sineGenerator
39+
visible: generatorRoot.viewModel.generatorIndex === 0
40+
}
41+
42+
WhiteSettings {
43+
viewModel: generatorRoot.viewModel.whiteGenerator
44+
visible: generatorRoot.viewModel.generatorIndex === 1
45+
}
46+
47+
PinkSettings {
48+
viewModel: generatorRoot.viewModel.pinkGenerator
49+
visible: generatorRoot.viewModel.generatorIndex === 2
50+
}
51+
52+
SweepSettings {
53+
viewModel: generatorRoot.viewModel.sweepGenerator
54+
visible: generatorRoot.viewModel.generatorIndex === 3
55+
}
56+
57+
BurstSettings {
58+
viewModel: generatorRoot.viewModel.burstGenerator
59+
visible: generatorRoot.viewModel.generatorIndex === 4
60+
}
61+
}
62+
}

friture/HistPlot.qml

Lines changed: 38 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3,71 +3,53 @@ import QtQuick.Window 2.2
33
import QtQuick.Layouts 1.15
44
import QtQuick.Shapes 1.15
55
import Friture 1.0
6-
import "plotItemColors.js" as PlotItemColors
76

8-
Item {
9-
id: container
10-
property var stateId
7+
Plot {
8+
required property var viewModel
9+
required property string fixedFont
1110

12-
SystemPalette { id: systemPalette; colorGroup: SystemPalette.Active }
11+
scopedata: viewModel
1312

14-
// delay the load of the Plot until stateId has been set
15-
Loader {
16-
id: loader
17-
anchors.fill: parent
18-
}
19-
20-
onStateIdChanged: {
21-
console.log("stateId changed: " + stateId)
22-
loader.sourceComponent = plotComponent
23-
}
13+
Repeater {
14+
model: scopedata.plot_items
2415

25-
Component {
26-
id: plotComponent
16+
PlotFilledCurve {
17+
anchors.fill: parent
18+
curve: modelData
19+
}
20+
}
2721

28-
Plot {
29-
scopedata: Store.dock_states[container.stateId]
22+
Item {
23+
visible: scopedata.bar_labels_x_distance * parent.width > fontMetrics.boundingRect("100").height
24+
anchors.fill: parent
3025

31-
Repeater {
32-
model: scopedata.plot_items
26+
FontMetrics {
27+
id: fontMetrics
28+
}
3329

34-
PlotFilledCurve {
35-
anchors.fill: parent
36-
curve: modelData
37-
}
38-
}
30+
SystemPalette { id: systemPalette; colorGroup: SystemPalette.Active }
31+
32+
Repeater {
33+
model: scopedata.barLabels
3934

4035
Item {
41-
visible: scopedata.bar_labels_x_distance * parent.width > fontMetrics.boundingRect("100").height
42-
anchors.fill: parent
43-
44-
FontMetrics {
45-
id: fontMetrics
46-
}
47-
48-
Repeater {
49-
model: scopedata.barLabels
50-
51-
Item {
52-
x: modelData.x * parent.width - barLabel.height / 2
53-
y: Math.max(4, Math.min(modelData.y * parent.height + 4, parent.height - barLabel.width - 4))
54-
55-
// width vs. height: childrenRect doesn't take transformations into account.
56-
// https://bugreports.qt-project.org/browse/QTBUG-38953
57-
implicitWidth: barLabel.height
58-
implicitHeight: barLabel.width
59-
60-
Text {
61-
id: barLabel
62-
text: modelData.unscaled_x
63-
rotation: 270
64-
transformOrigin: Item.Center
65-
anchors.centerIn: parent
66-
color: modelData.y * parent.parent.height + 4 > parent.parent.height - barLabel.width - 4 ? systemPalette.windowText : systemPalette.base
67-
}
68-
}
36+
x: modelData.x * parent.width - barLabel.height / 2
37+
y: Math.max(4, Math.min(modelData.y * parent.height + 4, parent.height - barLabel.width - 4))
38+
39+
// width vs. height: childrenRect doesn't take transformations into account.
40+
// https://bugreports.qt-project.org/browse/QTBUG-38953
41+
implicitWidth: barLabel.height
42+
implicitHeight: barLabel.width
43+
44+
Text {
45+
id: barLabel
46+
text: modelData.unscaled_x
47+
rotation: 270
48+
transformOrigin: Item.Center
49+
anchors.centerIn: parent
50+
color: modelData.y * parent.parent.height + 4 > parent.parent.height - barLabel.width - 4 ? systemPalette.windowText : systemPalette.base
6951
}
70-
}
71-
}
52+
}
53+
}
7254
}
7355
}

friture/ImagePlot.qml

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,19 @@ import QtQuick.Window 2.2
33
import QtQuick.Layouts 1.15
44
import QtQuick.Shapes 1.15
55
import Friture 1.0
6-
import "plotItemColors.js" as PlotItemColors
76

8-
Item {
9-
id: container
10-
property var stateId
7+
Plot {
8+
required property var viewModel
9+
required property string fixedFont
1110

12-
// delay the load of the Plot until stateId has been set
13-
Loader {
14-
id: loader
15-
anchors.fill: parent
16-
}
17-
18-
onStateIdChanged: {
19-
console.log("stateId changed: " + stateId)
20-
loader.sourceComponent = plotComponent
21-
}
22-
23-
Component {
24-
id: plotComponent
25-
26-
Plot {
27-
scopedata: Store.dock_states[container.stateId]
11+
scopedata: viewModel
2812

29-
Repeater {
30-
model: scopedata.plot_items
13+
Repeater {
14+
model: scopedata.plot_items
3115

32-
SpectrogramItem {
33-
anchors.fill: parent
34-
curve: modelData
35-
}
36-
}
37-
}
16+
SpectrogramItem {
17+
anchors.fill: parent
18+
curve: modelData
19+
}
3820
}
39-
}
21+
}

friture/Levels.qml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Rectangle {
1111
property var stateId
1212
property LevelViewModel level_view_model: Store.dock_states[stateId]
1313

14-
property var fixedFont
14+
property string fixedFont
1515

1616
// parent here will be unset on exit
1717
height: parent ? parent.height : 0

0 commit comments

Comments
 (0)