Kirigami2

controls/templates/InlineMessage.qml
1 /*
2  * SPDX-FileCopyrightText: 2018 Eike Hein <[email protected]>
3  * SPDX-FileCopyrightText: 2022 ivan tkachenko <[email protected]>
4  *
5  * SPDX-License-Identifier: LGPL-2.0-or-later
6  */
7 
8 import QtQuick 2.7
9 import QtQuick.Layouts 1.0
10 import QtQuick.Controls 2.0 as QQC2
11 import QtQuick.Templates 2.0 as T2
12 import org.kde.kirigami 2.20 as Kirigami
13 import "private"
14 
15 /**
16  * An inline message item with support for informational, positive,
17  * warning and error types, and with support for associated actions.
18  *
19  * InlineMessage can be used to give information to the user or
20  * interact with the user, without requiring the use of a dialog.
21  *
22  * The InlineMessage item is hidden by default. It also manages its
23  * height (and implicitHeight) during an animated reveal when shown.
24  * You should avoid setting height on an InlineMessage unless it is
25  * already visible.
26  *
27  * Optionally an icon can be set, defaulting to an icon appropriate
28  * to the message type otherwise.
29  *
30  * Optionally a close button can be shown.
31  *
32  * Actions are added from left to right. If more actions are set than
33  * can fit, an overflow menu is provided.
34  *
35  * Example:
36  * @code
37  * InlineMessage {
38  * type: Kirigami.MessageType.Error
39  *
40  * text: "My error message"
41  *
42  * actions: [
43  * Kirigami.Action {
44  * icon.name: "edit"
45  * text: "Action text"
46  * onTriggered: {
47  * // do stuff
48  * }
49  * },
50  * Kirigami.Action {
51  * icon.name: "edit"
52  * text: "Action text"
53  * onTriggered: {
54  * // do stuff
55  * }
56  * }
57  * ]
58  * }
59  * @endcode
60  *
61  * @since 5.45
62  * @inherit QtQuick.QQC2.Control
63  */
64 T2.Control {
65  id: root
66 
67  visible: false
68 
69  /**
70  * This signal is emitted when a link is hovered in the message text.
71  * @param The hovered link.
72  */
73  signal linkHovered(string link)
74 
75  /**
76  * This signal is emitted when a link is clicked or tapped in the message text.
77  * @param The clicked or tapped link.
78  */
79  signal linkActivated(string link)
80 
81  /**
82  * This property holds the link embedded in the message text that the user is hovering over.
83  */
84  readonly property string hoveredLink: label.hoveredLink
85 
86  /**
87  * This property holds the message type. One of Information, Positive, Warning or Error.
88  *
89  * The default is Kirigami.MessageType.Information.
90  */
91  property int type: Kirigami.MessageType.Information
92 
93  /**
94  * This grouped property holds the description of an optional icon.
95  *
96  * * source: The source of the icon, a freedesktop-compatible icon name is recommended.
97  * * color: An optional tint color for the icon.
98  *
99  * If no custom icon is set, an icon appropriate to the message type
100  * is shown.
101  */
102  property IconPropertiesGroup icon: IconPropertiesGroup {}
103 
104  /**
105  * This property holds the message text.
106  */
107  property string text
108 
109  /**
110  * This property holds whether the close button is displayed.
111  *
112  * The default is false.
113  */
114  property bool showCloseButton: false
115 
116  /**
117  * This property holds the list of actions to show. Actions are added from left to
118  * right. If more actions are set than can fit, an overflow menu is
119  * provided.
120  */
121  property list<QtObject> actions
122 
123  /**
124  * This property holds whether the current message item is animating.
125  */
126  readonly property bool animating: _animating
127 
128  property bool _animating: false
129 
130  implicitHeight: visible ? (contentLayout.implicitHeight + topPadding + bottomPadding) : 0
131 
132  padding: Kirigami.Units.smallSpacing
133  // base style (such as qqc2-desktop-style) may define unique paddings for Control, reset it to uniform
134  topPadding: undefined
135  leftPadding: undefined
136  rightPadding: undefined
137  bottomPadding: undefined
138 
139  Behavior on implicitHeight {
140  enabled: !root.visible
141 
142  SequentialAnimation {
143  PropertyAction { targets: root; property: "_animating"; value: true }
144  NumberAnimation { duration: Kirigami.Units.longDuration }
145  }
146  }
147 
148  onVisibleChanged: {
149  if (!visible) {
150  contentLayout.opacity = 0;
151  }
152  }
153 
154  opacity: visible ? 1 : 0
155 
156  Behavior on opacity {
157  enabled: !root.visible
158 
159  NumberAnimation { duration: Kirigami.Units.shortDuration }
160  }
161 
162  onOpacityChanged: {
163  if (opacity === 0) {
164  contentLayout.opacity = 0;
165  } else if (opacity === 1) {
166  contentLayout.opacity = 1;
167  }
168  }
169 
170  onImplicitHeightChanged: {
171  height = implicitHeight;
172  }
173 
174  contentItem: Item {
175  id: contentLayout
176 
177  // Used to defer opacity animation until we know if InlineMessage was
178  // initialized visible.
179  property bool complete: false
180 
181  Behavior on opacity {
182  enabled: root.visible && contentLayout.complete
183 
184  SequentialAnimation {
185  NumberAnimation { duration: Kirigami.Units.shortDuration * 2 }
186  PropertyAction { targets: root; property: "_animating"; value: false }
187  }
188  }
189 
190  implicitHeight: {
191  if (actionsLayout.atBottom) {
192  return label.implicitHeight + actionsLayout.height + Kirigami.Units.gridUnit
193  } else {
194  return Math.max(icon.implicitHeight, label.implicitHeight, closeButton.implicitHeight, actionsLayout.height)
195  }
196  }
197 
198  readonly property real remainingWidth: width - (
199  icon.width
200  + labelArea.anchors.leftMargin + label.implicitWidth + labelArea.anchors.rightMargin
201  + (root.showCloseButton ? closeButton.width : 0)
202  )
203  readonly property bool multiline: remainingWidth <= 0 || actionsLayout.atBottom
204 
205  Kirigami.Icon {
206  id: icon
207 
208  width: Kirigami.Units.iconSizes.smallMedium
209  height: Kirigami.Units.iconSizes.smallMedium
210 
211  anchors {
212  left: parent.left
213  top: actionsLayout.atBottom ? parent.top : undefined
214  verticalCenter: actionsLayout.atBottom ? undefined : parent.verticalCenter
215  }
216 
217  source: {
218  if (root.icon.name) {
219  return root.icon.name;
220  } else if (root.icon.source) {
221  return root.icon.source;
222  }
223 
224  if (root.type === Kirigami.MessageType.Positive) {
225  return "dialog-positive";
226  } else if (root.type === Kirigami.MessageType.Warning) {
227  return "dialog-warning";
228  } else if (root.type === Kirigami.MessageType.Error) {
229  return "dialog-error";
230  }
231 
232  return "dialog-information";
233  }
234 
235  color: root.icon.color
236  }
237 
238  MouseArea {
239  id: labelArea
240 
241  anchors {
242  left: icon.right
243  leftMargin: Kirigami.Units.smallSpacing
244  right: root.showCloseButton ? closeButton.left : parent.right
245  rightMargin: root.showCloseButton ? Kirigami.Units.smallSpacing : 0
246  top: parent.top
247  bottom: contentLayout.multiline ? undefined : parent.bottom
248  }
249 
250  acceptedButtons: Qt.NoButton
251  cursorShape: label.hoveredLink.length > 0 ? Qt.PointingHandCursor : undefined
252  propagateComposedEvents: true
253 
254  implicitWidth: label.implicitWidth
255  height: contentLayout.multiline ? label.implicitHeight : implicitHeight
256 
257  Kirigami.SelectableLabel {
258  id: label
259 
260  width: parent.width
261  height: parent.height
262 
263  color: Kirigami.Theme.textColor
264  wrapMode: Text.WordWrap
265 
266  text: root.text
267 
268  verticalAlignment: Text.AlignVCenter
269 
270  onLinkHovered: link => root.linkHovered(link)
271  onLinkActivated: link => root.linkActivated(link)
272  }
273  }
274 
275  Kirigami.ActionToolBar {
276  id: actionsLayout
277 
278  flat: false
279  actions: root.actions
280  visible: root.actions.length > 0
281  alignment: Qt.AlignRight
282 
283  readonly property bool atBottom: (root.actions.length > 0) && (label.lineCount > 1 || implicitWidth > contentLayout.remainingWidth)
284 
285  anchors {
286  left: parent.left
287  top: atBottom ? labelArea.bottom : parent.top
288  topMargin: atBottom ? Kirigami.Units.gridUnit : 0
289  right: (!atBottom && root.showCloseButton) ? closeButton.left : parent.right
290  rightMargin: !atBottom && root.showCloseButton ? Kirigami.Units.smallSpacing : 0
291  }
292  }
293 
294  QQC2.ToolButton {
295  id: closeButton
296 
297  visible: root.showCloseButton
298 
299  anchors {
300  right: parent.right
301  top: actionsLayout.atBottom ? parent.top : undefined
302  verticalCenter: actionsLayout.atBottom ? undefined : parent.verticalCenter
303  }
304 
305  height: actionsLayout.atBottom ? implicitHeight : implicitHeight
306 
307  icon.name: "dialog-close"
308 
309  onClicked: root.visible = false
310  }
311 
312  Component.onCompleted: complete = true
313  }
314 }
QTextStream & right(QTextStream &stream)
QTextStream & left(QTextStream &stream)
KIOCORE_EXPORT CopyJob * link(const QList< QUrl > &src, const QUrl &destDir, JobFlags flags=DefaultFlags)
int length() const const
QTextStream & left(QTextStream &s)
QString label(StandardShortcut id)
QTextStream & right(QTextStream &s)
Class for rendering an icon in UI.
Definition: icon.h:26
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sun Jan 29 2023 04:11:03 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.