diff --git a/discover/qml/ApplicationDelegate.qml b/discover/qml/ApplicationDelegate.qml index cdb5e379685a8bdb008f2076d76ad72268a70684..27a44fb028db91b4e52a34d2bdf3476369397573 100644 --- a/discover/qml/ApplicationDelegate.qml +++ b/discover/qml/ApplicationDelegate.qml @@ -18,6 +18,7 @@ Kirigami.AbstractCard property alias application: installButton.application property bool compact: false property bool showRating: true + property bool featured: false property bool showSize: false readonly property bool appIsFromNonDefaultBackend: ResourcesModel.currentApplicationBackend !== application.backend && application.backend.hasApplications @@ -34,94 +35,63 @@ Kirigami.AbstractCard onClicked: trigger() contentItem: Item { - implicitHeight: delegateArea.compact ? Kirigami.Units.gridUnit * 2 : Kirigami.Units.gridUnit * 4 - - // App icon - Kirigami.Icon { - id: resourceIcon - readonly property real contHeight: delegateArea.compact ? Kirigami.Units.iconSizes.large : Kirigami.Units.iconSizes.huge - source: application.icon - height: contHeight - width: contHeight - anchors { - verticalCenter: parent.verticalCenter - left: parent.left - leftMargin: delegateArea.compact ? Kirigami.Units.largeSpacing : Kirigami.Units.largeSpacing * 2 - } - } + implicitHeight: featured ? Kirigami.Units.gridUnit * 5 : Kirigami.Units.gridUnit * 4 // Container for everything but the app icon ColumnLayout { anchors { verticalCenter: parent.verticalCenter - right: parent.right - left: resourceIcon.right - leftMargin: Kirigami.Units.largeSpacing * 2 + fill: parent + leftMargin: Kirigami.Units.largeSpacing + rightMargin: Kirigami.Units.largeSpacing } spacing: 0 // Container for app name and backend name labels RowLayout { + spacing: Kirigami.Units.largeSpacing - // App name label - Kirigami.Heading { - id: head - Layout.fillWidth: true - level: delegateArea.compact ? 2 : 1 - type: Kirigami.Heading.Type.Primary - text: delegateArea.application.name - elide: Text.ElideRight - maximumLineCount: 1 - } - - // Backend name label (shown if app is from a non-default backend) - RowLayout { - Layout.alignment: Qt.AlignRight - visible: delegateArea.appIsFromNonDefaultBackend - spacing: 0 - + // App icon + ColumnLayout { Kirigami.Icon { - source: application.sourceIcon - implicitWidth: Kirigami.Units.iconSizes.smallMedium - implicitHeight: Kirigami.Units.iconSizes.smallMedium + id: resourceIcon + source: application.icon + readonly property real contHeight: delegateArea.compact ? Kirigami.Units.iconSizes.large : Kirigami.Units.iconSizes.huge + implicitWidth: contHeight + implicitHeight: contHeight } - Label { - text: application.backend.displayName - font: Kirigami.Theme.smallFont + + Item { + Layout.fillHeight: featured } } - } - // Description/"Comment" label - Label { - id: description - Layout.fillWidth: true - text: delegateArea.application.comment - elide: Text.ElideRight - maximumLineCount: 1 - textFormat: Text.PlainText - } - - // Spacer - Item { - implicitHeight: delegateArea.compact ? Kirigami.Units.smallSpacing : Kirigami.Units.largeSpacing - } + ColumnLayout { + // App name label + Kirigami.Heading { + id: head + Layout.fillWidth: true + level: 2 + type: Kirigami.Heading.Type.Primary + text: delegateArea.application.name + elide: Text.ElideRight + maximumLineCount: 1 + } - // Container for rating, category, size, and install button - RowLayout { - Layout.fillWidth: true + // Description + Label { + id: description + maximumLineCount: 1 + Layout.fillWidth: true + wrapMode: Text.WordWrap + text: delegateArea.application.comment + elide: Text.ElideRight + textFormat: Text.PlainText + } - // Container for rating, category and size labels - ColumnLayout { - Layout.fillWidth: true - // Include height of compactInfo for full-sized view even when - // the actual compactInfo layout isn't visible. This tightens up - // the layout and prevents the install button from appearing - // at a different position based on whether or not the - // compactInfo text is visible, because the base layout is - // vertically centered rather than filling a distinct space. - Layout.preferredHeight: delegateArea.compact ? -1 : rating.implicitHeight + compactInfo.implicitHeight - spacing: 0 + Item { + Layout.fillHeight: featured + } // Rating stars + label RowLayout { @@ -133,7 +103,7 @@ Kirigami.AbstractCard Rating { rating: delegateArea.application.rating ? delegateArea.application.rating.sortableRating : 0 - starSize: delegateArea.compact ? description.font.pointSize : head.font.pointSize + starSize: head.font.pointSize } Label { Layout.fillWidth: true @@ -144,25 +114,19 @@ Kirigami.AbstractCard } } - // Category and Size labels - RowLayout { - id: compactInfo + // Category label + Label { + id: category Layout.fillWidth: true + visible: featured opacity: 0.6 - spacing: Kirigami.Units.largeSpacing - - Label { - id: category - Layout.fillWidth: true - visible: delegateArea.application.categoryDisplay && delegateArea.application.categoryDisplay !== page.title && !delegateArea.compact - opacity: 0.6 - text: delegateArea.application.categoryDisplay - font: Kirigami.Theme.smallFont - elide: Text.ElideRight - maximumLineCount: 1 - } + text: delegateArea.application.categoryDisplay + font: Kirigami.Theme.smallFont + elide: Text.ElideRight + maximumLineCount: 1 + } - Label { + Label { id: size Layout.fillWidth: true visible: showSize && !delegateArea.compact @@ -173,14 +137,37 @@ Kirigami.AbstractCard elide: Text.ElideRight maximumLineCount: 1 } - } } - // Install button - InstallApplicationButton { - id: installButton - Layout.alignment: Qt.AlignVCenter | Qt.AlignRight - visible: !delegateArea.compact + ColumnLayout { + InstallApplicationButton { + id: installButton + Layout.alignment: Qt.AlignVCenter | Qt.AlignRight + hideText: delegateArea.compact + } + + // Backend name label (shown if app is from a non-default backend) + RowLayout { + Layout.alignment: Qt.AlignCenter + visible: delegateArea.appIsFromNonDefaultBackend + spacing: 0 + + Kirigami.Icon { + source: application.sourceIcon + implicitWidth: Kirigami.Units.iconSizes.smallMedium + implicitHeight: Kirigami.Units.iconSizes.smallMedium + } + Label { + text: application.backend.displayName + font: Kirigami.Theme.smallFont + visible: !delegateArea.compact + } + } + + // Align items to top + Item { + Layout.fillHeight: true + } } } } diff --git a/discover/qml/BrowsingPage.qml b/discover/qml/BrowsingPage.qml index b7f6ae6270851a8c67e3ec5c9926a610b5ee9ad4..af6356dbaf635867c87e3db099b1eb3ec2ac52ea 100644 --- a/discover/qml/BrowsingPage.qml +++ b/discover/qml/BrowsingPage.qml @@ -71,7 +71,7 @@ DiscoverPage signal clearSearch() - readonly property bool compact: page.width < 550 || !applicationWindow().wideScreen + readonly property bool compact: page.width < Kirigami.Units.gridUnit * 25 footer: ColumnLayout { spacing: 0 @@ -113,6 +113,7 @@ DiscoverPage delegate: ApplicationDelegate { application: model.application compact: page.compact + featured: true } } } diff --git a/discover/qml/InstallApplicationButton.qml b/discover/qml/InstallApplicationButton.qml index 48e09de971b99eb3fc6468c334bf95b0dfe191e5..26662b42eb16a0796acbf37b520879d84cb1c923 100644 --- a/discover/qml/InstallApplicationButton.qml +++ b/discover/qml/InstallApplicationButton.qml @@ -9,6 +9,7 @@ ConditionalLoader id: root property Component additionalItem: null property alias application: listener.resource + property bool hideText: false readonly property alias isActive: listener.isActive readonly property alias progress: listener.progress @@ -21,17 +22,19 @@ ConditionalLoader readonly property Kirigami.Action action: Kirigami.Action { text: { - if (!root.isStateAvailable) { + if (root.hideText) { + return ""; + } + else if (!root.isStateAvailable) { return i18nc("State being fetched", "Loading…") } - if (!application.isInstalled) { + else if (!application.isInstalled) { return i18n("Install"); } return i18n("Remove"); } icon { name: application.isInstalled ? "edit-delete" : "download" - color: !enabled ? Kirigami.Theme.backgroundColor : !listener.isActive ? (application.isInstalled ? Kirigami.Theme.negativeTextColor : Kirigami.Theme.positiveTextColor) : Kirigami.Theme.backgroundColor } visible: !listener.isActive && (!application.isInstalled || application.isRemovable) enabled: !listener.isActive && root.isStateAvailable @@ -82,6 +85,7 @@ ConditionalLoader visible: !application.isInstalled || application.isRemovable enabled: application.state !== AbstractResource.Broken text: root.action.text + icon: root.action.icon activeFocusOnTab: false onClicked: root.click()