- deleted NCard, we already have NBox - assign a color to each widget for better overview when moving stuff around - minor QOL improvements to NComboBox
180 lines
5.2 KiB
QML
180 lines
5.2 KiB
QML
import QtQuick
|
|
import QtQuick.Controls
|
|
import QtQuick.Layouts
|
|
import qs.Commons
|
|
import qs.Widgets
|
|
|
|
NBox {
|
|
id: root
|
|
|
|
property string sectionName: ""
|
|
property var widgetModel: []
|
|
property var availableWidgets: []
|
|
property var scrollView: null
|
|
|
|
signal addWidget(string widgetName, string section)
|
|
signal removeWidget(string section, int index)
|
|
signal reorderWidget(string section, int fromIndex, int toIndex)
|
|
|
|
color: Color.mSurface
|
|
Layout.fillWidth: true
|
|
Layout.minimumHeight: {
|
|
var widgetCount = widgetModel.length
|
|
if (widgetCount === 0)
|
|
return 140 * scaling
|
|
|
|
var availableWidth = scrollView ? scrollView.availableWidth - (Style.marginM * scaling * 2) : 400 * scaling
|
|
var avgWidgetWidth = 150 * scaling
|
|
var widgetsPerRow = Math.max(1, Math.floor(availableWidth / avgWidgetWidth))
|
|
var rows = Math.ceil(widgetCount / widgetsPerRow)
|
|
|
|
return (50 + 20 + (rows * 48) + ((rows - 1) * Style.marginS) + 20) * scaling
|
|
}
|
|
|
|
// Generate widget color from name checksum
|
|
function getWidgetColor(name) {
|
|
const totalSum = name.split('').reduce((acc, character) => {
|
|
return acc + character.charCodeAt(0)
|
|
}, 0)
|
|
switch (totalSum % 5) {
|
|
case 0:
|
|
return Color.mPrimary
|
|
case 1:
|
|
return Color.mSecondary
|
|
case 2:
|
|
return Color.mTertiary
|
|
case 3:
|
|
return Color.mError
|
|
case 4:
|
|
return Color.mOnSurface
|
|
}
|
|
}
|
|
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
anchors.margins: Style.marginM * scaling
|
|
spacing: Style.marginM * scaling
|
|
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
|
|
NText {
|
|
text: sectionName + " Section"
|
|
font.pointSize: Style.fontSizeL * scaling
|
|
font.weight: Style.fontWeightBold
|
|
color: Color.mSecondary
|
|
Layout.alignment: Qt.AlignVCenter
|
|
}
|
|
|
|
Item {
|
|
Layout.fillWidth: true
|
|
}
|
|
NComboBox {
|
|
id: comboBox
|
|
model: availableWidgets
|
|
label: ""
|
|
description: ""
|
|
placeholder: "Add widget to the " + sectionName.toLowerCase() + " section..."
|
|
onSelected: key => {
|
|
comboBox.currentKey = key
|
|
}
|
|
Layout.alignment: Qt.AlignVCenter
|
|
}
|
|
|
|
NIconButton {
|
|
icon: "add"
|
|
|
|
colorBg: Color.mPrimary
|
|
colorFg: Color.mOnPrimary
|
|
colorBgHover: Color.mSecondary
|
|
colorFgHover: Color.mOnSecondary
|
|
enabled: comboBox.selectedKey !== ""
|
|
Layout.alignment: Qt.AlignVCenter
|
|
onClicked: {
|
|
if (comboBox.currentKey !== "") {
|
|
addWidget(comboBox.currentKey, sectionName.toLowerCase())
|
|
comboBox.currentKey = "battery"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Flow {
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
Layout.minimumHeight: 65 * scaling
|
|
spacing: Style.marginS * scaling
|
|
flow: Flow.LeftToRight
|
|
|
|
Repeater {
|
|
model: widgetModel
|
|
delegate: Rectangle {
|
|
width: widgetContent.implicitWidth + 16 * scaling
|
|
height: 40 * scaling
|
|
radius: Style.radiusL * scaling
|
|
color: root.getWidgetColor(modelData)
|
|
border.color: Color.mOutline
|
|
border.width: Math.max(1, Style.borderS * scaling)
|
|
|
|
RowLayout {
|
|
id: widgetContent
|
|
anchors.centerIn: parent
|
|
spacing: Style.marginXS * scaling
|
|
|
|
NIconButton {
|
|
icon: "chevron_left"
|
|
size: 20 * scaling
|
|
colorBorder: Color.applyOpacity(Color.mOutline, "40")
|
|
colorBg: Color.mOnSurface
|
|
colorFg: Color.mOnPrimary
|
|
colorBgHover: Color.applyOpacity(Color.mOnPrimary, "40")
|
|
colorFgHover: Color.mOnPrimary
|
|
enabled: index > 0
|
|
onClicked: {
|
|
if (index > 0) {
|
|
reorderWidget(sectionName.toLowerCase(), index, index - 1)
|
|
}
|
|
}
|
|
}
|
|
|
|
NText {
|
|
text: modelData
|
|
font.pointSize: Style.fontSizeS * scaling
|
|
color: Color.mOnPrimary
|
|
horizontalAlignment: Text.AlignHCenter
|
|
}
|
|
|
|
NIconButton {
|
|
icon: "chevron_right"
|
|
size: 20 * scaling
|
|
colorBorder: Color.applyOpacity(Color.mOutline, "40")
|
|
colorBg: Color.mOnSurface
|
|
colorFg: Color.mOnPrimary
|
|
colorBgHover: Color.applyOpacity(Color.mOnPrimary, "40")
|
|
colorFgHover: Color.mOnPrimary
|
|
enabled: index < widgetModel.length - 1
|
|
onClicked: {
|
|
if (index < widgetModel.length - 1) {
|
|
reorderWidget(sectionName.toLowerCase(), index, index + 1)
|
|
}
|
|
}
|
|
}
|
|
|
|
NIconButton {
|
|
icon: "close"
|
|
size: 20 * scaling
|
|
colorBorder: Color.applyOpacity(Color.mOutline, "40")
|
|
colorBg: Color.mOnSurface
|
|
colorFg: Color.mOnPrimary
|
|
colorBgHover: Color.applyOpacity(Color.mOnPrimary, "40")
|
|
colorFgHover: Color.mOnPrimary
|
|
onClicked: {
|
|
removeWidget(sectionName.toLowerCase(), index)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|