4pragma ComponentBehavior: Bound
7import "../core/UiMetrics.js" as UiMetrics
8import "../internal/MotionAnimation.js" as MotionAnimation
11import QtQuick.Templates as T
46 objectName: "richToolTip"
48 MD.Style.theme: control.parent ? control.parent.MD.Style.theme : MD.Style.System
51 property string headline:
""
54 property alias body: control.text
63 property list<MD.Action> actions
66 readonly
property int _displayedActionCount: Math.min(actions.length, 2)
68 readonly
property bool _hasStructuredContent: headline.length > 0
69 || _displayedActionCount > 0
71 readonly
property real _anchorWindowY: parent
72 ? parent.mapToItem(null, 0, 0).y + parent.y * 0 : 0
74 readonly
property bool _opensBelow: parent
75 ? _anchorWindowY - height
76 - MD.Tokens.toolTip.anchorSpacing
77 < MD.Tokens.toolTip.viewportMargin :
false
79 readonly
property bool _layoutMirrored: mirrored
80 || locale.textDirection === Qt.RightToLeft
81 || (parent && parent.LayoutMirroring.enabled)
83 readonly property real _actionNaturalWidth: (_displayedActionCount > 0
84 ? firstActionButton.implicitWidth : 0)
85 + (_displayedActionCount > 1
86 ? secondActionButton.implicitWidth : 0)
88 readonly property real _naturalContentWidth: Math.max(headlineLabel.implicitWidth,
89 bodyLabel.implicitWidth,
92 property Item _previousFocusItem: null
94 function _rememberFocus() {
95 const anchorWindow = control.parent ? control.parent.Window.window : null;
96 control._previousFocusItem = anchorWindow ? anchorWindow.activeFocusItem : null;
99 function _focusFirstAction() {
100 if (firstActionButton.visible && firstActionButton.enabled) {
101 firstActionButton.forceActiveFocus(Qt.PopupFocusReason);
102 }
else if (secondActionButton.visible && secondActionButton.enabled) {
103 secondActionButton.forceActiveFocus(Qt.PopupFocusReason);
107 function _restoreFocus() {
108 if (control._previousFocusItem)
109 control._previousFocusItem.forceActiveFocus(Qt.PopupFocusReason);
110 control._previousFocusItem = null;
114 if (actions.length > 2)
115 console.warn(
"RichToolTip supports at most two actions; additional actions are ignored");
117 onAboutToShow: control._rememberFocus()
118 onOpened: Qt.callLater(control._focusFirstAction)
119 onClosed: control._restoreFocus()
121 x: parent ? (_layoutMirrored ? parent.width - width : 0) : 0
122 y: parent ? (_opensBelow
123 ? parent.height + MD.
Tokens.toolTip.anchorSpacing
124 : -height - MD.
Tokens.toolTip.anchorSpacing) : 0
126 implicitWidth: Math.max(MD.
Tokens.toolTip.minimumWidth,
127 Math.min(MD.
Tokens.toolTip.richMaximumWidth,
128 _naturalContentWidth + leftPadding + rightPadding))
129 implicitHeight: Math.max(MD.
Tokens.toolTip.minimumHeight, implicitContentHeight)
131 margins: MD.
Tokens.toolTip.viewportMargin
132 leftPadding: MD.
Tokens.toolTip.richHorizontalPadding
133 rightPadding: MD.
Tokens.toolTip.richHorizontalPadding
136 focus: _displayedActionCount > 0
137 closePolicy: T.Popup.CloseOnEscape | T.Popup.CloseOnPressOutside
140 return _layoutMirrored ? Item.TopRight : Item.TopLeft;
141 return _layoutMirrored ? Item.BottomRight : Item.BottomLeft;
144 contentItem: Column {
146 objectName:
"richToolTipContent"
147 width: control.availableWidth
148 Accessible.role: Accessible.ToolTip
149 Accessible.name: control.headline.length > 0 ? control.headline : control.text
150 Accessible.description: control.headline.length > 0 ? control.text :
""
154 objectName:
"richToolTipHeadlineSlot"
156 height: control.headline.length > 0
157 ? MD.
Tokens.toolTip.richHeadlineFirstBaseline
158 + Math.max(0, headlineLabel.implicitHeight
159 - headlineLabel.baselineOffset) : 0
160 visible: control.headline.length > 0
164 objectName:
"richToolTipHeadline"
165 y: MD.Tokens.toolTip.richHeadlineFirstBaseline - baselineOffset
167 text: control.headline
168 typescale: MD.Tokens.typescale.titleSmall
169 color: control.MD.Style.onSurfaceVariantColor
170 horizontalAlignment: control._layoutMirrored ? Text.AlignRight : Text.AlignLeft
172 elide: Text.ElideNone
173 Accessible.ignored:
true
179 objectName:
"richToolTipBodySlot"
181 readonly
property real labelY: control._hasStructuredContent
182 ? MD.Tokens.toolTip.richBodyFirstBaseline
183 - bodyLabel.baselineOffset
184 : MD.Tokens.toolTip.plainVerticalPadding
185 height: labelY + bodyLabel.implicitHeight
186 + (control._hasStructuredContent
187 ? MD.Tokens.toolTip.richBodyBottomPadding
188 : MD.Tokens.toolTip.plainVerticalPadding)
192 objectName:
"richToolTipBody"
196 typescale: MD.
Tokens.typescale.bodyMedium
197 color: control.MD.Style.onSurfaceVariantColor
198 horizontalAlignment: control._layoutMirrored ? Text.AlignRight : Text.AlignLeft
200 elide: Text.ElideNone
201 Accessible.ignored: true
207 objectName:
"richToolTipActionSlot"
209 readonly property bool actionsWrap: control._displayedActionCount > 1
210 && control._actionNaturalWidth > width
211 readonly property real actionContentHeight: actionsWrap
212 ? firstActionButton.implicitHeight
213 + secondActionButton.implicitHeight
214 : Math.max(firstActionButton.implicitHeight,
215 secondActionButton.implicitHeight)
216 height: control._displayedActionCount > 0
217 ? Math.max(MD.
Tokens.toolTip.richActionMinimumHeight, actionContentHeight)
218 + MD.
Tokens.toolTip.richActionBottomPadding : 0
219 visible: control._displayedActionCount > 0
223 objectName:
"richToolTipActionFlow"
225 height: actionSlot.height - MD.
Tokens.toolTip.richActionBottomPadding
227 layoutDirection: control._layoutMirrored ? Qt.RightToLeft : Qt.LeftToRight
230 id: firstActionButton
231 objectName:
"richToolTipAction0"
232 width: Math.min(implicitWidth, actionFlow.width)
233 action: control.actions.length > 0 ? control.actions[0] : null
235 size: MD.
Button.ExtraSmall
236 display: MD.
Button.TextOnly
237 typescale: MD.
Tokens.typescale.labelLarge
238 visible: control._displayedActionCount > 0
239 KeyNavigation.tab: secondActionButton.visible ? secondActionButton : firstActionButton
240 KeyNavigation.backtab: secondActionButton.visible ? secondActionButton : firstActionButton
241 Accessible.role: Accessible.
Button
242 Accessible.name: action ? action.text : text
244 onClicked: control.close()
248 id: secondActionButton
249 objectName:
"richToolTipAction1"
250 width: Math.min(implicitWidth, actionFlow.width)
251 action: control.actions.length > 1 ? control.actions[1] : null
253 size: MD.
Button.ExtraSmall
254 display: MD.
Button.TextOnly
255 typescale: MD.
Tokens.typescale.labelLarge
256 visible: control._displayedActionCount > 1
257 KeyNavigation.tab: firstActionButton
258 KeyNavigation.backtab: firstActionButton.visible ? firstActionButton : null
259 Accessible.role: Accessible.
Button
260 Accessible.name: action ? action.text : text
262 onClicked: control.close()
269 objectName:
"richToolTipBackground"
270 readonly property var containerShape: MD.
Tokens.toolTip.richContainerShape
272 implicitWidth: MD.
Tokens.toolTip.minimumWidth
273 implicitHeight: MD.
Tokens.toolTip.minimumHeight
274 color: control.MD.Style.surfaceContainerColor
275 topLeftRadius: UiMetrics.resolveShapeRadius(containerShape.topLeft, width, height)
276 topRightRadius: UiMetrics.resolveShapeRadius(containerShape.topRight, width, height)
277 bottomLeftRadius: UiMetrics.resolveShapeRadius(containerShape.bottomLeft, width, height)
278 bottomRightRadius: UiMetrics.resolveShapeRadius(containerShape.bottomRight, width, height)
279 elevation: MD.
Tokens.toolTip.richContainerElevation
285 from: MD.
Tokens.toolTip.closedScale
287 duration: MotionAnimation.expressiveFastSpatialDuration
288 easing.type: Easing.BezierSpline
289 easing.bezierCurve: MotionAnimation.expressiveFastSpatialCurve
295 duration: MotionAnimation.expressiveFastEffectsDuration
296 easing.type: Easing.BezierSpline
297 easing.bezierCurve: MotionAnimation.expressiveFastEffectsCurve
305 to: MD.
Tokens.toolTip.closedScale
306 duration: MotionAnimation.expressiveFastSpatialDuration
307 easing.type: Easing.BezierSpline
308 easing.bezierCurve: MotionAnimation.expressiveFastSpatialCurve
314 duration: MotionAnimation.expressiveFastEffectsDuration
315 easing.type: Easing.BezierSpline
316 easing.bezierCurve: MotionAnimation.expressiveFastEffectsCurve
A rectangle that casts a Material 3 elevation shadow.
Material Design 3 design tokens.
Tokens(QObject *parent=nullptr)