From 07fb609095291f8d8544441925dea3d60d636f87 Mon Sep 17 00:00:00 2001 From: Andrew Branson Date: Tue, 16 Feb 2016 23:40:04 +0100 Subject: Moved qml to subdir to unbundle --- rockwork/AppSettingsPage.qml | 78 -------- rockwork/AppStoreDetailsPage.qml | 278 ----------------------------- rockwork/AppStorePage.qml | 266 --------------------------- rockwork/ContentPeerPickerPage.qml | 41 ----- rockwork/DeveloperToolsPage.qml | 157 ---------------- rockwork/FirmwareUpgradePage.qml | 58 ------ rockwork/HealthSettingsDialog.qml | 115 ------------ rockwork/ImportPackagePage.qml | 32 ---- rockwork/InfoPage.qml | 86 --------- rockwork/InstalledAppDelegate.qml | 88 --------- rockwork/InstalledAppsPage.qml | 201 --------------------- rockwork/Main.qml | 53 ------ rockwork/MainMenuPage.qml | 317 --------------------------------- rockwork/NotificationsPage.qml | 88 --------- rockwork/PebbleModels.qml | 28 --- rockwork/PebblesPage.qml | 69 ------- rockwork/ScreenshotsPage.qml | 107 ----------- rockwork/SettingsPage.qml | 80 --------- rockwork/SystemAppIcon.qml | 67 ------- rockwork/qml/AppSettingsPage.qml | 78 ++++++++ rockwork/qml/AppStoreDetailsPage.qml | 278 +++++++++++++++++++++++++++++ rockwork/qml/AppStorePage.qml | 266 +++++++++++++++++++++++++++ rockwork/qml/ContentPeerPickerPage.qml | 41 +++++ rockwork/qml/DeveloperToolsPage.qml | 157 ++++++++++++++++ rockwork/qml/FirmwareUpgradePage.qml | 58 ++++++ rockwork/qml/HealthSettingsDialog.qml | 115 ++++++++++++ rockwork/qml/ImportPackagePage.qml | 32 ++++ rockwork/qml/InfoPage.qml | 86 +++++++++ rockwork/qml/InstalledAppDelegate.qml | 88 +++++++++ rockwork/qml/InstalledAppsPage.qml | 201 +++++++++++++++++++++ rockwork/qml/Main.qml | 53 ++++++ rockwork/qml/MainMenuPage.qml | 317 +++++++++++++++++++++++++++++++++ rockwork/qml/NotificationsPage.qml | 88 +++++++++ rockwork/qml/PebbleModels.qml | 28 +++ rockwork/qml/PebblesPage.qml | 69 +++++++ rockwork/qml/ScreenshotsPage.qml | 107 +++++++++++ rockwork/qml/SettingsPage.qml | 80 +++++++++ rockwork/qml/SystemAppIcon.qml | 67 +++++++ 38 files changed, 2209 insertions(+), 2209 deletions(-) delete mode 100644 rockwork/AppSettingsPage.qml delete mode 100644 rockwork/AppStoreDetailsPage.qml delete mode 100644 rockwork/AppStorePage.qml delete mode 100644 rockwork/ContentPeerPickerPage.qml delete mode 100644 rockwork/DeveloperToolsPage.qml delete mode 100644 rockwork/FirmwareUpgradePage.qml delete mode 100644 rockwork/HealthSettingsDialog.qml delete mode 100644 rockwork/ImportPackagePage.qml delete mode 100644 rockwork/InfoPage.qml delete mode 100644 rockwork/InstalledAppDelegate.qml delete mode 100644 rockwork/InstalledAppsPage.qml delete mode 100644 rockwork/Main.qml delete mode 100644 rockwork/MainMenuPage.qml delete mode 100644 rockwork/NotificationsPage.qml delete mode 100644 rockwork/PebbleModels.qml delete mode 100644 rockwork/PebblesPage.qml delete mode 100644 rockwork/ScreenshotsPage.qml delete mode 100644 rockwork/SettingsPage.qml delete mode 100644 rockwork/SystemAppIcon.qml create mode 100644 rockwork/qml/AppSettingsPage.qml create mode 100644 rockwork/qml/AppStoreDetailsPage.qml create mode 100644 rockwork/qml/AppStorePage.qml create mode 100644 rockwork/qml/ContentPeerPickerPage.qml create mode 100644 rockwork/qml/DeveloperToolsPage.qml create mode 100644 rockwork/qml/FirmwareUpgradePage.qml create mode 100644 rockwork/qml/HealthSettingsDialog.qml create mode 100644 rockwork/qml/ImportPackagePage.qml create mode 100644 rockwork/qml/InfoPage.qml create mode 100644 rockwork/qml/InstalledAppDelegate.qml create mode 100644 rockwork/qml/InstalledAppsPage.qml create mode 100644 rockwork/qml/Main.qml create mode 100644 rockwork/qml/MainMenuPage.qml create mode 100644 rockwork/qml/NotificationsPage.qml create mode 100644 rockwork/qml/PebbleModels.qml create mode 100644 rockwork/qml/PebblesPage.qml create mode 100644 rockwork/qml/ScreenshotsPage.qml create mode 100644 rockwork/qml/SettingsPage.qml create mode 100644 rockwork/qml/SystemAppIcon.qml diff --git a/rockwork/AppSettingsPage.qml b/rockwork/AppSettingsPage.qml deleted file mode 100644 index d8d865b..0000000 --- a/rockwork/AppSettingsPage.qml +++ /dev/null @@ -1,78 +0,0 @@ -import QtQuick 2.4 -import Ubuntu.Web 0.2 -import Ubuntu.Components 1.3 -import com.canonical.Oxide 1.0 as Oxide - -Page { - id: settings - - property string uuid; - property string url; - property var pebble; - - title: i18n.tr("App Settings") - - WebContext { - id: webcontext - userAgent: "Mozilla/5.0 (Linux; Android 5.0; Nexus 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.102 Mobile Safari/537.36 Ubuntu Touch (RockWork)" - } - - WebView { - id: webview - anchors { - fill: parent - bottom: parent.bottom - } - width: parent.width - height: parent.height - - context: webcontext - url: settings.url - preferences.localStorageEnabled: true - preferences.appCacheEnabled: true - preferences.javascriptCanAccessClipboard: true - - function navigationRequestedDelegate(request) { - //The pebblejs:// protocol is handeled by the urihandler, as it appears we can't intercept it - - var url = request.url.toString(); - console.log(url, url.substring(0, 16)); - if (url.substring(0, 16) == 'pebblejs://close') { - pebble.configurationClosed(settings.uuid, url); - request.action = Oxide.NavigationRequest.ActionReject; - pageStack.pop(); - } - } - - Component.onCompleted: { - preferences.localStorageEnabled = true; - } - } - - ProgressBar { - height: units.dp(3) - anchors { - left: parent.left - right: parent.right - top: parent.top - } - - showProgressPercentage: false - value: (webview.loadProgress / 100) - visible: (webview.loading && !webview.lastLoadStopped) - } - - Connections { - target: UriHandler - onOpened: { - if (uris && uris[0] && uris[0].length) { - var url = uris[0]; - - if (url.substring(0, 16) == 'pebblejs://close') { - pebble.configurationClosed(settings.uuid, url); - pageStack.pop(); - } - } - } - } -} diff --git a/rockwork/AppStoreDetailsPage.qml b/rockwork/AppStoreDetailsPage.qml deleted file mode 100644 index 696e3c6..0000000 --- a/rockwork/AppStoreDetailsPage.qml +++ /dev/null @@ -1,278 +0,0 @@ -import QtQuick 2.4 -import QtQuick.Layouts 1.1 -import Ubuntu.Components 1.3 -import Ubuntu.Components.ListItems 1.3 -import QtGraphicalEffects 1.0 - -Page { - id: root - title: i18n.tr("App details") - - property var pebble: null - property var app: null - - ColumnLayout { - anchors.fill: parent - spacing: units.gu(1) - - Item { - Layout.fillWidth: true - height: headerColumn.height + units.gu(1) - - RowLayout { - anchors.fill: parent - anchors.margins: units.gu(1) - spacing: units.gu(1) - height: headerColumn.height - - UbuntuShape { - id: iconShape - Layout.fillHeight: true - Layout.preferredWidth: height - - source: Image { - height: iconShape.height - width: iconShape.width - source: root.app.icon - } - } - - ColumnLayout { - id: headerColumn - Layout.fillWidth: true - Label { - text: root.app.name - fontSize: "large" - Layout.fillWidth: true - elide: Text.ElideRight - } - Label { - text: root.app.vendor - Layout.fillWidth: true - } - } - - Button { - id: installButton - text: enabled ? i18n.tr("Install") : (installing && !installed ? i18n.tr("Installing...") : i18n.tr("Installed")) - color: UbuntuColors.green - enabled: !installed && !installing - property bool installing: false - property bool installed: root.pebble.installedApps.contains(root.app.storeId) || root.pebble.installedWatchfaces.contains(root.app.storeId) - Connections { - target: root.pebble.installedApps - onChanged: { - installButton.installed = root.pebble.installedApps.contains(root.app.storeId) || root.pebble.installedWatchfaces.contains(root.app.storeId) - } - } - - Connections { - target: root.pebble.installedWatchfaces - onChanged: { - installButton.installed = root.pebble.installedApps.contains(root.app.storeId) || root.pebble.installedWatchfaces.contains(root.app.storeId) - } - } - - onClicked: { - root.pebble.installApp(root.app.storeId) - installButton.installing = true - } - } - } - } - - Flickable { - Layout.fillHeight: true - Layout.fillWidth: true - contentHeight: contentColumn.height - bottomMargin: units.gu(1) - clip: true - - Column { - id: contentColumn - width: parent.width - height: childrenRect.height - - Image { - width: parent.width - // ss.w : ss.h = w : h - height: sourceSize.height * width / sourceSize.width - fillMode: Image.PreserveAspectFit - source: root.app.headerImage - } - - RowLayout { - anchors { - left: parent.left - right: parent.right - } - height: units.gu(6) - - Item { - Layout.fillWidth: true - Layout.fillHeight: true - Row { - anchors.centerIn: parent - spacing: units.gu(1) - Icon { - name: "like" - height: parent.height - width: height - } - Label { - text: root.app.hearts - } - } - } - - Rectangle { - Layout.preferredHeight: parent.height - units.gu(2) - Layout.preferredWidth: units.dp(1) - color: UbuntuColors.lightGrey - } - - Item { - Layout.fillWidth: true - Layout.fillHeight: true - Row { - anchors.centerIn: parent - spacing: units.gu(1) - Icon { - name: root.app.isWatchFace ? "clock-app-symbolic" : "stock_application" - height: parent.height - width: height - } - Label { - text: root.app.isWatchFace ? "Watchface" : "Watchapp" - } - } - } - } - - ColumnLayout { - anchors { left: parent.left; right: parent.right; margins: units.gu(1) } - spacing: units.gu(1) - - PebbleModels { - id: modelModel - } - - - Item { - id: screenshotsItem - Layout.preferredHeight: units.gu(20) - Layout.fillWidth: true - - property bool isRound: modelModel.get(root.pebble.model).shape === "round" - - ListView { - id: screenshotsListView - anchors.centerIn: parent - width: parent.width - height: screenshotsItem.isRound ? units.gu(10) : units.gu(9.5) - orientation: ListView.Horizontal - spacing: units.gu(1) - snapMode: ListView.SnapToItem - preferredHighlightBegin: (screenshotsListView.width - height * .95) / 2 - preferredHighlightEnd: (screenshotsListView.width + height * .95) / 2 - highlightRangeMode: ListView.StrictlyEnforceRange - - model: root.app.screenshotImages - delegate: AnimatedImage { - height: screenshotsListView.height - width: height * 0.95 - fillMode: Image.PreserveAspectFit - source: modelData - } - } - Image { - id: watchImage - // ssw : ssh = w : h - height: parent.height - width: height * sourceSize.width / sourceSize.height - fillMode: Image.PreserveAspectFit - anchors.centerIn: parent - source: modelModel.get(root.pebble.model).image - Rectangle { - anchors.centerIn: parent - height: units.gu(10) - width: height - color: "black" - radius: screenshotsItem.isRound ? height / 2 : 0 - } - } - - OpacityMask { - anchors.fill: screenshotsListView - source: screenshotsListView - maskSource: maskRect - } - - Rectangle { - id: maskRect - anchors.fill: screenshotsListView - color: "transparent" - visible: false - - Rectangle { - color: "blue" - anchors.centerIn: parent - height: screenshotsListView.height - width: screenshotsItem.isRound ? height : height * 0.9 - radius: screenshotsItem.isRound ? height / 2 : units.gu(.5) -// anchors.fill: watchImage -// anchors.margins: units.gu(5) -// radius: modelModel.get(root.pebble.model).shape === "rectangle" ? units.gu(.5) : height / 2 -// visible: false - } - } - - } - - Label { - Layout.fillWidth: true - font.bold: true - text: i18n.tr("Description") - } - - Rectangle { - Layout.fillWidth: true - Layout.preferredHeight: units.dp(1) - color: UbuntuColors.lightGrey - } - - Label { - Layout.fillWidth: true - Layout.fillHeight: true - wrapMode: Text.WordWrap - text: root.app.description - } - - GridLayout { - Layout.fillWidth: true - Layout.fillHeight: true - columns: 2 - columnSpacing: units.gu(1) - rowSpacing: units.gu(1) - Label { - text: i18n.tr("Developer") - font.bold: true - } - Label { - text: root.app.vendor - Layout.fillWidth: true - } - Label { - text: i18n.tr("Version") - font.bold: true - } - Label { - text: root.app.version - Layout.fillWidth: true - } - } - } - } - } - } -} diff --git a/rockwork/AppStorePage.qml b/rockwork/AppStorePage.qml deleted file mode 100644 index bb8712b..0000000 --- a/rockwork/AppStorePage.qml +++ /dev/null @@ -1,266 +0,0 @@ -import QtQuick 2.4 -import Ubuntu.Components 1.3 -import QtQuick.Layouts 1.1 -import RockWork 1.0 - -Page { - id: root - title: showWatchApps ? i18n.tr("Add new watchapp") : i18n.tr("Add new watchface") - - property var pebble: null - property bool showWatchApps: false - property bool showWatchFaces: false - - property string link: "" - - function fetchHome() { - if (showWatchApps) { - client.fetchHome(AppStoreClient.TypeWatchapp) - } else { - client.fetchHome(AppStoreClient.TypeWatchface) - } - } - - head { - actions: [ - Action { - iconName: "search" - onTriggered: { - if (searchField.shown) { - searchField.shown = false; - root.fetchHome(); - } else { - searchField.shown = true; - } - } - } - ] - } - - Component.onCompleted: { - if (root.link) { - client.fetchLink(link) - } else { - root.fetchHome() - } - } - - AppStoreClient { - id: client - hardwarePlatform: pebble.hardwarePlatform - } - - Item { - id: searchField - anchors { left: parent.left; right: parent.right; top: parent.top } - anchors.topMargin: shown ? 0 : -height - Behavior on anchors.topMargin { UbuntuNumberAnimation {} } - opacity: shown ? 1 : 0 - Behavior on opacity { UbuntuNumberAnimation {} } - height: units.gu(6) - - property bool shown: false - onShownChanged: { - if (shown) { - searchTextField.focus = true; - } - } - - TextField { - id: searchTextField - anchors.centerIn: parent - width: parent.width - units.gu(2) - onDisplayTextChanged: { - searchTimer.restart() - } - - Timer { - id: searchTimer - interval: 300 - onTriggered: { - client.search(searchTextField.displayText, root.showWatchApps ? AppStoreClient.TypeWatchapp : AppStoreClient.TypeWatchface); - } - } - } - } - - Item { - anchors { left: parent.left; top: searchField.bottom; right: parent.right; bottom: parent.bottom } - ListView { - anchors.fill: parent - model: ApplicationsFilterModel { - id: appsFilterModel - model: client.model - } - clip: true - section.property: "groupId" - section.labelPositioning: ViewSection.CurrentLabelAtStart | - ViewSection.InlineLabels - section.delegate: ListItem { - height: section ? label.implicitHeight + units.gu(3) : 0 - - Rectangle { - anchors.fill: parent - color: "white" - } - - RowLayout { - anchors.fill: parent - anchors.margins: units.gu(1) - Label { - id: label - text: client.model.groupName(section) - fontSize: "large" -// font.weight: Font.DemiBold - elide: Text.ElideRight - Layout.fillWidth: true - } - AbstractButton { - Layout.fillHeight: true - implicitWidth: seeAllLabel.implicitWidth + height - Row { - anchors.verticalCenter: parent.verticalCenter - Label { - id: seeAllLabel - text: i18n.tr("See all") - } - Icon { - implicitHeight: parent.height - implicitWidth: height - name: "go-next" - } - } - onClicked: { - pageStack.push(Qt.resolvedUrl("AppStorePage.qml"), {pebble: root.pebble, link: client.model.groupLink(section), title: client.model.groupName(section)}); - } - } - } - } - - footer: Item { - height: client.model.links.length > 0 ? units.gu(6) : 0 - width: parent.width - - RowLayout { - anchors { - fill: parent - margins: units.gu(1) - } - spacing: units.gu(1) - - Repeater { - model: client.model.links - Button { - text: client.model.linkName(client.model.links[index]) - onClicked: client.fetchLink(client.model.links[index]); - color: UbuntuColors.orange - Layout.fillWidth: true - } - } - } - } - - delegate: ListItem { - height: delegateColumn.height + units.gu(2) - - RowLayout { - id: delegateRow - anchors.fill: parent - anchors.margins: units.gu(1) - spacing: units.gu(1) - - AnimatedImage { - Layout.fillHeight: true - Layout.preferredWidth: height - source: model.icon - asynchronous: true -// sourceSize.width: width -// sourceSize.height: height - } - - ColumnLayout { - id: delegateColumn - Layout.fillWidth: true; - Layout.fillHeight: true; - Label { - Layout.fillWidth: true - text: model.name - font.weight: Font.DemiBold - elide: Text.ElideRight - } - Label { - Layout.fillWidth: true - text: model.category - } - RowLayout { - Icon { - name: "like" - Layout.preferredHeight: parent.height - Layout.preferredWidth: height - implicitHeight: parent.height - } - Label { - Layout.fillWidth: true - text: model.hearts - } - Icon { - id: tickIcon - name: "tick" - implicitHeight: parent.height - Layout.preferredWidth: height - visible: root.pebble.installedApps.contains(model.storeId) || root.pebble.installedWatchfaces.contains(model.storeId) - Connections { - target: root.pebble.installedApps - onChanged: { - tickIcon.visible = root.pebble.installedApps.contains(model.storeId) || root.pebble.installedWatchfaces.contains(model.storeId) - } - } - - Connections { - target: root.pebble.installedWatchfaces - onChanged: { - tickIcon.visible = root.pebble.installedApps.contains(model.storeId) || root.pebble.installedWatchfaces.contains(model.storeId) - } - } - - } - } - } - - } - - onClicked: { - client.fetchAppDetails(model.storeId); - pageStack.push(Qt.resolvedUrl("AppStoreDetailsPage.qml"), {app: appsFilterModel.get(index), pebble: root.pebble}) - } - } - } - -// RowLayout { -// id: buttonRow -// anchors { left: parent.left; bottom: parent.bottom; right: parent.right; margins: units.gu(1) } -// spacing: units.gu(1) -// Button { -// text: i18n.tr("Previous") -// Layout.fillWidth: true -// enabled: client.offset > 0 -// onClicked: { -// client.previous() -// } -// } -// Button { -// text: i18n.tr("Next") -// Layout.fillWidth: true -// onClicked: { -// client.next() -// } -// } -// } - } - - ActivityIndicator { - anchors.centerIn: parent - running: client.busy - } -} - diff --git a/rockwork/ContentPeerPickerPage.qml b/rockwork/ContentPeerPickerPage.qml deleted file mode 100644 index 7ee9702..0000000 --- a/rockwork/ContentPeerPickerPage.qml +++ /dev/null @@ -1,41 +0,0 @@ -import QtQuick 2.4 -import Ubuntu.Components 1.3 -import Ubuntu.Content 1.3 -import RockWork 1.0 - -Page { - id: pickerPage - head { - locked: true - visible: false - } - - property alias contentType: contentPeerPicker.contentType - property string itemName - property alias handler: contentPeerPicker.handler - property string filename - - Component { - id: exportItemComponent - ContentItem { - name: pickerPage.itemName - } - } - ContentPeerPicker { - id: contentPeerPicker - anchors.fill: parent - - onCancelPressed: pageStack.pop() - - onPeerSelected: { - var transfer = peer.request(); - var items = []; - var item = exportItemComponent.createObject(); - item.url = "file://" + pickerPage.filename; - items.push(item) - transfer.items = items; - transfer.state = ContentTransfer.Charged; - pageStack.pop(); - } - } -} diff --git a/rockwork/DeveloperToolsPage.qml b/rockwork/DeveloperToolsPage.qml deleted file mode 100644 index 2f77254..0000000 --- a/rockwork/DeveloperToolsPage.qml +++ /dev/null @@ -1,157 +0,0 @@ -import QtQuick 2.4 -import QtQuick.Layouts 1.1 -import Ubuntu.Components 1.3 -import Ubuntu.Components.Popups 1.3 -import Ubuntu.Content 1.3 - -Page { - id: root - title: i18n.tr("Developer Tools") - - property var pebble: null - - //Creating the menu list this way to allow the text field to be translatable (http://askubuntu.com/a/476331) - ListModel { - id: devMenuModel - dynamicRoles: true - } - - Component.onCompleted: { - populateDevMenu(); - } - - function populateDevMenu() { - devMenuModel.clear(); - - devMenuModel.append({ - icon: "camera-app-symbolic", - text: i18n.tr("Screenshots"), - page: "ScreenshotsPage.qml", - dialog: "", - color: "gold" - }); - devMenuModel.append({ - icon: "dialog-warning-symbolic", - text: i18n.tr("Report problem"), - page: "", - dialog: sendLogsComponent, - color: UbuntuColors.red - }); - devMenuModel.append({ - icon: "stock_application", - text: i18n.tr("Install app or watchface from file"), - page: "ImportPackagePage.qml", - dialog: null, - color: UbuntuColors.blue - }); - - } - - ColumnLayout { - anchors.fill: parent - - Repeater { - id: menuRepeater - model: devMenuModel - delegate: ListItem { - - RowLayout { - anchors.fill: parent - anchors.margins: units.gu(1) - - UbuntuShape { - Layout.fillHeight: true - Layout.preferredWidth: height - backgroundColor: model.color - Icon { - anchors.fill: parent - anchors.margins: units.gu(.5) - name: model.icon - color: "white" - } - } - - - Label { - text: model.text - Layout.fillWidth: true - } - } - - onClicked: { - if (model.page) { - pageStack.push(Qt.resolvedUrl(model.page), {pebble: root.pebble}) - } - if (model.dialog) { - PopupUtils.open(model.dialog) - } - } - } - } - - Item { - Layout.fillHeight: true - Layout.fillWidth: true - } - } - - Component { - id: sendLogsComponent - Dialog { - id: sendLogsDialog - title: i18n.tr("Report problem") - ActivityIndicator { - id: busyIndicator - visible: false - running: visible - } - Label { - text: i18n.tr("Preparing logs package...") - visible: busyIndicator.visible - horizontalAlignment: Text.AlignHCenter - fontSize: "large" - } - - Connections { - target: root.pebble - onLogsDumped: { - if (success) { - var filename = "/tmp/pebble.log" - pageStack.push(Qt.resolvedUrl("ContentPeerPickerPage.qml"), {itemName: i18n.tr("pebble.log"),handler: ContentHandler.Share, contentType: ContentType.All, filename: filename }) - } - PopupUtils.close(sendLogsDialog) - } - } - - Button { - text: i18n.tr("Send rockworkd.log") - color: UbuntuColors.blue - visible: !busyIndicator.visible - onClicked: { - var filename = homePath + "/.cache/upstart/rockworkd.log" - pageStack.push(Qt.resolvedUrl("ContentPeerPickerPage.qml"), {itemName: i18n.tr("rockworkd.log"),handler: ContentHandler.Share, contentType: ContentType.All, filename: filename }) - PopupUtils.close(sendLogsDialog) - } - } - Button { - text: i18n.tr("Send watch logs") - color: UbuntuColors.blue - visible: !busyIndicator.visible - onClicked: { - busyIndicator.visible = true - root.pebble.dumpLogs("/tmp/pebble.log") - } - } - Button { - text: i18n.tr("Cancel") - color: UbuntuColors.red - visible: !busyIndicator.visible - onClicked: { - PopupUtils.close(sendLogsDialog) - } - } - } - } - -} - diff --git a/rockwork/FirmwareUpgradePage.qml b/rockwork/FirmwareUpgradePage.qml deleted file mode 100644 index 3281a12..0000000 --- a/rockwork/FirmwareUpgradePage.qml +++ /dev/null @@ -1,58 +0,0 @@ -import QtQuick 2.4 -import Ubuntu.Components 1.3 - -Page { - id: root - title: i18n.tr("Firmware upgrade") - - property var pebble: null - - Column { - anchors.fill: parent - anchors.margins: units.gu(1) - spacing: units.gu(2) - - Label { - text: i18n.tr("A new firmware upgrade is available for your Pebble smartwatch.") - fontSize: "large" - width: parent.width - wrapMode: Text.WordWrap - } - - Label { - text: i18n.tr("Currently installed firmware: %1").arg("" + root.pebble.softwareVersion + "") - width: parent.width - wrapMode: Text.WordWrap - } - - Label { - text: i18n.tr("Candidate firmware version: %1").arg("" + root.pebble.candidateVersion + "") - width: parent.width - wrapMode: Text.WordWrap - } - - Label { - text: "" + i18n.tr("Release Notes: %1").arg("
" + root.pebble.firmwareReleaseNotes) - width: parent.width - wrapMode: Text.WordWrap - } - - Label { - text: "" + i18n.tr("Important:") + " " + i18n.tr("This update will also upgrade recovery data. Make sure your Pebble smartwarch is connected to a power adapter.") - width: parent.width - wrapMode: Text.WordWrap - visible: root.pebble.candidateVersion.indexOf("mig") > 0 - } - - Button { - text: "Upgrade now" - anchors.horizontalCenter: parent.horizontalCenter - color: UbuntuColors.blue - onClicked: { - root.pebble.performFirmwareUpgrade(); - pageStack.pop(); - } - } - } -} - diff --git a/rockwork/HealthSettingsDialog.qml b/rockwork/HealthSettingsDialog.qml deleted file mode 100644 index 94e5d22..0000000 --- a/rockwork/HealthSettingsDialog.qml +++ /dev/null @@ -1,115 +0,0 @@ -import QtQuick 2.4 -import QtQuick.Layouts 1.1 -import Ubuntu.Components 1.3 -import Ubuntu.Components.Popups 1.3 -import Ubuntu.Components.ListItems 1.3 - -Dialog { - id: root - title: i18n.tr("Health settings") - - property var healthParams: null - - signal accepted(); - - RowLayout { - Label { - text: i18n.tr("Health app enabled") - Layout.fillWidth: true - } - Switch { - id: enabledSwitch - checked: healthParams["enabled"] - } - } - - ItemSelector { - id: genderSelector - model: [i18n.tr("Female"), i18n.tr("Male")] - selectedIndex: root.healthParams["gender"] === "female" ? 0 : 1 - } - - RowLayout { - Label { - text: i18n.tr("Age") - Layout.fillWidth: true - } - TextField { - id: ageField - inputMethodHints: Qt.ImhDigitsOnly - text: healthParams["age"] - Layout.preferredWidth: units.gu(10) - } - } - - RowLayout { - Label { - text: i18n.tr("Height (cm)") - Layout.fillWidth: true - } - TextField { - id: heightField - inputMethodHints: Qt.ImhDigitsOnly - text: healthParams["height"] - Layout.preferredWidth: units.gu(10) - } - } - - RowLayout { - Label { - text: i18n.tr("Weight") - Layout.fillWidth: true - } - TextField { - id: weightField - inputMethodHints: Qt.ImhDigitsOnly - text: healthParams["weight"] - Layout.preferredWidth: units.gu(10) - } - } - - RowLayout { - Label { - text: i18n.tr("I want to be more active") - Layout.fillWidth: true - } - Switch { - id: moreActiveSwitch - checked: healthParams["moreActive"] - } - } - - RowLayout { - Label { - text: i18n.tr("I want to sleep more") - Layout.fillWidth: true - } - Switch { - id: sleepMoreSwitch - checked: healthParams["sleepMore"] - } - } - - - Button { - text: i18n.tr("OK") - color: UbuntuColors.green - onClicked: { - root.healthParams["enabled"] = enabledSwitch.checked; - root.healthParams["gender"] = genderSelector.selectedIndex == 0 ? "female" : "male" - root.healthParams["age"] = ageField.text; - root.healthParams["height"] = heightField.text; - root.healthParams["weight"] = weightField.text; - root.healthParams["moreActive"] = moreActiveSwitch.checked; - root.healthParams["sleepMore"] = sleepMoreSwitch.checked; - root.accepted(); - PopupUtils.close(root); - } - } - Button { - text: i18n.tr("Cancel") - color: UbuntuColors.red - onClicked: PopupUtils.close(root) - } -} - diff --git a/rockwork/ImportPackagePage.qml b/rockwork/ImportPackagePage.qml deleted file mode 100644 index 4f86f78..0000000 --- a/rockwork/ImportPackagePage.qml +++ /dev/null @@ -1,32 +0,0 @@ -import QtQuick 2.4 -import Ubuntu.Components 1.3 -import Ubuntu.Content 1.3 - -Page { - id: root - title: i18n.tr("Import watchapp or watchface") - - property var pebble: null - - ContentPeerPicker { - anchors.fill: parent - handler: ContentHandler.Source - contentType: ContentType.All - showTitle: false - - onPeerSelected: { - var transfer = peer.request(); - - transfer.stateChanged.connect(function() { - if (transfer.state == ContentTransfer.Charged) { - for (var i = 0; i < transfer.items.length; i++) { - print("sideloading package", transfer.items[i].url) - root.pebble.sideloadApp(transfer.items[i].url) - } - pageStack.pop(); - } - }) - } - } -} - diff --git a/rockwork/InfoPage.qml b/rockwork/InfoPage.qml deleted file mode 100644 index 3eec387..0000000 --- a/rockwork/InfoPage.qml +++ /dev/null @@ -1,86 +0,0 @@ -import QtQuick 2.4 -import QtQuick.Layouts 1.1 -import Ubuntu.Components 1.3 -import Ubuntu.Components.ListItems 1.3 - -Page { - title: "About RockWork" - - Flickable { - anchors.fill: parent - contentHeight: contentColumn.height + units.gu(4) - - ColumnLayout { - id: contentColumn - anchors { left: parent.left; top: parent.top; right: parent.right; margins: units.gu(2) } - spacing: units.gu(2) - - RowLayout { - Layout.fillWidth: true - spacing: units.gu(2) - UbuntuShape { - source: Image { - anchors.fill: parent - source: "artwork/rockwork.svg" - } - height: units.gu(6) - width: height - } - - Label { - text: i18n.tr("Version %1").arg(version) - Layout.fillWidth: true - fontSize: "large" - } - } - - ThinDivider {} - - Label { - text: i18n.tr("Contributors") - Layout.fillWidth: true - font.bold: true - } - Label { - text: "Michael Zanetti
Brian Douglas
Katharine Berry" - Layout.fillWidth: true - } - - ThinDivider {} - - Label { - text: i18n.tr("Legal") - Layout.fillWidth: true - font.bold: true - } - - Label { - text: "This program is free software: you can redistribute it and/or modify" + - "it under the terms of the GNU General Public License as published by" + - "the Free Software Foundation, version 3 of the License.
" + - - "This program is distributed in the hope that it will be useful," + - "but WITHOUT ANY WARRANTY; without even the implied warranty of" + - "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" + - "GNU General Public License for more details.
" + - - "You should have received a copy of the GNU General Public License" + - "along with this program. If not, see ." - Layout.fillWidth: true - wrapMode: Text.WordWrap - } - - Label { - text: i18n.tr("This application is neither affiliated with nor endorsed by Pebble Technology Corp.") - Layout.fillWidth: true - wrapMode: Text.WordWrap - } - Label { - text: i18n.tr("Pebble is a trademark of Pebble Technology Corp.") - Layout.fillWidth: true - wrapMode: Text.WordWrap - } - } - } -} - diff --git a/rockwork/InstalledAppDelegate.qml b/rockwork/InstalledAppDelegate.qml deleted file mode 100644 index 89f6ba8..0000000 --- a/rockwork/InstalledAppDelegate.qml +++ /dev/null @@ -1,88 +0,0 @@ -import QtQuick 2.4 -import QtQuick.Layouts 1.1 -import Ubuntu.Components 1.3 -import RockWork 1.0 - -ListItem { - id: root - - property string uuid: "" - property string name: "" - property string iconSource: "" - property string vendor: "" - property bool hasSettings: false - property alias hasGrip: grip.visible - property bool isSystemApp: false - - signal deleteApp(); - signal configureApp(); - - leadingActions: ListItemActions { - actions: [ - Action { - visible: !root.isSystemApp - iconName: "delete" - onTriggered: { - root.deleteApp(); - } - } - ] - } - - trailingActions: ListItemActions { - actions: [ - Action { - visible: root.hasSettings - iconName: "settings" - onTriggered: { - print("settings triggered") - root.configureApp(); - } - } - ] - } - - RowLayout { - anchors { - fill: parent - margins: units.gu(1) - } - spacing: units.gu(1) - - SystemAppIcon { - Layout.fillHeight: true - Layout.preferredWidth: height - isSystemApp: root.isSystemApp - uuid: root.uuid - iconSource: root.iconSource - } - - ColumnLayout { - Layout.fillWidth: true - Label { - text: root.name - Layout.fillWidth: true - } - - Label { - text: root.vendor - Layout.fillWidth: true - fontSize: "small" - } - } - - Item { - id: grip - Layout.fillHeight: true - Layout.preferredWidth: height - opacity: (root.contentMoving || root.swiped || root.dragging) ? 0 : 1 - Behavior on opacity { UbuntuNumberAnimation {} } - Icon { - width: units.gu(3) - height: width - anchors.centerIn: parent - name: "grip-large" - } - } - } -} diff --git a/rockwork/InstalledAppsPage.qml b/rockwork/InstalledAppsPage.qml deleted file mode 100644 index a18cd3f..0000000 --- a/rockwork/InstalledAppsPage.qml +++ /dev/null @@ -1,201 +0,0 @@ -import QtQuick 2.4 -import QtQuick.Layouts 1.1 -import Ubuntu.Components 1.3 -import Ubuntu.Components.Popups 1.3 -import RockWork 1.0 - -Page { - id: root - title: showWatchApps ? (showWatchFaces ? i18n.tr("Apps & Watchfaces") : i18n.tr("Apps")) : i18n.tr("Watchfaces") - - property var pebble: null - property bool showWatchApps: false - property bool showWatchFaces: false - - head { - actions: [ - Action { - iconName: "add" - onTriggered: pageStack.push(Qt.resolvedUrl("AppStorePage.qml"), {pebble: root.pebble, showWatchApps: root.showWatchApps, showWatchFaces: root.showWatchFaces}) - } - ] - } - - function configureApp(uuid) { - // The health app is special :/ - if (uuid == "{36d8c6ed-4c83-4fa1-a9e2-8f12dc941f8c}") { - var popup = PopupUtils.open(Qt.resolvedUrl("HealthSettingsDialog.qml"), root, {healthParams: pebble.healthParams}); - popup.accepted.connect(function() { - pebble.healthParams = popup.healthParams - }) - } else { - pebble.requestConfigurationURL(uuid); - } - } - - Item { - anchors.fill: parent - ListView { - id: listView - anchors.fill: parent - model: root.showWatchApps ? root.pebble.installedApps : root.pebble.installedWatchfaces - clip: true - property real realContentY: contentY + originY - - delegate: InstalledAppDelegate { - id: delegate - uuid: model.uuid - name: model.name - iconSource: model.icon - vendor: model.vendor - visible: dndArea.draggedIndex !== index - hasGrip: index > 0 - isSystemApp: model.isSystemApp - hasSettings: model.hasSettings - - onDeleteApp: { - pebble.removeApp(model.uuid) - } - onConfigureApp: { - root.configureApp(model.uuid) - } - onClicked: { - PopupUtils.open(dialogComponent, root, {app: listView.model.get(index)}) - } - } - } - MouseArea { - id: dndArea - anchors { - top: parent.top - bottom: parent.bottom - right: parent.right - } - drag.axis: Drag.YAxis - propagateComposedEvents: true - width: units.gu(5) - - property int startY: 0 - property int draggedIndex: -1 - - - onPressAndHold: { - startY = mouseY; - draggedIndex = Math.floor((listView.realContentY + mouseY) / fakeDragItem.height) - if (draggedIndex == 0) { - print("cannot drag settings app"); - return; - } - - var draggedItem = listView.model.get(draggedIndex); - fakeDragItem.uuid = draggedItem.uuid; - fakeDragItem.name = draggedItem.name; - fakeDragItem.vendor = draggedItem.vendor; - fakeDragItem.iconSource = draggedItem.icon; - fakeDragItem.isSystemApp = draggedItem.isSystemApp; - fakeDragItem.y = (fakeDragItem.height * draggedIndex) - listView.realContentY - drag.target = fakeDragItem; - } - - onMouseYChanged: { - var newIndex = Math.floor((listView.realContentY + mouseY) / fakeDragItem.height) - - if (newIndex > draggedIndex) { - newIndex = draggedIndex + 1; - } else if (newIndex < draggedIndex) { - newIndex = draggedIndex - 1; - } else { - return; - } - - if (newIndex >= 1 && newIndex < listView.count) { - listView.model.move(draggedIndex, newIndex); - draggedIndex = newIndex; - } - } - - onReleased: { - if (draggedIndex > -1) { - listView.model.commitMove(); - draggedIndex = -1; - drag.target = null; - } - } - } - } - - - - InstalledAppDelegate { - id: fakeDragItem - visible: dndArea.draggedIndex != -1 - - } - - Component { - id: dialogComponent - Dialog { - id: dialog - property var app: null - - RowLayout { - SystemAppIcon { - height: titleCol.height - width: height - isSystemApp: app.isSystemApp - uuid: app.uuid - iconSource: app.icon - } - - ColumnLayout { - id: titleCol - Layout.fillWidth: true - - Label { - Layout.fillWidth: true - text: app.name - fontSize: "large" - } - Label { - Layout.fillWidth: true - text: app.vendor - } - } - } - - Button { - text: i18n.tr("Launch") - color: UbuntuColors.green - onClicked: { - pebble.launchApp(app.uuid); - PopupUtils.close(dialog); - } - } - - Button { - text: i18n.tr("Configure") - color: UbuntuColors.blue - visible: app.hasSettings - onClicked: { - root.configureApp(app.uuid); - PopupUtils.close(dialog); - } - } - - Button { - text: i18n.tr("Delete") - color: UbuntuColors.red - visible: !app.isSystemApp - onClicked: { - pebble.removeApp(app.uuid); - PopupUtils.close(dialog); - } - } - - Button { - text: i18n.tr("Close") - onClicked: PopupUtils.close(dialog) - } - } - } -} diff --git a/rockwork/Main.qml b/rockwork/Main.qml deleted file mode 100644 index 2bdece3..0000000 --- a/rockwork/Main.qml +++ /dev/null @@ -1,53 +0,0 @@ -import QtQuick 2.4 -import QtQuick.Layouts 1.1 -import Ubuntu.Components 1.3 -import RockWork 1.0 - -/*! - \brief MainView with a Label and Button elements. -*/ - -MainView { - applicationName: "rockwork.mzanetti" - - width: units.gu(40) - height: units.gu(70) - - ServiceController { - id: serviceController - serviceName: "rockworkd" - Component.onCompleted: { - if (!serviceController.serviceFileInstalled) { - print("Service file not installed. Installing now.") - serviceController.installServiceFile(); - } - if (!serviceController.serviceRunning) { - print("Service not running. Starting now.") - serviceController.startService(); - } - if (pebbles.version !== version) { - print("Service file version (", version, ") is not equal running service version (", pebbles.version, "). Restarting service.") - serviceController.restartService(); - } - } - } - - Pebbles { - id: pebbles - onCountChanged: loadStack() - } - - function loadStack() { - pageStack.clear() - if (pebbles.count == 1) { - pageStack.push(Qt.resolvedUrl("MainMenuPage.qml"), {pebble: pebbles.get(0)}) - } else { - pageStack.push(Qt.resolvedUrl("PebblesPage.qml")) - } - } - - PageStack { - id: pageStack - Component.onCompleted: loadStack(); - } -} diff --git a/rockwork/MainMenuPage.qml b/rockwork/MainMenuPage.qml deleted file mode 100644 index 32c7b96..0000000 --- a/rockwork/MainMenuPage.qml +++ /dev/null @@ -1,317 +0,0 @@ -import QtQuick 2.4 -import QtQuick.Layouts 1.1 -import Ubuntu.Components 1.3 - -Page { - id: root - title: pebble.name - - property var pebble: null - - head { - actions: [ - Action { - iconName: "info" - text: i18n.tr("About") - onTriggered: { - pageStack.push(Qt.resolvedUrl("InfoPage.qml")) - } - }, - Action { - iconName: "ubuntu-sdk-symbolic" - text: i18n.tr("Developer tools") - onTriggered: { - pageStack.push(Qt.resolvedUrl("DeveloperToolsPage.qml"), {pebble: root.pebble}) - } - } - ] - } - - //Creating the menu list this way to allow the text field to be translatable (http://askubuntu.com/a/476331) - ListModel { - id: mainMenuModel - dynamicRoles: true - } - - Component.onCompleted: { - populateMainMenu(); - } - - Connections { - target: root.pebble - onFirmwareUpgradeAvailableChanged: { - populateMainMenu(); - } - } - - function populateMainMenu() { - mainMenuModel.clear(); - - mainMenuModel.append({ - icon: "stock_notification", - text: i18n.tr("Manage notifications"), - page: "NotificationsPage.qml", - color: "blue" - }); - - mainMenuModel.append({ - icon: "stock_application", - text: i18n.tr("Manage Apps"), - page: "InstalledAppsPage.qml", - showWatchApps: true, - color: UbuntuColors.green - }); - - mainMenuModel.append({ - icon: "clock-app-symbolic", - text: i18n.tr("Manage Watchfaces"), - page: "InstalledAppsPage.qml", - showWatchFaces: true, - color: "black" - }); - - mainMenuModel.append({ - icon: "settings", - text: i18n.tr("Settings"), - page: "SettingsPage.qml", - showWatchFaces: true, - color: "gold" - }); - - if (root.pebble.firmwareUpgradeAvailable) { - mainMenuModel.append({ - icon: "preferences-system-updates-symbolic", - text: i18n.tr("Firmware upgrade"), - page: "FirmwareUpgradePage.qml", - color: "red" - }); - } - - } - - PebbleModels { - id: modelModel - } - - GridLayout { - anchors.fill: parent - columns: parent.width > parent.height ? 2 : 1 - - Item { - Layout.fillWidth: true - Layout.fillHeight: true - Layout.maximumHeight: units.gu(30) - - RowLayout { - anchors.fill: parent - anchors.margins: units.gu(1) - spacing: units.gu(1) - - Item { - Layout.alignment: Qt.AlignHCenter - Layout.fillHeight: true - Layout.fillWidth: true - Layout.minimumWidth: watchImage.width - Image { - id: watchImage - width: implicitWidth * height / implicitHeight - height: parent.height - anchors.horizontalCenter: parent.horizontalCenter - - source: modelModel.get(root.pebble.model).image - fillMode: Image.PreserveAspectFit - - Item { - id: watchFace - height: parent.height * (modelModel.get(root.pebble.model - 1).shape === "rectangle" ? .5 : .515) - width: height * (modelModel.get(root.pebble.model - 1).shape === "rectangle" ? .85 : 1) - anchors.centerIn: parent - anchors.horizontalCenterOffset: units.dp(1) - anchors.verticalCenterOffset: units.dp(modelModel.get(root.pebble.model - 1).shape === "rectangle" ? 0 : 1) - - Image { - id: image - anchors.fill: parent - source: "file://" + root.pebble.screenshots.latestScreenshot - visible: false - } - - Component.onCompleted: { - if (!root.pebble.screenshots.latestScreenshot) { - root.pebble.requestScreenshot(); - } - } - - Rectangle { - id: textItem - anchors.fill: parent - layer.enabled: true - radius: modelModel.get(root.pebble.model - 1).shape === "rectangle" ? units.gu(.5) : height / 2 - // This item should be used as the 'mask' - layer.samplerName: "maskSource" - layer.effect: ShaderEffect { - property var colorSource: image; - fragmentShader: " - uniform lowp sampler2D colorSource; - uniform lowp sampler2D maskSource; - uniform lowp float qt_Opacity; - varying highp vec2 qt_TexCoord0; - void main() { - gl_FragColor = - texture2D(colorSource, qt_TexCoord0) - * texture2D(maskSource, qt_TexCoord0).a - * qt_Opacity; - } - " - } - } - } - } - } - ColumnLayout { - Layout.fillWidth: true - Layout.fillHeight: true - spacing: units.gu(2) - Rectangle { - height: units.gu(10) - width: height - radius: height / 2 - color: root.pebble.connected ? UbuntuColors.green : UbuntuColors.red - - Icon { - anchors.fill: parent - anchors.margins: units.gu(2) - color: "white" - name: root.pebble.connected ? "tick" : "dialog-error-symbolic" - } - } - - Label { - text: root.pebble.connected ? i18n.tr("Connected") : i18n.tr("Disconnected") - Layout.fillWidth: true - } - } - } - } - - - Column { - Layout.fillWidth: true - Layout.preferredHeight: childrenRect.height - spacing: menuRepeater.count > 0 ? 0 : units.gu(2) - Label { - text: i18n.tr("Your Pebble smartwatch is disconnected. Please make sure it is powered on, within range and it is paired properly in the Bluetooth System Settings.") - width: parent.width - units.gu(4) - anchors.horizontalCenter: parent.horizontalCenter - wrapMode: Text.WordWrap - visible: !root.pebble.connected - fontSize: "large" - horizontalAlignment: Text.AlignHCenter - } - - Button { - text: i18n.tr("Open System Settings") - visible: !root.pebble.connected - onClicked: Qt.openUrlExternally("settings://system/bluetooth") - color: UbuntuColors.orange - anchors.horizontalCenter: parent.horizontalCenter - } - - Label { - text: i18n.tr("Your Pebble smartwatch is in factory mode and needs to be initialized.") - width: parent.width - units.gu(4) - anchors.horizontalCenter: parent.horizontalCenter - wrapMode: Text.WordWrap - visible: root.pebble.connected && root.pebble.recovery && !root.pebble.upgradingFirmware - fontSize: "large" - horizontalAlignment: Text.AlignHCenter - } - Button { - text: i18n.tr("Initialize Pebble") - onClicked: root.pebble.performFirmwareUpgrade(); - visible: root.pebble.connected && root.pebble.recovery && !root.pebble.upgradingFirmware - color: UbuntuColors.orange - anchors.horizontalCenter: parent.horizontalCenter - } - - Rectangle { - id: upgradeIcon - height: units.gu(10) - width: height - radius: width / 2 - color: UbuntuColors.orange - anchors.horizontalCenter: parent.horizontalCenter - Icon { - anchors.fill: parent - anchors.margins: units.gu(1) - name: "preferences-system-updates-symbolic" - color: "white" - } - - RotationAnimation on rotation { - duration: 2000 - loops: Animation.Infinite - from: 0 - to: 360 - running: upgradeIcon.visible - } - visible: root.pebble.connected && root.pebble.upgradingFirmware - } - - Label { - text: i18n.tr("Upgrading...") - fontSize: "large" - anchors.horizontalCenter: parent.horizontalCenter - visible: root.pebble.connected && root.pebble.upgradingFirmware - } - - Repeater { - id: menuRepeater - model: root.pebble.connected && !root.pebble.recovery && !root.pebble.upgradingFirmware ? mainMenuModel : null - delegate: ListItem { - - RowLayout { - anchors.fill: parent - anchors.margins: units.gu(1) - - UbuntuShape { - Layout.fillHeight: true - Layout.preferredWidth: height - backgroundColor: model.color - Icon { - anchors.fill: parent - anchors.margins: units.gu(.5) - name: model.icon - color: "white" - } - } - - - Label { - text: model.text - Layout.fillWidth: true - } - } - - onClicked: { - var options = {}; - options["pebble"] = root.pebble - var modelItem = mainMenuModel.get(index) - options["showWatchApps"] = modelItem.showWatchApps - options["showWatchFaces"] = modelItem.showWatchFaces - pageStack.push(Qt.resolvedUrl(model.page), options) - } - } - } - } - } - - Connections { - target: pebble - onOpenURL: { - if (url) { - pageStack.push(Qt.resolvedUrl("AppSettingsPage.qml"), {uuid: uuid, url: url, pebble: pebble}) - } - } - } -} diff --git a/rockwork/NotificationsPage.qml b/rockwork/NotificationsPage.qml deleted file mode 100644 index 9802b05..0000000 --- a/rockwork/NotificationsPage.qml +++ /dev/null @@ -1,88 +0,0 @@ -import QtQuick 2.4 -import QtQuick.Layouts 1.1 -import Ubuntu.Components 1.3 -import RockWork 1.0 - -Page { - id: root - title: i18n.tr("Notifications") - - property var pebble: null - - ColumnLayout { - anchors.fill: parent - anchors.topMargin: units.gu(1) - - Item { - Layout.fillWidth: true - implicitHeight: infoLabel.height - - Label { - id: infoLabel - anchors { - left: parent.left - right: parent.right - margins: units.gu(2) - } - - wrapMode: Text.WordWrap - text: i18n.tr("Entries here will be added as notifications appear on the phone. Selected notifications will be shown on your Pebble smartwatch.") - } - } - - - ListView { - Layout.fillWidth: true - Layout.fillHeight: true - clip: true - model: root.pebble.notifications - - delegate: ListItem { - ListItemLayout { - title.text: model.name - - UbuntuShape { - SlotsLayout.position: SlotsLayout.Leading; - height: units.gu(5) - width: height - backgroundColor: { - // Add some hacks for known icons - switch (model.icon) { - case "calendar": - return UbuntuColors.orange; - case "settings": - return "grey"; - case "dialog-question-symbolic": - return UbuntuColors.red; - case "alarm-clock": - return UbuntuColors.purple; - case "gpm-battery-050": - return UbuntuColors.green; - } - return "black" - } - source: Image { - height: parent.height - width: parent.width - source: model.icon.indexOf("/") === 0 ? "file://" + model.icon : "" - } - Icon { - anchors.fill: parent - anchors.margins: units.gu(.5) - name: model.icon.indexOf("/") !== 0 ? model.icon : "" - color: "white" - } - } - - Switch { - checked: model.enabled - SlotsLayout.position: SlotsLayout.Trailing; - onClicked: { - root.pebble.setNotificationFilter(model.name, checked) - } - } - } - } - } - } -} diff --git a/rockwork/PebbleModels.qml b/rockwork/PebbleModels.qml deleted file mode 100644 index 103064a..0000000 --- a/rockwork/PebbleModels.qml +++ /dev/null @@ -1,28 +0,0 @@ -import QtQuick 2.4 - -ListModel { - id: modelModel - ListElement { image: 'artwork/tintin-black.png'; shape: "rectangle" } // Fallback for Unknown - ListElement { image: 'artwork/tintin-black.png'; shape: "rectangle" } - ListElement { image: 'artwork/tintin-white.png'; shape: "rectangle" } - ListElement { image: 'artwork/tintin-red.png'; shape: "rectangle" } - ListElement { image: 'artwork/tintin-orange.png'; shape: "rectangle" } - ListElement { image: 'artwork/tintin-grey.png'; shape: "rectangle" } - ListElement { image: 'artwork/bianca-silver.png'; shape: "rectangle" } - ListElement { image: 'artwork/bianca-black.png'; shape: "rectangle" } - ListElement { image: 'artwork/tintin-blue.png'; shape: "rectangle" } - ListElement { image: 'artwork/tintin-green.png'; shape: "rectangle" } - ListElement { image: 'artwork/tintin-pink.png'; shape: "rectangle" } - ListElement { image: 'artwork/snowy-white.png'; shape: "rectangle" } - ListElement { image: 'artwork/snowy-black.png'; shape: "rectangle" } - ListElement { image: 'artwork/snowy-red.png'; shape: "rectangle" } - ListElement { image: 'artwork/bobby-silver.png'; shape: "rectangle" } - ListElement { image: 'artwork/bobby-black.png'; shape: "rectangle" } - ListElement { image: 'artwork/bobby-gold.png'; shape: "rectangle" } - ListElement { image: 'artwork/spalding-14mm-silver.png'; shape: "round" } - ListElement { image: 'artwork/spalding-14mm-black.png'; shape: "round" } - ListElement { image: 'artwork/spalding-20mm-silver.png'; shape: "round" } - ListElement { image: 'artwork/spalding-20mm-black.png'; shape: "round" } - ListElement { image: 'artwork/spalding-14mm-rose-gold.png'; shape: "round" } -} - diff --git a/rockwork/PebblesPage.qml b/rockwork/PebblesPage.qml deleted file mode 100644 index a973b0a..0000000 --- a/rockwork/PebblesPage.qml +++ /dev/null @@ -1,69 +0,0 @@ -import QtQuick 2.4 -import QtQuick.Layouts 1.1 -import Ubuntu.Components 1.3 - -Page { - title: i18n.tr("Manage Pebble Watches") - - head { - actions: [ - Action { - iconName: "settings" - onTriggered: { - onClicked: Qt.openUrlExternally("settings://system/bluetooth") - } - } - ] - } - - ListView { - anchors.fill: parent - model: pebbles - delegate: ListItem { - RowLayout { - anchors.fill: parent - anchors.margins: units.gu(1) - - ColumnLayout { - Layout.fillHeight: true - Layout.fillWidth: true - - Label { - text: model.name - } - - Label { - text: model.connected ? i18n.tr("Connected") : i18n.tr("Disconnected") - fontSize: "small" - } - } - } - - onClicked: { - var p = pebbles.get(index); - print("opening pebble:", p.name, p.hardwarePlatform) - pageStack.push(Qt.resolvedUrl("MainMenuPage.qml"), {pebble: pebbles.get(index)}) - } - } - } - - Column { - anchors.centerIn: parent - width: parent.width - units.gu(4) - spacing: units.gu(4) - visible: pebbles.count === 0 - - Label { - text: i18n.tr("No Pebble smartwatches configured yet. Please connect your Pebble smartwatch using System Settings.") - fontSize: "large" - width: parent.width - wrapMode: Text.WordWrap - } - - Button { - text: i18n.tr("Open System Settings") - anchors.horizontalCenter: parent.horizontalCenter - onClicked: Qt.openUrlExternally("settings://system/bluetooth") - } - } -} diff --git a/rockwork/ScreenshotsPage.qml b/rockwork/ScreenshotsPage.qml deleted file mode 100644 index fdbeb9a..0000000 --- a/rockwork/ScreenshotsPage.qml +++ /dev/null @@ -1,107 +0,0 @@ -import QtQuick 2.4 -import QtQuick.Layouts 1.1 -import Ubuntu.Components 1.3 -import Ubuntu.Components.Popups 1.3 -import Ubuntu.Content 1.3 -import RockWork 1.0 - -Page { - id: root - - title: i18n.tr("Screenshots") - - property var pebble: null - - head { - actions: [ - Action { - iconName: "camera-app-symbolic" - onTriggered: root.pebble.requestScreenshot() - } - ] - } - - ColumnLayout { - anchors.fill: parent - anchors.margins: units.gu(1) - spacing: units.gu(1) - - GridView { - id: grid - Layout.fillHeight: true - Layout.fillWidth: true - clip: true - - property int columns: 2 - - cellWidth: width / columns - cellHeight: cellWidth - - model: root.pebble.screenshots - - displaced: Transition { - UbuntuNumberAnimation { properties: "x,y" } - } - - delegate: Item { - width: grid.cellWidth - height: grid.cellHeight - Image { - anchors.fill: parent - anchors.margins: units.gu(.5) - fillMode: Image.PreserveAspectFit - source: "file://" + model.filename - } - MouseArea { - anchors.fill: parent - onClicked: { - PopupUtils.open(dialogComponent, root, {filename: model.filename}) - } - } - } - } - } - - Component { - id: dialogComponent - Dialog { - id: dialog - title: i18n.tr("Screenshot options") - - property string filename - - Button { - text: i18n.tr("Share") - color: UbuntuColors.blue - onClicked: { - pageStack.push(Qt.resolvedUrl("ContentPeerPickerPage.qml"), {itemName: i18n.tr("Pebble screenshot"), handler: ContentHandler.Share, contentType: ContentType.Pictures, filename: filename }) - PopupUtils.close(dialog) - } - } - Button { - text: i18n.tr("Save") - color: UbuntuColors.green - onClicked: { - pageStack.push(Qt.resolvedUrl("ContentPeerPickerPage.qml"), {itemName: i18n.tr("Pebble screenshot"),handler: ContentHandler.Destination, contentType: ContentType.Pictures, filename: filename }) - PopupUtils.close(dialog) - } - } - - Button { - text: i18n.tr("Delete") - color: UbuntuColors.red - onClicked: { - root.pebble.removeScreenshot(filename) - PopupUtils.close(dialog) - } - } - Button { - text: i18n.tr("Cancel") - onClicked: { - PopupUtils.close(dialog) - } - } - } - } -} - diff --git a/rockwork/SettingsPage.qml b/rockwork/SettingsPage.qml deleted file mode 100644 index 153aaf4..0000000 --- a/rockwork/SettingsPage.qml +++ /dev/null @@ -1,80 +0,0 @@ -import QtQuick 2.4 -import QtQuick.Layouts 1.1 -import Ubuntu.Components 1.3 -import Ubuntu.Components.ListItems 1.3 - -Page { - id: root - title: i18n.tr("Settings") - - property var pebble: null - - ColumnLayout { - anchors.fill: parent - anchors.margins: units.gu(1) - spacing: units.gu(1) - - Label { - Layout.fillWidth: true - text: i18n.tr("Distance Units") - font.bold: true - } - - RowLayout { - Layout.fillWidth: true - CheckBox { - id: metricUnitsCheckbox - checked: !root.pebble.imperialUnits - onClicked: { - checked = true - root.pebble.imperialUnits = false; - imperialUnitsCheckBox.checked = false; - } - } - Label { - text: i18n.tr("Metric") - Layout.fillWidth: true - } - CheckBox { - id: imperialUnitsCheckBox - checked: root.pebble.imperialUnits - onClicked: { - checked = true - root.pebble.imperialUnits = true; - metricUnitsCheckbox.checked = false; - } - } - Label { - text: i18n.tr("Imperial") - Layout.fillWidth: true - } - } - ThinDivider {} - - Label { - text: i18n.tr("Calendar") - Layout.fillWidth: true - font.bold: true - } - RowLayout { - Layout.fillWidth: true - Label { - text: i18n.tr("Sync calendar to timeline") - Layout.fillWidth: true - } - Switch { - checked: root.pebble.calendarSyncEnabled - onClicked: { - root.pebble.calendarSyncEnabled = checked; - } - } - } - ThinDivider {} - - Item { - Layout.fillWidth: true - Layout.fillHeight: true - } - } -} - diff --git a/rockwork/SystemAppIcon.qml b/rockwork/SystemAppIcon.qml deleted file mode 100644 index 88e37bc..0000000 --- a/rockwork/SystemAppIcon.qml +++ /dev/null @@ -1,67 +0,0 @@ -import QtQuick 2.4 -import Ubuntu.Components 1.3 - -Item { - id: root - - property bool isSystemApp: false - property string uuid: "" - property string iconSource: "" - - UbuntuShape { - anchors.fill: parent - visible: root.isSystemApp - backgroundColor: { - switch (root.uuid) { - case "{07e0d9cb-8957-4bf7-9d42-35bf47caadfe}": - return "gray"; - case "{18e443ce-38fd-47c8-84d5-6d0c775fbe55}": - return "blue"; - case "{36d8c6ed-4c83-4fa1-a9e2-8f12dc941f8c}": - return UbuntuColors.red; - case "{1f03293d-47af-4f28-b960-f2b02a6dd757}": - return "gold" - case "{b2cae818-10f8-46df-ad2b-98ad2254a3c1}": - return "darkviolet" - case "{67a32d95-ef69-46d4-a0b9-854cc62f97f9}": - return "green"; - case "{8f3c8686-31a1-4f5f-91f5-01600c9bdc59}": - return "black" - } - - return ""; - } - } - Icon { - anchors.fill: parent - implicitHeight: height - anchors.margins: units.gu(1) - visible: root.isSystemApp - color: "white" - name: { - switch (root.uuid) { - case "{07e0d9cb-8957-4bf7-9d42-35bf47caadfe}": - return "settings"; - case "{18e443ce-38fd-47c8-84d5-6d0c775fbe55}": - return "clock-app-symbolic"; - case "{36d8c6ed-4c83-4fa1-a9e2-8f12dc941f8c}": - return "like"; - case "{1f03293d-47af-4f28-b960-f2b02a6dd757}": - return "stock_music"; - case "{b2cae818-10f8-46df-ad2b-98ad2254a3c1}": - return "stock_notification"; - case "{67a32d95-ef69-46d4-a0b9-854cc62f97f9}": - return "stock_alarm-clock"; - case "{8f3c8686-31a1-4f5f-91f5-01600c9bdc59}": - return "clock-app-symbolic"; - } - return ""; - } - } - - Image { - source: root.isSystemApp ? "" : "file://" + root.iconSource; - anchors.fill: parent - visible: !root.isSystemApp - } -} diff --git a/rockwork/qml/AppSettingsPage.qml b/rockwork/qml/AppSettingsPage.qml new file mode 100644 index 0000000..d8d865b --- /dev/null +++ b/rockwork/qml/AppSettingsPage.qml @@ -0,0 +1,78 @@ +import QtQuick 2.4 +import Ubuntu.Web 0.2 +import Ubuntu.Components 1.3 +import com.canonical.Oxide 1.0 as Oxide + +Page { + id: settings + + property string uuid; + property string url; + property var pebble; + + title: i18n.tr("App Settings") + + WebContext { + id: webcontext + userAgent: "Mozilla/5.0 (Linux; Android 5.0; Nexus 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.102 Mobile Safari/537.36 Ubuntu Touch (RockWork)" + } + + WebView { + id: webview + anchors { + fill: parent + bottom: parent.bottom + } + width: parent.width + height: parent.height + + context: webcontext + url: settings.url + preferences.localStorageEnabled: true + preferences.appCacheEnabled: true + preferences.javascriptCanAccessClipboard: true + + function navigationRequestedDelegate(request) { + //The pebblejs:// protocol is handeled by the urihandler, as it appears we can't intercept it + + var url = request.url.toString(); + console.log(url, url.substring(0, 16)); + if (url.substring(0, 16) == 'pebblejs://close') { + pebble.configurationClosed(settings.uuid, url); + request.action = Oxide.NavigationRequest.ActionReject; + pageStack.pop(); + } + } + + Component.onCompleted: { + preferences.localStorageEnabled = true; + } + } + + ProgressBar { + height: units.dp(3) + anchors { + left: parent.left + right: parent.right + top: parent.top + } + + showProgressPercentage: false + value: (webview.loadProgress / 100) + visible: (webview.loading && !webview.lastLoadStopped) + } + + Connections { + target: UriHandler + onOpened: { + if (uris && uris[0] && uris[0].length) { + var url = uris[0]; + + if (url.substring(0, 16) == 'pebblejs://close') { + pebble.configurationClosed(settings.uuid, url); + pageStack.pop(); + } + } + } + } +} diff --git a/rockwork/qml/AppStoreDetailsPage.qml b/rockwork/qml/AppStoreDetailsPage.qml new file mode 100644 index 0000000..696e3c6 --- /dev/null +++ b/rockwork/qml/AppStoreDetailsPage.qml @@ -0,0 +1,278 @@ +import QtQuick 2.4 +import QtQuick.Layouts 1.1 +import Ubuntu.Components 1.3 +import Ubuntu.Components.ListItems 1.3 +import QtGraphicalEffects 1.0 + +Page { + id: root + title: i18n.tr("App details") + + property var pebble: null + property var app: null + + ColumnLayout { + anchors.fill: parent + spacing: units.gu(1) + + Item { + Layout.fillWidth: true + height: headerColumn.height + units.gu(1) + + RowLayout { + anchors.fill: parent + anchors.margins: units.gu(1) + spacing: units.gu(1) + height: headerColumn.height + + UbuntuShape { + id: iconShape + Layout.fillHeight: true + Layout.preferredWidth: height + + source: Image { + height: iconShape.height + width: iconShape.width + source: root.app.icon + } + } + + ColumnLayout { + id: headerColumn + Layout.fillWidth: true + Label { + text: root.app.name + fontSize: "large" + Layout.fillWidth: true + elide: Text.ElideRight + } + Label { + text: root.app.vendor + Layout.fillWidth: true + } + } + + Button { + id: installButton + text: enabled ? i18n.tr("Install") : (installing && !installed ? i18n.tr("Installing...") : i18n.tr("Installed")) + color: UbuntuColors.green + enabled: !installed && !installing + property bool installing: false + property bool installed: root.pebble.installedApps.contains(root.app.storeId) || root.pebble.installedWatchfaces.contains(root.app.storeId) + Connections { + target: root.pebble.installedApps + onChanged: { + installButton.installed = root.pebble.installedApps.contains(root.app.storeId) || root.pebble.installedWatchfaces.contains(root.app.storeId) + } + } + + Connections { + target: root.pebble.installedWatchfaces + onChanged: { + installButton.installed = root.pebble.installedApps.contains(root.app.storeId) || root.pebble.installedWatchfaces.contains(root.app.storeId) + } + } + + onClicked: { + root.pebble.installApp(root.app.storeId) + installButton.installing = true + } + } + } + } + + Flickable { + Layout.fillHeight: true + Layout.fillWidth: true + contentHeight: contentColumn.height + bottomMargin: units.gu(1) + clip: true + + Column { + id: contentColumn + width: parent.width + height: childrenRect.height + + Image { + width: parent.width + // ss.w : ss.h = w : h + height: sourceSize.height * width / sourceSize.width + fillMode: Image.PreserveAspectFit + source: root.app.headerImage + } + + RowLayout { + anchors { + left: parent.left + right: parent.right + } + height: units.gu(6) + + Item { + Layout.fillWidth: true + Layout.fillHeight: true + Row { + anchors.centerIn: parent + spacing: units.gu(1) + Icon { + name: "like" + height: parent.height + width: height + } + Label { + text: root.app.hearts + } + } + } + + Rectangle { + Layout.preferredHeight: parent.height - units.gu(2) + Layout.preferredWidth: units.dp(1) + color: UbuntuColors.lightGrey + } + + Item { + Layout.fillWidth: true + Layout.fillHeight: true + Row { + anchors.centerIn: parent + spacing: units.gu(1) + Icon { + name: root.app.isWatchFace ? "clock-app-symbolic" : "stock_application" + height: parent.height + width: height + } + Label { + text: root.app.isWatchFace ? "Watchface" : "Watchapp" + } + } + } + } + + ColumnLayout { + anchors { left: parent.left; right: parent.right; margins: units.gu(1) } + spacing: units.gu(1) + + PebbleModels { + id: modelModel + } + + + Item { + id: screenshotsItem + Layout.preferredHeight: units.gu(20) + Layout.fillWidth: true + + property bool isRound: modelModel.get(root.pebble.model).shape === "round" + + ListView { + id: screenshotsListView + anchors.centerIn: parent + width: parent.width + height: screenshotsItem.isRound ? units.gu(10) : units.gu(9.5) + orientation: ListView.Horizontal + spacing: units.gu(1) + snapMode: ListView.SnapToItem + preferredHighlightBegin: (screenshotsListView.width - height * .95) / 2 + preferredHighlightEnd: (screenshotsListView.width + height * .95) / 2 + highlightRangeMode: ListView.StrictlyEnforceRange + + model: root.app.screenshotImages + delegate: AnimatedImage { + height: screenshotsListView.height + width: height * 0.95 + fillMode: Image.PreserveAspectFit + source: modelData + } + } + Image { + id: watchImage + // ssw : ssh = w : h + height: parent.height + width: height * sourceSize.width / sourceSize.height + fillMode: Image.PreserveAspectFit + anchors.centerIn: parent + source: modelModel.get(root.pebble.model).image + Rectangle { + anchors.centerIn: parent + height: units.gu(10) + width: height + color: "black" + radius: screenshotsItem.isRound ? height / 2 : 0 + } + } + + OpacityMask { + anchors.fill: screenshotsListView + source: screenshotsListView + maskSource: maskRect + } + + Rectangle { + id: maskRect + anchors.fill: screenshotsListView + color: "transparent" + visible: false + + Rectangle { + color: "blue" + anchors.centerIn: parent + height: screenshotsListView.height + width: screenshotsItem.isRound ? height : height * 0.9 + radius: screenshotsItem.isRound ? height / 2 : units.gu(.5) +// anchors.fill: watchImage +// anchors.margins: units.gu(5) +// radius: modelModel.get(root.pebble.model).shape === "rectangle" ? units.gu(.5) : height / 2 +// visible: false + } + } + + } + + Label { + Layout.fillWidth: true + font.bold: true + text: i18n.tr("Description") + } + + Rectangle { + Layout.fillWidth: true + Layout.preferredHeight: units.dp(1) + color: UbuntuColors.lightGrey + } + + Label { + Layout.fillWidth: true + Layout.fillHeight: true + wrapMode: Text.WordWrap + text: root.app.description + } + + GridLayout { + Layout.fillWidth: true + Layout.fillHeight: true + columns: 2 + columnSpacing: units.gu(1) + rowSpacing: units.gu(1) + Label { + text: i18n.tr("Developer") + font.bold: true + } + Label { + text: root.app.vendor + Layout.fillWidth: true + } + Label { + text: i18n.tr("Version") + font.bold: true + } + Label { + text: root.app.version + Layout.fillWidth: true + } + } + } + } + } + } +} diff --git a/rockwork/qml/AppStorePage.qml b/rockwork/qml/AppStorePage.qml new file mode 100644 index 0000000..bb8712b --- /dev/null +++ b/rockwork/qml/AppStorePage.qml @@ -0,0 +1,266 @@ +import QtQuick 2.4 +import Ubuntu.Components 1.3 +import QtQuick.Layouts 1.1 +import RockWork 1.0 + +Page { + id: root + title: showWatchApps ? i18n.tr("Add new watchapp") : i18n.tr("Add new watchface") + + property var pebble: null + property bool showWatchApps: false + property bool showWatchFaces: false + + property string link: "" + + function fetchHome() { + if (showWatchApps) { + client.fetchHome(AppStoreClient.TypeWatchapp) + } else { + client.fetchHome(AppStoreClient.TypeWatchface) + } + } + + head { + actions: [ + Action { + iconName: "search" + onTriggered: { + if (searchField.shown) { + searchField.shown = false; + root.fetchHome(); + } else { + searchField.shown = true; + } + } + } + ] + } + + Component.onCompleted: { + if (root.link) { + client.fetchLink(link) + } else { + root.fetchHome() + } + } + + AppStoreClient { + id: client + hardwarePlatform: pebble.hardwarePlatform + } + + Item { + id: searchField + anchors { left: parent.left; right: parent.right; top: parent.top } + anchors.topMargin: shown ? 0 : -height + Behavior on anchors.topMargin { UbuntuNumberAnimation {} } + opacity: shown ? 1 : 0 + Behavior on opacity { UbuntuNumberAnimation {} } + height: units.gu(6) + + property bool shown: false + onShownChanged: { + if (shown) { + searchTextField.focus = true; + } + } + + TextField { + id: searchTextField + anchors.centerIn: parent + width: parent.width - units.gu(2) + onDisplayTextChanged: { + searchTimer.restart() + } + + Timer { + id: searchTimer + interval: 300 + onTriggered: { + client.search(searchTextField.displayText, root.showWatchApps ? AppStoreClient.TypeWatchapp : AppStoreClient.TypeWatchface); + } + } + } + } + + Item { + anchors { left: parent.left; top: searchField.bottom; right: parent.right; bottom: parent.bottom } + ListView { + anchors.fill: parent + model: ApplicationsFilterModel { + id: appsFilterModel + model: client.model + } + clip: true + section.property: "groupId" + section.labelPositioning: ViewSection.CurrentLabelAtStart | + ViewSection.InlineLabels + section.delegate: ListItem { + height: section ? label.implicitHeight + units.gu(3) : 0 + + Rectangle { + anchors.fill: parent + color: "white" + } + + RowLayout { + anchors.fill: parent + anchors.margins: units.gu(1) + Label { + id: label + text: client.model.groupName(section) + fontSize: "large" +// font.weight: Font.DemiBold + elide: Text.ElideRight + Layout.fillWidth: true + } + AbstractButton { + Layout.fillHeight: true + implicitWidth: seeAllLabel.implicitWidth + height + Row { + anchors.verticalCenter: parent.verticalCenter + Label { + id: seeAllLabel + text: i18n.tr("See all") + } + Icon { + implicitHeight: parent.height + implicitWidth: height + name: "go-next" + } + } + onClicked: { + pageStack.push(Qt.resolvedUrl("AppStorePage.qml"), {pebble: root.pebble, link: client.model.groupLink(section), title: client.model.groupName(section)}); + } + } + } + } + + footer: Item { + height: client.model.links.length > 0 ? units.gu(6) : 0 + width: parent.width + + RowLayout { + anchors { + fill: parent + margins: units.gu(1) + } + spacing: units.gu(1) + + Repeater { + model: client.model.links + Button { + text: client.model.linkName(client.model.links[index]) + onClicked: client.fetchLink(client.model.links[index]); + color: UbuntuColors.orange + Layout.fillWidth: true + } + } + } + } + + delegate: ListItem { + height: delegateColumn.height + units.gu(2) + + RowLayout { + id: delegateRow + anchors.fill: parent + anchors.margins: units.gu(1) + spacing: units.gu(1) + + AnimatedImage { + Layout.fillHeight: true + Layout.preferredWidth: height + source: model.icon + asynchronous: true +// sourceSize.width: width +// sourceSize.height: height + } + + ColumnLayout { + id: delegateColumn + Layout.fillWidth: true; + Layout.fillHeight: true; + Label { + Layout.fillWidth: true + text: model.name + font.weight: Font.DemiBold + elide: Text.ElideRight + } + Label { + Layout.fillWidth: true + text: model.category + } + RowLayout { + Icon { + name: "like" + Layout.preferredHeight: parent.height + Layout.preferredWidth: height + implicitHeight: parent.height + } + Label { + Layout.fillWidth: true + text: model.hearts + } + Icon { + id: tickIcon + name: "tick" + implicitHeight: parent.height + Layout.preferredWidth: height + visible: root.pebble.installedApps.contains(model.storeId) || root.pebble.installedWatchfaces.contains(model.storeId) + Connections { + target: root.pebble.installedApps + onChanged: { + tickIcon.visible = root.pebble.installedApps.contains(model.storeId) || root.pebble.installedWatchfaces.contains(model.storeId) + } + } + + Connections { + target: root.pebble.installedWatchfaces + onChanged: { + tickIcon.visible = root.pebble.installedApps.contains(model.storeId) || root.pebble.installedWatchfaces.contains(model.storeId) + } + } + + } + } + } + + } + + onClicked: { + client.fetchAppDetails(model.storeId); + pageStack.push(Qt.resolvedUrl("AppStoreDetailsPage.qml"), {app: appsFilterModel.get(index), pebble: root.pebble}) + } + } + } + +// RowLayout { +// id: buttonRow +// anchors { left: parent.left; bottom: parent.bottom; right: parent.right; margins: units.gu(1) } +// spacing: units.gu(1) +// Button { +// text: i18n.tr("Previous") +// Layout.fillWidth: true +// enabled: client.offset > 0 +// onClicked: { +// client.previous() +// } +// } +// Button { +// text: i18n.tr("Next") +// Layout.fillWidth: true +// onClicked: { +// client.next() +// } +// } +// } + } + + ActivityIndicator { + anchors.centerIn: parent + running: client.busy + } +} + diff --git a/rockwork/qml/ContentPeerPickerPage.qml b/rockwork/qml/ContentPeerPickerPage.qml new file mode 100644 index 0000000..7ee9702 --- /dev/null +++ b/rockwork/qml/ContentPeerPickerPage.qml @@ -0,0 +1,41 @@ +import QtQuick 2.4 +import Ubuntu.Components 1.3 +import Ubuntu.Content 1.3 +import RockWork 1.0 + +Page { + id: pickerPage + head { + locked: true + visible: false + } + + property alias contentType: contentPeerPicker.contentType + property string itemName + property alias handler: contentPeerPicker.handler + property string filename + + Component { + id: exportItemComponent + ContentItem { + name: pickerPage.itemName + } + } + ContentPeerPicker { + id: contentPeerPicker + anchors.fill: parent + + onCancelPressed: pageStack.pop() + + onPeerSelected: { + var transfer = peer.request(); + var items = []; + var item = exportItemComponent.createObject(); + item.url = "file://" + pickerPage.filename; + items.push(item) + transfer.items = items; + transfer.state = ContentTransfer.Charged; + pageStack.pop(); + } + } +} diff --git a/rockwork/qml/DeveloperToolsPage.qml b/rockwork/qml/DeveloperToolsPage.qml new file mode 100644 index 0000000..2f77254 --- /dev/null +++ b/rockwork/qml/DeveloperToolsPage.qml @@ -0,0 +1,157 @@ +import QtQuick 2.4 +import QtQuick.Layouts 1.1 +import Ubuntu.Components 1.3 +import Ubuntu.Components.Popups 1.3 +import Ubuntu.Content 1.3 + +Page { + id: root + title: i18n.tr("Developer Tools") + + property var pebble: null + + //Creating the menu list this way to allow the text field to be translatable (http://askubuntu.com/a/476331) + ListModel { + id: devMenuModel + dynamicRoles: true + } + + Component.onCompleted: { + populateDevMenu(); + } + + function populateDevMenu() { + devMenuModel.clear(); + + devMenuModel.append({ + icon: "camera-app-symbolic", + text: i18n.tr("Screenshots"), + page: "ScreenshotsPage.qml", + dialog: "", + color: "gold" + }); + devMenuModel.append({ + icon: "dialog-warning-symbolic", + text: i18n.tr("Report problem"), + page: "", + dialog: sendLogsComponent, + color: UbuntuColors.red + }); + devMenuModel.append({ + icon: "stock_application", + text: i18n.tr("Install app or watchface from file"), + page: "ImportPackagePage.qml", + dialog: null, + color: UbuntuColors.blue + }); + + } + + ColumnLayout { + anchors.fill: parent + + Repeater { + id: menuRepeater + model: devMenuModel + delegate: ListItem { + + RowLayout { + anchors.fill: parent + anchors.margins: units.gu(1) + + UbuntuShape { + Layout.fillHeight: true + Layout.preferredWidth: height + backgroundColor: model.color + Icon { + anchors.fill: parent + anchors.margins: units.gu(.5) + name: model.icon + color: "white" + } + } + + + Label { + text: model.text + Layout.fillWidth: true + } + } + + onClicked: { + if (model.page) { + pageStack.push(Qt.resolvedUrl(model.page), {pebble: root.pebble}) + } + if (model.dialog) { + PopupUtils.open(model.dialog) + } + } + } + } + + Item { + Layout.fillHeight: true + Layout.fillWidth: true + } + } + + Component { + id: sendLogsComponent + Dialog { + id: sendLogsDialog + title: i18n.tr("Report problem") + ActivityIndicator { + id: busyIndicator + visible: false + running: visible + } + Label { + text: i18n.tr("Preparing logs package...") + visible: busyIndicator.visible + horizontalAlignment: Text.AlignHCenter + fontSize: "large" + } + + Connections { + target: root.pebble + onLogsDumped: { + if (success) { + var filename = "/tmp/pebble.log" + pageStack.push(Qt.resolvedUrl("ContentPeerPickerPage.qml"), {itemName: i18n.tr("pebble.log"),handler: ContentHandler.Share, contentType: ContentType.All, filename: filename }) + } + PopupUtils.close(sendLogsDialog) + } + } + + Button { + text: i18n.tr("Send rockworkd.log") + color: UbuntuColors.blue + visible: !busyIndicator.visible + onClicked: { + var filename = homePath + "/.cache/upstart/rockworkd.log" + pageStack.push(Qt.resolvedUrl("ContentPeerPickerPage.qml"), {itemName: i18n.tr("rockworkd.log"),handler: ContentHandler.Share, contentType: ContentType.All, filename: filename }) + PopupUtils.close(sendLogsDialog) + } + } + Button { + text: i18n.tr("Send watch logs") + color: UbuntuColors.blue + visible: !busyIndicator.visible + onClicked: { + busyIndicator.visible = true + root.pebble.dumpLogs("/tmp/pebble.log") + } + } + Button { + text: i18n.tr("Cancel") + color: UbuntuColors.red + visible: !busyIndicator.visible + onClicked: { + PopupUtils.close(sendLogsDialog) + } + } + } + } + +} + diff --git a/rockwork/qml/FirmwareUpgradePage.qml b/rockwork/qml/FirmwareUpgradePage.qml new file mode 100644 index 0000000..3281a12 --- /dev/null +++ b/rockwork/qml/FirmwareUpgradePage.qml @@ -0,0 +1,58 @@ +import QtQuick 2.4 +import Ubuntu.Components 1.3 + +Page { + id: root + title: i18n.tr("Firmware upgrade") + + property var pebble: null + + Column { + anchors.fill: parent + anchors.margins: units.gu(1) + spacing: units.gu(2) + + Label { + text: i18n.tr("A new firmware upgrade is available for your Pebble smartwatch.") + fontSize: "large" + width: parent.width + wrapMode: Text.WordWrap + } + + Label { + text: i18n.tr("Currently installed firmware: %1").arg("" + root.pebble.softwareVersion + "") + width: parent.width + wrapMode: Text.WordWrap + } + + Label { + text: i18n.tr("Candidate firmware version: %1").arg("" + root.pebble.candidateVersion + "") + width: parent.width + wrapMode: Text.WordWrap + } + + Label { + text: "" + i18n.tr("Release Notes: %1").arg("
" + root.pebble.firmwareReleaseNotes) + width: parent.width + wrapMode: Text.WordWrap + } + + Label { + text: "" + i18n.tr("Important:") + " " + i18n.tr("This update will also upgrade recovery data. Make sure your Pebble smartwarch is connected to a power adapter.") + width: parent.width + wrapMode: Text.WordWrap + visible: root.pebble.candidateVersion.indexOf("mig") > 0 + } + + Button { + text: "Upgrade now" + anchors.horizontalCenter: parent.horizontalCenter + color: UbuntuColors.blue + onClicked: { + root.pebble.performFirmwareUpgrade(); + pageStack.pop(); + } + } + } +} + diff --git a/rockwork/qml/HealthSettingsDialog.qml b/rockwork/qml/HealthSettingsDialog.qml new file mode 100644 index 0000000..94e5d22 --- /dev/null +++ b/rockwork/qml/HealthSettingsDialog.qml @@ -0,0 +1,115 @@ +import QtQuick 2.4 +import QtQuick.Layouts 1.1 +import Ubuntu.Components 1.3 +import Ubuntu.Components.Popups 1.3 +import Ubuntu.Components.ListItems 1.3 + +Dialog { + id: root + title: i18n.tr("Health settings") + + property var healthParams: null + + signal accepted(); + + RowLayout { + Label { + text: i18n.tr("Health app enabled") + Layout.fillWidth: true + } + Switch { + id: enabledSwitch + checked: healthParams["enabled"] + } + } + + ItemSelector { + id: genderSelector + model: [i18n.tr("Female"), i18n.tr("Male")] + selectedIndex: root.healthParams["gender"] === "female" ? 0 : 1 + } + + RowLayout { + Label { + text: i18n.tr("Age") + Layout.fillWidth: true + } + TextField { + id: ageField + inputMethodHints: Qt.ImhDigitsOnly + text: healthParams["age"] + Layout.preferredWidth: units.gu(10) + } + } + + RowLayout { + Label { + text: i18n.tr("Height (cm)") + Layout.fillWidth: true + } + TextField { + id: heightField + inputMethodHints: Qt.ImhDigitsOnly + text: healthParams["height"] + Layout.preferredWidth: units.gu(10) + } + } + + RowLayout { + Label { + text: i18n.tr("Weight") + Layout.fillWidth: true + } + TextField { + id: weightField + inputMethodHints: Qt.ImhDigitsOnly + text: healthParams["weight"] + Layout.preferredWidth: units.gu(10) + } + } + + RowLayout { + Label { + text: i18n.tr("I want to be more active") + Layout.fillWidth: true + } + Switch { + id: moreActiveSwitch + checked: healthParams["moreActive"] + } + } + + RowLayout { + Label { + text: i18n.tr("I want to sleep more") + Layout.fillWidth: true + } + Switch { + id: sleepMoreSwitch + checked: healthParams["sleepMore"] + } + } + + + Button { + text: i18n.tr("OK") + color: UbuntuColors.green + onClicked: { + root.healthParams["enabled"] = enabledSwitch.checked; + root.healthParams["gender"] = genderSelector.selectedIndex == 0 ? "female" : "male" + root.healthParams["age"] = ageField.text; + root.healthParams["height"] = heightField.text; + root.healthParams["weight"] = weightField.text; + root.healthParams["moreActive"] = moreActiveSwitch.checked; + root.healthParams["sleepMore"] = sleepMoreSwitch.checked; + root.accepted(); + PopupUtils.close(root); + } + } + Button { + text: i18n.tr("Cancel") + color: UbuntuColors.red + onClicked: PopupUtils.close(root) + } +} + diff --git a/rockwork/qml/ImportPackagePage.qml b/rockwork/qml/ImportPackagePage.qml new file mode 100644 index 0000000..4f86f78 --- /dev/null +++ b/rockwork/qml/ImportPackagePage.qml @@ -0,0 +1,32 @@ +import QtQuick 2.4 +import Ubuntu.Components 1.3 +import Ubuntu.Content 1.3 + +Page { + id: root + title: i18n.tr("Import watchapp or watchface") + + property var pebble: null + + ContentPeerPicker { + anchors.fill: parent + handler: ContentHandler.Source + contentType: ContentType.All + showTitle: false + + onPeerSelected: { + var transfer = peer.request(); + + transfer.stateChanged.connect(function() { + if (transfer.state == ContentTransfer.Charged) { + for (var i = 0; i < transfer.items.length; i++) { + print("sideloading package", transfer.items[i].url) + root.pebble.sideloadApp(transfer.items[i].url) + } + pageStack.pop(); + } + }) + } + } +} + diff --git a/rockwork/qml/InfoPage.qml b/rockwork/qml/InfoPage.qml new file mode 100644 index 0000000..3eec387 --- /dev/null +++ b/rockwork/qml/InfoPage.qml @@ -0,0 +1,86 @@ +import QtQuick 2.4 +import QtQuick.Layouts 1.1 +import Ubuntu.Components 1.3 +import Ubuntu.Components.ListItems 1.3 + +Page { + title: "About RockWork" + + Flickable { + anchors.fill: parent + contentHeight: contentColumn.height + units.gu(4) + + ColumnLayout { + id: contentColumn + anchors { left: parent.left; top: parent.top; right: parent.right; margins: units.gu(2) } + spacing: units.gu(2) + + RowLayout { + Layout.fillWidth: true + spacing: units.gu(2) + UbuntuShape { + source: Image { + anchors.fill: parent + source: "artwork/rockwork.svg" + } + height: units.gu(6) + width: height + } + + Label { + text: i18n.tr("Version %1").arg(version) + Layout.fillWidth: true + fontSize: "large" + } + } + + ThinDivider {} + + Label { + text: i18n.tr("Contributors") + Layout.fillWidth: true + font.bold: true + } + Label { + text: "Michael Zanetti
Brian Douglas
Katharine Berry" + Layout.fillWidth: true + } + + ThinDivider {} + + Label { + text: i18n.tr("Legal") + Layout.fillWidth: true + font.bold: true + } + + Label { + text: "This program is free software: you can redistribute it and/or modify" + + "it under the terms of the GNU General Public License as published by" + + "the Free Software Foundation, version 3 of the License.
" + + + "This program is distributed in the hope that it will be useful," + + "but WITHOUT ANY WARRANTY; without even the implied warranty of" + + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" + + "GNU General Public License for more details.
" + + + "You should have received a copy of the GNU General Public License" + + "along with this program. If not, see ." + Layout.fillWidth: true + wrapMode: Text.WordWrap + } + + Label { + text: i18n.tr("This application is neither affiliated with nor endorsed by Pebble Technology Corp.") + Layout.fillWidth: true + wrapMode: Text.WordWrap + } + Label { + text: i18n.tr("Pebble is a trademark of Pebble Technology Corp.") + Layout.fillWidth: true + wrapMode: Text.WordWrap + } + } + } +} + diff --git a/rockwork/qml/InstalledAppDelegate.qml b/rockwork/qml/InstalledAppDelegate.qml new file mode 100644 index 0000000..89f6ba8 --- /dev/null +++ b/rockwork/qml/InstalledAppDelegate.qml @@ -0,0 +1,88 @@ +import QtQuick 2.4 +import QtQuick.Layouts 1.1 +import Ubuntu.Components 1.3 +import RockWork 1.0 + +ListItem { + id: root + + property string uuid: "" + property string name: "" + property string iconSource: "" + property string vendor: "" + property bool hasSettings: false + property alias hasGrip: grip.visible + property bool isSystemApp: false + + signal deleteApp(); + signal configureApp(); + + leadingActions: ListItemActions { + actions: [ + Action { + visible: !root.isSystemApp + iconName: "delete" + onTriggered: { + root.deleteApp(); + } + } + ] + } + + trailingActions: ListItemActions { + actions: [ + Action { + visible: root.hasSettings + iconName: "settings" + onTriggered: { + print("settings triggered") + root.configureApp(); + } + } + ] + } + + RowLayout { + anchors { + fill: parent + margins: units.gu(1) + } + spacing: units.gu(1) + + SystemAppIcon { + Layout.fillHeight: true + Layout.preferredWidth: height + isSystemApp: root.isSystemApp + uuid: root.uuid + iconSource: root.iconSource + } + + ColumnLayout { + Layout.fillWidth: true + Label { + text: root.name + Layout.fillWidth: true + } + + Label { + text: root.vendor + Layout.fillWidth: true + fontSize: "small" + } + } + + Item { + id: grip + Layout.fillHeight: true + Layout.preferredWidth: height + opacity: (root.contentMoving || root.swiped || root.dragging) ? 0 : 1 + Behavior on opacity { UbuntuNumberAnimation {} } + Icon { + width: units.gu(3) + height: width + anchors.centerIn: parent + name: "grip-large" + } + } + } +} diff --git a/rockwork/qml/InstalledAppsPage.qml b/rockwork/qml/InstalledAppsPage.qml new file mode 100644 index 0000000..a18cd3f --- /dev/null +++ b/rockwork/qml/InstalledAppsPage.qml @@ -0,0 +1,201 @@ +import QtQuick 2.4 +import QtQuick.Layouts 1.1 +import Ubuntu.Components 1.3 +import Ubuntu.Components.Popups 1.3 +import RockWork 1.0 + +Page { + id: root + title: showWatchApps ? (showWatchFaces ? i18n.tr("Apps & Watchfaces") : i18n.tr("Apps")) : i18n.tr("Watchfaces") + + property var pebble: null + property bool showWatchApps: false + property bool showWatchFaces: false + + head { + actions: [ + Action { + iconName: "add" + onTriggered: pageStack.push(Qt.resolvedUrl("AppStorePage.qml"), {pebble: root.pebble, showWatchApps: root.showWatchApps, showWatchFaces: root.showWatchFaces}) + } + ] + } + + function configureApp(uuid) { + // The health app is special :/ + if (uuid == "{36d8c6ed-4c83-4fa1-a9e2-8f12dc941f8c}") { + var popup = PopupUtils.open(Qt.resolvedUrl("HealthSettingsDialog.qml"), root, {healthParams: pebble.healthParams}); + popup.accepted.connect(function() { + pebble.healthParams = popup.healthParams + }) + } else { + pebble.requestConfigurationURL(uuid); + } + } + + Item { + anchors.fill: parent + ListView { + id: listView + anchors.fill: parent + model: root.showWatchApps ? root.pebble.installedApps : root.pebble.installedWatchfaces + clip: true + property real realContentY: contentY + originY + + delegate: InstalledAppDelegate { + id: delegate + uuid: model.uuid + name: model.name + iconSource: model.icon + vendor: model.vendor + visible: dndArea.draggedIndex !== index + hasGrip: index > 0 + isSystemApp: model.isSystemApp + hasSettings: model.hasSettings + + onDeleteApp: { + pebble.removeApp(model.uuid) + } + onConfigureApp: { + root.configureApp(model.uuid) + } + onClicked: { + PopupUtils.open(dialogComponent, root, {app: listView.model.get(index)}) + } + } + } + MouseArea { + id: dndArea + anchors { + top: parent.top + bottom: parent.bottom + right: parent.right + } + drag.axis: Drag.YAxis + propagateComposedEvents: true + width: units.gu(5) + + property int startY: 0 + property int draggedIndex: -1 + + + onPressAndHold: { + startY = mouseY; + draggedIndex = Math.floor((listView.realContentY + mouseY) / fakeDragItem.height) + if (draggedIndex == 0) { + print("cannot drag settings app"); + return; + } + + var draggedItem = listView.model.get(draggedIndex); + fakeDragItem.uuid = draggedItem.uuid; + fakeDragItem.name = draggedItem.name; + fakeDragItem.vendor = draggedItem.vendor; + fakeDragItem.iconSource = draggedItem.icon; + fakeDragItem.isSystemApp = draggedItem.isSystemApp; + fakeDragItem.y = (fakeDragItem.height * draggedIndex) - listView.realContentY + drag.target = fakeDragItem; + } + + onMouseYChanged: { + var newIndex = Math.floor((listView.realContentY + mouseY) / fakeDragItem.height) + + if (newIndex > draggedIndex) { + newIndex = draggedIndex + 1; + } else if (newIndex < draggedIndex) { + newIndex = draggedIndex - 1; + } else { + return; + } + + if (newIndex >= 1 && newIndex < listView.count) { + listView.model.move(draggedIndex, newIndex); + draggedIndex = newIndex; + } + } + + onReleased: { + if (draggedIndex > -1) { + listView.model.commitMove(); + draggedIndex = -1; + drag.target = null; + } + } + } + } + + + + InstalledAppDelegate { + id: fakeDragItem + visible: dndArea.draggedIndex != -1 + + } + + Component { + id: dialogComponent + Dialog { + id: dialog + property var app: null + + RowLayout { + SystemAppIcon { + height: titleCol.height + width: height + isSystemApp: app.isSystemApp + uuid: app.uuid + iconSource: app.icon + } + + ColumnLayout { + id: titleCol + Layout.fillWidth: true + + Label { + Layout.fillWidth: true + text: app.name + fontSize: "large" + } + Label { + Layout.fillWidth: true + text: app.vendor + } + } + } + + Button { + text: i18n.tr("Launch") + color: UbuntuColors.green + onClicked: { + pebble.launchApp(app.uuid); + PopupUtils.close(dialog); + } + } + + Button { + text: i18n.tr("Configure") + color: UbuntuColors.blue + visible: app.hasSettings + onClicked: { + root.configureApp(app.uuid); + PopupUtils.close(dialog); + } + } + + Button { + text: i18n.tr("Delete") + color: UbuntuColors.red + visible: !app.isSystemApp + onClicked: { + pebble.removeApp(app.uuid); + PopupUtils.close(dialog); + } + } + + Button { + text: i18n.tr("Close") + onClicked: PopupUtils.close(dialog) + } + } + } +} diff --git a/rockwork/qml/Main.qml b/rockwork/qml/Main.qml new file mode 100644 index 0000000..2bdece3 --- /dev/null +++ b/rockwork/qml/Main.qml @@ -0,0 +1,53 @@ +import QtQuick 2.4 +import QtQuick.Layouts 1.1 +import Ubuntu.Components 1.3 +import RockWork 1.0 + +/*! + \brief MainView with a Label and Button elements. +*/ + +MainView { + applicationName: "rockwork.mzanetti" + + width: units.gu(40) + height: units.gu(70) + + ServiceController { + id: serviceController + serviceName: "rockworkd" + Component.onCompleted: { + if (!serviceController.serviceFileInstalled) { + print("Service file not installed. Installing now.") + serviceController.installServiceFile(); + } + if (!serviceController.serviceRunning) { + print("Service not running. Starting now.") + serviceController.startService(); + } + if (pebbles.version !== version) { + print("Service file version (", version, ") is not equal running service version (", pebbles.version, "). Restarting service.") + serviceController.restartService(); + } + } + } + + Pebbles { + id: pebbles + onCountChanged: loadStack() + } + + function loadStack() { + pageStack.clear() + if (pebbles.count == 1) { + pageStack.push(Qt.resolvedUrl("MainMenuPage.qml"), {pebble: pebbles.get(0)}) + } else { + pageStack.push(Qt.resolvedUrl("PebblesPage.qml")) + } + } + + PageStack { + id: pageStack + Component.onCompleted: loadStack(); + } +} diff --git a/rockwork/qml/MainMenuPage.qml b/rockwork/qml/MainMenuPage.qml new file mode 100644 index 0000000..32c7b96 --- /dev/null +++ b/rockwork/qml/MainMenuPage.qml @@ -0,0 +1,317 @@ +import QtQuick 2.4 +import QtQuick.Layouts 1.1 +import Ubuntu.Components 1.3 + +Page { + id: root + title: pebble.name + + property var pebble: null + + head { + actions: [ + Action { + iconName: "info" + text: i18n.tr("About") + onTriggered: { + pageStack.push(Qt.resolvedUrl("InfoPage.qml")) + } + }, + Action { + iconName: "ubuntu-sdk-symbolic" + text: i18n.tr("Developer tools") + onTriggered: { + pageStack.push(Qt.resolvedUrl("DeveloperToolsPage.qml"), {pebble: root.pebble}) + } + } + ] + } + + //Creating the menu list this way to allow the text field to be translatable (http://askubuntu.com/a/476331) + ListModel { + id: mainMenuModel + dynamicRoles: true + } + + Component.onCompleted: { + populateMainMenu(); + } + + Connections { + target: root.pebble + onFirmwareUpgradeAvailableChanged: { + populateMainMenu(); + } + } + + function populateMainMenu() { + mainMenuModel.clear(); + + mainMenuModel.append({ + icon: "stock_notification", + text: i18n.tr("Manage notifications"), + page: "NotificationsPage.qml", + color: "blue" + }); + + mainMenuModel.append({ + icon: "stock_application", + text: i18n.tr("Manage Apps"), + page: "InstalledAppsPage.qml", + showWatchApps: true, + color: UbuntuColors.green + }); + + mainMenuModel.append({ + icon: "clock-app-symbolic", + text: i18n.tr("Manage Watchfaces"), + page: "InstalledAppsPage.qml", + showWatchFaces: true, + color: "black" + }); + + mainMenuModel.append({ + icon: "settings", + text: i18n.tr("Settings"), + page: "SettingsPage.qml", + showWatchFaces: true, + color: "gold" + }); + + if (root.pebble.firmwareUpgradeAvailable) { + mainMenuModel.append({ + icon: "preferences-system-updates-symbolic", + text: i18n.tr("Firmware upgrade"), + page: "FirmwareUpgradePage.qml", + color: "red" + }); + } + + } + + PebbleModels { + id: modelModel + } + + GridLayout { + anchors.fill: parent + columns: parent.width > parent.height ? 2 : 1 + + Item { + Layout.fillWidth: true + Layout.fillHeight: true + Layout.maximumHeight: units.gu(30) + + RowLayout { + anchors.fill: parent + anchors.margins: units.gu(1) + spacing: units.gu(1) + + Item { + Layout.alignment: Qt.AlignHCenter + Layout.fillHeight: true + Layout.fillWidth: true + Layout.minimumWidth: watchImage.width + Image { + id: watchImage + width: implicitWidth * height / implicitHeight + height: parent.height + anchors.horizontalCenter: parent.horizontalCenter + + source: modelModel.get(root.pebble.model).image + fillMode: Image.PreserveAspectFit + + Item { + id: watchFace + height: parent.height * (modelModel.get(root.pebble.model - 1).shape === "rectangle" ? .5 : .515) + width: height * (modelModel.get(root.pebble.model - 1).shape === "rectangle" ? .85 : 1) + anchors.centerIn: parent + anchors.horizontalCenterOffset: units.dp(1) + anchors.verticalCenterOffset: units.dp(modelModel.get(root.pebble.model - 1).shape === "rectangle" ? 0 : 1) + + Image { + id: image + anchors.fill: parent + source: "file://" + root.pebble.screenshots.latestScreenshot + visible: false + } + + Component.onCompleted: { + if (!root.pebble.screenshots.latestScreenshot) { + root.pebble.requestScreenshot(); + } + } + + Rectangle { + id: textItem + anchors.fill: parent + layer.enabled: true + radius: modelModel.get(root.pebble.model - 1).shape === "rectangle" ? units.gu(.5) : height / 2 + // This item should be used as the 'mask' + layer.samplerName: "maskSource" + layer.effect: ShaderEffect { + property var colorSource: image; + fragmentShader: " + uniform lowp sampler2D colorSource; + uniform lowp sampler2D maskSource; + uniform lowp float qt_Opacity; + varying highp vec2 qt_TexCoord0; + void main() { + gl_FragColor = + texture2D(colorSource, qt_TexCoord0) + * texture2D(maskSource, qt_TexCoord0).a + * qt_Opacity; + } + " + } + } + } + } + } + ColumnLayout { + Layout.fillWidth: true + Layout.fillHeight: true + spacing: units.gu(2) + Rectangle { + height: units.gu(10) + width: height + radius: height / 2 + color: root.pebble.connected ? UbuntuColors.green : UbuntuColors.red + + Icon { + anchors.fill: parent + anchors.margins: units.gu(2) + color: "white" + name: root.pebble.connected ? "tick" : "dialog-error-symbolic" + } + } + + Label { + text: root.pebble.connected ? i18n.tr("Connected") : i18n.tr("Disconnected") + Layout.fillWidth: true + } + } + } + } + + + Column { + Layout.fillWidth: true + Layout.preferredHeight: childrenRect.height + spacing: menuRepeater.count > 0 ? 0 : units.gu(2) + Label { + text: i18n.tr("Your Pebble smartwatch is disconnected. Please make sure it is powered on, within range and it is paired properly in the Bluetooth System Settings.") + width: parent.width - units.gu(4) + anchors.horizontalCenter: parent.horizontalCenter + wrapMode: Text.WordWrap + visible: !root.pebble.connected + fontSize: "large" + horizontalAlignment: Text.AlignHCenter + } + + Button { + text: i18n.tr("Open System Settings") + visible: !root.pebble.connected + onClicked: Qt.openUrlExternally("settings://system/bluetooth") + color: UbuntuColors.orange + anchors.horizontalCenter: parent.horizontalCenter + } + + Label { + text: i18n.tr("Your Pebble smartwatch is in factory mode and needs to be initialized.") + width: parent.width - units.gu(4) + anchors.horizontalCenter: parent.horizontalCenter + wrapMode: Text.WordWrap + visible: root.pebble.connected && root.pebble.recovery && !root.pebble.upgradingFirmware + fontSize: "large" + horizontalAlignment: Text.AlignHCenter + } + Button { + text: i18n.tr("Initialize Pebble") + onClicked: root.pebble.performFirmwareUpgrade(); + visible: root.pebble.connected && root.pebble.recovery && !root.pebble.upgradingFirmware + color: UbuntuColors.orange + anchors.horizontalCenter: parent.horizontalCenter + } + + Rectangle { + id: upgradeIcon + height: units.gu(10) + width: height + radius: width / 2 + color: UbuntuColors.orange + anchors.horizontalCenter: parent.horizontalCenter + Icon { + anchors.fill: parent + anchors.margins: units.gu(1) + name: "preferences-system-updates-symbolic" + color: "white" + } + + RotationAnimation on rotation { + duration: 2000 + loops: Animation.Infinite + from: 0 + to: 360 + running: upgradeIcon.visible + } + visible: root.pebble.connected && root.pebble.upgradingFirmware + } + + Label { + text: i18n.tr("Upgrading...") + fontSize: "large" + anchors.horizontalCenter: parent.horizontalCenter + visible: root.pebble.connected && root.pebble.upgradingFirmware + } + + Repeater { + id: menuRepeater + model: root.pebble.connected && !root.pebble.recovery && !root.pebble.upgradingFirmware ? mainMenuModel : null + delegate: ListItem { + + RowLayout { + anchors.fill: parent + anchors.margins: units.gu(1) + + UbuntuShape { + Layout.fillHeight: true + Layout.preferredWidth: height + backgroundColor: model.color + Icon { + anchors.fill: parent + anchors.margins: units.gu(.5) + name: model.icon + color: "white" + } + } + + + Label { + text: model.text + Layout.fillWidth: true + } + } + + onClicked: { + var options = {}; + options["pebble"] = root.pebble + var modelItem = mainMenuModel.get(index) + options["showWatchApps"] = modelItem.showWatchApps + options["showWatchFaces"] = modelItem.showWatchFaces + pageStack.push(Qt.resolvedUrl(model.page), options) + } + } + } + } + } + + Connections { + target: pebble + onOpenURL: { + if (url) { + pageStack.push(Qt.resolvedUrl("AppSettingsPage.qml"), {uuid: uuid, url: url, pebble: pebble}) + } + } + } +} diff --git a/rockwork/qml/NotificationsPage.qml b/rockwork/qml/NotificationsPage.qml new file mode 100644 index 0000000..9802b05 --- /dev/null +++ b/rockwork/qml/NotificationsPage.qml @@ -0,0 +1,88 @@ +import QtQuick 2.4 +import QtQuick.Layouts 1.1 +import Ubuntu.Components 1.3 +import RockWork 1.0 + +Page { + id: root + title: i18n.tr("Notifications") + + property var pebble: null + + ColumnLayout { + anchors.fill: parent + anchors.topMargin: units.gu(1) + + Item { + Layout.fillWidth: true + implicitHeight: infoLabel.height + + Label { + id: infoLabel + anchors { + left: parent.left + right: parent.right + margins: units.gu(2) + } + + wrapMode: Text.WordWrap + text: i18n.tr("Entries here will be added as notifications appear on the phone. Selected notifications will be shown on your Pebble smartwatch.") + } + } + + + ListView { + Layout.fillWidth: true + Layout.fillHeight: true + clip: true + model: root.pebble.notifications + + delegate: ListItem { + ListItemLayout { + title.text: model.name + + UbuntuShape { + SlotsLayout.position: SlotsLayout.Leading; + height: units.gu(5) + width: height + backgroundColor: { + // Add some hacks for known icons + switch (model.icon) { + case "calendar": + return UbuntuColors.orange; + case "settings": + return "grey"; + case "dialog-question-symbolic": + return UbuntuColors.red; + case "alarm-clock": + return UbuntuColors.purple; + case "gpm-battery-050": + return UbuntuColors.green; + } + return "black" + } + source: Image { + height: parent.height + width: parent.width + source: model.icon.indexOf("/") === 0 ? "file://" + model.icon : "" + } + Icon { + anchors.fill: parent + anchors.margins: units.gu(.5) + name: model.icon.indexOf("/") !== 0 ? model.icon : "" + color: "white" + } + } + + Switch { + checked: model.enabled + SlotsLayout.position: SlotsLayout.Trailing; + onClicked: { + root.pebble.setNotificationFilter(model.name, checked) + } + } + } + } + } + } +} diff --git a/rockwork/qml/PebbleModels.qml b/rockwork/qml/PebbleModels.qml new file mode 100644 index 0000000..103064a --- /dev/null +++ b/rockwork/qml/PebbleModels.qml @@ -0,0 +1,28 @@ +import QtQuick 2.4 + +ListModel { + id: modelModel + ListElement { image: 'artwork/tintin-black.png'; shape: "rectangle" } // Fallback for Unknown + ListElement { image: 'artwork/tintin-black.png'; shape: "rectangle" } + ListElement { image: 'artwork/tintin-white.png'; shape: "rectangle" } + ListElement { image: 'artwork/tintin-red.png'; shape: "rectangle" } + ListElement { image: 'artwork/tintin-orange.png'; shape: "rectangle" } + ListElement { image: 'artwork/tintin-grey.png'; shape: "rectangle" } + ListElement { image: 'artwork/bianca-silver.png'; shape: "rectangle" } + ListElement { image: 'artwork/bianca-black.png'; shape: "rectangle" } + ListElement { image: 'artwork/tintin-blue.png'; shape: "rectangle" } + ListElement { image: 'artwork/tintin-green.png'; shape: "rectangle" } + ListElement { image: 'artwork/tintin-pink.png'; shape: "rectangle" } + ListElement { image: 'artwork/snowy-white.png'; shape: "rectangle" } + ListElement { image: 'artwork/snowy-black.png'; shape: "rectangle" } + ListElement { image: 'artwork/snowy-red.png'; shape: "rectangle" } + ListElement { image: 'artwork/bobby-silver.png'; shape: "rectangle" } + ListElement { image: 'artwork/bobby-black.png'; shape: "rectangle" } + ListElement { image: 'artwork/bobby-gold.png'; shape: "rectangle" } + ListElement { image: 'artwork/spalding-14mm-silver.png'; shape: "round" } + ListElement { image: 'artwork/spalding-14mm-black.png'; shape: "round" } + ListElement { image: 'artwork/spalding-20mm-silver.png'; shape: "round" } + ListElement { image: 'artwork/spalding-20mm-black.png'; shape: "round" } + ListElement { image: 'artwork/spalding-14mm-rose-gold.png'; shape: "round" } +} + diff --git a/rockwork/qml/PebblesPage.qml b/rockwork/qml/PebblesPage.qml new file mode 100644 index 0000000..a973b0a --- /dev/null +++ b/rockwork/qml/PebblesPage.qml @@ -0,0 +1,69 @@ +import QtQuick 2.4 +import QtQuick.Layouts 1.1 +import Ubuntu.Components 1.3 + +Page { + title: i18n.tr("Manage Pebble Watches") + + head { + actions: [ + Action { + iconName: "settings" + onTriggered: { + onClicked: Qt.openUrlExternally("settings://system/bluetooth") + } + } + ] + } + + ListView { + anchors.fill: parent + model: pebbles + delegate: ListItem { + RowLayout { + anchors.fill: parent + anchors.margins: units.gu(1) + + ColumnLayout { + Layout.fillHeight: true + Layout.fillWidth: true + + Label { + text: model.name + } + + Label { + text: model.connected ? i18n.tr("Connected") : i18n.tr("Disconnected") + fontSize: "small" + } + } + } + + onClicked: { + var p = pebbles.get(index); + print("opening pebble:", p.name, p.hardwarePlatform) + pageStack.push(Qt.resolvedUrl("MainMenuPage.qml"), {pebble: pebbles.get(index)}) + } + } + } + + Column { + anchors.centerIn: parent + width: parent.width - units.gu(4) + spacing: units.gu(4) + visible: pebbles.count === 0 + + Label { + text: i18n.tr("No Pebble smartwatches configured yet. Please connect your Pebble smartwatch using System Settings.") + fontSize: "large" + width: parent.width + wrapMode: Text.WordWrap + } + + Button { + text: i18n.tr("Open System Settings") + anchors.horizontalCenter: parent.horizontalCenter + onClicked: Qt.openUrlExternally("settings://system/bluetooth") + } + } +} diff --git a/rockwork/qml/ScreenshotsPage.qml b/rockwork/qml/ScreenshotsPage.qml new file mode 100644 index 0000000..fdbeb9a --- /dev/null +++ b/rockwork/qml/ScreenshotsPage.qml @@ -0,0 +1,107 @@ +import QtQuick 2.4 +import QtQuick.Layouts 1.1 +import Ubuntu.Components 1.3 +import Ubuntu.Components.Popups 1.3 +import Ubuntu.Content 1.3 +import RockWork 1.0 + +Page { + id: root + + title: i18n.tr("Screenshots") + + property var pebble: null + + head { + actions: [ + Action { + iconName: "camera-app-symbolic" + onTriggered: root.pebble.requestScreenshot() + } + ] + } + + ColumnLayout { + anchors.fill: parent + anchors.margins: units.gu(1) + spacing: units.gu(1) + + GridView { + id: grid + Layout.fillHeight: true + Layout.fillWidth: true + clip: true + + property int columns: 2 + + cellWidth: width / columns + cellHeight: cellWidth + + model: root.pebble.screenshots + + displaced: Transition { + UbuntuNumberAnimation { properties: "x,y" } + } + + delegate: Item { + width: grid.cellWidth + height: grid.cellHeight + Image { + anchors.fill: parent + anchors.margins: units.gu(.5) + fillMode: Image.PreserveAspectFit + source: "file://" + model.filename + } + MouseArea { + anchors.fill: parent + onClicked: { + PopupUtils.open(dialogComponent, root, {filename: model.filename}) + } + } + } + } + } + + Component { + id: dialogComponent + Dialog { + id: dialog + title: i18n.tr("Screenshot options") + + property string filename + + Button { + text: i18n.tr("Share") + color: UbuntuColors.blue + onClicked: { + pageStack.push(Qt.resolvedUrl("ContentPeerPickerPage.qml"), {itemName: i18n.tr("Pebble screenshot"), handler: ContentHandler.Share, contentType: ContentType.Pictures, filename: filename }) + PopupUtils.close(dialog) + } + } + Button { + text: i18n.tr("Save") + color: UbuntuColors.green + onClicked: { + pageStack.push(Qt.resolvedUrl("ContentPeerPickerPage.qml"), {itemName: i18n.tr("Pebble screenshot"),handler: ContentHandler.Destination, contentType: ContentType.Pictures, filename: filename }) + PopupUtils.close(dialog) + } + } + + Button { + text: i18n.tr("Delete") + color: UbuntuColors.red + onClicked: { + root.pebble.removeScreenshot(filename) + PopupUtils.close(dialog) + } + } + Button { + text: i18n.tr("Cancel") + onClicked: { + PopupUtils.close(dialog) + } + } + } + } +} + diff --git a/rockwork/qml/SettingsPage.qml b/rockwork/qml/SettingsPage.qml new file mode 100644 index 0000000..153aaf4 --- /dev/null +++ b/rockwork/qml/SettingsPage.qml @@ -0,0 +1,80 @@ +import QtQuick 2.4 +import QtQuick.Layouts 1.1 +import Ubuntu.Components 1.3 +import Ubuntu.Components.ListItems 1.3 + +Page { + id: root + title: i18n.tr("Settings") + + property var pebble: null + + ColumnLayout { + anchors.fill: parent + anchors.margins: units.gu(1) + spacing: units.gu(1) + + Label { + Layout.fillWidth: true + text: i18n.tr("Distance Units") + font.bold: true + } + + RowLayout { + Layout.fillWidth: true + CheckBox { + id: metricUnitsCheckbox + checked: !root.pebble.imperialUnits + onClicked: { + checked = true + root.pebble.imperialUnits = false; + imperialUnitsCheckBox.checked = false; + } + } + Label { + text: i18n.tr("Metric") + Layout.fillWidth: true + } + CheckBox { + id: imperialUnitsCheckBox + checked: root.pebble.imperialUnits + onClicked: { + checked = true + root.pebble.imperialUnits = true; + metricUnitsCheckbox.checked = false; + } + } + Label { + text: i18n.tr("Imperial") + Layout.fillWidth: true + } + } + ThinDivider {} + + Label { + text: i18n.tr("Calendar") + Layout.fillWidth: true + font.bold: true + } + RowLayout { + Layout.fillWidth: true + Label { + text: i18n.tr("Sync calendar to timeline") + Layout.fillWidth: true + } + Switch { + checked: root.pebble.calendarSyncEnabled + onClicked: { + root.pebble.calendarSyncEnabled = checked; + } + } + } + ThinDivider {} + + Item { + Layout.fillWidth: true + Layout.fillHeight: true + } + } +} + diff --git a/rockwork/qml/SystemAppIcon.qml b/rockwork/qml/SystemAppIcon.qml new file mode 100644 index 0000000..88e37bc --- /dev/null +++ b/rockwork/qml/SystemAppIcon.qml @@ -0,0 +1,67 @@ +import QtQuick 2.4 +import Ubuntu.Components 1.3 + +Item { + id: root + + property bool isSystemApp: false + property string uuid: "" + property string iconSource: "" + + UbuntuShape { + anchors.fill: parent + visible: root.isSystemApp + backgroundColor: { + switch (root.uuid) { + case "{07e0d9cb-8957-4bf7-9d42-35bf47caadfe}": + return "gray"; + case "{18e443ce-38fd-47c8-84d5-6d0c775fbe55}": + return "blue"; + case "{36d8c6ed-4c83-4fa1-a9e2-8f12dc941f8c}": + return UbuntuColors.red; + case "{1f03293d-47af-4f28-b960-f2b02a6dd757}": + return "gold" + case "{b2cae818-10f8-46df-ad2b-98ad2254a3c1}": + return "darkviolet" + case "{67a32d95-ef69-46d4-a0b9-854cc62f97f9}": + return "green"; + case "{8f3c8686-31a1-4f5f-91f5-01600c9bdc59}": + return "black" + } + + return ""; + } + } + Icon { + anchors.fill: parent + implicitHeight: height + anchors.margins: units.gu(1) + visible: root.isSystemApp + color: "white" + name: { + switch (root.uuid) { + case "{07e0d9cb-8957-4bf7-9d42-35bf47caadfe}": + return "settings"; + case "{18e443ce-38fd-47c8-84d5-6d0c775fbe55}": + return "clock-app-symbolic"; + case "{36d8c6ed-4c83-4fa1-a9e2-8f12dc941f8c}": + return "like"; + case "{1f03293d-47af-4f28-b960-f2b02a6dd757}": + return "stock_music"; + case "{b2cae818-10f8-46df-ad2b-98ad2254a3c1}": + return "stock_notification"; + case "{67a32d95-ef69-46d4-a0b9-854cc62f97f9}": + return "stock_alarm-clock"; + case "{8f3c8686-31a1-4f5f-91f5-01600c9bdc59}": + return "clock-app-symbolic"; + } + return ""; + } + } + + Image { + source: root.isSystemApp ? "" : "file://" + root.iconSource; + anchors.fill: parent + visible: !root.isSystemApp + } +} -- cgit v1.2.3