ListView replaced by proper NListView

This commit is contained in:
ItsLemmy
2025-09-22 20:53:59 -04:00
parent c4764c0e5b
commit 9b8c0b9cf0
5 changed files with 356 additions and 365 deletions

View File

@@ -96,7 +96,7 @@ NBox {
x: playerSelector.width * 0.5
y: playerSelector.height * 0.75
width: playerSelector.width * 0.5
implicitHeight: Math.min(160 * scaling, contentItem.implicitHeight + Style.marginM * scaling)
implicitHeight: Math.min(160 * scaling, contentItem.implicitHeight + Style.marginM * 2 * scaling)
padding: Style.marginS * scaling
onOpened: {
@@ -107,38 +107,37 @@ NBox {
PanelService.willClosePopup(root)
}
contentItem: ListView {
clip: true
contentItem: NListView {
implicitHeight: contentHeight
model: playerSelector.popup.visible ? playerSelector.delegateModel : null
currentIndex: playerSelector.highlightedIndex
ScrollIndicator.vertical: ScrollIndicator {}
horizontalPolicy: ScrollBar.AlwaysOff
verticalPolicy: ScrollBar.AsNeeded
}
background: Rectangle {
color: Color.mSurface
border.color: Color.mOutline
border.width: Math.max(1, Style.borderS * scaling)
radius: Style.radiusXS * scaling
radius: Style.radiusS * scaling
}
}
delegate: ItemDelegate {
width: playerSelector.width
highlighted: playerSelector.highlightedIndex === index
background: Rectangle {
width: popup.width - Style.marginS * scaling * 2
color: highlighted ? Color.mTertiary : Color.transparent
radius: Style.radiusXS * scaling
}
contentItem: NText {
text: modelData.identity
font.pointSize: Style.fontSizeS * scaling
color: highlighted ? Color.mSurface : Color.mOnSurface
color: highlighted ? Color.mOnTertiary : Color.mOnSurface
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
highlighted: playerSelector.highlightedIndex === index
background: Rectangle {
width: popup.width - Style.marginS * scaling * 2
color: highlighted ? Color.mSecondary : Color.transparent
radius: Style.radiusXS * scaling
}
}
onActivated: {

View File

@@ -84,7 +84,7 @@ ColumnLayout {
NHeader {
label: "Clock display"
description: "Arrange your clock's layout. Click a token below to add it to the selected field."
description: "Customize your clock's display by adding tokens from the list below. To use the 12-hour format, you must include the 'AP' token."
}
RowLayout {

View File

@@ -85,7 +85,7 @@ RowLayout {
popup: Popup {
y: combo.height
width: combo.width
implicitWidth: combo.width - Style.marginM * scaling
implicitHeight: Math.min(root.popupHeight, contentItem.implicitHeight + Style.marginM * scaling * 2)
padding: Style.marginM * scaling
@@ -97,12 +97,11 @@ RowLayout {
PanelService.willClosePopup(root)
}
contentItem: ListView {
property var comboBoxRoot: root
clip: true
implicitHeight: contentHeight
contentItem: NListView {
model: combo.popup.visible ? root.model : null
ScrollIndicator.vertical: ScrollIndicator {}
implicitHeight: contentHeight
horizontalPolicy: ScrollBar.AlwaysOff
verticalPolicy: ScrollBar.AsNeeded
delegate: ItemDelegate {
width: combo.width
@@ -116,17 +115,15 @@ RowLayout {
}
onClicked: {
ListView.view.comboBoxRoot.selected(ListView.view.comboBoxRoot.model.get(index).key)
root.selected(root.model.get(index).key)
combo.currentIndex = index
combo.popup.close()
}
contentItem: NText {
text: name
font.pointSize: Style.fontSizeM * scaling
color: highlighted ? Color.mSurface : Color.mOnSurface
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
background: Rectangle {
width: combo.width - Style.marginM * scaling * 3
color: highlighted ? Color.mTertiary : Color.transparent
radius: Style.radiusS * scaling
Behavior on color {
ColorAnimation {
duration: Style.animationFast
@@ -134,10 +131,12 @@ RowLayout {
}
}
background: Rectangle {
width: combo.width - Style.marginM * scaling * 3
color: highlighted ? Color.mTertiary : Color.transparent
radius: Style.radiusS * scaling
contentItem: NText {
text: name
font.pointSize: Style.fontSizeM * scaling
color: highlighted ? Color.mOnTertiary : Color.mOnSurface
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
Behavior on color {
ColorAnimation {
duration: Style.animationFast

View File

@@ -21,335 +21,312 @@ Rectangle {
anchors.margins: Style.marginS * scaling
spacing: Style.marginS * scaling
// Scrollable list of tokens
NScrollView {
NListView {
id: tokensList
Layout.fillWidth: true
Layout.fillHeight: true
clip: true
horizontalPolicy: ScrollBar.AlwaysOff
verticalPolicy: ScrollBar.AsNeeded
model: ListModel {
ListView {
id: tokensList
model: ListModel {
// Common format combinations
ListElement {
category: "Common"
token: "h:mm AP"
description: "12-hour time with minutes"
example: "2:30 PM"
}
ListElement {
category: "Common"
token: "HH:mm"
description: "24-hour time with minutes"
example: "14:30"
}
ListElement {
category: "Common"
token: "HH:mm:ss"
description: "24-hour time with seconds"
example: "14:30:45"
}
ListElement {
category: "Common"
token: "ddd MMM d"
description: "Weekday, month and day"
example: "Mon Dec 25"
}
ListElement {
category: "Common"
token: "yyyy-MM-dd"
description: "ISO date format"
example: "2023-12-25"
}
ListElement {
category: "Common"
token: "MM/dd/yyyy"
description: "US date format"
example: "12/25/2023"
}
ListElement {
category: "Common"
token: "dd.MM.yyyy"
description: "European date format"
example: "25.12.2023"
}
ListElement {
category: "Common"
token: "ddd, MMM dd"
description: "Weekday with date"
example: "Fri, Dec 12"
}
// Common format combinations
ListElement {
category: "Common"
token: "h:mm AP"
description: "12-hour time with minutes"
example: "2:30 PM"
}
ListElement {
category: "Common"
token: "HH:mm"
description: "24-hour time with minutes"
example: "14:30"
}
ListElement {
category: "Common"
token: "HH:mm:ss"
description: "24-hour time with seconds"
example: "14:30:45"
}
ListElement {
category: "Common"
token: "ddd MMM d"
description: "Weekday, month and day"
example: "Mon Dec 25"
}
ListElement {
category: "Common"
token: "yyyy-MM-dd"
description: "ISO date format"
example: "2023-12-25"
}
ListElement {
category: "Common"
token: "MM/dd/yyyy"
description: "US date format"
example: "12/25/2023"
}
ListElement {
category: "Common"
token: "dd.MM.yyyy"
description: "European date format"
example: "25.12.2023"
}
ListElement {
category: "Common"
token: "ddd, MMM dd"
description: "Weekday with date"
example: "Fri, Dec 12"
}
// Hour tokens
// ListElement {
// category: "Hour"
// token: "h"
// description: "Hour without leading zero (12-hour when used with AP/ap, otherwise 24-hour)"
// example: "2 (needs AP/ap for 12hr)"
// }
// ListElement {
// category: "Hour"
// token: "hh"
// description: "Hour with leading zero (12-hour when used with AP/ap, otherwise 24-hour)"
// example: "02 (needs AP/ap for 12hr)"
// }
// ListElement {
// category: "Hour"
// token: "h AP"
// description: "12-hour format with AM/PM"
// example: "2 PM"
// }
// ListElement {
// category: "Hour"
// token: "hh AP"
// description: "12-hour format with leading zero and AM/PM"
// example: "02 PM"
// }
ListElement {
category: "Hour"
token: "H"
description: "Hour without leading zero (0-23) - 24-hour format"
example: "14"
}
ListElement {
category: "Hour"
token: "HH"
description: "Hour with leading zero (00-23) - 24-hour format"
example: "14"
}
// Hour tokens
// ListElement {
// category: "Hour"
// token: "h"
// description: "Hour without leading zero (12-hour when used with AP/ap, otherwise 24-hour)"
// example: "2 (needs AP/ap for 12hr)"
// }
// ListElement {
// category: "Hour"
// token: "hh"
// description: "Hour with leading zero (12-hour when used with AP/ap, otherwise 24-hour)"
// example: "02 (needs AP/ap for 12hr)"
// }
// ListElement {
// category: "Hour"
// token: "h AP"
// description: "12-hour format with AM/PM"
// example: "2 PM"
// }
// ListElement {
// category: "Hour"
// token: "hh AP"
// description: "12-hour format with leading zero and AM/PM"
// example: "02 PM"
// }
ListElement {
category: "Hour"
token: "H"
description: "Hour without leading zero (0-23) - 24-hour format"
example: "14"
}
ListElement {
category: "Hour"
token: "HH"
description: "Hour with leading zero (00-23) - 24-hour format"
example: "14"
}
// Minute tokens
ListElement {
category: "Minute"
token: "m"
description: "Minute without leading zero (0-59)"
example: "30"
}
ListElement {
category: "Minute"
token: "mm"
description: "Minute with leading zero (00-59)"
example: "30"
}
// Minute tokens
ListElement {
category: "Minute"
token: "m"
description: "Minute without leading zero (0-59)"
example: "30"
}
ListElement {
category: "Minute"
token: "mm"
description: "Minute with leading zero (00-59)"
example: "30"
}
// Second tokens
ListElement {
category: "Second"
token: "s"
description: "Second without leading zero (0-59)"
example: "45"
}
ListElement {
category: "Second"
token: "ss"
description: "Second with leading zero (00-59)"
example: "45"
}
// Second tokens
ListElement {
category: "Second"
token: "s"
description: "Second without leading zero (0-59)"
example: "45"
}
ListElement {
category: "Second"
token: "ss"
description: "Second with leading zero (00-59)"
example: "45"
}
// AM/PM tokens
ListElement {
category: "AM/PM"
token: "AP"
description: "AM/PM in uppercase"
example: "PM"
}
ListElement {
category: "AM/PM"
token: "ap"
description: "am/pm in lowercase"
example: "pm"
}
// AM/PM tokens
ListElement {
category: "AM/PM"
token: "AP"
description: "AM/PM in uppercase"
example: "PM"
}
ListElement {
category: "AM/PM"
token: "ap"
description: "am/pm in lowercase"
example: "pm"
}
// Timezone tokens
ListElement {
category: "Timezone"
token: "t"
description: "Timezone abbreviation"
example: "UTC"
}
// Timezone tokens
ListElement {
category: "Timezone"
token: "t"
description: "Timezone abbreviation"
example: "UTC"
}
// Year tokens
ListElement {
category: "Year"
token: "yy"
description: "Year as two-digit number (00-99)"
example: "23"
}
ListElement {
category: "Year"
token: "yyyy"
description: "Year as four-digit number"
example: "2023"
}
// Year tokens
ListElement {
category: "Year"
token: "yy"
description: "Year as two-digit number (00-99)"
example: "23"
}
ListElement {
category: "Year"
token: "yyyy"
description: "Year as four-digit number"
example: "2023"
}
// Month tokens
ListElement {
category: "Month"
token: "M"
description: "Month as number without leading zero (1-12)"
example: "12"
}
ListElement {
category: "Month"
token: "MM"
description: "Month as number with leading zero (01-12)"
example: "12"
}
ListElement {
category: "Month"
token: "MMM"
description: "Abbreviated month name"
example: "Dec"
}
ListElement {
category: "Month"
token: "MMMM"
description: "Full month name"
example: "December"
}
// Month tokens
ListElement {
category: "Month"
token: "M"
description: "Month as number without leading zero (1-12)"
example: "12"
}
ListElement {
category: "Month"
token: "MM"
description: "Month as number with leading zero (01-12)"
example: "12"
}
ListElement {
category: "Month"
token: "MMM"
description: "Abbreviated month name"
example: "Dec"
}
ListElement {
category: "Month"
token: "MMMM"
description: "Full month name"
example: "December"
}
// Day tokens
ListElement {
category: "Day"
token: "d"
description: "Day without leading zero (1-31)"
example: "25"
}
ListElement {
category: "Day"
token: "dd"
description: "Day with leading zero (01-31)"
example: "25"
}
ListElement {
category: "Day"
token: "ddd"
description: "Abbreviated day name"
example: "Mon"
}
ListElement {
category: "Day"
token: "dddd"
description: "Full day name"
example: "Monday"
}
}
// Day tokens
ListElement {
category: "Day"
token: "d"
description: "Day without leading zero (1-31)"
example: "25"
delegate: Rectangle {
id: tokenDelegate
width: tokensList.width
height: layout.implicitHeight + Style.marginS * scaling
radius: Style.radiusS * scaling
color: {
if (tokenMouseArea.containsMouse) {
return Qt.alpha(Color.mPrimary, 0.1)
}
ListElement {
category: "Day"
token: "dd"
description: "Day with leading zero (01-31)"
example: "25"
}
ListElement {
category: "Day"
token: "ddd"
description: "Abbreviated day name"
example: "Mon"
}
ListElement {
category: "Day"
token: "dddd"
description: "Full day name"
example: "Monday"
return index % 2 === 0 ? Color.mSurfaceVariant : Qt.alpha(Color.mSurfaceVariant, 0.6)
}
// Mouse area for the entire delegate
MouseArea {
id: tokenMouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
// Emit the signal with the token
root.tokenClicked(model.token)
// Visual feedback
clickAnimation.start()
}
}
delegate: Rectangle {
id: tokenDelegate
width: tokensList.width
height: layout.implicitHeight + Style.marginS * scaling
radius: Style.radiusS * scaling
color: {
if (tokenMouseArea.containsMouse) {
return Qt.alpha(Color.mPrimary, 0.1)
}
return index % 2 === 0 ? Color.mSurfaceVariant : Qt.alpha(Color.mSurfaceVariant, 0.6)
// Click animation
SequentialAnimation {
id: clickAnimation
PropertyAnimation {
target: tokenDelegate
property: "color"
to: Qt.alpha(Color.mPrimary, 0.3)
duration: 100
}
// Mouse area for the entire delegate
MouseArea {
id: tokenMouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
// Emit the signal with the token
root.tokenClicked(model.token)
// Visual feedback
clickAnimation.start()
}
PropertyAnimation {
target: tokenDelegate
property: "color"
to: tokenMouseArea.containsMouse ? Qt.alpha(Color.mPrimary, 0.1) : (index % 2 === 0 ? Color.mSurface : Color.mSurfaceVariant)
duration: 200
}
}
// Click animation
SequentialAnimation {
id: clickAnimation
PropertyAnimation {
target: tokenDelegate
property: "color"
to: Qt.alpha(Color.mPrimary, 0.3)
duration: 100
}
PropertyAnimation {
target: tokenDelegate
property: "color"
to: tokenMouseArea.containsMouse ? Qt.alpha(Color.mPrimary, 0.1) : (index % 2 === 0 ? Color.mSurface : Color.mSurfaceVariant)
duration: 200
}
}
RowLayout {
id: layout
anchors.fill: parent
anchors.margins: Style.marginXS * scaling
spacing: Style.marginM * scaling
RowLayout {
id: layout
anchors.fill: parent
anchors.margins: Style.marginXS * scaling
spacing: Style.marginM * scaling
// Category badge
Rectangle {
Layout.alignment: Qt.AlignVCenter
width: 70 * scaling
height: 22 * scaling
color: getCategoryColor(model.category)[0]
radius: Style.radiusS * scaling
opacity: tokenMouseArea.containsMouse ? 0.9 : 1.0
// Category badge
Rectangle {
Layout.alignment: Qt.AlignVCenter
width: 70 * scaling
height: 22 * scaling
color: getCategoryColor(model.category)[0]
radius: Style.radiusS * scaling
opacity: tokenMouseArea.containsMouse ? 0.9 : 1.0
Behavior on opacity {
NumberAnimation {
duration: Style.animationFast
}
}
NText {
anchors.centerIn: parent
text: model.category
color: getCategoryColor(model.category)[1]
font.pointSize: Style.fontSizeXS * scaling
Behavior on opacity {
NumberAnimation {
duration: Style.animationFast
}
}
// Token - Made more prominent and clickable
Rectangle {
id: tokenButton
Layout.alignment: Qt.AlignVCenter // Added this line
width: 100 * scaling
height: 22 * scaling
color: tokenMouseArea.containsMouse ? Color.mPrimary : Color.mOnSurface
radius: Style.radiusS * scaling
Behavior on color {
ColorAnimation {
duration: Style.animationFast
}
}
NText {
anchors.centerIn: parent
text: model.token
color: tokenMouseArea.containsMouse ? Color.mOnPrimary : Color.mSurface
font.pointSize: Style.fontSizeS * scaling
font.weight: Style.fontWeightBold
Behavior on color {
ColorAnimation {
duration: Style.animationFast
}
}
}
}
// Description
NText {
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter // Added this line
text: model.description
color: tokenMouseArea.containsMouse ? Color.mOnSurface : Color.mOnSurfaceVariant
anchors.centerIn: parent
text: model.category
color: getCategoryColor(model.category)[1]
font.pointSize: Style.fontSizeXS * scaling
}
}
// Token - Made more prominent and clickable
Rectangle {
id: tokenButton
Layout.alignment: Qt.AlignVCenter // Added this line
width: 100 * scaling
height: 22 * scaling
color: tokenMouseArea.containsMouse ? Color.mPrimary : Color.mOnSurface
radius: Style.radiusS * scaling
Behavior on color {
ColorAnimation {
duration: Style.animationFast
}
}
NText {
anchors.centerIn: parent
text: model.token
color: tokenMouseArea.containsMouse ? Color.mOnPrimary : Color.mSurface
font.pointSize: Style.fontSizeS * scaling
wrapMode: Text.WordWrap
font.weight: Style.fontWeightBold
Behavior on color {
ColorAnimation {
@@ -357,41 +334,57 @@ Rectangle {
}
}
}
}
// Live example
Rectangle {
Layout.alignment: Qt.AlignVCenter // Added this line
width: 90 * scaling
height: 22 * scaling
color: tokenMouseArea.containsMouse ? Color.mPrimary : Color.mOnSurfaceVariant
radius: Style.radiusS * scaling
border.color: tokenMouseArea.containsMouse ? Color.mPrimary : Color.mOutline
border.width: Math.max(1, Style.borderS * scaling)
// Description
NText {
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter // Added this line
text: model.description
color: tokenMouseArea.containsMouse ? Color.mOnSurface : Color.mOnSurfaceVariant
font.pointSize: Style.fontSizeS * scaling
wrapMode: Text.WordWrap
Behavior on color {
ColorAnimation {
duration: Style.animationFast
}
}
}
// Live example
Rectangle {
Layout.alignment: Qt.AlignVCenter // Added this line
width: 90 * scaling
height: 22 * scaling
color: tokenMouseArea.containsMouse ? Color.mPrimary : Color.mOnSurfaceVariant
radius: Style.radiusS * scaling
border.color: tokenMouseArea.containsMouse ? Color.mPrimary : Color.mOutline
border.width: Math.max(1, Style.borderS * scaling)
Behavior on color {
ColorAnimation {
duration: Style.animationFast
}
}
Behavior on border.color {
ColorAnimation {
duration: Style.animationFast
}
}
NText {
anchors.centerIn: parent
text: Qt.formatDateTime(root.sampleDate, model.token)
color: tokenMouseArea.containsMouse ? Color.mOnPrimary : Color.mSurfaceVariant
font.pointSize: Style.fontSizeS * scaling
Behavior on color {
ColorAnimation {
duration: Style.animationFast
}
}
Behavior on border.color {
ColorAnimation {
duration: Style.animationFast
}
}
NText {
anchors.centerIn: parent
text: Qt.formatDateTime(root.sampleDate, model.token)
color: tokenMouseArea.containsMouse ? Color.mOnPrimary : Color.mSurfaceVariant
font.pointSize: Style.fontSizeS * scaling
Behavior on color {
ColorAnimation {
duration: Style.animationFast
}
}
}
}
}
}

View File

@@ -174,13 +174,13 @@ RowLayout {
fontSize: Style.fontSizeS * scaling
}
ListView {
NListView {
id: listView
Layout.fillWidth: true
Layout.fillHeight: true
clip: true
model: combo.popup.visible ? filteredModel : null
ScrollIndicator.vertical: ScrollIndicator {}
horizontalPolicy: ScrollBar.AlwaysOff
verticalPolicy: ScrollBar.AsNeeded
delegate: ItemDelegate {
width: listView.width