diff --git a/nymea-app/main.cpp b/nymea-app/main.cpp
index 7e009a31..86f2b3c0 100644
--- a/nymea-app/main.cpp
+++ b/nymea-app/main.cpp
@@ -157,6 +157,7 @@ int main(int argc, char *argv[])
}
qmlRegisterSingletonType(QUrl("qrc:///styles/" + styleController.currentStyle() + "/Style.qml"), "Nymea", 1, 0, "Style" );
+ qmlRegisterType(QUrl("qrc:///styles/" + styleController.currentStyle() + "/Background.qml"), "Nymea", 1, 0, "Background" );
qmlRegisterSingletonType(QUrl("qrc:///ui/Configuration.qml"), "Nymea", 1, 0, "Configuration");
engine->rootContext()->setContextProperty("styleController", &styleController);
diff --git a/nymea-app/styles.qrc b/nymea-app/styles.qrc
index fa2a73c6..4fa9cbde 100644
--- a/nymea-app/styles.qrc
+++ b/nymea-app/styles.qrc
@@ -39,5 +39,11 @@
ui/Configuration.qml
styles/dark/Dialog.qml
styles/light/Dialog.qml
+ styles/dark/Background.qml
+ styles/light/Background.qml
+ styles/energize/Background.qml
+ styles/lime/Background.qml
+ styles/mellow/Background.qml
+ styles/noir/Background.qml
diff --git a/nymea-app/styles/dark/Background.qml b/nymea-app/styles/dark/Background.qml
new file mode 100644
index 00000000..64d39bee
--- /dev/null
+++ b/nymea-app/styles/dark/Background.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+
+Rectangle {
+ color: Style.backgroundColor
+}
diff --git a/nymea-app/styles/dark/Page.qml b/nymea-app/styles/dark/Page.qml
index aa70bdf8..9255efa4 100644
--- a/nymea-app/styles/dark/Page.qml
+++ b/nymea-app/styles/dark/Page.qml
@@ -33,8 +33,5 @@ import QtQuick.Templates 2.2
import QtQuick.Controls.Material 2.2
Page {
-
- background: Rectangle {
- color: Material.background
- }
+ background: Background {}
}
diff --git a/nymea-app/styles/energize/Background.qml b/nymea-app/styles/energize/Background.qml
new file mode 100644
index 00000000..ebe3d4fb
--- /dev/null
+++ b/nymea-app/styles/energize/Background.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+
+Rectangle {
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: "#e3eae4" }
+ GradientStop { position: 1.0; color: "#cde2d8" }
+ }
+}
diff --git a/nymea-app/styles/energize/Page.qml b/nymea-app/styles/energize/Page.qml
index 683758c2..9255efa4 100644
--- a/nymea-app/styles/energize/Page.qml
+++ b/nymea-app/styles/energize/Page.qml
@@ -33,11 +33,5 @@ import QtQuick.Templates 2.2
import QtQuick.Controls.Material 2.2
Page {
-
- background: Rectangle {
- gradient: Gradient {
- GradientStop { position: 0.0; color: "#e3eae4" }
- GradientStop { position: 1.0; color: "#cde2d8" }
- }
- }
+ background: Background {}
}
diff --git a/nymea-app/styles/light/Background.qml b/nymea-app/styles/light/Background.qml
new file mode 100644
index 00000000..64d39bee
--- /dev/null
+++ b/nymea-app/styles/light/Background.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+
+Rectangle {
+ color: Style.backgroundColor
+}
diff --git a/nymea-app/styles/light/Page.qml b/nymea-app/styles/light/Page.qml
index aa70bdf8..9255efa4 100644
--- a/nymea-app/styles/light/Page.qml
+++ b/nymea-app/styles/light/Page.qml
@@ -33,8 +33,5 @@ import QtQuick.Templates 2.2
import QtQuick.Controls.Material 2.2
Page {
-
- background: Rectangle {
- color: Material.background
- }
+ background: Background {}
}
diff --git a/nymea-app/styles/lime/Background.qml b/nymea-app/styles/lime/Background.qml
new file mode 100644
index 00000000..64d39bee
--- /dev/null
+++ b/nymea-app/styles/lime/Background.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+
+Rectangle {
+ color: Style.backgroundColor
+}
diff --git a/nymea-app/styles/lime/Page.qml b/nymea-app/styles/lime/Page.qml
index aa70bdf8..9255efa4 100644
--- a/nymea-app/styles/lime/Page.qml
+++ b/nymea-app/styles/lime/Page.qml
@@ -33,8 +33,5 @@ import QtQuick.Templates 2.2
import QtQuick.Controls.Material 2.2
Page {
-
- background: Rectangle {
- color: Material.background
- }
+ background: Background {}
}
diff --git a/nymea-app/styles/mellow/Background.qml b/nymea-app/styles/mellow/Background.qml
new file mode 100644
index 00000000..64d39bee
--- /dev/null
+++ b/nymea-app/styles/mellow/Background.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+
+Rectangle {
+ color: Style.backgroundColor
+}
diff --git a/nymea-app/styles/mellow/Page.qml b/nymea-app/styles/mellow/Page.qml
index aa70bdf8..9255efa4 100644
--- a/nymea-app/styles/mellow/Page.qml
+++ b/nymea-app/styles/mellow/Page.qml
@@ -33,8 +33,5 @@ import QtQuick.Templates 2.2
import QtQuick.Controls.Material 2.2
Page {
-
- background: Rectangle {
- color: Material.background
- }
+ background: Background {}
}
diff --git a/nymea-app/styles/noir/Background.qml b/nymea-app/styles/noir/Background.qml
new file mode 100644
index 00000000..64d39bee
--- /dev/null
+++ b/nymea-app/styles/noir/Background.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+
+Rectangle {
+ color: Style.backgroundColor
+}
diff --git a/nymea-app/styles/noir/Page.qml b/nymea-app/styles/noir/Page.qml
index 7c8b3b33..db69bf21 100644
--- a/nymea-app/styles/noir/Page.qml
+++ b/nymea-app/styles/noir/Page.qml
@@ -34,7 +34,5 @@ import QtQuick.Controls.Material 2.2
import Nymea 1.0
Page {
- background: Rectangle {
- color: Style.backgroundColor
- }
+ background: Background {}
}
diff --git a/nymea-app/ui/MainPage.qml b/nymea-app/ui/MainPage.qml
index acd17b56..6042ec7a 100644
--- a/nymea-app/ui/MainPage.qml
+++ b/nymea-app/ui/MainPage.qml
@@ -54,6 +54,11 @@ Page {
d.configOverlay = configComponent.createObject(contentContainer)
}
+ // Removing the background from this page only because the MainViewBase adds it again in
+ // a deepter layer as we need to include it in the blurring of the header and footer.
+ // We don't want to paint the background on the entire screen twice (overdraw is costly)
+ background: null
+
header: Item {
id: mainHeader
height: 0
@@ -70,20 +75,6 @@ Page {
}
}
-
-// Label {
-// anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter }
-// horizontalAlignment: Text.AlignHCenter
-// leftPadding: Math.max(menuButton.width, additionalIcons.width)
-// rightPadding: leftPadding
-// elide: Text.ElideRight
-// font: Style.bigFont
-// text: d.configOverlay !== null ?
-// qsTr("Configure main view")
-// : swipeView.currentItem.item.title.length > 0 ? swipeView.currentItem.item.title : filteredContentModel.modelData(swipeView.currentIndex, "displayName")
-// }
-
-
Row {
id: additionalIcons
anchors { right: parent.right; top: parent.top }
@@ -222,8 +213,7 @@ Page {
}
}
- tabBar.currentIndex = Qt.binding(function() { return mainViewSettings.currentIndex; })
- swipeView.currentIndex = Qt.binding(function() { return tabBar.currentIndex; })
+ swipeView.currentIndex = mainViewSettings.currentIndex
mainViewSettings.currentIndex = Qt.binding(function() { return swipeView.currentIndex; })
}
}
@@ -242,16 +232,11 @@ Page {
clip: true
property int headerSize: 48
+ property int footerSize: app.landscape ? 48 : 64
- readonly property int scrollOffset: swipeView.currentItem.item.contentY
+ readonly property int scrollOffset: swipeView.currentItem ? swipeView.currentItem.item.contentY : 0
readonly property int headerBlurSize: Math.min(headerSize, scrollOffset * 2)
- Rectangle {
- width: parent.width
- height: contentContainer.headerBlurSize
- color: Style.backgroundColor
- }
-
SwipeView {
id: swipeView
anchors.fill: parent
@@ -276,6 +261,12 @@ Page {
value: swipeView.currentIndex == index
}
+ Binding {
+ target: mainViewLoader.item
+ property: "bottomMargin"
+ value: footer.visible ? contentContainer.footerSize : 0
+ }
+
Image {
source: "qrc:/styles/%1/logo-wide.svg".arg(styleController.currentStyle)
anchors {
@@ -287,12 +278,13 @@ Page {
height: 28
sourceSize.height: height
antialiasing: true
+ z: 2
}
-
}
}
}
+
ColumnLayout {
anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter; margins: app.margins }
spacing: app.margins
@@ -314,9 +306,9 @@ Page {
ShaderEffectSource {
id: headerBlurSource
width: contentContainer.width
- height: contentContainer.headerBlurSize
+ height: d.configOverlay ? contentContainer.headerSize : contentContainer.headerBlurSize
sourceItem: contentContainer
- sourceRect: Qt.rect(0, 0, contentContainer.width, contentContainer.headerBlurSize)
+ sourceRect: Qt.rect(0, 0, contentContainer.width, d.configOverlay ? contentContainer.headerSize : contentContainer.headerBlurSize)
visible: false
}
@@ -326,7 +318,7 @@ Page {
top: parent.top;
right: parent.right;
}
- height: contentContainer.headerBlurSize
+ height: d.configOverlay ? contentContainer.headerSize : contentContainer.headerBlurSize
radius: 40
transparentBorder: true
source: headerBlurSource
@@ -339,7 +331,7 @@ Page {
top: parent.top
right: parent.right
}
- height: contentContainer.headerBlurSize
+ height: d.configOverlay ? contentContainer.headerSize : contentContainer.headerBlurSize
gradient: Gradient {
GradientStop { position: 0.1; color: Style.backgroundColor }
@@ -348,17 +340,53 @@ Page {
}
}
- footer: Item {
- readonly property bool shown: tabsRepeater.count > 1 || d.configOverlay
- implicitHeight: shown ? 64 + (app.landscape ? -20 : 0) : 0
- Behavior on implicitHeight { NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }}
+ ShaderEffectSource {
+ id: footerBlurSource
+ width: contentContainer.width
+ height: contentContainer.footerSize
+ sourceItem: contentContainer
+ sourceRect: Qt.rect(0, contentContainer.height - height, contentContainer.width, contentContainer.footerSize)
+ visible: false
+ enabled: footer.shown
+ }
- TabBar {
- id: tabBar
- anchors { left: parent.left; top: parent.top; right: parent.right }
- height: 64 + (app.landscape ? -20 : 0)
- Material.elevation: 3
- position: TabBar.Footer
+ FastBlur {
+ anchors {
+ left: parent.left;
+ bottom: parent.bottom;
+ right: parent.right;
+ }
+ height: contentContainer.footerSize
+ radius: 40
+ transparentBorder: false
+ source: footerBlurSource
+ visible: footer.shown
+ }
+
+ Rectangle {
+ id: footer
+ readonly property bool shown: tabsRepeater.count > 1 || d.configOverlay
+ visible: shown
+ anchors {
+ left: parent.left
+ bottom: parent.bottom
+ right: parent.right
+ }
+ height: contentContainer.footerSize
+ Behavior on height { NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }}
+
+// color: "transparent"
+
+ gradient: Gradient {
+ GradientStop { position: 0; color: "transparent" }
+ GradientStop { position: 0.4; color: Qt.rgba(Style.backgroundColor.r, Style.backgroundColor.g, Style.backgroundColor.b, 0.7) }
+ GradientStop { position: 1; color: Style.backgroundColor }
+ }
+
+ RowLayout {
+ id: tabsLayout
+ anchors.fill: parent
+ spacing: 0
opacity: d.configOverlay ? 0 : 1
Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.InOutQuad } }
@@ -366,14 +394,18 @@ Page {
Repeater {
id: tabsRepeater
model: d.configOverlay != null ? null : filteredContentModel
-
+// model: filteredContentModel
delegate: MainPageTabButton {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
alignment: app.landscape ? Qt.Horizontal : Qt.Vertical
+ checked: index === swipeView.currentIndex
height: tabBar.height
- anchors.verticalCenter: parent.verticalCenter
+// anchors.verticalCenter: parent.verticalCenter
text: model.displayName
iconSource: "../images/" + model.icon + ".svg"
+ onClicked: swipeView.currentIndex = index
onPressAndHold: {
root.configureViews();
}
@@ -381,80 +413,83 @@ Page {
}
}
- TabBar {
- anchors.fill: tabBar
- Material.elevation: 3
- position: TabBar.Footer
+
+ MainPageTabButton {
+ anchors.fill: parent
+ alignment: app.landscape ? Qt.Horizontal : Qt.Vertical
+ text: d.configOverlay ? qsTr("Done") : qsTr("Configure")
+ iconSource: "../images/configure.svg"
opacity: d.configOverlay ? 1 : 0
Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.InOutQuad } }
visible: opacity > 0
- MainPageTabButton {
- height: tabBar.height
- alignment: app.landscape ? Qt.Horizontal : Qt.Vertical
- text: d.configOverlay ? qsTr("Done") : qsTr("Configure")
- iconSource: "../images/configure.svg"
- anchors.verticalCenter: parent.verticalCenter
+ checked: true
- checked: false
- checkable: false
-
- onClicked: {
- if (d.configOverlay) {
- d.configOverlay.destroy()
- } else {
- PlatformHelper.vibrate(PlatformHelper.HapticsFeedbackSelection)
- d.configOverlay = configComponent.createObject(contentContainer)
- }
+ onClicked: {
+ if (d.configOverlay) {
+ d.configOverlay.destroy()
+ } else {
+ PlatformHelper.vibrate(PlatformHelper.HapticsFeedbackSelection)
+ d.configOverlay = configComponent.createObject(contentContainer)
}
}
}
-
}
Component {
id: configComponent
- Item {
+ Background {
id: configOverlay
width: contentContainer.width
height: contentContainer.height
- NumberAnimation {
- target: configOverlay
- property: "scale"
- duration: 200
- easing.type: Easing.InOutQuad
- from: 2
- to: 1
- running: true
- }
- NumberAnimation {
- target: configOverlay
- property: "opacity"
- duration: 200
- easing.type: Easing.InOutQuad
- from: 0
- to: 1
- running: true
- }
-
ListView {
id: configListView
+ anchors.fill: parent
model: mainMenuModel
- width: parent.width
- height: parent.height / 3
- anchors.centerIn: parent
- orientation: ListView.Horizontal
- moveDisplaced: Transition {
- NumberAnimation { properties: "x,y"; duration: 200 }
- }
-
- property int delegateWidth: width / 3
+ topMargin: contentContainer.headerSize
+ bottomMargin: contentContainer.footerSize
property bool dragging: draggingIndex >= 0
property int draggingIndex : -1
+ moveDisplaced: Transition { NumberAnimation { properties: "y" } }
+
+ delegate: NymeaItemDelegate {
+ id: viewConfigDelegate
+ width: parent.width
+ text: model.displayName
+ iconName: Qt.resolvedUrl("images/" + model.icon + ".svg")
+ progressive: false
+ checked: mainViewSettings.filterList.indexOf(model.name) >= 0
+ visible: index !== configListView.draggingIndex
+ additionalItem: CheckBox {
+ checked: viewConfigDelegate.checked
+ anchors.verticalCenter: parent.verticalCenter
+ onClicked: {
+ var newList = []
+ for (var i = 0; i < mainMenuModel.count; i++) {
+ var entry = mainMenuModel.get(i).name;
+ if (entry === model.name) {
+ if (!isEnabled) {
+ newList.push(model.name)
+ }
+ } else {
+ if (mainViewSettings.filterList.indexOf(entry) >= 0) {
+ newList.push(entry)
+ }
+ }
+ }
+ if (newList.length === 0) {
+ newList.push(Configuration.defaultMainView)
+ }
+
+ mainViewSettings.filterList = newList
+ }
+ }
+ }
+
MouseArea {
id: dndArea
anchors.fill: parent
@@ -463,22 +498,28 @@ Page {
onPressAndHold: {
mouse.accepted = true
- var mouseXInListView = configListView.contentItem.mapFromItem(dndArea, mouseX, mouseY).x;
- configListView.draggingIndex = configListView.indexAt(mouseXInListView, mouseY)
+ var mouseYInListView = configListView.contentItem.mapFromItem(dndArea, mouseX, mouseY).y;
+ configListView.draggingIndex = configListView.indexAt(mouseX, mouseYInListView)
var item = mainMenuModel.get(configListView.draggingIndex)
- dndItem.displayName = item.displayName
- dndItem.icon = item.icon
- var visualItem = configListView.itemAt(mouseXInListView, mouseY)
- dndItem.isEnabled = visualItem.isEnabled
- dndArea.dragOffset = configListView.mapToItem(visualItem, mouseX, mouseY).x
+ print("draggingIndex", configListView.draggingIndex)
+ dndItem.text = item.displayName
+ dndItem.iconName = item.icon
+ var visualItem = configListView.itemAt(mouseX, mouseYInListView)
+ dndItem.checked = visualItem.checked
+ dndArea.dragOffset = configListView.mapToItem(visualItem, mouseX, mouseY).y
PlatformHelper.vibrate(PlatformHelper.HapticsFeedbackImpact)
}
onMouseYChanged: {
if (configListView.dragging) {
- var mouseXInListView = configListView.contentItem.mapFromItem(dndArea, mouseX, mouseY).x;
- var indexUnderMouse = configListView.indexAt(mouseXInListView - dndArea.dragOffset / 2, mouseY)
+ var mouseYInListView = configListView.contentItem.mapFromItem(dndArea, mouseX, mouseY).y;
+ var indexUnderMouse = configListView.indexAt(mouseX, mouseYInListView - dndArea.dragOffset / 2)
+ if (indexUnderMouse < 0) {
+ return;
+ }
+
indexUnderMouse = Math.min(Math.max(0, indexUnderMouse), configListView.count - 1)
if (configListView.draggingIndex !== indexUnderMouse) {
+ print("moving to", indexUnderMouse)
PlatformHelper.vibrate(PlatformHelper.HapticsFeedbackSelection)
mainMenuModel.move(configListView.draggingIndex, indexUnderMouse, 1)
configListView.draggingIndex = indexUnderMouse;
@@ -487,8 +528,8 @@ Page {
}
onReleased: {
print("released!")
- var mouseXInListView = configListView.contentItem.mapFromItem(dndArea, mouseX, mouseY).x;
- var clickedIndex = configListView.indexAt(mouseXInListView, mouseY)
+ var mouseYInListView = configListView.contentItem.mapFromItem(dndArea, mouseX, mouseY).y;
+ var clickedIndex = configListView.indexAt(mouseX, mouseYInListView)
var item = mainMenuModel.get(clickedIndex)
var isEnabled = mainViewSettings.filterList.indexOf(item.name) >= 0;
if (!configListView.dragging) {
@@ -519,114 +560,244 @@ Page {
}
mainViewSettings.sortOrder = newSortOrder;
}
- Timer {
- id: scroller
- interval: 2
- repeat: true
- running: direction != 0
- property int direction: {
- if (!configListView.dragging) {
- return 0;
- }
- return dndArea.mouseX < 50 ? -2 : dndArea.mouseX > dndArea.width - 50 ? 2 : 0
- }
- onTriggered: {
- configListView.contentX = Math.min(Math.max(0, configListView.contentX + direction), configListView.contentWidth - configListView.width)
- }
- }
+// Timer {
+// id: scroller
+// interval: 2
+// repeat: true
+// running: direction != 0
+// property int direction: {
+// if (!configListView.dragging) {
+// return 0;
+// }
+// return dndArea.mouseY < 50 ? -2 : dndArea.mouseY > dndArea.height - 50 ? 2 : 0
+// }
+// onTriggered: {
+// configListView.contentY = Math.min(Math.max(0, configListView.contentY + direction), configListView.contentHeight - configListView.height)
+// }
+// }
}
- delegate: BigTile {
- id: configDelegate
- width: configListView.delegateWidth
- height: configListView.height
- property bool isEnabled: mainViewSettings.filterList.indexOf(model.name) >= 0
- visible: configListView.draggingIndex !== index
-
- leftPadding: 0
- rightPadding: 0
- topPadding: 0
- bottomPadding: 0
-
- header: RowLayout {
- id: headerRow
- width: parent.width
- Label {
- text: model.displayName
- Layout.fillWidth: true
- elide: Text.ElideRight
- }
- }
-
- contentItem: Item {
- Layout.fillWidth: true
- implicitHeight: configListView.height - headerRow.height - Style.margins * 2
-
- ColorIcon {
- anchors.centerIn: parent
- width: Math.min(parent.width, parent.height) * .6
- height: width
- name: Qt.resolvedUrl("images/" + model.icon + ".svg")
- color: configDelegate.isEnabled ? Style.accentColor : Style.iconColor
- }
- }
- }
- Item {
+ NymeaItemDelegate {
id: dndItem
- width: configListView.delegateWidth
- height: configListView.height
- property bool isEnabled: false
- property string displayName: ""
- property string icon: "things"
visible: configListView.dragging
- x: dndArea.mouseX - dndArea.dragOffset
- onVisibleChanged: {
- if (visible) {
- dragStartAnimation.start();
- }
+ y: dndArea.mouseY - dndArea.dragOffset
+ width: configListView.width
+ progressive: false
+ additionalItem: CheckBox {
+ checked: dndItem.checked
+ anchors.verticalCenter: parent.verticalCenter
}
- NumberAnimation {
- id: dragStartAnimation
- target: dndItem
- property: "scale"
- from: 1
- to: 0.95
- duration: 200
- }
-
- BigTile {
- id: dndTile
- anchors.fill: parent
- // anchors.margins: app.margins / 2
- Material.elevation: 2
-
- leftPadding: 0
- rightPadding: 0
- topPadding: 0
- bottomPadding: 0
-
- header: RowLayout {
- Label {
- text: dndItem.displayName
- }
- }
-
- contentItem: Item {
- Layout.fillWidth: true
- implicitHeight: configListView.height - header.height
-
- ColorIcon {
- anchors.centerIn: parent
- width: Math.min(parent.width, parent.height) * .6
- height: width
- name: Qt.resolvedUrl("images/" + dndItem.icon + ".svg")
- color: dndItem.isEnabled ? Style.accentColor : Style.iconColor
- }
- }
- }
}
}
+
+// NumberAnimation {
+// target: configOverlay
+// property: "scale"
+// duration: 200
+// easing.type: Easing.InOutQuad
+// from: 2
+// to: 1
+// running: true
+// }
+// NumberAnimation {
+// target: configOverlay
+// property: "opacity"
+// duration: 200
+// easing.type: Easing.InOutQuad
+// from: 0
+// to: 1
+// running: true
+// }
+
+// ListView {
+// id: configListView
+// model: mainMenuModel
+// width: parent.width
+// height: parent.height / 3
+// anchors.centerIn: parent
+// orientation: ListView.Horizontal
+// moveDisplaced: Transition {
+// NumberAnimation { properties: "x,y"; duration: 200 }
+// }
+
+// property int delegateWidth: width / 3
+
+// property bool dragging: draggingIndex >= 0
+// property int draggingIndex : -1
+
+// MouseArea {
+// id: dndArea
+// anchors.fill: parent
+// preventStealing: configListView.dragging
+// property int dragOffset: 0
+
+// onPressAndHold: {
+// mouse.accepted = true
+// var mouseXInListView = configListView.contentItem.mapFromItem(dndArea, mouseX, mouseY).x;
+// configListView.draggingIndex = configListView.indexAt(mouseXInListView, mouseY)
+// var item = mainMenuModel.get(configListView.draggingIndex)
+// dndItem.displayName = item.displayName
+// dndItem.icon = item.icon
+// var visualItem = configListView.itemAt(mouseXInListView, mouseY)
+// dndItem.isEnabled = visualItem.isEnabled
+// dndArea.dragOffset = configListView.mapToItem(visualItem, mouseX, mouseY).x
+// PlatformHelper.vibrate(PlatformHelper.HapticsFeedbackImpact)
+// }
+// onMouseYChanged: {
+// if (configListView.dragging) {
+// var mouseXInListView = configListView.contentItem.mapFromItem(dndArea, mouseX, mouseY).x;
+// var indexUnderMouse = configListView.indexAt(mouseXInListView - dndArea.dragOffset / 2, mouseY)
+// indexUnderMouse = Math.min(Math.max(0, indexUnderMouse), configListView.count - 1)
+// if (configListView.draggingIndex !== indexUnderMouse) {
+// PlatformHelper.vibrate(PlatformHelper.HapticsFeedbackSelection)
+// mainMenuModel.move(configListView.draggingIndex, indexUnderMouse, 1)
+// configListView.draggingIndex = indexUnderMouse;
+// }
+// }
+// }
+// onReleased: {
+// print("released!")
+// var mouseXInListView = configListView.contentItem.mapFromItem(dndArea, mouseX, mouseY).x;
+// var clickedIndex = configListView.indexAt(mouseXInListView, mouseY)
+// var item = mainMenuModel.get(clickedIndex)
+// var isEnabled = mainViewSettings.filterList.indexOf(item.name) >= 0;
+// if (!configListView.dragging) {
+// var newList = []
+// for (var i = 0; i < mainMenuModel.count; i++) {
+// var entry = mainMenuModel.get(i).name;
+// if (entry === item.name) {
+// if (!isEnabled) {
+// newList.push(item.name)
+// }
+// } else {
+// if (mainViewSettings.filterList.indexOf(entry) >= 0) {
+// newList.push(entry)
+// }
+// }
+// }
+// if (newList.length === 0) {
+// newList.push(Configuration.defaultMainView)
+// }
+
+// mainViewSettings.filterList = newList
+// }
+// configListView.draggingIndex = -1;
+
+// var newSortOrder = []
+// for (var i = 0; i < mainMenuModel.count; i++) {
+// newSortOrder.push(mainMenuModel.get(i).name)
+// }
+// mainViewSettings.sortOrder = newSortOrder;
+// }
+// Timer {
+// id: scroller
+// interval: 2
+// repeat: true
+// running: direction != 0
+// property int direction: {
+// if (!configListView.dragging) {
+// return 0;
+// }
+// return dndArea.mouseX < 50 ? -2 : dndArea.mouseX > dndArea.width - 50 ? 2 : 0
+// }
+// onTriggered: {
+// configListView.contentX = Math.min(Math.max(0, configListView.contentX + direction), configListView.contentWidth - configListView.width)
+// }
+// }
+// }
+
+// delegate: BigTile {
+// id: configDelegate
+// width: configListView.delegateWidth
+// height: configListView.height
+// property bool isEnabled: mainViewSettings.filterList.indexOf(model.name) >= 0
+// visible: configListView.draggingIndex !== index
+
+// leftPadding: 0
+// rightPadding: 0
+// topPadding: 0
+// bottomPadding: 0
+
+// header: RowLayout {
+// id: headerRow
+// width: parent.width
+// Label {
+// text: model.displayName
+// Layout.fillWidth: true
+// elide: Text.ElideRight
+// }
+// }
+
+// contentItem: Item {
+// Layout.fillWidth: true
+// implicitHeight: configListView.height - headerRow.height - Style.margins * 2
+
+// ColorIcon {
+// anchors.centerIn: parent
+// width: Math.min(parent.width, parent.height) * .6
+// height: width
+// name: Qt.resolvedUrl("images/" + model.icon + ".svg")
+// color: configDelegate.isEnabled ? Style.accentColor : Style.iconColor
+// }
+// }
+// }
+// Item {
+// id: dndItem
+// width: configListView.delegateWidth
+// height: configListView.height
+// property bool isEnabled: false
+// property string displayName: ""
+// property string icon: "things"
+// visible: configListView.dragging
+// x: dndArea.mouseX - dndArea.dragOffset
+// onVisibleChanged: {
+// if (visible) {
+// dragStartAnimation.start();
+// }
+// }
+
+// NumberAnimation {
+// id: dragStartAnimation
+// target: dndItem
+// property: "scale"
+// from: 1
+// to: 0.95
+// duration: 200
+// }
+
+// BigTile {
+// id: dndTile
+// anchors.fill: parent
+// // anchors.margins: app.margins / 2
+// Material.elevation: 2
+
+// leftPadding: 0
+// rightPadding: 0
+// topPadding: 0
+// bottomPadding: 0
+
+// header: RowLayout {
+// Label {
+// text: dndItem.displayName
+// }
+// }
+
+// contentItem: Item {
+// Layout.fillWidth: true
+// implicitHeight: configListView.height - header.height
+
+// ColorIcon {
+// anchors.centerIn: parent
+// width: Math.min(parent.width, parent.height) * .6
+// height: width
+// name: Qt.resolvedUrl("images/" + dndItem.icon + ".svg")
+// color: dndItem.isEnabled ? Style.accentColor : Style.iconColor
+// }
+// }
+// }
+// }
+// }
}
}
diff --git a/nymea-app/ui/components/MainPageTabButton.qml b/nymea-app/ui/components/MainPageTabButton.qml
index 55980f62..ca8d3523 100644
--- a/nymea-app/ui/components/MainPageTabButton.qml
+++ b/nymea-app/ui/components/MainPageTabButton.qml
@@ -47,18 +47,20 @@ TabButton {
spacing: root.alignment == Qt.Horizontal ? app.margins : app.margins / 2
horizontalItemAlignment: Grid.AlignHCenter
verticalItemAlignment: Grid.AlignVCenter
+ opacity: root.checked ? 1 : .4
+ Behavior on opacity { NumberAnimation { duration: Style.animationDuration; easing.type: Easing.InOutQuad } }
ColorIcon {
width: Style.iconSize
height: Style.iconSize
name: root.iconSource
- color: root.checked ? Style.accentColor : Style.iconColor
+ color: Style.foregroundColor
}
Label {
id: textLabel
text: root.text
font.pixelSize: app.smallFont
- color: root.checked ? Style.accentColor : Material.foreground
+ color: Style.foregroundColor
}
}
}
diff --git a/nymea-app/ui/components/MainViewBase.qml b/nymea-app/ui/components/MainViewBase.qml
index 799b7d65..86845e10 100644
--- a/nymea-app/ui/components/MainViewBase.qml
+++ b/nymea-app/ui/components/MainViewBase.qml
@@ -44,10 +44,15 @@ Item {
property bool isCurrentItem: false
property int topMargin: 40
+ property int bottomMargin: 64
property int contentY: 0 // Relative to topMargin
property var headerButtons: []
+ Background {
+ anchors.fill: parent
+ }
+
// Prevent scroll events to swipe left/right in case they fall through the grid
MouseArea {
anchors.fill: parent
diff --git a/nymea-app/ui/mainviews/EnergyView.qml b/nymea-app/ui/mainviews/EnergyView.qml
index e8251412..f14e925b 100644
--- a/nymea-app/ui/mainviews/EnergyView.qml
+++ b/nymea-app/ui/mainviews/EnergyView.qml
@@ -97,6 +97,7 @@ MainViewBase {
contentHeight: energyGrid.childrenRect.height
visible: !engine.thingManager.fetchingData && engine.jsonRpcClient.experiences.hasOwnProperty("Energy") && engine.jsonRpcClient.experiences["Energy"] >= "0.2"
topMargin: root.topMargin
+ bottomMargin: root.bottomMargin
// GridLayout directly in a flickable causes problems at initialisation
Item {
diff --git a/nymea-app/ui/mainviews/FavoritesView.qml b/nymea-app/ui/mainviews/FavoritesView.qml
index c819349c..4b783d83 100644
--- a/nymea-app/ui/mainviews/FavoritesView.qml
+++ b/nymea-app/ui/mainviews/FavoritesView.qml
@@ -53,6 +53,8 @@ MainViewBase {
anchors.fill: parent
anchors.margins: app.margins / 2
topMargin: root.topMargin
+ bottomMargin: root.bottomMargin
+
readonly property int minTileWidth: 172
readonly property int tilesPerRow: root.width / minTileWidth
diff --git a/nymea-app/ui/mainviews/GaragesView.qml b/nymea-app/ui/mainviews/GaragesView.qml
index 7b6a3b5f..96bdb662 100644
--- a/nymea-app/ui/mainviews/GaragesView.qml
+++ b/nymea-app/ui/mainviews/GaragesView.qml
@@ -51,7 +51,7 @@ MainViewBase {
id: swipeView
anchors.fill: parent
anchors.topMargin: root.topMargin
- anchors.bottomMargin: pageIndicator.visible ? pageIndicator.height : 0
+ anchors.bottomMargin: root.bottomMargin + (pageIndicator.visible ? pageIndicator.height : 0)
Repeater {
model: garagesFilterModel
diff --git a/nymea-app/ui/mainviews/GroupsView.qml b/nymea-app/ui/mainviews/GroupsView.qml
index bb0f280d..3c5bd888 100644
--- a/nymea-app/ui/mainviews/GroupsView.qml
+++ b/nymea-app/ui/mainviews/GroupsView.qml
@@ -44,6 +44,7 @@ MainViewBase {
anchors.fill: parent
anchors.margins: app.margins / 2
topMargin: root.topMargin
+ bottomMargin: root.bottomMargin
readonly property int minTileWidth: 172
readonly property int tilesPerRow: root.width / minTileWidth
diff --git a/nymea-app/ui/mainviews/MediaView.qml b/nymea-app/ui/mainviews/MediaView.qml
index 6a295f2b..bd99bead 100644
--- a/nymea-app/ui/mainviews/MediaView.qml
+++ b/nymea-app/ui/mainviews/MediaView.qml
@@ -50,7 +50,7 @@ MainViewBase {
SwipeView {
id: swipeView
- anchors { left: parent.left; top: parent.top; right: parent.right; bottom: parent.bottom }
+ anchors { left: parent.left; top: parent.top; right: parent.right; bottom: parent.bottom; bottomMargin: root.bottomMargin }
currentIndex: pageIndicator.currentIndex
Repeater {
@@ -67,6 +67,7 @@ MainViewBase {
currentIndex: swipeView.currentIndex
interactive: true
anchors.bottom: parent.bottom
+ anchors.bottomMargin: root.bottomMargin
anchors.horizontalCenter: parent.horizontalCenter
}
diff --git a/nymea-app/ui/mainviews/ScenesView.qml b/nymea-app/ui/mainviews/ScenesView.qml
index 7ed31e94..9cd6083a 100644
--- a/nymea-app/ui/mainviews/ScenesView.qml
+++ b/nymea-app/ui/mainviews/ScenesView.qml
@@ -45,6 +45,7 @@ MainViewBase {
anchors.fill: parent
anchors.margins: app.margins / 2
topMargin: root.topMargin
+ bottomMargin: root.bottomMargin
readonly property int minTileWidth: 172
readonly property int tilesPerRow: root.width / minTileWidth
diff --git a/nymea-app/ui/mainviews/ThingsView.qml b/nymea-app/ui/mainviews/ThingsView.qml
index 15f122a4..e371ab26 100644
--- a/nymea-app/ui/mainviews/ThingsView.qml
+++ b/nymea-app/ui/mainviews/ThingsView.qml
@@ -57,6 +57,7 @@ MainViewBase {
anchors.fill: parent
anchors.margins: app.margins / 2
topMargin: root.topMargin
+ bottomMargin: root.bottomMargin
model: mainModel
readonly property int minTileWidth: 172
diff --git a/nymea-app/ui/mainviews/dashboard/Dashboard.qml b/nymea-app/ui/mainviews/dashboard/Dashboard.qml
index e3e9a4e5..fdd92bfa 100644
--- a/nymea-app/ui/mainviews/dashboard/Dashboard.qml
+++ b/nymea-app/ui/mainviews/dashboard/Dashboard.qml
@@ -37,7 +37,7 @@ import Nymea 1.0
import "../../components"
import "../../delegates"
-Item {
+MainViewBase {
id: root
property var model: null
@@ -75,9 +75,10 @@ Item {
Flickable {
id: flickable
anchors.fill: parent
- anchors.margins: app.margins / 2
+ anchors.margins: Style.smallMargins
contentHeight: Math.max(layout.implicitHeight, height)
contentWidth: width
+ bottomMargin: root.bottomMargin
MouseArea {
width: flickable.contentWidth