feat(ProfileShowcase): Display counter in `In showcase` section header and elements limit

- Added counter in showcase header.
- Added placeholder when limit reached and section expanded.
- Added placeholder when limit reached and section collapsed.
- Added green animation when section collapsed and element added.
- Disabled showcase delegate context menu when limit reached.
- Dynamic tooltip offset center added.
- Added model changes tracker to track the in showcase count.

Closes #13507
This commit is contained in:
Noelia 2024-03-03 12:02:30 +01:00 committed by Noelia
parent 33c3fcf582
commit b92974ffff
9 changed files with 267 additions and 128 deletions

View File

@ -99,6 +99,7 @@ SplitView {
inShowcaseModel: emptyModelChecker.checked ? emptyModel : inShowcaseModelItem inShowcaseModel: emptyModelChecker.checked ? emptyModel : inShowcaseModelItem
hiddenModel: emptyModelChecker.checked ? emptyModel : hiddenModelItem hiddenModel: emptyModelChecker.checked ? emptyModel : hiddenModelItem
currentWallet: root.currentWallet currentWallet: root.currentWallet
showcaseLimit: 5
} }
LogsAndControlsPanel { LogsAndControlsPanel {

View File

@ -66,6 +66,7 @@ SplitView {
SplitView.preferredHeight: 500 SplitView.preferredHeight: 500
inShowcaseModel: inShowcaseModelItem inShowcaseModel: inShowcaseModelItem
hiddenModel: hiddenShowcaseModelItem hiddenModel: hiddenShowcaseModelItem
showcaseLimit: 8
addAccountsButtonVisible: !hasAllAccountsChecker.checked addAccountsButtonVisible: !hasAllAccountsChecker.checked

View File

@ -211,6 +211,7 @@ SplitView {
SplitView.preferredHeight: 500 SplitView.preferredHeight: 500
inShowcaseModel: emptyModelChecker.checked ? emptyModelItem : joinedInShowcase inShowcaseModel: emptyModelChecker.checked ? emptyModelItem : joinedInShowcase
hiddenModel: emptyModelChecker.checked ? emptyModelItem : joinedHiddenModel hiddenModel: emptyModelChecker.checked ? emptyModelItem : joinedHiddenModel
showcaseLimit: 8
addAccountsButtonVisible: !hasAllAccountsChecker.checked addAccountsButtonVisible: !hasAllAccountsChecker.checked

View File

@ -129,6 +129,7 @@ SplitView {
inShowcaseModel: emptyModelChecker.checked ? emptyModel : inShowcaseModelItem inShowcaseModel: emptyModelChecker.checked ? emptyModel : inShowcaseModelItem
hiddenModel: emptyModelChecker.checked ? emptyModel : hiddenModelItem hiddenModel: emptyModelChecker.checked ? emptyModel : hiddenModelItem
showcaseLimit: 5
} }
LogsAndControlsPanel { LogsAndControlsPanel {

View File

@ -70,6 +70,7 @@ SplitView {
SplitView.fillHeight: true SplitView.fillHeight: true
emptyInShowcasePlaceholderText: "No items in showcase" emptyInShowcasePlaceholderText: "No items in showcase"
emptyHiddenPlaceholderText: "No hidden items" emptyHiddenPlaceholderText: "No hidden items"
showcaseLimit: limitCounter.value
onChangePositionRequested: function (from, to) { onChangePositionRequested: function (from, to) {
inShowcaseModelItem.move(from, to, 1) inShowcaseModelItem.move(from, to, 1)
} }
@ -100,6 +101,8 @@ SplitView {
} }
delegate: ProfileShowcasePanelDelegate { delegate: ProfileShowcasePanelDelegate {
id: delegate
title: model ? model.title : "" title: model ? model.title : ""
secondaryTitle: model ? model.secondaryTitle : "" secondaryTitle: model ? model.secondaryTitle : ""
hasImage: model ? model.hasImage : false hasImage: model ? model.hasImage : false
@ -137,11 +140,13 @@ SplitView {
Slider { Slider {
id: inShowcaseCounter id: inShowcaseCounter
from: 0 from: 0
to: 200 to: limitCounter.value
stepSize: 1 stepSize: 1
value: 25 value: limitCounter.value > 0 ? limitCounter.value - 1 : 0
} }
}
ColumnLayout {
Label { Label {
text: "Hidden: " + hiddenCounter.value text: "Hidden: " + hiddenCounter.value
} }
@ -153,31 +158,43 @@ SplitView {
value: 25 value: 25
} }
} }
ColumnLayout {
Label {
text: "Showcase limit: " + limitCounter.value
}
Slider {
id: limitCounter
from: 0
to: 200
stepSize: 1
value: 5
}
}
} }
} }
onInShowcaseModelCountChanged: { onInShowcaseModelCountChanged: {
let count = inShowcaseModelCount - inShowcaseModelItem.count; let count = inShowcaseModelCount - inShowcaseModelItem.count;
let operation = count > 0 ? (i) =>{ let operation = count > 0 ? (i) =>{
inShowcaseModelItem.append({ inShowcaseModelItem.append({
showcaseKey: Math.random() * Math.random() * Math.random() * 1000, showcaseKey: Math.random() * Math.random() * Math.random() * 1000,
title: "Item " + i, title: "Item " + i,
secondaryTitle: "Description " + i, secondaryTitle: "Description " + i,
hasImage: true, hasImage: true,
image: "https://picsum.photos/200/300?random=" + i, image: "https://picsum.photos/200/300?random=" + i,
iconName: "https://picsum.photos/40/40?random=" + i, iconName: "https://picsum.photos/40/40?random=" + i,
showcaseVisibility: Math.ceil(Math.random() * 3), showcaseVisibility: Math.ceil(Math.random() * 3),
name: "Test community", name: "Test community",
joined: true, joined: true,
isControlNode: true, isControlNode: true,
color: "yellow", color: "yellow",
hasTag: Math.random() > 0.5, hasTag: Math.random() > 0.5,
tagText: "New " + 1, tagText: "New " + 1,
tagAsset: "https://picsum.photos/40/40?random=" + i, tagAsset: "https://picsum.photos/40/40?random=" + i,
tagLoading: Math.random() > 0.5 tagLoading: Math.random() > 0.5
})} : (i) => { })} : (i) => {
inShowcaseModelItem.remove(inShowcaseModelItem.count - 1); inShowcaseModelItem.remove(inShowcaseModelItem.count - 1);
} }
for (var i = 0; i < Math.abs(count); i++) { for (var i = 0; i < Math.abs(count); i++) {
operation(i) operation(i)
@ -187,26 +204,26 @@ SplitView {
onHiddenModelCountChanged: { onHiddenModelCountChanged: {
let count = hiddenModelCount - hiddenModelItem.count; let count = hiddenModelCount - hiddenModelItem.count;
let operation = count > 0 ? (i) =>{ let operation = count > 0 ? (i) =>{
hiddenModelItem.append({ hiddenModelItem.append({
showcaseKey: Math.random() * Math.random() * Math.random() * 1000, showcaseKey: Math.random() * Math.random() * Math.random() * 1000,
title: "Item " + i, title: "Item " + i,
secondaryTitle: "Description " + i, secondaryTitle: "Description " + i,
hasImage: true, hasImage: true,
image: "https://picsum.photos/200/300?random=" + i, image: "https://picsum.photos/200/300?random=" + i,
iconName: "https://picsum.photos/40/40?random=" + i, iconName: "https://picsum.photos/40/40?random=" + i,
showcaseVisibility: 0, showcaseVisibility: 0,
name: "Test community", name: "Test community",
joined: true, joined: true,
memberRole: Constants.memberRole.owner, memberRole: Constants.memberRole.owner,
isControlNode: true, isControlNode: true,
color: "yellow", color: "yellow",
hasTag: Math.random() > 0.5, hasTag: Math.random() > 0.5,
tagText: "New " + i, tagText: "New " + i,
tagAsset: "https://picsum.photos/40/40?random=" + i, tagAsset: "https://picsum.photos/40/40?random=" + i,
tagLoading: Math.random() > 0.8 tagLoading: Math.random() > 0.8
})} : (i) => { })} : (i) => {
hiddenModelItem.remove(hiddenModelItem.count - 1); hiddenModelItem.remove(hiddenModelItem.count - 1);
} }
for (var i = 0; i < Math.abs(count); i++) { for (var i = 0; i < Math.abs(count); i++) {
operation(i) operation(i)

View File

@ -13,6 +13,7 @@ import StatusQ.Core.Theme 0.1
import AppLayouts.Wallet.controls 1.0 import AppLayouts.Wallet.controls 1.0
import utils 1.0 import utils 1.0
import shared.controls 1.0
StatusDraggableListItem { StatusDraggableListItem {
id: root id: root
@ -20,6 +21,8 @@ StatusDraggableListItem {
property alias actionComponent: additionalActionsLoader.sourceComponent property alias actionComponent: additionalActionsLoader.sourceComponent
property int showcaseVisibility: Constants.ShowcaseVisibility.NoOne property int showcaseVisibility: Constants.ShowcaseVisibility.NoOne
property bool blurState: false property bool blurState: false
property bool contextMenuEnabled: true
property string tooltipTextWhenContextMenuDisabled
signal showcaseVisibilityRequested(int value) signal showcaseVisibilityRequested(int value)
@ -46,66 +49,71 @@ StatusDraggableListItem {
actions: [ actions: [
Loader { Loader {
Layout.maximumWidth: root.width *.4
id: additionalActionsLoader id: additionalActionsLoader
}
,
StatusRoundButton {
icon.name: ProfileUtils.visibilityIcon(root.showcaseVisibility)
Layout.preferredWidth: 58
Layout.preferredHeight: 28
border.width: 1
border.color: Theme.palette.directColor7
radius: 14
highlighted: menuLoader.item && menuLoader.item.opened
onClicked: {
menuLoader.active = true
menuLoader.item.popup(width - menuLoader.item.width, height)
}
ButtonGroup { Layout.maximumWidth: root.width *.4
id: showcaseVisibilityGroup },
exclusive: true DisabledTooltipButton {
onClicked: function(button) { interactive: root.contextMenuEnabled
const newVisibility = (button as ShowcaseVisibilityAction).showcaseVisibility tooltipText: root.tooltipTextWhenContextMenuDisabled
if (newVisibility !== root.showcaseVisibility) buttonComponent: StatusRoundButton {
root.showcaseVisibilityRequested(newVisibility) enabled: root.contextMenuEnabled
icon.name: ProfileUtils.visibilityIcon(root.showcaseVisibility)
width: 58
height: 30
border.width: 1
border.color: Theme.palette.directColor7
radius: 14
highlighted: menuLoader.item && menuLoader.item.opened
onClicked: {
menuLoader.active = true
menuLoader.item.popup(width - menuLoader.item.width, height)
} }
}
Loader { ButtonGroup {
id: menuLoader id: showcaseVisibilityGroup
active: false exclusive: true
sourceComponent: StatusMenu { onClicked: function(button) {
onClosed: menuLoader.active = false const newVisibility = (button as ShowcaseVisibilityAction).showcaseVisibility
StatusMenuHeadline { text: qsTr("Show to") } if (newVisibility !== root.showcaseVisibility)
root.showcaseVisibilityRequested(newVisibility)
ShowcaseVisibilityAction {
ButtonGroup.group: showcaseVisibilityGroup
showcaseVisibility: Constants.ShowcaseVisibility.Everyone
text: qsTr("Everyone")
checked: root.showcaseVisibility === showcaseVisibility
}
ShowcaseVisibilityAction {
ButtonGroup.group: showcaseVisibilityGroup
showcaseVisibility: Constants.ShowcaseVisibility.Contacts
text: qsTr("Contacts")
checked: root.showcaseVisibility === showcaseVisibility
}
ShowcaseVisibilityAction {
ButtonGroup.group: showcaseVisibilityGroup
showcaseVisibility: Constants.ShowcaseVisibility.IdVerifiedContacts
text: qsTr("ID verified contacts")
checked: root.showcaseVisibility === showcaseVisibility
} }
}
StatusMenuSeparator {} Loader {
id: menuLoader
active: false
sourceComponent: StatusMenu {
onClosed: menuLoader.active = false
StatusMenuHeadline { text: qsTr("Show to") }
ShowcaseVisibilityAction { ShowcaseVisibilityAction {
ButtonGroup.group: showcaseVisibilityGroup ButtonGroup.group: showcaseVisibilityGroup
showcaseVisibility: Constants.ShowcaseVisibility.NoOne showcaseVisibility: Constants.ShowcaseVisibility.Everyone
text: qsTr("No one") text: qsTr("Everyone")
checked: root.showcaseVisibility === showcaseVisibility checked: root.showcaseVisibility === showcaseVisibility
}
ShowcaseVisibilityAction {
ButtonGroup.group: showcaseVisibilityGroup
showcaseVisibility: Constants.ShowcaseVisibility.Contacts
text: qsTr("Contacts")
checked: root.showcaseVisibility === showcaseVisibility
}
ShowcaseVisibilityAction {
ButtonGroup.group: showcaseVisibilityGroup
showcaseVisibility: Constants.ShowcaseVisibility.IdVerifiedContacts
text: qsTr("ID verified contacts")
checked: root.showcaseVisibility === showcaseVisibility
}
StatusMenuSeparator {}
ShowcaseVisibilityAction {
ButtonGroup.group: showcaseVisibilityGroup
showcaseVisibility: Constants.ShowcaseVisibility.NoOne
text: qsTr("No one")
checked: root.showcaseVisibility === showcaseVisibility
}
} }
} }
} }

View File

@ -19,7 +19,7 @@ DoubleFlickableWithFolding {
property Component delegate: ProfileShowcasePanelDelegate {} property Component delegate: ProfileShowcasePanelDelegate {}
// Expected roles: // Expected roles:
// - visibility: int // - visibility: int
property var inShowcaseModel property var inShowcaseModel
property var hiddenModel property var hiddenModel
@ -30,8 +30,11 @@ DoubleFlickableWithFolding {
property string emptyInShowcasePlaceholderText property string emptyInShowcasePlaceholderText
property string emptyHiddenPlaceholderText property string emptyHiddenPlaceholderText
// Signal to requst position change of the visible items property int showcaseLimit: ProfileUtils.showcaseLimit
// Signal to request position change of the visible items
signal changePositionRequested(int from, int to) signal changePositionRequested(int from, int to)
// Signal to request visibility change of the items // Signal to request visibility change of the items
signal setVisibilityRequested(var key, int toVisibility) signal setVisibilityRequested(var key, int toVisibility)
@ -43,6 +46,8 @@ DoubleFlickableWithFolding {
QtObject { QtObject {
id: d id: d
readonly property bool limitReached: root.showcaseLimit === inShowcaseCounterTracker.count
readonly property var dragHiddenItemKey: ["x-status-draggable-showcase-item-hidden"] readonly property var dragHiddenItemKey: ["x-status-draggable-showcase-item-hidden"]
readonly property var dragShowcaseItemKey: ["x-status-draggable-showcase-item"] readonly property var dragShowcaseItemKey: ["x-status-draggable-showcase-item"]
@ -51,6 +56,27 @@ DoubleFlickableWithFolding {
property int additionalHeaderComponentWidth: 350 // by design property int additionalHeaderComponentWidth: 350 // by design
property int additionalHeaderComponentHeight: 40 // by design property int additionalHeaderComponentHeight: 40 // by design
property bool startAnimation: false
signal setVisibilityInternalRequested(var key, int toVisibility)
onSetVisibilityInternalRequested: {
if(toVisibility !== Constants.ShowcaseVisibility.NoOne) {
startAnimation = !startAnimation
}
root.setVisibilityRequested(key, toVisibility)
}
}
ModelChangeTracker {
id: inShowcaseCounterTracker
property int count: {
revision
return model.rowCount()
}
model: root.inShowcaseModel
} }
clip: true clip: true
@ -67,23 +93,68 @@ DoubleFlickableWithFolding {
model: root.inShowcaseModel model: root.inShowcaseModel
header: FoldableHeader { header: FoldableHeader {
readonly property bool isDropAreaVisible: root.flickable1Folded && d.isAnyHiddenDragActive
width: ListView.view.width width: ListView.view.width
title: qsTr("In showcase") title: qsTr("In showcase")
folded: root.flickable1Folded folded: root.flickable1Folded
rightAdditionalComponent: VisibilityDropAreaButtonsRow { rightAdditionalComponent: isDropAreaVisible && d.limitReached ? limitReachedHeaderButton :
width: d.additionalHeaderComponentWidth isDropAreaVisible ? dropHeaderAreaComponent : counterComponent
height: d.additionalHeaderComponentHeight
margins: 0 Component {
visible: root.flickable1Folded && id: counterComponent
(d.isAnyHiddenDragActive || StatusBaseText {
parent.containsDrag || id: counterText
everyoneContainsDrag ||
contactsContainsDrag || width: d.additionalHeaderComponentWidth
verifiedContainsDrag) height: d.additionalHeaderComponentHeight
horizontalAlignment: Text.AlignRight
text: "%1 / %2".arg(inShowcaseCounterTracker.count).arg(root.showcaseLimit)
font.pixelSize: Style.current.tertiaryTextFontSize
color: Theme.palette.baseColor1
ColorAnimation {
id: animateColor
target: counterText
properties: "color"
from: Theme.palette.successColor1
to: Theme.palette.baseColor1
duration: 2000
}
Connections {
target: d
function onStartAnimationChanged() {
animateColor.start()
}
}
}
}
Component {
id: dropHeaderAreaComponent
VisibilityDropAreaButtonsRow {
margins: 0
width: d.additionalHeaderComponentWidth
height: d.additionalHeaderComponentHeight
}
}
Component {
id: limitReachedHeaderButton
VisibilityDropAreaButton {
width: d.additionalHeaderComponentWidth
height: d.additionalHeaderComponentHeight
rightInset: 1
text: qsTr("Showcase limit of %1 reached").arg(root.showcaseLimit)
enabled: false
textColor: Theme.palette.baseColor1
iconVisible: false
}
} }
onToggleFolding: root.flip1Folding() onToggleFolding: root.flip1Folding()
} }
// Overlaid showcase listview content drop area: // Overlaid showcase listview content drop area:
DropArea { DropArea {
@ -99,13 +170,30 @@ DoubleFlickableWithFolding {
width: parent.width width: parent.width
height: ProfileUtils.defaultDelegateHeight height: ProfileUtils.defaultDelegateHeight
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
visible: d.isAnyHiddenDragActive || visible: !d.limitReached &&
parent.containsDrag || (d.isAnyHiddenDragActive ||
everyoneContainsDrag || parent.containsDrag ||
contactsContainsDrag || everyoneContainsDrag ||
verifiedContainsDrag contactsContainsDrag ||
verifiedContainsDrag)
} }
} }
// Overlaid showcase listview content when limit reached:
VisibilityDropAreaButton {
id: limitReachedButton
anchors.bottom: parent.bottom
anchors.bottomMargin: Style.current.halfPadding
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width - Style.current.padding
height: ProfileUtils.defaultDelegateHeight - Style.current.padding
visible: d.isAnyHiddenDragActive && d.limitReached
enabled: false
text: qsTr("Showcase limit of %1 reached").arg(root.showcaseLimit)
textColor: Theme.palette.baseColor1
iconVisible: false
}
} }
flickable2: EmptyShapeRectangleFooterListView { flickable2: EmptyShapeRectangleFooterListView {
@ -165,8 +253,10 @@ DoubleFlickableWithFolding {
readonly property alias containsDrag: dropArea.containsDrag readonly property alias containsDrag: dropArea.containsDrag
property bool iconVisible: true
property string textColor: icon.color
property int showcaseVisibility: Constants.ShowcaseVisibility.NoOne property int showcaseVisibility: Constants.ShowcaseVisibility.NoOne
property var dropAreaKeys property var dropAreaKeys: []
padding: Style.current.halfPadding padding: Style.current.halfPadding
spacing: padding/2 spacing: padding/2
@ -175,7 +265,7 @@ DoubleFlickableWithFolding {
background: ShapeRectangle { background: ShapeRectangle {
path.strokeColor: dropArea.containsDrag ? Theme.palette.primaryColor2 : Theme.palette.directColor7 path.strokeColor: dropArea.containsDrag ? Theme.palette.primaryColor2 : Theme.palette.directColor7
path.fillColor: dropArea.containsDrag ? Theme.palette.primaryColor3 : Theme.palette.baseColor4 path.fillColor: dropArea.containsDrag ? Theme.palette.primaryColor3 : Theme.palette.getColor(Theme.palette.baseColor4, 0.7)
DropArea { DropArea {
id: dropArea id: dropArea
@ -188,7 +278,7 @@ DoubleFlickableWithFolding {
} }
onDropped: function(drop) { onDropped: function(drop) {
root.setVisibilityRequested(drop.source.key, visibilityDropAreaButton.showcaseVisibility) d.setVisibilityInternalRequested(drop.source.key, visibilityDropAreaButton.showcaseVisibility)
} }
} }
} }
@ -200,6 +290,7 @@ DoubleFlickableWithFolding {
spacing: visibilityDropAreaButton.spacing spacing: visibilityDropAreaButton.spacing
StatusIcon { StatusIcon {
visible: visibilityDropAreaButton.iconVisible
width: 20 width: 20
height: width height: width
icon: ProfileUtils.visibilityIcon(visibilityDropAreaButton.showcaseVisibility) icon: ProfileUtils.visibilityIcon(visibilityDropAreaButton.showcaseVisibility)
@ -211,7 +302,7 @@ DoubleFlickableWithFolding {
font.pixelSize: Style.current.additionalTextSize font.pixelSize: Style.current.additionalTextSize
font.weight: Font.Medium font.weight: Font.Medium
elide: Text.ElideRight elide: Text.ElideRight
color: visibilityDropAreaButton.icon.color color: visibilityDropAreaButton.textColor
text: visibilityDropAreaButton.text text: visibilityDropAreaButton.text
} }
} }
@ -270,7 +361,7 @@ DoubleFlickableWithFolding {
Component { Component {
id: delegateWrapper id: delegateWrapper
DropArea { DropArea {
id: showcaseDelegateRoot id: showcaseDelegateRoot
required property var model required property var model
@ -290,7 +381,7 @@ DoubleFlickableWithFolding {
} }
function handleDropped(drop) { function handleDropped(drop) {
if (showcaseDelegateRoot.isHiddenShowcaseItem) { if (showcaseDelegateRoot.isHiddenShowcaseItem) {
root.setVisibilityRequested(drop.source.key, Constants.ShowcaseVisibility.NoOne) d.setVisibilityInternalRequested(drop.source.key, Constants.ShowcaseVisibility.NoOne)
} }
} }
@ -315,32 +406,49 @@ DoubleFlickableWithFolding {
property var dragParentData: root property var dragParentData: root
property int visualIndexData: showcaseDelegateRoot.index property int visualIndexData: showcaseDelegateRoot.index
property var dragKeysData: showcaseDelegateRoot.isHiddenShowcaseItem ? property var dragKeysData: showcaseDelegateRoot.isHiddenShowcaseItem ?
d.dragHiddenItemKey : d.dragShowcaseItemKey d.dragHiddenItemKey : d.dragShowcaseItemKey
width: parent.width width: parent.width
sourceComponent: root.delegate sourceComponent: root.delegate
onItemChanged: { onItemChanged: {
if (item) { if (item) {
item.showcaseVisibilityRequested.connect((toVisibility) => root.setVisibilityRequested(showcaseDelegateRoot.model.showcaseKey, toVisibility)) item.showcaseVisibilityRequested.connect((toVisibility) => d.setVisibilityInternalRequested(showcaseDelegateRoot.model.showcaseKey, toVisibility))
} }
} }
} }
Binding { Binding {
when: showcaseDelegateRoot.isHiddenShowcaseItem ? d.isAnyShowcaseDragActive : d.isAnyHiddenDragActive when: showcaseDelegateRoot.isHiddenShowcaseItem ? d.isAnyShowcaseDragActive : (d.isAnyHiddenDragActive ||
target: showcaseDraggableDelegateLoader.item (d.isAnyHiddenDragActive && d.limitReached))
property: "blurState" target: showcaseDraggableDelegateLoader.item
value: true property: "blurState"
restoreMode: Binding.RestoreBindingOrValue value: true
} restoreMode: Binding.RestoreBindingOrValue
}
Binding { Binding {
when: showcaseShadow.visible when: showcaseShadow.visible
target: d target: d
property: showcaseDelegateRoot.isHiddenShowcaseItem ? "isAnyHiddenDragActive" : "isAnyShowcaseDragActive" property: showcaseDelegateRoot.isHiddenShowcaseItem ? "isAnyHiddenDragActive" : "isAnyShowcaseDragActive"
value: true value: true
restoreMode: Binding.RestoreBindingOrValue restoreMode: Binding.RestoreBindingOrValue
} }
Binding {
when: showcaseDelegateRoot.isHiddenShowcaseItem && d.limitReached
target: showcaseDraggableDelegateLoader.item
property: "contextMenuEnabled"
value: false
restoreMode: Binding.RestoreBindingOrValue
}
Binding {
when: showcaseDelegateRoot.isHiddenShowcaseItem && d.limitReached
target: showcaseDraggableDelegateLoader.item
property: "tooltipTextWhenContextMenuDisabled"
value: qsTr("Showcase limit of %1 reached. <br>Remove item from showcase to add more.").arg(root.showcaseLimit)
restoreMode: Binding.RestoreBindingOrValue
}
// Delegate shadow background when dragging: // Delegate shadow background when dragging:
ShadowDelegate { ShadowDelegate {

View File

@ -36,6 +36,7 @@ Item {
StatusToolTip { StatusToolTip {
id: tooltip id: tooltip
visible: hoverHandler.hovered && !!text visible: hoverHandler.hovered && !!text
offset: -(tooltip.x + tooltip.width/2 - root.width/2)
} }
Component{ Component{

View File

@ -7,6 +7,7 @@ import StatusQ.Core.Theme 0.1
QtObject { QtObject {
readonly property int defaultDelegateHeight: 76 readonly property int defaultDelegateHeight: 76
readonly property int showcaseLimit: 100
function displayName(nickName, ensName, displayName, aliasName) function displayName(nickName, ensName, displayName, aliasName)
{ {