feat(StatusQ.Components/Controls): New `StatusListPicker` and `StatusItemPicker` selector component / control (#583)

It adds the `StatusItemPicker` control and `StatusListPicker` component and its corresponding documentation.

The new selector component is composed by a `StatusButtonPicker` and a drop-down list.

It adds sections in `ListView` by using `category` model property.

It incorporates a searcher in header.

The selector type can be customised as a `StatusRadioButton` or a `StatusCheckbox`.

It adds dynamic selection mechanism.

It adds a dynamic text fit between `name` and `shortName` text components.

It adds a specific page in `sandbox` and some models to play with that.

It extends `StatusPickerButton` to allow more than one type.

Closes #563
This commit is contained in:
Noelia 2022-04-04 12:16:47 +02:00 committed by GitHub
parent a561a3fff8
commit 555ad8bea8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 949 additions and 18 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

View File

@ -22,6 +22,7 @@
\li \l{StatusDescriptionListItem} \li \l{StatusDescriptionListItem}
\li \l{StatusLetterIdenticon} \li \l{StatusLetterIdenticon}
\li \l{StatusListItem} \li \l{StatusListItem}
\li \l{StatusListPicker}
\li \l{StatusListSectionHeadline} \li \l{StatusListSectionHeadline}
\li \l{StatusLoadingIndicator} \li \l{StatusLoadingIndicator}
\li \l{StatusMemberListItem} \li \l{StatusMemberListItem}

View File

@ -32,6 +32,7 @@
\li \l{StatusBaseInput} \li \l{StatusBaseInput}
\li \l{StatusIdenticonRing} \li \l{StatusIdenticonRing}
\li \l{StatusInput} \li \l{StatusInput}
\li \l{StatusItemPicker}
\li \l{StatusPickerButton} \li \l{StatusPickerButton}
\li \l{StatusPinInput} \li \l{StatusPinInput}
\li \l{StatusProgressBar} \li \l{StatusProgressBar}

View File

@ -1052,4 +1052,309 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
notificationsCount: 0 notificationsCount: 0
} }
} }
property ListModel currencyPickerModel: ListModel {
ListElement {
key: 0
name: "United States Dollar"
shortName: "USD"
symbol: "$"
imageSource: "../../assets/twemoji/26x26/1f4b4.png"
category: ""
selected: false
}
ListElement {
key: 1
name: "British Pound"
shortName: "GBP"
symbol: "£"
imageSource: "../../assets/twemoji/26x26/1f4b5.png"
category: ""
selected: false
}
ListElement {
key: 2
name: "Euro"
shortName: "EUR"
symbol: "€"
imageSource: "../../assets/twemoji/26x26/1f4b6.png"
category: ""
selected: true
}
ListElement {
key: 3
name: "Shout Korean Won"
shortName: "KRW"
symbol: "₩"
imageSource: "../../assets/twemoji/26x26/1f4b8.png"
category: ""
selected: false
}
ListElement {
key: 4
name: "Ethereum"
shortName: "ETH"
symbol: "Ξ"
imageSource: "../../assets/twemoji/26x26/1f4b7.png"
category: "Tokens"
selected: true
}
ListElement {
key: 5
name: "Bitcoin"
shortName: "BTC"
symbol: "฿"
imageSource: "../../assets/twemoji/26x26/1f4b4.png"
category: "Tokens"
selected: false
}
ListElement {
key: 6
name: "Status Network Token"
shortName: "SNT"
symbol: ""
imageSource: "../../assets/twemoji/26x26/1f4b8.png"
category: "Tokens"
selected: false
}
ListElement {
key: 7
name: "Emirati Dirham"
shortName: "AED"
symbol: "د.إ"
imageSource: "../../assets/twemoji/26x26/1f4b4.png"
category: "Other Fiat"
selected: false
}
ListElement {
key: 8
name: "Afghani"
shortName: "AFN"
symbol: "؋"
imageSource: "../../assets/twemoji/26x26/1f4b7.png"
category: "Other Fiat"
selected: false
}
ListElement {
key: 9
name: "Argentine Peso"
shortName: "AFN"
symbol: "$"
imageSource: "../../assets/twemoji/26x26/1f4b4.png"
category: "Other Fiat"
selected: false
}
}
property ListModel currencyPickerModel2: ListModel {
ListElement {
key: 0
name: "United States Dollar"
shortName: "USD"
symbol: "$"
imageSource: "../../assets/twemoji/26x26/1f4b4.png"
category: ""
selected: false
}
ListElement {
key: 1
name: "British Pound"
shortName: "GBP"
symbol: "£"
imageSource: "../../assets/twemoji/26x26/1f4b5.png"
category: ""
selected: false
}
ListElement {
key: 2
name: "Euro"
shortName: "EUR"
symbol: "€"
imageSource: "../../assets/twemoji/26x26/1f4b6.png"
category: ""
selected: true
}
ListElement {
key: 3
name: "Shout Korean Won"
shortName: "KRW"
symbol: "₩"
imageSource: "../../assets/twemoji/26x26/1f4b8.png"
category: ""
selected: false
}
ListElement {
key: 4
name: "Ethereum"
shortName: "ETH"
symbol: "Ξ"
imageSource: "../../assets/twemoji/26x26/1f4b7.png"
category: "Tokens"
selected: true
}
ListElement {
key: 5
name: "Bitcoin"
shortName: "BTC"
symbol: "฿"
imageSource: "../../assets/twemoji/26x26/1f4b4.png"
category: "Tokens"
selected: false
}
ListElement {
key: 6
name: "Status Network Token"
shortName: "SNT"
symbol: ""
imageSource: "../../assets/twemoji/26x26/1f4b8.png"
category: "Tokens"
selected: false
}
ListElement {
key: 7
name: "Emirati Dirham"
shortName: "AED"
symbol: "د.إ"
imageSource: "../../assets/twemoji/26x26/1f4b4.png"
category: "Other Fiat"
selected: false
}
ListElement {
key: 8
name: "Afghani"
shortName: "AFN"
symbol: "؋"
imageSource: "../../assets/twemoji/26x26/1f4b7.png"
category: "Other Fiat"
selected: false
}
ListElement {
key: 9
name: "Argentine Peso"
shortName: "AFN"
symbol: "$"
imageSource: "../../assets/twemoji/26x26/1f4b4.png"
category: "Other Fiat"
selected: false
}
}
property ListModel languagePickerModel: ListModel {
ListElement {
key: 0
name: "English"
shortName: "English"
imageSource: "../../assets/twemoji/26x26/1f1ec-1f1e7.png"
category: ""
selected: false
}
ListElement {
key: 1
name: "Korean"
shortName: "한국어"
imageSource: "../../assets/twemoji/26x26/1f1f0-1f1f7.png"
category: ""
selected: false
}
ListElement {
key: 2
name: "Portuguese (Brazilian)"
shortName: "Português"
imageSource: "../../assets/twemoji/26x26/1f1e7-1f1f7.png"
category: ""
selected: true
}
ListElement {
key: 3
name: "Dutch"
shortName: "Nederlands"
imageSource: "../../assets/twemoji/26x26/1f1f3-1f1f1.png"
category: "Beta Languages"
selected: false
}
ListElement {
key: 4
name: "Indonesian"
shortName: "Bahasa Indonesia"
imageSource: "../../assets/twemoji/26x26/1f1ee-1f1e9.png"
category: "Beta Languages"
selected: false
}
ListElement {
key: 5
name: "Spanish"
shortName: "Español"
imageSource: "../../assets/twemoji/26x26/1f1ea-1f1e6.png"
category: "Beta Languages"
selected: false
}
}
property ListModel languageNoImagePickerModel: ListModel {
ListElement {
key: 0
name: "Chinese (Mainland China)"
shortName: "普通话"
category: ""
selected: true
}
ListElement {
key: 1
name: "Russian"
shortName: "Русский Язык"
category: ""
selected: false
}
ListElement {
key: 2
name: "Arabic"
shortName: "اَلْعَرَبِيَّةُ"
category: "Beta Languages"
selected: true
}
ListElement {
key: 3
name: "Chinese (Taiwan)"
shortName: "臺灣華語"
category: "Beta Languages"
selected: false
}
ListElement {
key: 4
name: "Filipino"
shortName: "Wikang Filipino"
category: "Beta Languages"
selected: false
}
ListElement {
key: 5
name: "French"
shortName: "Français"
category: "Beta Languages"
selected: false
}
ListElement {
key: 6
name: "Italian"
shortName: "Italiano"
category: "Beta Languages"
selected: false
}
ListElement {
key: 7
name: "Turkish"
shortName: "Türkçe"
category: "Beta Languages"
selected: false
}
ListElement {
key: 8
name: "Urdu"
shortName: "اُردُو"
category: "Beta Languages"
selected: false
}
}
} }

