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.panels 1.0 ColumnLayout { id: root property var store property int type: ExtendedDropdownContent.Type.Tokens signal goBack() signal itemClicked(string key, string name, url iconSource) enum Type{ Tokens, Collectibles } 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: "" function reset() { d.currentItemName = "" d.currentItemSource = "" d.currentModel = root.store.collectiblesModel d.currentSubitems = undefined root.state = d.listView_depth1_State } } spacing: 0 state: d.listView_depth1_State states: [ State { name: d.thumbnailsViewState PropertyChanges {target: contentLoader; sourceComponent: thumbnailsView} PropertyChanges {target: d; isFilterOptionVisible: true} PropertyChanges {target: d; currentModel: d.currentSubitems} }, State { name: d.listView_depth1_State PropertyChanges {target: contentLoader; sourceComponent: root.type === ExtendedDropdownContent.Type.Tokens ? tokensListView : collectiblesListView} PropertyChanges {target: d; isFilterOptionVisible: false} PropertyChanges {target: d; currentModel: root.type === ExtendedDropdownContent.Type.Tokens ? root.store.tokensModel : root.store.collectiblesModel} }, State { name: d.listView_depth2_State PropertyChanges {target: contentLoader; sourceComponent: collectiblesListView} PropertyChanges {target: d; isFilterOptionVisible: true } PropertyChanges {target: d; currentModel: d.currentSubitems} } ] // Header RowLayout { Layout.fillWidth: true Layout.leftMargin: 16 Layout.rightMargin: 8 Layout.topMargin: 5 StatusIconTextButton { Layout.alignment: Qt.AlignVCenter spacing: 0 statusIcon: "next" icon.width: 12 icon.height: 12 iconRotation: 180 text: qsTr("Back") onClicked: { if(root.state == d.listView_depth1_State) { root.goBack() } else { root.state = d.listView_depth1_State } } } // Just a filler to fit layout Item { Layout.fillWidth: true; height: filterButton.implicitHeight } StatusFlatRoundButton { id: filterButton implicitWidth: 32 implicitHeight: 32 visible: d.isFilterOptionVisible type: StatusFlatRoundButton.Type.Secondary icon.name: "filter" 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 Loader { id: contentLoader Layout.preferredWidth: 289 // by design Layout.bottomMargin: 5 Layout.preferredHeight: (item != null && typeof(item) !== 'undefined') ? item.implicitHeight : 0 } Component { id: tokensListView ListDropdownContent { headerModel: ListModel { ListElement { key: "MINT"; icon: "add"; iconSize: 16; description: qsTr("Mint token"); rotation: 0; spacing: 8 } ListElement { key: "IMPORT"; icon: "invite-users"; iconSize: 16; description: qsTr("Import existing token"); rotation: 180; spacing: 8 } } model: d.currentModel onHeaderItemClicked: { if(key === "MINT") console.log("TODO: Mint token") else if(key === "IMPORT") console.log("TODO: Import existing token") } 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 model: d.currentModel onItemClicked: { d.reset() root.itemClicked(key, name, iconSource) } } } }