fix(StatusBaseButton): adapt to handle actions when it is disabled
- add an `interactive` property as a drop-in replacement for `enabled`; the UI looks "disabled" but can still display e.g. a tooltip or some loading animation - add the ability to display a tooltip - remove DisabledTooltipButton and replace it with a regular `Status(Flat)Button`, using the above new features - update storybook with the new `interactive` switch Fixes #10185
This commit is contained in:
parent
ad7f39f91c
commit
d25cefcc2e
|
@ -51,10 +51,12 @@ SplitView {
|
|||
size: modelData
|
||||
text: ctrlText.text
|
||||
asset.emoji: d.effectiveEmoji
|
||||
tooltip.text: ctrlTooltip.text
|
||||
textPosition: d.effectiveTextPosition
|
||||
type: ctrlType.currentIndex
|
||||
loading: ctrlLoading.checked
|
||||
enabled: ctrlEnabled.checked
|
||||
interactive: ctrlInteractive.checked
|
||||
textFillWidth: ctrlFillWidth.checked
|
||||
}
|
||||
}
|
||||
|
@ -67,10 +69,12 @@ SplitView {
|
|||
size: modelData
|
||||
icon.name: ctrlIconName.text
|
||||
asset.emoji: d.effectiveEmoji
|
||||
tooltip.text: ctrlTooltip.text
|
||||
textPosition: d.effectiveTextPosition
|
||||
type: ctrlType.currentIndex
|
||||
loading: ctrlLoading.checked
|
||||
enabled: ctrlEnabled.checked
|
||||
interactive: ctrlInteractive.checked
|
||||
textFillWidth: ctrlFillWidth.checked
|
||||
}
|
||||
}
|
||||
|
@ -84,10 +88,12 @@ SplitView {
|
|||
text: ctrlText.text
|
||||
icon.name: ctrlIconName.text
|
||||
asset.emoji: d.effectiveEmoji
|
||||
tooltip.text: ctrlTooltip.text
|
||||
textPosition: d.effectiveTextPosition
|
||||
type: ctrlType.currentIndex
|
||||
loading: ctrlLoading.checked
|
||||
enabled: ctrlEnabled.checked
|
||||
interactive: ctrlInteractive.checked
|
||||
textFillWidth: ctrlFillWidth.checked
|
||||
}
|
||||
}
|
||||
|
@ -101,10 +107,12 @@ SplitView {
|
|||
size: modelData
|
||||
icon.name: ctrlIconName.text
|
||||
asset.emoji: d.effectiveEmoji
|
||||
tooltip.text: ctrlTooltip.text
|
||||
textPosition: d.effectiveTextPosition
|
||||
type: ctrlType.currentIndex
|
||||
loading: ctrlLoading.checked
|
||||
enabled: ctrlEnabled.checked
|
||||
interactive: ctrlInteractive.checked
|
||||
isRoundIcon: true
|
||||
radius: height/2
|
||||
textFillWidth: ctrlFillWidth.checked
|
||||
|
@ -125,10 +133,12 @@ SplitView {
|
|||
size: modelData
|
||||
text: ctrlText.text
|
||||
asset.emoji: d.effectiveEmoji
|
||||
tooltip.text: ctrlTooltip.text
|
||||
textPosition: d.effectiveTextPosition
|
||||
type: ctrlType.currentIndex
|
||||
loading: ctrlLoading.checked
|
||||
enabled: ctrlEnabled.checked
|
||||
interactive: ctrlInteractive.checked
|
||||
textFillWidth: ctrlFillWidth.checked
|
||||
}
|
||||
}
|
||||
|
@ -141,10 +151,12 @@ SplitView {
|
|||
size: modelData
|
||||
icon.name: ctrlIconName.text
|
||||
asset.emoji: d.effectiveEmoji
|
||||
tooltip.text: ctrlTooltip.text
|
||||
textPosition: d.effectiveTextPosition
|
||||
type: ctrlType.currentIndex
|
||||
loading: ctrlLoading.checked
|
||||
enabled: ctrlEnabled.checked
|
||||
interactive: ctrlInteractive.checked
|
||||
textFillWidth: ctrlFillWidth.checked
|
||||
}
|
||||
}
|
||||
|
@ -158,10 +170,12 @@ SplitView {
|
|||
text: ctrlText.text
|
||||
icon.name: ctrlIconName.text
|
||||
asset.emoji: d.effectiveEmoji
|
||||
tooltip.text: ctrlTooltip.text
|
||||
textPosition: d.effectiveTextPosition
|
||||
type: ctrlType.currentIndex
|
||||
loading: ctrlLoading.checked
|
||||
enabled: ctrlEnabled.checked
|
||||
interactive: ctrlInteractive.checked
|
||||
textFillWidth: ctrlFillWidth.checked
|
||||
}
|
||||
}
|
||||
|
@ -175,10 +189,12 @@ SplitView {
|
|||
size: modelData
|
||||
icon.name: ctrlIconName.text
|
||||
asset.emoji: d.effectiveEmoji
|
||||
tooltip.text: ctrlTooltip.text
|
||||
textPosition: d.effectiveTextPosition
|
||||
type: ctrlType.currentIndex
|
||||
loading: ctrlLoading.checked
|
||||
enabled: ctrlEnabled.checked
|
||||
interactive: ctrlInteractive.checked
|
||||
isRoundIcon: true
|
||||
radius: height/2
|
||||
textFillWidth: ctrlFillWidth.checked
|
||||
|
@ -234,6 +250,14 @@ SplitView {
|
|||
text: "enabled"
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Label { text: "Tooltip:" }
|
||||
TextField {
|
||||
id: ctrlTooltip
|
||||
placeholderText: "Tooltip"
|
||||
text: "Sample tooltip"
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Label { text: "Type:" }
|
||||
ComboBox {
|
||||
|
@ -260,6 +284,11 @@ SplitView {
|
|||
id: ctrlLoading
|
||||
text: "Loading"
|
||||
}
|
||||
Switch {
|
||||
id: ctrlInteractive
|
||||
text: "Interactive"
|
||||
checked: true
|
||||
}
|
||||
Switch {
|
||||
id: ctrlEnabled
|
||||
text: "Enabled"
|
||||
|
|
|
@ -33,7 +33,10 @@ Button {
|
|||
color: d.textColor
|
||||
}
|
||||
|
||||
property alias tooltip: tooltip
|
||||
|
||||
property bool loading
|
||||
property bool interactive: true
|
||||
|
||||
property color normalColor
|
||||
property color hoverColor
|
||||
|
@ -56,9 +59,14 @@ Button {
|
|||
QtObject {
|
||||
id: d
|
||||
|
||||
readonly property color textColor: root.hovered && (root.enabled || root.loading) ? root.textHoverColor :
|
||||
root.enabled || root.loading ? root.textColor
|
||||
: root.disabledTextColor
|
||||
readonly property color textColor: {
|
||||
if (!root.interactive || !root.enabled)
|
||||
return root.disabledTextColor
|
||||
if (root.hovered)
|
||||
return root.textHoverColor
|
||||
return root.textColor
|
||||
}
|
||||
|
||||
readonly property bool iconOnly: root.display === AbstractButton.IconOnly || root.text === ""
|
||||
readonly property int iconSize: {
|
||||
switch(root.size) {
|
||||
|
@ -119,9 +127,9 @@ Button {
|
|||
radius: root.radius
|
||||
border.color: root.borderColor
|
||||
color: {
|
||||
if (root.enabled)
|
||||
return !root.loading && (root.hovered || root.highlighted) ? hoverColor : normalColor;
|
||||
return disabledColor;
|
||||
if (!root.enabled || !root.interactive)
|
||||
return disabledColor
|
||||
return !root.loading && (root.hovered || root.highlighted) ? hoverColor : normalColor
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -151,7 +159,7 @@ Button {
|
|||
id: roundIcon
|
||||
|
||||
StatusRoundIcon {
|
||||
opacity: !root.loading && root.icon.name !== "" && root.display !== AbstractButton.TextOnly
|
||||
opacity: !root.loading && root.icon.name !== "" && root.display !== AbstractButton.TextOnly
|
||||
asset.name: root.icon.name
|
||||
asset.width: d.iconSize
|
||||
asset.height: d.iconSize
|
||||
|
@ -216,14 +224,21 @@ Button {
|
|||
}
|
||||
}
|
||||
|
||||
// stop the mouse clicks in the "loading" state w/o disabling the whole button
|
||||
// stop the mouse clicks in the "loading" or non-interactive state w/o disabling the whole button
|
||||
// as this would make it impossible to have hover events or a tooltip
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.AllButtons
|
||||
enabled: root.loading
|
||||
enabled: root.loading || !root.interactive
|
||||
onPressed: mouse.accepted = true
|
||||
onWheel: wheel.accepted = true
|
||||
cursorShape: !root.loading ? Qt.PointingHandCursor: undefined // always works; 'undefined' resets to default cursor
|
||||
cursorShape: root.interactive && !root.loading ? Qt.PointingHandCursor: undefined // always works; 'undefined' resets to default cursor
|
||||
}
|
||||
|
||||
StatusToolTip {
|
||||
id: tooltip
|
||||
visible: tooltip.text !== "" && root.hovered
|
||||
offset: -(tooltip.x + tooltip.width/2 - root.width/2)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,6 @@ StatusBaseButton {
|
|||
|
||||
disabledTextColor: Theme.palette.baseColor1
|
||||
|
||||
borderColor: (type === StatusBaseButton.Type.Normal || hovered) && !loading ? "transparent"
|
||||
: Theme.palette.baseColor2
|
||||
borderColor: (type === StatusBaseButton.Type.Normal || hovered) && !loading && interactive ? "transparent"
|
||||
: Theme.palette.baseColor2
|
||||
}
|
||||
|
|
|
@ -139,16 +139,12 @@ StackView {
|
|||
title: qsTr("Tokens")
|
||||
|
||||
buttons: [
|
||||
DisabledTooltipButton {
|
||||
readonly property bool buttonEnabled: root.isPrivilegedTokenOwnerProfile && root.arePrivilegedTokensDeployed
|
||||
|
||||
buttonType: DisabledTooltipButton.Normal
|
||||
aliasedObjectName: "addNewItemButton"
|
||||
StatusButton {
|
||||
objectName: "addNewItemButton"
|
||||
text: qsTr("Mint token")
|
||||
enabled: root.isAdminOnly || buttonEnabled
|
||||
interactive: buttonEnabled
|
||||
interactive: root.isPrivilegedTokenOwnerProfile && root.arePrivilegedTokensDeployed
|
||||
onClicked: root.push(newTokenViewComponent, StackView.Immediate)
|
||||
tooltipText: qsTr("In order to mint, you must hodl the TokenMaster token for %1").arg(root.communityName)
|
||||
tooltip.text: root.isAdminOnly ? qsTr("In order to mint, you must hodl the TokenMaster token for %1").arg(root.communityName) : ""
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
@ -282,16 +282,15 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
DisabledTooltipButton {
|
||||
StatusButton {
|
||||
id: startBtn
|
||||
interactive: startButtonEnabled
|
||||
buttonType: DisabledTooltipButton.Normal
|
||||
aliasedObjectName: "ensStartButton"
|
||||
objectName: "ensStartButton"
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: Style.current.padding
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: qsTr("Start")
|
||||
tooltipText: root.tooltipText
|
||||
tooltip.text: root.tooltipText
|
||||
onClicked: startBtnClicked()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,8 +65,7 @@ SettingsContentBase {
|
|||
priv.hasAnyProfileShowcaseChanges
|
||||
saveChangesButtonEnabled: !!descriptionPanel.displayName.text && descriptionPanel.displayName.valid
|
||||
|
||||
toast.saveChangesTooltipVisible: root.dirty
|
||||
toast.saveChangesTooltipText: qsTr("Invalid changes made to Identity")
|
||||
toast.saveChangesTooltipText: saveChangesButtonEnabled ? "" : qsTr("Invalid changes made to Identity")
|
||||
autoscrollWhenDirty: profileTabBar.currentIndex === MyProfileView.Identity
|
||||
|
||||
onResetChangesClicked: priv.reset()
|
||||
|
|
|
@ -38,14 +38,13 @@ Rectangle {
|
|||
height: parent.height
|
||||
spacing: Style.current.padding
|
||||
|
||||
DisabledTooltipButton {
|
||||
buttonType: DisabledTooltipButton.Flat
|
||||
aliasedObjectName: "walletFooterSendButton"
|
||||
icon: "send"
|
||||
StatusFlatButton {
|
||||
objectName: "walletFooterSendButton"
|
||||
icon.name: "send"
|
||||
text: root.isCommunityOwnershipTransfer ? qsTr("Send Owner token to transfer %1 Community ownership").arg(root.communityName) : qsTr("Send")
|
||||
interactive: networkConnectionStore.sendBuyBridgeEnabled
|
||||
onClicked: root.launchSendModal()
|
||||
tooltipText: networkConnectionStore.sendBuyBridgeToolTipText
|
||||
tooltip.text: networkConnectionStore.sendBuyBridgeToolTipText
|
||||
visible: !walletStore.overview.isWatchOnlyAccount && walletStore.overview.canSend
|
||||
}
|
||||
|
||||
|
@ -57,13 +56,12 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
DisabledTooltipButton {
|
||||
icon: "bridge"
|
||||
buttonType: DisabledTooltipButton.Flat
|
||||
StatusFlatButton {
|
||||
icon.name: "bridge"
|
||||
text: qsTr("Bridge")
|
||||
interactive: networkConnectionStore.sendBuyBridgeEnabled
|
||||
onClicked: root.launchBridgeModal()
|
||||
tooltipText: networkConnectionStore.sendBuyBridgeToolTipText
|
||||
tooltip.text: networkConnectionStore.sendBuyBridgeToolTipText
|
||||
visible: !walletStore.overview.isWatchOnlyAccount && !root.isCommunityOwnershipTransfer && walletStore.overview.canSend
|
||||
}
|
||||
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
import QtQuick 2.15
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property string aliasedObjectName
|
||||
property string text
|
||||
property string icon
|
||||
property alias tooltipText: tooltip.text
|
||||
property int buttonType: DisabledTooltipButton.Normal
|
||||
property bool interactive: true
|
||||
property Component buttonComponent: buttonType === DisabledTooltipButton.Normal ? normalButton : flatButton
|
||||
|
||||
signal clicked()
|
||||
|
||||
enum Type {
|
||||
Normal, // 0
|
||||
Flat // 1
|
||||
}
|
||||
|
||||
implicitWidth: !!buttonLoader.item ? buttonLoader.item.width : 0
|
||||
implicitHeight: !!buttonLoader.item ? buttonLoader.item.height : 0
|
||||
|
||||
Loader {
|
||||
id: buttonLoader
|
||||
anchors.centerIn: parent
|
||||
sourceComponent: buttonComponent
|
||||
active: root.visible
|
||||
}
|
||||
HoverHandler {
|
||||
id: hoverHandler
|
||||
enabled: !root.interactive
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
StatusToolTip {
|
||||
id: tooltip
|
||||
visible: hoverHandler.hovered && !!text
|
||||
offset: -(tooltip.x + tooltip.width/2 - root.width/2)
|
||||
}
|
||||
|
||||
Component{
|
||||
id: flatButton
|
||||
StatusFlatButton {
|
||||
objectName: root.aliasedObjectName
|
||||
icon.name: root.icon
|
||||
text: root.text
|
||||
enabled: root.interactive
|
||||
onClicked: root.clicked()
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id: normalButton
|
||||
StatusButton {
|
||||
objectName: root.aliasedObjectName
|
||||
icon.name: root.icon
|
||||
text: root.text
|
||||
enabled: root.interactive
|
||||
onClicked: root.clicked()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,7 +9,6 @@ CopyButton 1.0 CopyButton.qml
|
|||
CopyButtonWithCircle 1.0 CopyButtonWithCircle.qml
|
||||
CopyToClipBoardButton 1.0 CopyToClipBoardButton.qml
|
||||
CurrencyAmountInput 1.0 CurrencyAmountInput.qml
|
||||
DisabledTooltipButton 1.0 DisabledTooltipButton.qml
|
||||
EmojiHash 1.0 EmojiHash.qml
|
||||
EmptyShapeRectangleFooterListView 1.0 EmptyShapeRectangleFooterListView.qml
|
||||
ErrorDetails 1.0 ErrorDetails.qml
|
||||
|
|
|
@ -18,8 +18,7 @@ Rectangle {
|
|||
property bool saveChangesButtonEnabled: false
|
||||
property bool saveForLaterButtonVisible
|
||||
property alias saveChangesText: saveChangesButton.text
|
||||
property alias saveChangesTooltipText: saveChangesButton.tooltipText
|
||||
property alias saveChangesTooltipVisible: saveChangesButton.enabled
|
||||
property string saveChangesTooltipText
|
||||
property alias saveForLaterText: saveForLaterButton.text
|
||||
property alias cancelChangesText: cancelChangesButton.text
|
||||
property alias changesDetectedText: changesDetectedTextItem.text
|
||||
|
@ -148,13 +147,12 @@ Rectangle {
|
|||
onClicked: root.saveForLaterClicked()
|
||||
}
|
||||
|
||||
DisabledTooltipButton {
|
||||
StatusButton {
|
||||
id: saveChangesButton
|
||||
objectName: "settingsDirtyToastMessageSaveButton"
|
||||
buttonType: DisabledTooltipButton.Normal
|
||||
text: root.defaultSaveChangesText
|
||||
enabled: root.active && root.saveChangesButtonEnabled
|
||||
interactive: root.active && root.saveChangesButtonEnabled
|
||||
tooltip.text: root.saveChangesTooltipText
|
||||
onClicked: root.saveChangesClicked()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,7 +123,8 @@ Pane {
|
|||
objectName: "editProfileButton"
|
||||
size: StatusButton.Size.Small
|
||||
text: qsTr("Edit Profile")
|
||||
enabled: !root.readOnly
|
||||
interactive: !root.readOnly
|
||||
tooltip.text: interactive ? "" : qsTr("Not available in preview mode")
|
||||
onClicked: {
|
||||
Global.changeAppSectionBySectionType(Constants.appSection.profile)
|
||||
root.closeRequested()
|
||||
|
@ -319,15 +320,6 @@ Pane {
|
|||
Loader {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
Layout.preferredHeight: menuButton.visible ? menuButton.height : -1
|
||||
HoverHandler {
|
||||
id: actionButtonHoverHandler
|
||||
enabled: root.readOnly
|
||||
}
|
||||
|
||||
StatusToolTip {
|
||||
text: qsTr("Not available in preview mode")
|
||||
visible: actionButtonHoverHandler.hovered
|
||||
}
|
||||
|
||||
sourceComponent: {
|
||||
// current user
|
||||
|
|
Loading…
Reference in New Issue