import QtQuick 2.13 import QtQuick.Controls 2.13 import QtQuick.Layouts 1.14 import StatusQ.Controls 0.1 import StatusQ.Core.Theme 0.1 import StatusQ.Popups 0.1 import StatusQ.Core 0.1 import shared.controls 1.0 import shared.panels 1.0 import SortFilterProxyModel 0.2 Item { id: root property var store property int type: ExtendedDropdownContent.Type.Assets readonly property bool canGoBack: root.state !== d.listView_depth1_State signal itemClicked(string key, string name, url iconSource) enum Type{ Assets, Collectibles } function goBack() { root.state = d.listView_depth1_State } QtObject { id: d readonly property int filterItemsHeight: 36 readonly property int filterPopupWidth: 233 readonly property int filterPopupHeight: 205 // Internal management properties property bool isFilterOptionVisible: false readonly property string thumbnailsViewState: "THUMBNAILS" readonly property string listView_depth1_State: "LIST-DEPTH1" readonly property string listView_depth2_State: "LIST-DEPTH2" property var currentModel: root.store.collectiblesModel property var currentSubitems property string currentItemName: "" property url currentItemSource: "" readonly property SortFilterProxyModel filtered: SortFilterProxyModel { id: collectiblesFilteredModel sourceModel: root.store.collectiblesModel filters: ExpressionFilter { expression: { searcher.text return name.toLowerCase().includes(searcher.text.toLowerCase()) } } } function reset() { d.currentItemName = "" d.currentItemSource = "" d.currentModel = root.store.collectiblesModel d.currentSubitems = undefined root.state = d.listView_depth1_State } } state: d.listView_depth1_State states: [ State { name: d.listView_depth1_State PropertyChanges { target: contentLoader sourceComponent: root.type === ExtendedDropdownContent.Type.Assets ? assetsListView : collectiblesListView } PropertyChanges { target: d currentModel: root.type === ExtendedDropdownContent.Type.Assets ? root.store.assetsModel : collectiblesFilteredModel//root.store.collectiblesModel isFilterOptionVisible: false } PropertyChanges { target: searcher visible: type === ExtendedDropdownContent.Type.Collectibles } }, State { name: d.listView_depth2_State PropertyChanges { target: contentLoader sourceComponent: collectiblesListView } PropertyChanges { target: d currentModel: d.currentSubitems isFilterOptionVisible: true } }, State { name: d.thumbnailsViewState PropertyChanges { target: contentLoader sourceComponent: thumbnailsView } PropertyChanges { target: d currentModel: d.currentSubitems isFilterOptionVisible: true } } ] StatusFlatRoundButton { id: filterButton width: 32 height: 32 visible: d.isFilterOptionVisible type: StatusFlatRoundButton.Type.Secondary icon.name: "filter" anchors.right: parent.right anchors.bottom: parent.top anchors.bottomMargin: 3 onClicked: { filterOptionsPopup.x = filterButton.x + filterButton.width - filterOptionsPopup.width filterOptionsPopup.y = filterButton.y + filterButton.height + 8 filterOptionsPopup.open() } } // Filter options popup: StatusDropdown { id: filterOptionsPopup width: d.filterPopupWidth height: d.filterPopupHeight contentItem: ColumnLayout { anchors.fill: parent anchors.topMargin: 8 anchors.bottomMargin: 8 ListView { Layout.fillWidth: true Layout.preferredHeight: model.count * d.filterItemsHeight model: ListModel { ListElement { text: qsTr("Most viewed"); selected: true } ListElement { text: qsTr("Newest first"); selected: false } ListElement { text: qsTr("Oldest first"); selected: false } } delegate: StatusItemPicker { width: ListView.view.width height: d.filterItemsHeight color: sensor1.containsMouse ? Theme.palette.baseColor4 : "transparent" name: model.text namePixelSize: 13 selectorType: StatusItemPicker.SelectorType.RadioButton radioGroup: filterRadioBtnGroup radioButtonSize: StatusRadioButton.Size.Small selected: model.selected MouseArea { id: sensor1 anchors.fill: parent cursorShape: Qt.PointingHandCursor hoverEnabled: true onClicked: { selected = !selected console.log("TODO: Clicked filter option: " + model.text) filterOptionsPopup.close() } } } // Not visual element to control filter options ButtonGroup { id: filterRadioBtnGroup } } Separator { Layout.fillWidth: true } ListView { Layout.fillWidth: true Layout.preferredHeight: model.count * d.filterItemsHeight model: ListModel { ListElement { key: "LIST"; text: qsTr("List"); selected: true } ListElement { key: "THUMBNAILS"; text: qsTr("Thumbnails"); selected: false } } delegate: StatusItemPicker { width: ListView.view.width height: d.filterItemsHeight color: sensor2.containsMouse ? Theme.palette.baseColor4 : "transparent" name: model.text namePixelSize: 13 selectorType: StatusItemPicker.SelectorType.RadioButton radioGroup: visualizationRadioBtnGroup radioButtonSize: StatusRadioButton.Size.Small selected: model.selected MouseArea { id: sensor2 anchors.fill: parent cursorShape: Qt.PointingHandCursor hoverEnabled: true onClicked: { selected = !selected if(model.key === "LIST") { root.state = d.listView_depth2_State } else if(model.key === "THUMBNAILS") { root.state = d.thumbnailsViewState } filterOptionsPopup.close() } } } // Not visual element to control visualization options ButtonGroup { id: visualizationRadioBtnGroup } } } } // List elements content ColumnLayout { anchors.fill: parent SearchBox { id: searcher Layout.fillWidth: true visible: false topPadding: 0 bottomPadding: 0 minimumHeight: 36 maximumHeight: 36 } Loader { id: contentLoader Layout.fillWidth: true Layout.fillHeight: true } } Component { id: assetsListView ListDropdownContent { headerModel: ListModel { ListElement { key: "MINT"; icon: "add"; iconSize: 16; description: qsTr("Mint asset"); rotation: 0; spacing: 8 } ListElement { key: "IMPORT"; icon: "invite-users"; iconSize: 16; description: qsTr("Import existing asset"); rotation: 180; spacing: 8 } } isHeaderVisible: false // TEMPORARILY hidden. These 2 header options will be implemented after MVP. model: d.currentModel onHeaderItemClicked: { if(key === "MINT") console.log("TODO: Mint asset") else if(key === "IMPORT") console.log("TODO: Import existing asset") } onItemClicked: root.itemClicked(key, shortName, iconSource) } } Component { id: collectiblesListView ListDropdownContent { isHeaderVisible: root.state === d.listView_depth1_State headerModel: ListModel { ListElement { key: "MINT"; icon: "add"; iconSize: 16; description: qsTr("Mint collectible"); rotation: 0; spacing: 8 } } model: d.currentModel onHeaderItemClicked: { if(key === "MINT") console.log("TODO: Mint collectible") } onItemClicked: { if(subItems && root.state === d.listView_depth1_State) { // One deep navigation d.currentSubitems = subItems d.currentItemName = name d.currentItemSource = iconSource root.state = d.listView_depth2_State } else { d.reset() root.itemClicked(key, name, iconSource) } } } } Component { id: thumbnailsView ThumbnailsDropdownContent { title: d.currentItemName titleImage: d.currentItemSource padding: 0 model: d.currentModel onItemClicked: { d.reset() root.itemClicked(key, name, iconSource) } } } }