import QtQuick import QtQuick.Controls import QtQuick.Layouts import KomplexHub import KomplexHub.Controls import KomplexHub.Kero import KomplexHubPlugin Item { property string query readonly property bool searchable: true property int resultsPerRow: (resultsContainer.width - (Constants.largeMargin * 2)) / (resultWidth + Constants.mediumMargin) property int rows: ((resultsContainer.height - (Constants.largeMargin * 2)) / (resultHeight + Constants.mediumMargin)) property int resultsPerPage: resultsPerRow * rows property int emptyWidth: (resultsContainer.width - (Constants.largeMargin * 2)) - (resultsPerRow * (resultWidth + Constants.mediumMargin)) property int resultWidth: 256 property int resultHeight: 245 property bool loading: false property var model property Component delegate id: rootItem KeroErrorAvatar { id: errorOverlay anchors.fill: parent opacity: 0 } KeroNoResultsAvatar { id: noResultsOverlay anchors.fill: parent opacity: 0 } KeroChoiceAvatar { id: noSearchOverlay title: qsTr("No Search Term") description: qsTr("Kero needs a subject or term to search for wallpapers") anchors.fill: parent opacity: 0 } KeroLoadingAnimation { id: loadingOverlay anchors.fill: parent opacity: 0 } Rectangle { id: resultsContainer anchors.fill: parent color: palette.base RowLayout { anchors.fill: parent anchors.margins: Constants.largeMargin Item { Layout.fillHeight: true Layout.preferredWidth: emptyWidth / 2 Layout.maximumWidth: emptyWidth / 2 } GridView { id: resultsView Layout.fillHeight: true Layout.fillWidth: true cellWidth: 256 + Constants.mediumMargin cellHeight: 245 + Constants.mediumMargin focus: true model: rootItem.model delegate: rootItem.delegate add: Transition { NumberAnimation { properties: "x" from: resultsContainer.width duration: 250 } NumberAnimation { properties: "opacity,scale" to: 1.0 duration: 500 } } move: Transition { NumberAnimation { properties: "x,y" duration: 250 } } populate: Transition { NumberAnimation { properties: "opacity,scale" to: 1.0 duration: 500 } } remove: Transition { NumberAnimation { properties: "x" to: 0 duration: 250 } NumberAnimation { properties: "opacity" to: 0 duration: 250 } } } } PaginationBox { height: 35 anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom anchors.margins: Constants.largeMargin onNext: () => model.nextPage() onPrevious: () => model.previousPage() enablePrevious: model.hasPreviousPage enableNext: model.hasNextPage } } states: [ State { name: "loading" when: loading PropertyChanges { target: loadingOverlay opacity: 1 } PropertyChanges { target: resultsContainer opacity: 0 } PropertyChanges { target: noSearchOverlay opacity: 0 } PropertyChanges { target: errorOverlay opacity: 0 } PropertyChanges { target: buttonBoxLayout visible: false } }, State { name: "empty" when: model.totalResults === 0 && model.query.length > 0 PropertyChanges { target: noResultsOverlay opacity: 1 } PropertyChanges { target: noSearchOverlay opacity: 0 } PropertyChanges { target: resultsContainer opacity: 0 } PropertyChanges { target: buttonBoxLayout visible: false } }, State { name: "nosearch" when: model.query.length === 0 PropertyChanges { target: noResultsOverlay opacity: 0 } PropertyChanges { target: noSearchOverlay opacity: 1 } PropertyChanges { target: resultsContainer opacity: 0 } PropertyChanges { target: buttonBoxLayout visible: false } }, State { name: "idle" when: model.totalResults !== 0 && !loading PropertyChanges { target: loadingOverlay opacity: 0.0 } PropertyChanges { target: resultsContainer opacity: 1.0 } PropertyChanges { target: buttonBoxLayout visible: true } }, State { name: "error" when: model.errorString.length > 0 PropertyChanges { target: errorOverlay opacity: 1.0 } PropertyChanges { target: resultsContainer opacity: 0.0 } PropertyChanges { target: noSearchOverlay opacity: 0.0 } PropertyChanges { target: noResultsOverlay opacity: 0.0 } } ] transitions: [ Transition { from: "empty" to: "loading" NumberAnimation { target: noResultsOverlay duration: 250 property: "opacity"; } NumberAnimation { target: loadingOverlay duration: 250 property: "opacity"; } }, Transition { from: "nosearch" to: "loading" NumberAnimation { target: noSearchOverlay duration: 250 property: "opacity"; } NumberAnimation { target: loadingOverlay duration: 250 property: "opacity"; } }, Transition { from: "loading" to: "nosearch" NumberAnimation { target: noSearchOverlay duration: 250 property: "opacity"; } NumberAnimation { target: loadingOverlay duration: 250 property: "opacity"; } }, Transition { from: "loading" to: "empty" NumberAnimation { target: noResultsOverlay duration: 250 property: "opacity"; } NumberAnimation { target: loadingOverlay duration: 250 property: "opacity"; } }, Transition { from: "loading" to: "idle" NumberAnimation { target: loadingOverlay duration: 250 property: "opacity"; } NumberAnimation { target: resultsView duration: 250 property: "opacity"; } } ] }