Rework bottom panel
This commit is contained in:
parent
94b43cd00b
commit
db64033d56
@ -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);
|
||||
|
||||
@ -39,5 +39,11 @@
|
||||
<file>ui/Configuration.qml</file>
|
||||
<file>styles/dark/Dialog.qml</file>
|
||||
<file>styles/light/Dialog.qml</file>
|
||||
<file>styles/dark/Background.qml</file>
|
||||
<file>styles/light/Background.qml</file>
|
||||
<file>styles/energize/Background.qml</file>
|
||||
<file>styles/lime/Background.qml</file>
|
||||
<file>styles/mellow/Background.qml</file>
|
||||
<file>styles/noir/Background.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
5
nymea-app/styles/dark/Background.qml
Normal file
5
nymea-app/styles/dark/Background.qml
Normal file
@ -0,0 +1,5 @@
|
||||
import QtQuick 2.0
|
||||
|
||||
Rectangle {
|
||||
color: Style.backgroundColor
|
||||
}
|
||||
@ -33,8 +33,5 @@ import QtQuick.Templates 2.2
|
||||
import QtQuick.Controls.Material 2.2
|
||||
|
||||
Page {
|
||||
|
||||
background: Rectangle {
|
||||
color: Material.background
|
||||
}
|
||||
background: Background {}
|
||||
}
|
||||
|
||||
8
nymea-app/styles/energize/Background.qml
Normal file
8
nymea-app/styles/energize/Background.qml
Normal file
@ -0,0 +1,8 @@
|
||||
import QtQuick 2.0
|
||||
|
||||
Rectangle {
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0.0; color: "#e3eae4" }
|
||||
GradientStop { position: 1.0; color: "#cde2d8" }
|
||||
}
|
||||
}
|
||||
@ -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 {}
|
||||
}
|
||||
|
||||
5
nymea-app/styles/light/Background.qml
Normal file
5
nymea-app/styles/light/Background.qml
Normal file
@ -0,0 +1,5 @@
|
||||
import QtQuick 2.0
|
||||
|
||||
Rectangle {
|
||||
color: Style.backgroundColor
|
||||
}
|
||||
@ -33,8 +33,5 @@ import QtQuick.Templates 2.2
|
||||
import QtQuick.Controls.Material 2.2
|
||||
|
||||
Page {
|
||||
|
||||
background: Rectangle {
|
||||
color: Material.background
|
||||
}
|
||||
background: Background {}
|
||||
}
|
||||
|
||||
5
nymea-app/styles/lime/Background.qml
Normal file
5
nymea-app/styles/lime/Background.qml
Normal file
@ -0,0 +1,5 @@
|
||||
import QtQuick 2.0
|
||||
|
||||
Rectangle {
|
||||
color: Style.backgroundColor
|
||||
}
|
||||
@ -33,8 +33,5 @@ import QtQuick.Templates 2.2
|
||||
import QtQuick.Controls.Material 2.2
|
||||
|
||||
Page {
|
||||
|
||||
background: Rectangle {
|
||||
color: Material.background
|
||||
}
|
||||
background: Background {}
|
||||
}
|
||||
|
||||
5
nymea-app/styles/mellow/Background.qml
Normal file
5
nymea-app/styles/mellow/Background.qml
Normal file
@ -0,0 +1,5 @@
|
||||
import QtQuick 2.0
|
||||
|
||||
Rectangle {
|
||||
color: Style.backgroundColor
|
||||
}
|
||||
@ -33,8 +33,5 @@ import QtQuick.Templates 2.2
|
||||
import QtQuick.Controls.Material 2.2
|
||||
|
||||
Page {
|
||||
|
||||
background: Rectangle {
|
||||
color: Material.background
|
||||
}
|
||||
background: Background {}
|
||||
}
|
||||
|
||||
5
nymea-app/styles/noir/Background.qml
Normal file
5
nymea-app/styles/noir/Background.qml
Normal file
@ -0,0 +1,5 @@
|
||||
import QtQuick 2.0
|
||||
|
||||
Rectangle {
|
||||
color: Style.backgroundColor
|
||||
}
|
||||
@ -34,7 +34,5 @@ import QtQuick.Controls.Material 2.2
|
||||
import Nymea 1.0
|
||||
|
||||
Page {
|
||||
background: Rectangle {
|
||||
color: Style.backgroundColor
|
||||
}
|
||||
background: Background {}
|
||||
}
|
||||
|
||||
@ -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
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user