View File

@ -275,6 +275,11 @@ StatusWindow {
selected: viewLoader.source.toString().includes(title) selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title); onClicked: mainPageView.page(title);
} }
StatusNavigationListItem {
title: "StatusListPicker"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusListSectionHeadline { text: "StatusQ.Popup" } StatusListSectionHeadline { text: "StatusQ.Popup" }
StatusNavigationListItem { StatusNavigationListItem {
title: "StatusPopupMenu" title: "StatusPopupMenu"

View File

@ -0,0 +1,78 @@
import QtQuick 2.0
import QtQuick.Layouts 1.14
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core 0.1
import "../demoapp/data" 1.0
GridLayout {
id: root
columns: 1
rowSpacing: 150
GridLayout {
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
rows: 4
columns: 2
rowSpacing: 170
columnSpacing: 150
z: 100
StatusListPicker {
id: languagePicker
z: 100
inputList: Models.languagePickerModel
searchText: qsTr("Search Languages")
}
StatusListPicker {
id: languagePicker2
z: 100
inputList: Models.languageNoImagePickerModel
searchText: qsTr("Search Languages")
}
StatusListPicker {
id: currencyPicker
inputList: Models.currencyPickerModel
searchText: qsTr("Search Currencies")
multiSelection: true
}
StatusListPicker {
id: currencyPicker2
inputList: Models.currencyPickerModel2
searchText: qsTr("Search Currencies")
multiSelection: true
printSymbol: true
}
}
StatusBaseText {
id: pageDesc
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
height: 100
width: 500
text: "4 different configurations for the `StatusListPicker` component:\n
* Single selection. \n
* Single selection but dynamically changed to multiple selection (model provides multiple selected items).\n
* Multiple selection.\n
* Multiple selection and displayed name is the symbol + shortName\n"
color: Theme.palette.baseColor1
font.pixelSize: 15
}
// Outsite area
MouseArea {
height: root.height
width: root.width
onClicked: {
languagePicker.close()
languagePicker2.close()
currencyPicker.close()
currencyPicker2.close()
}
}
}

View File

@ -0,0 +1,324 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtGraphicalEffects 1.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
/*!
\qmltype StatusListPicker
\inherits Item
\inqmlmodule StatusQ.Components
\since StatusQ.Components 0.1
\brief It is a combination of StatusPickerButton and a drop-down list component that provides a way of presenting a list of selectable options to the user.
The \c StatusListPicker is populated with a data model. The data model is commonly a JavaScript array or a ListModel object.
StatusListPicker can be made as a single or multiple options picker by setting its StatusListPicker::multiSelection property properly or will be auto-set if the model contains / provides more than one selected items.
The StatusPickerButton text holds the text of the current item selected in the list picker. If there is more than one item selected, a string composed will be displayed.
The drop-down list incorporates a searcher by the following model roles: `name` or / and `shortName`.
NOTE: Make sure to set the appropriate z-index when instantiating the component in order to place it on top of your view in order to display the drop-down data properly.
Make sure to position the component inside its parent also when it is spanned in order to achieve a better user experience.
Example of how the component looks like:
\image status_list_picker.png
Example of how to use it:
\qml
StatusListPicker {
id: currencyPicker
inputList: Models.currencyPickerModel
searchText: qsTr("Search Language")
multiSelection: true
printSymbol: true
}
\endqml
For a list of components available see StatusQ.
*/
Item {
id: root
/*!
\qmlproperty string StatusListPicker::inputList
This property holds the data that will be populated in the list picker.
NOTE: This model property should not change so it is an in / out property where the selected role will be dynamically changed according to user actions.
Here an example of the model roles expected:
\qml
inputList: ListModel {
ListElement {
key: 0
name: "United States Dollar"
shortName: "USD"
symbol: "$"
imageSource: "../../assets/twemoji/26x26/1f4b4.png"
category: "fiat"
selected: true
}
ListElement {
key: 1
name: "British Pound"
shortName: "GBP"
symbol: "£"
imageSource: "../../assets/twemoji/26x26/1f4b5.png"
category: "fiat"
selected: false
}
}
\endqml
*/
property ListModel inputList: ListModel { }
/*!
\qmlproperty string StatusListPicker::searchText
This property holds the placeholder text the searcher input displays by default.
*/
property string searchText: qsTr("Search")
/*!
\qmlproperty string StatusListPicker::multiSelection
This property holds whether the list picker is a single or a multiple picker option by displaying a StatusRadioButton or StatusCheckBox instead.
*/
property bool multiSelection: false
/*!
\qmlproperty string StatusListPicker::printSymbol
This property holds whether the selected items will display a composition of the role `symbol` in the StatusPickerButton text or just only the role `shortName`.
*/
property bool printSymbol: false
/*!
\qmlproperty string StatusListPicker::maxPickerHeight
This property holds the maximum drop-down list height allowed. The drop-down list height will be set as the minimum value between the list content height and the maxPickerHeight property.
*/
property int maxPickerHeight: 718
/*
\qmlmethod StatusListPicker::close()
It can be used to force to close the drop-down picker list whenever the consumer needs it. For example by adding an outside MouseArea to close the picker when user clicks outsite the component:
\qml
// Outsite area
MouseArea {
height: root.height
width: root.width
onClicked: { currencyPicker.close() }
}
\endqml
*/
function close() { if(picker.visible) picker.visible = false }
QtObject {
id: d
property var filteredModel: ListModel { }
// Used to set up component and the needed private properties
function initialize() {
if(filteredModel.count === 0) {
// It is necessary to load the model, not loaded yet!
var selected = 0
var selectionText = ""
for(var i = 0; i < root.inputList.count; i++) {
var item = root.inputList.get(i)
d.filteredModel.append(item)
if(item.selected) selected++;
}
// If the given model has more than one selected elements, the behaviour of the list picker will be as a multiple selector with checkboxes although it is
// set in the radiobutton mode. Radiobutton mode is only for mutial-exclusion.
if(selected > 1)
multiSelection = true
// Update selected items text:
d.getSelectedItemsText()
}
}
// Used to update model elements given a specific text by filtering them for its `name` and / or `shortName`.
function applyFilter(text) {
const input = text.toLowerCase()
filteredModel.clear()
for(var i = 0; i < root.inputList.count; i++) {
let item = root.inputList.get(i)
if(item.name.toLowerCase().includes(input) || item.shortName.toLowerCase().includes(input))
filteredModel.append(item)
}
}
function formatSymbolShortNameText(symbol, shortName) {
var formattedText = ""
if(root.printSymbol && symbol)
formattedText = symbol + shortName
else
formattedText = shortName
return formattedText
}
function getSelectedItemsText() {
var res = ""
for(var i = 0; i < root.inputList.count; i++) {
var item = root.inputList.get(i)
if(item.selected) {
if(res != "")
res += ", "
res += d.formatSymbolShortNameText(item.symbol, item.shortName)
}
}
return res
}
// Used to update the base input list model with the new selected property
function updateInputListModel(key, selected, isSingleSelection) {
// If it is a single selection we must ensure that when a new key is selected others are cleared.
// It must be done manually because as there is the option of filterning, the model visualized changes
// and it could be possible to have a filtered list without an element selected (but in the base model
// it is) so, the binding to not selected will not be executed, as in the current filtered model
// there are no changes to update, just only the selected one.
for(var i = 0; i < root.inputList.count; i++) {
if(root.inputList.get(i).key === key) {
root.inputList.get(i).selected = selected
}
else if(isSingleSelection && selected) {
// Clear all the list
root.inputList.get(i).selected = false
}
}
}
}
width: 110
height: 38
Component.onCompleted: d.initialize()
StatusPickerButton {
id: btn
anchors.fill: parent
bgColor: Theme.palette.primaryColor3
contentColor: Theme.palette.primaryColor1
text: picker.selectedItemsText
type: StatusPickerButton.Type.Down
onClicked: {
picker.visible = !picker.visible
// Restart list position:
content.positionViewAtBeginning()
content.forceActiveFocus()
}
}
Rectangle {
id: picker
property string selectedItemsText: ""
width: content.itemWidth
height: Math.min(content.contentHeight + content.anchors.topMargin + content.anchors.bottomMargin, root.maxPickerHeight)
anchors.left: btn.left
anchors.top: btn.bottom
anchors.topMargin: 4
visible: false
color: Theme.palette.statusPopupMenu.backgroundColor
radius: 8
layer.enabled: true
layer.effect: DropShadow {
source: picker
horizontalOffset: 0
verticalOffset: 4
radius: 12
samples: 25
spread: 0.2
color: Theme.palette.dropShadow
}
ListView {
id: content
property int itemHeight: 40
property int itemWidth: 360
model: d.filteredModel
width: itemWidth
anchors.top: parent.top
anchors.topMargin: 8
anchors.bottom: parent.bottom
anchors.bottomMargin: 8
currentIndex: -1
clip: true
headerPositioning: ListView.OverlayHeader
header: Rectangle {
id: header
width: content.itemWidth
height: searchInput.height + 24
color: Theme.palette.statusPopupMenu.backgroundColor
z: 3 // Above delegate (z=1) and above section.delegate (z = 2)
StatusBaseInput {
id: searchInput
implicitHeight: 36
width: content.itemWidth - 2 * 18
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
topPadding: 8
bottomPadding: 0
placeholderText: root.searchText
icon.name: "search"
onTextChanged: { d.applyFilter(text) }
}
}// End of search input item
delegate: StatusItemPicker {
width: content.itemWidth
height: content.itemHeight
image: StatusImageSettings {
source: model.imageSource ? model.imageSource : ""
width: 15
height: 15
isIdenticon: false
}
name: model.name
shortName: model.shortName
selectorType: root.multiSelection ? StatusItemPicker.SelectorType.CheckBox : StatusItemPicker.SelectorType.RadioButton
selected: model.selected
radioGroup: radioBtnGroup
onCheckedChanged: {
d.updateInputListModel(model.key, checked, selectorType === StatusItemPicker.SelectorType.RadioButton)
if(selectorType === StatusItemPicker.SelectorType.RadioButton && checked) {
// Update selected item text
picker.selectedItemsText = d.formatSymbolShortNameText(model.symbol, model.shortName)
}
else {
// Update selected items text (multiple selection, text chain).
picker.selectedItemsText = d.getSelectedItemsText()
}
}
}
section.property: "category"
section.criteria: ViewSection.FullString
section.delegate: Item {
width: content.itemWidth
height: content.itemHeight
StatusBaseText {
anchors.leftMargin: 18
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
text: section
color: Theme.palette.baseColor1
font.pixelSize: 15
elide: Text.ElideRight
}
}// End of Category item
onActiveFocusChanged: { if(!activeFocus) root.close() }
// Not visual element to control mutual-exclusion of radiobuttons that are not sharing the same parent (inside list view)
ButtonGroup {
id: radioBtnGroup
}
}// End of Content
}// End of Rectangle picker
}

View File

@ -24,6 +24,7 @@ StatusRoundedImage 0.1 StatusRoundedImage.qml
StatusMacWindowButtons 0.1 StatusMacWindowButtons.qml StatusMacWindowButtons 0.1 StatusMacWindowButtons.qml
StatusListItemBadge 0.1 StatusListItemBadge.qml StatusListItemBadge 0.1 StatusListItemBadge.qml
StatusListItemTag 0.1 StatusListItemTag.qml StatusListItemTag 0.1 StatusListItemTag.qml
StatusListPicker 0.1 StatusListPicker.qml
StatusExpandableItem 0.1 StatusExpandableItem.qml StatusExpandableItem 0.1 StatusExpandableItem.qml
StatusSmartIdenticon 0.1 StatusSmartIdenticon.qml StatusSmartIdenticon 0.1 StatusSmartIdenticon.qml
StatusMessage 0.1 StatusMessage.qml StatusMessage 0.1 StatusMessage.qml

View File

@ -0,0 +1,183 @@
import QtQuick 2.0
import QtQuick.Controls 2.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
/*!
\qmltype StatusItemPicker
\inherits Item
\inqmlmodule StatusQ.Controls
\since StatusQ.Controls 0.1
\brief It presents a selectable item to the user.
The \c StatusItemPicker is populated with the given properties data.
StatusItemPicker can be made as a RadioButton or CheckBox selectable item.
Example of how the component looks like:
\image status_item_picker.png
Example of how to use it:
\qml
StatusItemPicker {
width: 300
height: 40
imageSource: model.imageSource
name: model.name
shortName: model.shortName
selectorType: root.multiSelection ? StatusItemPicker.SelectorType.CheckBox : StatusItemPicker.SelectorType.RadioButton
selected: model.selected
radioGroup: content.radioGroup
onCheckedChanged: { // Some updates }
}
\endqml
For a list of components available see StatusQ.
*/
Item {
id: root
/*!
\qmlproperty string StatusItemPicker::image
This property holds the image settings information.
*/
property StatusImageSettings image
/*!
\qmlproperty string StatusItemPicker::name
This property holds the main text or name to be displayed.
*/
property string name
/*!
\qmlproperty string StatusItemPicker::shortName
This property holds the secondary text or short name to be displayed.
*/
property string shortName
/*!
\qmlproperty string StatusItemPicker::selectorType
This property holds the selector type. Possible options are:
\qml
enum SelectorType {
RadioButton,
CheckBox
}
\endqml
By default, RadioButton.
*/
property int selectorType: StatusItemPicker.SelectorType.RadioButton
/*!
\qmlproperty string StatusItemPicker::selected
This property holds if the item is selected.
*/
property bool selected
/*!
\qmlproperty string StatusItemPicker::radioGroup
This property holds the button group object the radiobutton belongs to.
*/
property ButtonGroup radioGroup
/*!
\qmlsignal StatusItemPicker::checkedChanged(bool checked)
This signal is emitted when the item is selected by pressing the radiobutton or the checkbox.
*/
signal checkedChanged(bool checked)
enum SelectorType {
RadioButton,
CheckBox
}
QtObject {
id: d
property int minShortNameWidth: 50
function availableTextWidth() {
return root.width - imageItem.width - row.spacing - shortNameItem.anchors.rightMargin - selector.width - selector.anchors.rightMargin - 24/*Margin between both texts*/
}
}
Row {
id: row
anchors.left: parent.left
anchors.leftMargin: 18
anchors.verticalCenter: parent.verticalCenter
spacing: 8
StatusIcon {
id: imageItem
anchors.verticalCenter: parent.verticalCenter
source: root.image.source ? root.image.source : ""
width: root.image.width
height: root.image.height
visible: root.image.source !== undefined
}
StatusBaseText {
id: nameItem
anchors.verticalCenter: parent.verticalCenter
width: dummyNameItem.width > d.availableTextWidth() - d.minShortNameWidth ?
d.availableTextWidth() - d.minShortNameWidth :
dummyNameItem.width
text: root.name
color: Theme.palette.directColor1
font.pixelSize: 15
clip: true
elide: Text.ElideRight
}
// Dummy object just to exactly know the width needed by `name` and dynamically set a limit for nameItem and shortNameItem components
StatusBaseText {
id: dummyNameItem
visible: false
text: root.name
font.pixelSize: 15
}
}
StatusBaseText {
id: shortNameItem
width: d.availableTextWidth() - nameItem.width < d.minShortNameWidth ?
d.minShortNameWidth :
d.availableTextWidth() - nameItem.width
anchors.right: selector.left
anchors.rightMargin: 10
anchors.verticalCenter: parent.verticalCenter
text: root.shortName
color: Theme.palette.baseColor1
font.pixelSize: 15
clip: true
elide: Text.ElideRight
horizontalAlignment: Text.AlignRight
}
// 2 different options: Or with radio buttons or with checkboxes:
Loader {
id: selector
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: 18
sourceComponent: root.selectorType === StatusItemPicker.SelectorType.RadioButton ? radioBtn : checkbox
}
Component {
id: radioBtn
StatusRadioButton {
ButtonGroup.group: root.radioGroup
checked: root.selected
onCheckedChanged: root.checkedChanged(checked)
}
}
Component {
id: checkbox
StatusCheckBox {
checked: root.selected
onCheckedChanged: root.checkedChanged(checked)
}
}
}// End of Content item

View File

@ -11,7 +11,13 @@ Button {
property color bgColor: Theme.palette.baseColor2 property color bgColor: Theme.palette.baseColor2
property color contentColor: Theme.palette.baseColor1 property color contentColor: Theme.palette.baseColor1
signal clicked() property var type: StatusPickerButton.Type.Next
property int lateralMargins: 16
enum Type {
Next,
Down
}
background: Item { background: Item {
anchors.fill: parent anchors.fill: parent
@ -20,31 +26,57 @@ Button {
anchors.fill: parent anchors.fill: parent
radius: 8 radius: 8
color: root.bgColor color: root.bgColor
} }
StatusIcon {
id: nextIcon
anchors.right: parent.right
anchors.rightMargin: 8
anchors.verticalCenter: parent.verticalCenter
icon: "next"
color: !Qt.colorEqual(root.contentColor, Theme.palette.baseColor1)
? root.contentColor : Theme.palette.directColor1
}
} }
contentItem: Item { contentItem: Item {
anchors.fill: parent anchors.fill: parent
state: root.type === StatusPickerButton.Type.Next ? "NEXT" : "DOWN"
StatusBaseText { StatusBaseText {
id: textLabel id: textLabel
anchors { anchors.verticalCenter: parent.verticalCenter
fill: parent width: parent.width - icon.width - anchors.rightMargin - anchors.leftMargin - icon.anchors.rightMargin - icon.anchors.leftMargin
leftMargin: 16
}
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
font.pixelSize: 15 font.pixelSize: 15
color: root.contentColor color: root.contentColor
text: root.text text: root.text
clip: true
elide: Text.ElideRight
} }
StatusIcon {
id: icon
anchors.verticalCenter: parent.verticalCenter
color: !Qt.colorEqual(root.contentColor, Theme.palette.baseColor1) ? root.contentColor : Theme.palette.directColor1
}
states: [
State {
name: "NEXT"
PropertyChanges {target: icon; icon: "next"}
PropertyChanges {target: icon; anchors.left: undefined }
PropertyChanges {target: icon; anchors.right: parent.right }
PropertyChanges {target: icon; anchors.rightMargin: root.lateralMargins / 2 }
PropertyChanges {target: icon; anchors.leftMargin: root.lateralMargins / 2 }
PropertyChanges {target: textLabel; anchors.left: parent.left }
PropertyChanges {target: textLabel; anchors.right: undefined }
PropertyChanges {target: textLabel; anchors.rightMargin: undefined }
PropertyChanges {target: textLabel; anchors.leftMargin: root.lateralMargins }
},
State {
name: "DOWN"
PropertyChanges {target: icon; icon: "chevron-down"}
PropertyChanges {target: icon; anchors.left: parent.left }
PropertyChanges {target: icon; anchors.right: undefined }
PropertyChanges {target: icon; anchors.rightMargin: root.lateralMargins / 2 }
PropertyChanges {target: icon; anchors.leftMargin: root.lateralMargins }
PropertyChanges {target: textLabel; anchors.left: icon.right }
PropertyChanges {target: textLabel; anchors.right: undefined }
PropertyChanges {target: textLabel; anchors.rightMargin: root.lateralMargins / 2 }
PropertyChanges {target: textLabel; anchors.leftMargin: undefined }
}
]
} }
MouseArea { MouseArea {
@ -52,8 +84,6 @@ Button {
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: { root.clicked() }
root.clicked();
}
} }
} }

View File

@ -9,6 +9,7 @@ StatusChatListCategoryItemButton 0.1 StatusChatListCategoryItemButton.qml
StatusColorSelector 0.1 StatusColorSelector.qml StatusColorSelector 0.1 StatusColorSelector.qml
StatusIconTabButton 0.1 StatusIconTabButton.qml StatusIconTabButton 0.1 StatusIconTabButton.qml
StatusIdenticonRing 0.1 StatusIdenticonRing.qml StatusIdenticonRing 0.1 StatusIdenticonRing.qml
StatusItemPicker 0.1 StatusItemPicker.qml
StatusNavBarTabButton 0.1 StatusNavBarTabButton.qml StatusNavBarTabButton 0.1 StatusNavBarTabButton.qml
StatusTabBarIconButton 0.1 StatusTabBarIconButton.qml StatusTabBarIconButton 0.1 StatusTabBarIconButton.qml
StatusToolTip 0.1 StatusToolTip.qml StatusToolTip 0.1 StatusToolTip.qml

View File

@ -335,5 +335,7 @@
<file>src/assets/img/icons/OMG.png</file> <file>src/assets/img/icons/OMG.png</file>
<file>src/assets/img/icons/ETH.png</file> <file>src/assets/img/icons/ETH.png</file>
<file>src/assets/img/icons/MANA.png</file> <file>src/assets/img/icons/MANA.png</file>
<file>src/StatusQ/Components/StatusListPicker.qml</file>
<file>src/StatusQ/Controls/StatusItemPicker.qml</file>
</qresource> </qresource>
</RCC> </RCC>