on xenial help sign in
Initial playlist support
5969428Albert Astals Cid
plugins/Dash/CardCreator.js+2−1
@@ -119,6 +119,7 @@ var kAudioButtonCode = 'AbstractButton { \n\
119 width: %2; \n\
119 width: %2; \n\
120 height: %3; \n\
120 height: %3; \n\
121 readonly property url source: (cardData["quickPreviewData"] && cardData["quickPreviewData"]["uri"]) || ""; \n\
121 readonly property url source: (cardData["quickPreviewData"] && cardData["quickPreviewData"]["uri"]) || ""; \n\
122+ readonly property url playlist: (cardData["quickPreviewData"] && cardData["quickPreviewData"]["playlist"]) || null; \n\
122 UbuntuShape { \n\
123 UbuntuShape { \n\
123 anchors.fill: parent; \n\
124 anchors.fill: parent; \n\
124 visible: parent.pressed; \n\
125 visible: parent.pressed; \n\
@@ -139,7 +140,7 @@ var kAudioButtonCode = 'AbstractButton { \n\
139 DashAudioPlayer.play(); \n\
140 DashAudioPlayer.play(); \n\
140 } \n\
141 } \n\
141 } else { \n\
142 } else { \n\
142− DashAudioPlayer.playSource(source); \n\
143+ DashAudioPlayer.playSource(source, playlist); \n\
143 } \n\
144 } \n\
144 } \n\
145 } \n\
145 onPressAndHold: { \n\
146 onPressAndHold: { \n\
plugins/Dash/DashAudioPlayer.qml+38−4
@@ -27,14 +27,44 @@ QtObject {
27 readonly property alias position: audio.position
27 readonly property alias position: audio.position
28
28
29 function isCurrentSource(source) {
29 function isCurrentSource(source) {
30+ if (source != "") {
31+ if (audio.playlist) {
32+ return AudioUrlComparer.compare(source, audio.playlist.currentSource);
33+ } else {
30− return source != "" && AudioUrlComparer.compare(source, audio.source);
34+ return AudioUrlComparer.compare(source, audio.source);
35+ }
36+ }
37+ return false;
31 }
38 }
32
39
33− function playSource(newSource) {
40+ function playSource(newSource, newPlaylist) {
34 stop();
41 stop();
35 // Make sure we change the source, even if two items point to the same uri location
42 // Make sure we change the source, even if two items point to the same uri location
36 audio.source = "";
43 audio.source = "";
44+ audio.playlist = null;
45+ if (newPlaylist) {
46+ playlist.clear();
47+ // Look for newSource in newPlaylist
48+ var sourceIndex = -1;
49+ for (var i in newPlaylist) {
50+ if (AudioUrlComparer.compare(newSource, newPlaylist[i])) {
51+ sourceIndex = i;
52+ break;
53+ }
54+ }
55+ if (sourceIndex === -1 && newSource != "") {
56+ // If the playing song is not in the playlist, add it
57+ playlist.addSource(newSource);
58+ sourceIndex = 0;
59+ }
60+ for (var i in newPlaylist) {
61+ playlist.addSource(newPlaylist[i]);
62+ }
63+ playlist.currentIndex = sourceIndex;
64+ audio.playlist = playlist;
65+ } else {
37− audio.source = newSource;
66+ audio.source = newSource;
67+ }
38 play();
68 play();
39 }
69 }
40
70
@@ -50,12 +80,16 @@ QtObject {
50 audio.pause();
80 audio.pause();
51 }
81 }
52
82
53− property QtObject d: Audio {
83+ property QtObject audio: Audio {
54 id: audio
84 id: audio
55 objectName: "audio"
85 objectName: "audio"
56
86
57 onErrorStringChanged: console.warn("Dash Audio player error:", errorString)
87 onErrorStringChanged: console.warn("Dash Audio player error:", errorString)
58 }
88 }
89+ property QtObject playlist: Playlist {
90+ id: playlist
91+ objectName: "playlist"
92+ }
59
93
60 function lengthToString(s) {
94 function lengthToString(s) {
61 if (typeof(s) !== "number" || s < 0) return "";
95 if (typeof(s) !== "number" || s < 0) return "";
tests/mocks/QtMultimedia/CMakeLists.txt+1
@@ -1,6 +1,7 @@
1add_library(QtMultimedia-qml MODULE
1add_library(QtMultimedia-qml MODULE
2 plugin.cpp
2 plugin.cpp
3 audio.cpp
3 audio.cpp
4+ declarativeplaylist.cpp
4 )
5 )
5
6
6qt5_use_modules(QtMultimedia-qml Qml)
7qt5_use_modules(QtMultimedia-qml Qml)
tests/mocks/QtMultimedia/audio.cpp+37−10
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013, 2015 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -20,11 +20,18 @@
20
20
21Audio::Audio(QObject* parent):
21Audio::Audio(QObject* parent):
22 QObject(parent),
22 QObject(parent),
23− m_playbackState(StoppedState)
23+ m_playbackState(StoppedState),
24+ m_playlist(0)
24{
25{
25 qsrand(time(nullptr));
26 qsrand(time(nullptr));
26 m_timer.setInterval(1000);
27 m_timer.setInterval(1000);
27 connect(&m_timer, SIGNAL(timeout()), SLOT(timerEvent()));
28 connect(&m_timer, SIGNAL(timeout()), SLOT(timerEvent()));
29+
30+ m_position = 0;
31+ Q_EMIT positionChanged(m_position);
32+
33+ m_duration = (qrand() % 20000) + 10000;
34+ Q_EMIT durationChanged(m_duration);
28}
35}
29
36
30QUrl Audio::source() const
37QUrl Audio::source() const
@@ -34,16 +41,20 @@ QUrl Audio::source() const
34
41
35void Audio::setSource(const QUrl &source)
42void Audio::setSource(const QUrl &source)
36{
43{
37− if (m_source != source) {
44+ if (source == m_source && m_playlist == NULL)
38− m_source = source;
45+ return;
39− Q_EMIT sourceChanged(source);
40
46
41− m_position = 0;
47+ m_playlist = NULL;
42− Q_EMIT positionChanged(m_position);
48+ Q_EMIT playlistChanged();
43
49
50+ m_source = source;
51+ Q_EMIT sourceChanged(source);
52+
53+ m_position = 0;
54+ Q_EMIT positionChanged(m_position);
55+
44− m_duration = (qrand() % 20000) + 10000;
56+ m_duration = (qrand() % 20000) + 10000;
45− Q_EMIT durationChanged(m_duration);
57+ Q_EMIT durationChanged(m_duration);
46− }
47}
58}
48
59
49Audio::PlaybackState Audio::playbackState() const
60Audio::PlaybackState Audio::playbackState() const
@@ -115,3 +126,19 @@ void Audio::setAudioRole(Audio::AudioRole audioRole)
115{
126{
116 Q_UNUSED(audioRole);
127 Q_UNUSED(audioRole);
117}
128}
129+
130+DeclarativePlaylist *Audio::playlist() const
131+{
132+ return m_playlist;
133+}
134+
135+void Audio::setPlaylist(DeclarativePlaylist *playlist)
136+{
137+ if (playlist == m_playlist && m_source.isEmpty())
138+ return;
139+
140+ m_source.clear();
141+ Q_EMIT sourceChanged(m_source);
142+ m_playlist = playlist;
143+ Q_EMIT playlistChanged();
144+}
tests/mocks/QtMultimedia/audio.h+9−2
@@ -1,5 +1,5 @@
1/*
1/*
2− * Copyright (C) 2012,2013 Canonical, Ltd.
2+ * Copyright (C) 2012, 2013, 2015 Canonical, Ltd.
3 *
3 *
4 * This program is free software; you can redistribute it and/or modify
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
5 * it under the terms of the GNU General Public License as published by
@@ -13,7 +13,6 @@
13 * You should have received a copy of the GNU General Public License
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
15 *
16− * Authors: Michael Zanetti <michael.zanetti@canonical.com>
17 */
16 */
18
17
19#ifndef MOCK_AUDIO_H
18#ifndef MOCK_AUDIO_H
@@ -23,6 +22,8 @@
23#include <QUrl>
22#include <QUrl>
24#include <QTimer>
23#include <QTimer>
25
24
25+class DeclarativePlaylist;
26+
26class Audio: public QObject
27class Audio: public QObject
27{
28{
28 Q_OBJECT
29 Q_OBJECT
@@ -34,6 +35,7 @@ class Audio: public QObject
34 Q_PROPERTY(int duration READ duration NOTIFY durationChanged)
35 Q_PROPERTY(int duration READ duration NOTIFY durationChanged)
35 Q_PROPERTY(QString errorString READ errorString NOTIFY errorStringChanged)
36 Q_PROPERTY(QString errorString READ errorString NOTIFY errorStringChanged)
36 Q_PROPERTY(AudioRole audioRole READ audioRole WRITE setAudioRole)
37 Q_PROPERTY(AudioRole audioRole READ audioRole WRITE setAudioRole)
38+ Q_PROPERTY(DeclarativePlaylist *playlist READ playlist WRITE setPlaylist NOTIFY playlistChanged)
37public:
39public:
38 enum PlaybackState {
40 enum PlaybackState {
39 PlayingState,
41 PlayingState,
@@ -53,6 +55,9 @@ public:
53 QUrl source() const;
55 QUrl source() const;
54 void setSource(const QUrl &source);
56 void setSource(const QUrl &source);
55
57
58+ DeclarativePlaylist *playlist() const;
59+ void setPlaylist(DeclarativePlaylist *playlist);
60+
56 PlaybackState playbackState() const;
61 PlaybackState playbackState() const;
57
62
58 int position() const;
63 int position() const;
@@ -70,6 +75,7 @@ public Q_SLOTS:
70 void stop();
75 void stop();
71
76
72Q_SIGNALS:
77Q_SIGNALS:
78+ void playlistChanged();
73 void sourceChanged(const QUrl &source);
79 void sourceChanged(const QUrl &source);
74 void playbackStateChanged(PlaybackState playbackState);
80 void playbackStateChanged(PlaybackState playbackState);
75 void positionChanged(int position);
81 void positionChanged(int position);
@@ -85,6 +91,7 @@ private:
85 QTimer m_timer;
91 QTimer m_timer;
86 int m_position;
92 int m_position;
87 int m_duration;
93 int m_duration;
94+ DeclarativePlaylist *m_playlist;
88};
95};
89
96
90#endif
97#endif
tests/mocks/QtMultimedia/declarativeplaylist.cppnew file+61
@@ -0,0 +1,61 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ */
17+
18+#include "declarativeplaylist.h"
19+
20+DeclarativePlaylist::DeclarativePlaylist(QObject *parent)
21+ : QObject(parent)
22+ , m_currentIndex(-1)
23+{
24+}
25+
26+QUrl DeclarativePlaylist::currentSource() const
27+{
28+ return source(currentIndex());
29+}
30+
31+int DeclarativePlaylist::currentIndex() const
32+{
33+ return m_currentIndex;
34+}
35+
36+void DeclarativePlaylist::setCurrentIndex(int index)
37+{
38+ if (currentIndex() == index)
39+ return;
40+
41+ m_currentIndex = index;
42+ Q_EMIT currentIndexChanged();
43+}
44+
45+QUrl DeclarativePlaylist::source(int index) const
46+{
47+ return m_medias[index];
48+}
49+
50+bool DeclarativePlaylist::addSource(const QUrl &source)
51+{
52+ m_medias << source;
53+ return true;
54+}
55+
56+
57+bool DeclarativePlaylist::clear()
58+{
59+ m_medias.clear();
60+ return true;
61+}
tests/mocks/QtMultimedia/declarativeplaylist.hnew file+53
@@ -0,0 +1,53 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ */
17+
18+#ifndef DECLARATIVEPLAYLIST_H
19+#define DECLARATIVEPLAYLIST_H
20+
21+#include <QObject>
22+#include <QUrl>
23+
24+class DeclarativePlaylist : public QObject
25+{
26+ Q_OBJECT
27+ Q_PROPERTY(QUrl currentSource READ currentSource NOTIFY currentSourceChanged)
28+ Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
29+
30+public:
31+ DeclarativePlaylist(QObject *parent = 0);
32+
33+ QUrl currentSource() const;
34+ int currentIndex() const;
35+ void setCurrentIndex(int currentIndex);
36+
37+public Q_SLOTS:
38+ QUrl source(int index) const;
39+ bool addSource(const QUrl &source);
40+ bool clear();
41+
42+Q_SIGNALS:
43+ void currentSourceChanged();
44+ void currentIndexChanged();
45+
46+private:
47+ Q_DISABLE_COPY(DeclarativePlaylist)
48+
49+ int m_currentIndex;
50+ QList<QUrl> m_medias;
51+};
52+
53+#endif
tests/mocks/QtMultimedia/plugin.cpp+2
@@ -18,6 +18,7 @@
18
18
19#include "plugin.h"
19#include "plugin.h"
20#include "audio.h"
20#include "audio.h"
21+#include "declarativeplaylist.h"
21
22
22#include <QtQml/qqml.h>
23#include <QtQml/qqml.h>
23
24
@@ -25,4 +26,5 @@ void MockQtMultimediaPlugin::registerTypes(const char *uri)
25{
26{
26 Q_ASSERT(uri == QLatin1String("QtMultimedia"));
27 Q_ASSERT(uri == QLatin1String("QtMultimedia"));
27 qmlRegisterType<Audio>(uri, 5, 0, "Audio");
28 qmlRegisterType<Audio>(uri, 5, 0, "Audio");
29+ qmlRegisterType<DeclarativePlaylist>(uri, 5, 0, "Playlist");
28}
30}
tests/plugins/Dash/cardcreator/8.res+97−97
@@ -1,112 +1,112 @@
1−AbstractButton {
1+AbstractButton {
2− id: root;
2+ id: root;
3− property var template;
4− property var components;
3+ property var components;
5− property var cardData;
4+ property var cardData;
6− property var artShapeBorderSource: undefined;
5+ property var artShapeBorderSource: undefined;
7− property real fontScale: 1.0;
6+ property real fontScale: 1.0;
8− property var scopeStyle: null;
7+ property var scopeStyle: null;
9− property int titleAlignment: Text.AlignLeft;
8+ property int titleAlignment: Text.AlignLeft;
10− property int fixedHeaderHeight: -1;
9+ property int fixedHeaderHeight: -1;
11− property size fixedArtShapeSize: Qt.size(-1, -1);
10+ property size fixedArtShapeSize: Qt.size(-1, -1);
12− readonly property string title: cardData && cardData["title"] || "";
11+ readonly property string title: cardData && cardData["title"] || "";
13− property bool asynchronous: true;
12+ property bool asynchronous: true;
14− property bool showHeader: true;
13+ property bool showHeader: true;
15− implicitWidth: childrenRect.width;
14+ implicitWidth: childrenRect.width;
16− enabled: root.template == null ? true : (root.template["non-interactive"] !== undefined ? !root.template["non-interactive"] : true);
15+ enabled: true;
17−
16+
18readonly property size artShapeSize: Qt.size(-1, -1);
17readonly property size artShapeSize: Qt.size(-1, -1);
19readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin + audioProgressBar.height + audioProgressBar.anchors.topMargin;
18readonly property int headerHeight: titleLabel.height + subtitleLabel.height + subtitleLabel.anchors.topMargin + audioProgressBar.height + audioProgressBar.anchors.topMargin;
20Label {
19Label {
21− id: titleLabel;
20+ id: titleLabel;
22− objectName: "titleLabel";
21+ objectName: "titleLabel";
23− anchors { right: parent.right;
22+ anchors { right: parent.right;
24rightMargin: units.gu(1);
23rightMargin: units.gu(1);
25left: audioButton.right;
24left: audioButton.right;
26 leftMargin: units.gu(1);
25 leftMargin: units.gu(1);
27top: parent.top;
26top: parent.top;
28 topMargin: units.gu(1);
27 topMargin: units.gu(1);
29 }
28 }
30− elide: Text.ElideRight;
29+ elide: Text.ElideRight;
31− fontSize: "small";
30+ fontSize: "small";
32− wrapMode: Text.Wrap;
31+ wrapMode: Text.Wrap;
33− maximumLineCount: 2;
32+ maximumLineCount: 2;
34− font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
33+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
35− color: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText;
34+ color: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText;
36− visible: showHeader ;
35+ visible: showHeader ;
37− text: root.title;
36+ text: root.title;
38− font.weight: cardData && cardData["subtitle"] ? Font.DemiBold : Font.Normal;
37+ font.weight: cardData && cardData["subtitle"] ? Font.DemiBold : Font.Normal;
39− horizontalAlignment: root.titleAlignment;
38+ horizontalAlignment: root.titleAlignment;
40 }
39 }
41−Label {
40+Label {
42− id: subtitleLabel;
41+ id: subtitleLabel;
43− objectName: "subtitleLabel";
42+ objectName: "subtitleLabel";
44− anchors { left: titleLabel.left;
43+ anchors { left: titleLabel.left;
45− leftMargin: titleLabel.leftMargin;
44+ leftMargin: titleLabel.leftMargin;
46−rightMargin: units.gu(1);
45+rightMargin: units.gu(1);
47−right: titleLabel.right;
46+right: titleLabel.right;
48top: titleLabel.bottom;
47top: titleLabel.bottom;
49− }
48+ }
50− anchors.topMargin: units.dp(2);
49+ anchors.topMargin: units.dp(2);
51− elide: Text.ElideRight;
50+ elide: Text.ElideRight;
52− maximumLineCount: 1;
51+ maximumLineCount: 1;
53− fontSize: "x-small";
52+ fontSize: "x-small";
54− font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
53+ font.pixelSize: Math.round(FontUtils.sizeToPixels(fontSize) * fontScale);
55− color: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText;
54+ color: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText;
56− visible: titleLabel.visible && titleLabel.text;
55+ visible: titleLabel.visible && titleLabel.text;
57− text: cardData && cardData["subtitle"] || "";
56+ text: cardData && cardData["subtitle"] || "";
58− font.weight: Font.Light;
57+ font.weight: Font.Light;
59 }
58 }
60−CardAudioProgress {
59+CardAudioProgress {
61− id: audioProgressBar;
60+ id: audioProgressBar;
62− duration: (cardData["quickPreviewData"] && cardData["quickPreviewData"]["duration"]) || 0;
61+ duration: (cardData["quickPreviewData"] && cardData["quickPreviewData"]["duration"]) || 0;
63− source: (cardData["quickPreviewData"] && cardData["quickPreviewData"]["uri"]) || "";
62+ source: (cardData["quickPreviewData"] && cardData["quickPreviewData"]["uri"]) || "";
64− anchors {
63+ anchors {
65− bottom: audioButton.bottom;
64+ bottom: audioButton.bottom;
66− left: audioButton.right;
65+ left: audioButton.right;
67− right: parent.right;
66+ right: parent.right;
68− margins: units.gu(1);
67+ margins: units.gu(1);
69− }
68+ }
70− color: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText;
69+ color: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText;
71− }AbstractButton {
70+ }AbstractButton {
72− id: audioButton;
71+ id: audioButton;
73− anchors.fill: undefined;
72+ anchors.fill: undefined;
74− width: height;
73+ width: height;
75− height: (root.fixedHeaderHeight > 0 ? root.fixedHeaderHeight : headerHeight) + 2 * units.gu(1);
74+ height: (root.fixedHeaderHeight > 0 ? root.fixedHeaderHeight : headerHeight) + 2 * units.gu(1);
76− readonly property url source: (cardData["quickPreviewData"] && cardData["quickPreviewData"]["uri"]) || "";
75+ readonly property url source: (cardData["quickPreviewData"] && cardData["quickPreviewData"]["uri"]) || "";
76+ readonly property url playlist: (cardData["quickPreviewData"] && cardData["quickPreviewData"]["playlist"]) || null;
77− UbuntuShape {
77+ UbuntuShape {
78− anchors.fill: parent;
78+ anchors.fill: parent;
79− visible: parent.pressed;
79+ visible: parent.pressed;
80− radius: "medium";
80+ radius: "medium";
81− borderSource: "radius_pressed.sci"
81+ borderSource: "radius_pressed.sci"
82− }
82+ }
83− Icon {
83+ Icon {
84− anchors.fill: parent;
84+ anchors.fill: parent;
85− anchors.margins: parent.height > units.gu(5) ? units.gu(2) : units.gu(0);
85+ anchors.margins: parent.height > units.gu(5) ? units.gu(2) : units.gu(0);
86− opacity: 0.9;
86+ opacity: 0.9;
87− name: DashAudioPlayer.isCurrentSource(parent.source) && DashAudioPlayer.playing ? "media-playback-pause" : "media-playback-start";
87+ name: DashAudioPlayer.isCurrentSource(parent.source) && DashAudioPlayer.playing ? "media-playback-pause" : "media-playback-start";
88− }
88+ }
89− onClicked: {
89+ onClicked: {
90− if (DashAudioPlayer.isCurrentSource(source)) {
90+ if (DashAudioPlayer.isCurrentSource(source)) {
91− if (DashAudioPlayer.playing) {
91+ if (DashAudioPlayer.playing) {
92− DashAudioPlayer.pause();
92+ DashAudioPlayer.pause();
93− } else {
93+ } else {
94− DashAudioPlayer.play();
94+ DashAudioPlayer.play();
95− }
95+ }
96− } else {
96+ } else {
97− DashAudioPlayer.playSource(source);
97+ DashAudioPlayer.playSource(source, playlist);
98− }
98+ }
99− }
99+ }
100− onPressAndHold: {
100+ onPressAndHold: {
101− root.pressAndHold();
101+ root.pressAndHold();
102− }
102+ }
103− }UbuntuShape {
103+ }UbuntuShape {
104− id: touchdown;
104+ id: touchdown;
105− objectName: "touchdown";
105+ objectName: "touchdown";
106− anchors { fill: root }
106+ anchors { fill: root }
107− visible: root.pressed;
107+ visible: root.pressed;
108− radius: "medium";
108+ radius: "medium";
109− borderSource: "radius_pressed.sci"
109+ borderSource: "radius_pressed.sci"
110 }
110 }
111implicitHeight: audioButton.height;
111implicitHeight: audioButton.height;
112}
112}