status-desktop/ui/app/AppLayouts/Chat/controls/community/ExtendedDropdownContent.qml

278 lines
10 KiB
QML
Raw Normal View History

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)
}
}
}
}