summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/Radio.qml107
-rw-r--r--app/api/Binding.qml196
-rw-r--r--app/app.pro6
-rw-r--r--app/images/Radio_Active_Icon.svg134
-rw-r--r--app/images/images.qrc1
-rw-r--r--app/main.cpp3
-rw-r--r--app/radio.qrc1
7 files changed, 72 insertions, 376 deletions
diff --git a/app/Radio.qml b/app/Radio.qml
index 894b9a3..6b7c951 100644
--- a/app/Radio.qml
+++ b/app/Radio.qml
@@ -19,7 +19,6 @@ import QtQuick 2.6
import QtQuick.Layouts 1.1
import QtQuick.Controls 2.0
import AGL.Demo.Controls 1.0
-import 'api' as API
ApplicationWindow {
id: root
@@ -27,16 +26,13 @@ ApplicationWindow {
width: container.width * container.scale
height: container.height * container.scale
- API.Binding {
- id: radio
+ property string title
- property string title
-
- onBandChanged: frequency = minimumFrequency
- onStationFound: title = stationId
- onFrequencyChanged: {
- title = ''
- slider.value = frequency
+ function freq2str(freq) {
+ if (freq > 5000000) {
+ return '%1 MHz'.arg((freq / 1000000).toFixed(1))
+ } else {
+ return '%1 kHz'.arg((freq / 1000).toFixed(0))
}
}
@@ -88,7 +84,7 @@ ApplicationWindow {
// onImage: './images/FM_Icons_AM.svg'
// onCheckedChanged: {
// radio.band = checked ? radio.amBand : radio.fmBand
-// radio.frequency = radio.minimumFrequency
+// radio.frequency = radio.minFrequency
// }
// }
}
@@ -97,14 +93,14 @@ ApplicationWindow {
Label {
id: label
Layout.alignment: Layout.Center
- text: radio.freq2str(radio.frequency)
+ text: freq2str(radio.frequency)
horizontalAlignment: Label.AlignHCenter
verticalAlignment: Label.AlignVCenter
}
Label {
id: artist
Layout.alignment: Layout.Center
- text: radio.title
+ text: root.title
horizontalAlignment: Label.AlignHCenter
verticalAlignment: Label.AlignVCenter
font.pixelSize: label.font.pixelSize * 0.6
@@ -114,22 +110,26 @@ ApplicationWindow {
Slider {
id: slider
Layout.fillWidth: true
- from: radio.minimumFrequency
- to: radio.maximumFrequency
+ from: radio.minFrequency
+ to: radio.maxFrequency
stepSize: radio.frequencyStep
snapMode: Slider.SnapOnRelease
- onValueChanged: radio.frequency = value
+ value: radio.frequency
+ onPressedChanged: {
+ radio.frequency = value
+ root.title = ''
+ }
Label {
anchors.left: parent.left
anchors.bottom: parent.top
font.pixelSize: 32
- text: radio.freq2str(radio.minimumFrequency)
+ text: freq2str(radio.minFrequency)
}
Label {
anchors.right: parent.right
anchors.bottom: parent.top
font.pixelSize: 32
- text: radio.freq2str(radio.maximumFrequency)
+ text: freq2str(radio.maxFrequency)
}
}
RowLayout {
@@ -146,7 +146,12 @@ ApplicationWindow {
triggeredOnStart: true
interval: 100
repeat: true
- onTriggered: radio.tuneDown()
+ onTriggered: {
+ if(radio.frequency > radio.minFrequency) {
+ radio.frequency -= radio.frequencyStep
+ root.title = ''
+ }
+ }
}
}
@@ -157,7 +162,12 @@ ApplicationWindow {
triggeredOnStart: true
interval: 100
repeat: true
- onTriggered: radio.tuneUp()
+ onTriggered: {
+ if(radio.frequency < radio.maxFrequency) {
+ radio.frequency += radio.frequencyStep
+ root.title = ''
+ }
+ }
}
}
@@ -166,10 +176,12 @@ ApplicationWindow {
ImageButton {
id: play
offImage: './images/AGL_MediaPlayer_Player_Play.svg'
- onClicked: radio.start()
+ onClicked: {
+ radio.start()
+ }
states: [
State {
- when: radio.state === radio.activeState
+ when: radio.playing
PropertyChanges {
target: play
offImage: './images/AGL_MediaPlayer_Player_Pause.svg'
@@ -182,32 +194,44 @@ ApplicationWindow {
Item { Layout.fillWidth: true }
Label {
- //Layout.fillWidth: true
+ id: scanLabel
text: 'SCAN'
+ color: radio.scanning ? '#59FF7F' : '#FFFFFF'
}
ImageButton {
+ id: scanBackwardBtn
offImage: './images/AGL_MediaPlayer_BackArrow.svg'
- Timer {
- running: parent.pressed
- triggeredOnStart: true
- interval: 100
- repeat: true
- onTriggered: radio.scanDown()
- }
+ states: [
+ State {
+ when: radio.playing
+ PropertyChanges {
+ target: scanBackwardBtn
+ onClicked: {
+ radio.scanBackward()
+ root.title = ''
+ }
+ }
+ }
+ ]
}
ImageButton {
+ id: scanForwardBtn
offImage: './images/AGL_MediaPlayer_ForwardArrow.svg'
- Timer {
- running: parent.pressed
- triggeredOnStart: true
- interval: 100
- repeat: true
- onTriggered: radio.scanUp()
- }
+ states: [
+ State {
+ when: radio.playing
+ PropertyChanges {
+ target: scanForwardBtn
+ onClicked: {
+ radio.scanForward()
+ root.title = ''
+ }
+ }
+ }
+ ]
}
-
}
}
}
@@ -231,14 +255,11 @@ ApplicationWindow {
onClicked: {
radio.band = model.modelData.band
radio.frequency = model.modelData.frequency
- radio.title = model.modelData.title
+ root.title = model.modelData.title
}
RowLayout {
anchors.fill: parent
- Image {
- source: './images/Radio_Active_Icon.svg'
- }
ColumnLayout {
Layout.fillWidth: true
Label {
@@ -247,7 +268,7 @@ ApplicationWindow {
}
Label {
Layout.fillWidth: true
- text: radio.freq2str(model.frequency)
+ text: freq2str(model.frequency)
color: '#59FF7F'
font.pixelSize: 32
}
diff --git a/app/api/Binding.qml b/app/api/Binding.qml
deleted file mode 100644
index 3b43510..0000000
--- a/app/api/Binding.qml
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2016 The Qt Company Ltd.
- * Copyright (C) 2017 Konsulko Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import QtQuick 2.6
-import QtWebSockets 1.0
-
-WebSocket {
- id: root
- active: true
- url: bindingAddress
-
- property string apiString: "radio"
- property var verbs: []
- property string payloadLength: "9999"
-
- readonly property var msgid: {
- "call": 2,
- "retok": 3,
- "reterr": 4,
- "event": 5
- }
-
- readonly property int amBand: 0
- readonly property int fmBand: 1
-
- readonly property int stoppedState: 0
- readonly property int activeState: 1
-
- property int band: fmBand
- property int frequency
- property int frequencyStep
- property int minimumFrequency
- property int maximumFrequency
- property int state: stoppedState
- property int scanningState: stoppedState
- property bool scanningFreqUpdate: false
- property string stationId: ""
-
- signal stationFound
-
- property Connections c : Connections {
- target: root
-
- onFrequencyChanged: {
- if(scanningState != activeState) {
- // Not scanning, push update
- sendSocketMessage("frequency", { value: frequency })
- } else if(!scanningFreqUpdate) {
- // External change, stop scanning
- sendSocketMessage("scan_stop", 'None')
- scanningState = stoppedState
- sendSocketMessage("frequency", { value: frequency })
- } else {
- // This update was from scanning, clear state
- scanningFreqUpdate = false
- }
- }
-
- onBandChanged: {
- sendSocketMessage("band", { value: band })
- updateFrequencyRange(band)
- updateFrequencyStep(band)
- frequency = minimumFrequency
- }
- }
-
- onTextMessageReceived: {
- var json = JSON.parse(message)
- //console.debug("Raw response: " + message)
- var request = json[2].request
- var response = json[2].response
-
- switch (json[0]) {
- case msgid.call:
- break
- case msgid.retok:
- var verb = verbs.shift()
- if (verb == "frequency_range") {
- minimumFrequency = response.min
- maximumFrequency = response.max
- } else if (verb == "frequency_step") {
- frequencyStep = response.step
- }
- break
- case msgid.event:
- var event = JSON.parse(JSON.stringify(json[2]))
- if (event.event === "radio/frequency") {
- if(scanningState == activeState) {
- scanningFreqUpdate = true
- frequency = event.data.value
- }
- } else if (event.event === "radio/station_found") {
- if(scanningState == activeState) {
- scanningState = stoppedState
- stationId = freq2str(event.data.value)
- root.stationFound()
- }
- }
- break
- case msg.reterr:
- console.debug("Bad return value, binding probably not installed")
- break
- case MessageId.event:
- break
- }
- }
-
- onStatusChanged: {
- switch (status) {
- case WebSocket.Open:
- // Initialize band values now that we're connected to the
- // binding
- updateFrequencyRange(band)
- updateFrequencyStep(band)
- frequency = minimumFrequency
- sendSocketMessage("subscribe", { value: "frequency" })
- sendSocketMessage("subscribe", { value: "station_found" })
- break
- case WebSocket.Error:
- console.debug("WebSocket error: " + root.errorString)
- break
- }
- }
-
- function freq2str(freq) {
- if (freq > 5000000) {
- return '%1 MHz'.arg((freq / 1000000).toFixed(1))
- } else {
- return '%1 kHz'.arg((freq / 1000).toFixed(0))
- }
- }
-
- function sendSocketMessage(verb, parameter) {
- var requestJson = [ msgid.call, payloadLength, apiString + '/'
- + verb, parameter ]
- //console.debug("sendSocketMessage: " + JSON.stringify(requestJson))
- verbs.push(verb)
- sendTextMessage(JSON.stringify(requestJson))
- }
-
- function start() {
- sendSocketMessage("start", 'None')
- state = activeState
- }
-
- function stop() {
- sendSocketMessage("stop", 'None')
- state = stoppedState
- }
-
- function tuneUp() {
- frequency += frequencyStep
- if(frequency > maximumFrequency) {
- frequency = minimumFrequency
- }
- }
-
- function tuneDown() {
- frequency -= frequencyStep
- if(frequency < minimumFrequency) {
- frequency = maximumFrequency
- }
- }
-
- function scanUp() {
- scanningState = activeState
- sendSocketMessage("scan_start", { direction: "forward" })
- }
-
- function scanDown() {
- scanningState = activeState
- sendSocketMessage("scan_start", { direction: "backward" })
- }
-
- function updateFrequencyRange(band) {
- sendSocketMessage("frequency_range", { band: band })
- }
-
- function updateFrequencyStep(band) {
- sendSocketMessage("frequency_step", { band: band })
- }
-}
diff --git a/app/app.pro b/app/app.pro
index d1e8274..497ac8c 100644
--- a/app/app.pro
+++ b/app/app.pro
@@ -5,7 +5,11 @@ HEADERS = PresetDataObject.h
SOURCES = main.cpp PresetDataObject.cpp
CONFIG += link_pkgconfig
-PKGCONFIG += libhomescreen qlibwindowmanager
+PKGCONFIG += libhomescreen qlibwindowmanager qtappfw-radio
+
+CONFIG(release, debug|release) {
+ QMAKE_POST_LINK = $(STRIP) --strip-unneeded $(TARGET)
+}
RESOURCES += \
radio.qrc \
diff --git a/app/images/Radio_Active_Icon.svg b/app/images/Radio_Active_Icon.svg
deleted file mode 100644
index cfcc502..0000000
--- a/app/images/Radio_Active_Icon.svg
+++ /dev/null
@@ -1,134 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
- <!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/">
- <!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/">
- <!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/">
- <!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/">
- <!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/">
- <!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/">
- <!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/">
- <!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/">
-]>
-<svg version="1.1" id="Layer_1" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"
- xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 80 80"
- style="enable-background:new 0 0 80 80;" xml:space="preserve">
-<style type="text/css">
- .st0{fill:url(#SVGID_1_);}
- .st1{fill:url(#SVGID_2_);}
- .st2{fill:url(#SVGID_3_);}
- .st3{fill:url(#SVGID_4_);}
- .st4{fill:url(#SVGID_5_);}
- .st5{fill:url(#SVGID_6_);}
- .st6{fill:url(#SVGID_7_);}
- .st7{fill:url(#SVGID_8_);}
- .st8{fill:url(#SVGID_9_);}
- .st9{fill:url(#SVGID_10_);}
- .st10{fill:url(#SVGID_11_);}
- .st11{fill:url(#SVGID_12_);}
- .st12{fill:url(#SVGID_13_);}
-</style>
-<switch>
- <g i:extraneous="self">
- <g>
- <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="3.9276" y1="95.1698" x2="82.4232" y2="-24.8823">
- <stop offset="0" style="stop-color:#00ADDC"/>
- <stop offset="1" style="stop-color:#6BFBFF"/>
- </linearGradient>
- <path class="st0" d="M40,80c-0.1,0-0.1,0-0.2,0C17.7,79.9-0.1,61.8,0,39.8C0.1,17.8,18,0,40,0c0.1,0,0.1,0,0.2,0
- C62.3,0.1,80.1,18.2,80,40.2l0,0C79.9,62.2,62,80,40,80z M40,1.4C18.8,1.4,1.5,18.6,1.4,39.8C1.3,61.1,18.5,78.5,39.8,78.6
- c0.1,0,0.1,0,0.2,0c21.2,0,38.5-17.2,38.6-38.4C78.7,18.9,61.5,1.5,40.2,1.4C40.1,1.4,40.1,1.4,40,1.4z"/>
- <g>
- <g>
- <linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="0.6657" y1="93.037" x2="79.1612" y2="-27.015">
- <stop offset="0" style="stop-color:#00ADDC"/>
- <stop offset="1" style="stop-color:#6BFBFF"/>
- </linearGradient>
- <path class="st1" d="M43.8,51.7l-0.5-1.6c3.7-1.2,6.1-4.4,6.1-8V23.5c0-4.7-4.2-8.5-9.3-8.5s-9.3,3.8-9.3,8.5v18.6
- c0,3.5,2.4,6.7,6.1,8l-0.5,1.6c-4.3-1.5-7.2-5.3-7.2-9.6V23.5c0-5.6,4.9-10.2,11-10.2s11,4.6,11,10.2v18.6
- C51,46.4,48.1,50.3,43.8,51.7z"/>
- </g>
- <g>
- <linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="6.4911" y1="96.8461" x2="84.9869" y2="-23.2062">
- <stop offset="0" style="stop-color:#00ADDC"/>
- <stop offset="1" style="stop-color:#6BFBFF"/>
- </linearGradient>
- <path class="st2" d="M40,56.6c-8.4,0-15.3-5.6-15.3-12.5h1.7c0,6,6.1,10.9,13.6,10.9S53.6,50,53.6,44h1.7
- C55.3,50.9,48.4,56.6,40,56.6z"/>
- </g>
- <g>
- <linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="13.5651" y1="101.4712" x2="92.0607" y2="-18.5808">
- <stop offset="0" style="stop-color:#00ADDC"/>
- <stop offset="1" style="stop-color:#6BFBFF"/>
- </linearGradient>
- <rect x="39.2" y="59.2" class="st3" width="1.7" height="3.7"/>
- </g>
- <g>
- <linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="-6.0323" y1="88.6578" x2="72.4634" y2="-31.3946">
- <stop offset="0" style="stop-color:#00ADDC"/>
- <stop offset="1" style="stop-color:#6BFBFF"/>
- </linearGradient>
- <rect x="29.9" y="27.8" class="st4" width="6.6" height="1.7"/>
- </g>
- <g>
- <linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="-8.3573" y1="87.1376" x2="70.1385" y2="-32.9148">
- <stop offset="0" style="stop-color:#00ADDC"/>
- <stop offset="1" style="stop-color:#6BFBFF"/>
- </linearGradient>
- <rect x="29.9" y="22.7" class="st5" width="6.6" height="1.7"/>
- </g>
- <g>
- <linearGradient id="SVGID_7_" gradientUnits="userSpaceOnUse" x1="-3.6831" y1="90.1938" x2="74.8127" y2="-29.8586">
- <stop offset="0" style="stop-color:#00ADDC"/>
- <stop offset="1" style="stop-color:#6BFBFF"/>
- </linearGradient>
- <rect x="29.9" y="32.9" class="st6" width="6.6" height="1.7"/>
- </g>
- <g>
- <linearGradient id="SVGID_8_" gradientUnits="userSpaceOnUse" x1="-1.3579" y1="91.7141" x2="77.1379" y2="-28.3383">
- <stop offset="0" style="stop-color:#00ADDC"/>
- <stop offset="1" style="stop-color:#6BFBFF"/>
- </linearGradient>
- <rect x="29.9" y="38" class="st7" width="6.6" height="1.7"/>
- </g>
- <g>
- <linearGradient id="SVGID_9_" gradientUnits="userSpaceOnUse" x1="3.4647" y1="94.8674" x2="81.9605" y2="-25.185">
- <stop offset="0" style="stop-color:#00ADDC"/>
- <stop offset="1" style="stop-color:#6BFBFF"/>
- </linearGradient>
- <rect x="43.5" y="27.8" class="st8" width="6.6" height="1.7"/>
- </g>
- <g>
- <linearGradient id="SVGID_10_" gradientUnits="userSpaceOnUse" x1="1.1397" y1="93.3472" x2="79.6355" y2="-26.7052">
- <stop offset="0" style="stop-color:#00ADDC"/>
- <stop offset="1" style="stop-color:#6BFBFF"/>
- </linearGradient>
- <rect x="43.5" y="22.7" class="st9" width="6.6" height="1.7"/>
- </g>
- <g>
- <linearGradient id="SVGID_11_" gradientUnits="userSpaceOnUse" x1="5.8139" y1="96.4034" x2="84.3097" y2="-23.649">
- <stop offset="0" style="stop-color:#00ADDC"/>
- <stop offset="1" style="stop-color:#6BFBFF"/>
- </linearGradient>
- <rect x="43.5" y="32.9" class="st10" width="6.6" height="1.7"/>
- </g>
- <g>
- <linearGradient id="SVGID_12_" gradientUnits="userSpaceOnUse" x1="8.1391" y1="97.9237" x2="86.6349" y2="-22.1287">
- <stop offset="0" style="stop-color:#00ADDC"/>
- <stop offset="1" style="stop-color:#6BFBFF"/>
- </linearGradient>
- <rect x="43.5" y="38" class="st11" width="6.6" height="1.7"/>
- </g>
- <g>
- <linearGradient id="SVGID_13_" gradientUnits="userSpaceOnUse" x1="15.826" y1="102.9496" x2="94.3218" y2="-17.1028">
- <stop offset="0" style="stop-color:#00ADDC"/>
- <stop offset="1" style="stop-color:#6BFBFF"/>
- </linearGradient>
- <path class="st12" d="M50.2,66.7h-1.7c0-2.1-1.1-2.5-4.1-2.5h-8.8c-3,0-4.1,0.4-4.1,2.5h-1.7c0-4.2,3.6-4.2,5.8-4.2h8.8
- C46.6,62.5,50.2,62.5,50.2,66.7z"/>
- </g>
- </g>
- </g>
- </g>
-</switch>
-</svg>
diff --git a/app/images/images.qrc b/app/images/images.qrc
index 9161221..dcbcc11 100644
--- a/app/images/images.qrc
+++ b/app/images/images.qrc
@@ -7,6 +7,5 @@
<file>FM_Icons_AM.svg</file>
<file>FM_Icons_FM.svg</file>
<file>HMI_Radio_Equalizer.svg</file>
- <file>Radio_Active_Icon.svg</file>
</qresource>
</RCC>
diff --git a/app/main.cpp b/app/main.cpp
index 319e1e7..7cc7a10 100644
--- a/app/main.cpp
+++ b/app/main.cpp
@@ -29,6 +29,7 @@
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
+#include <radio.h>
#include "PresetDataObject.h"
#define APP_DATA_PRESETS_PATH "/app-data/radio/presets.conf"
@@ -131,6 +132,8 @@ int main(int argc, char *argv[])
qwm->activateWindow(graphic_role);
});
+ context->setContextProperty("radio", new Radio(bindingAddress, context));
+
engine.load(QUrl(QStringLiteral("qrc:/Radio.qml")));
QObject *root = engine.rootObjects().first();
QQuickWindow *window = qobject_cast<QQuickWindow *>(root);
diff --git a/app/radio.qrc b/app/radio.qrc
index 38ce4f8..347894c 100644
--- a/app/radio.qrc
+++ b/app/radio.qrc
@@ -1,6 +1,5 @@
<RCC>
<qresource prefix="/">
<file>Radio.qml</file>
- <file>api/Binding.qml</file>
</qresource>
</RCC>