8import QtQuick.Controls as QQC2
10import QtQuick.Templates as T
11import org.kde.kirigami as Kirigami
139 property color
textColor: Kirigami.Theme.textColor
161 readonly
property bool actionsVisible: actionsLayout.hasVisibleActions
178 property list<T.Action>
actions
188 readonly
property alias
overlayWidth: overlayLoader.width
192 LayoutMirroring.childrenInherit:
true
195 implicitWidth: contentItem ? implicitContentWidth : Kirigami.Units.gridUnit * 12
196 width: parent ? parent.width : implicitWidth
197 implicitHeight: Math.max(Kirigami.Units.gridUnit * 2, implicitContentHeight) + topPadding + bottomPadding
199 padding: !listItem.alwaysVisibleActions && Kirigami.Settings.tabletMode ? Kirigami.Units.largeSpacing : Kirigami.Units.smallSpacing
201 leftPadding: padding * 2 + (mirrored ? overlayLoader.paddingOffset : 0)
202 rightPadding: padding * 2 + (mirrored ? 0 : overlayLoader.paddingOffset)
205 bottomPadding: padding
207 Keys.onTabPressed: (event) => {
208 if (actionsLayout.hasVisibleActions) {
209 actionsLayout.children[0].tabbedFromDelegate = true
210 actionsLayout.children[0].forceActiveFocus(Qt.TabFocusReason)
212 event.accepted = false
216 Keys.onPressed: (event) => {
217 if ((actionsLayout.hasVisibleActions && activeFocus && event.key ==
Qt.Key_Right &&
Qt.application.layoutDirection ==
Qt.LeftToRight) ||
218 (actionsLayout.hasVisibleActions && activeFocus && event.key ==
Qt.Key_Left &&
Qt.application.layoutDirection ==
Qt.RightToLeft)) {
219 for (var target = 0; target < actionsRep.count; target ++) {
220 if (actionsLayout.children[target].visible) {
224 if (target < actionsRep.count) {
225 actionsLayout.children[target].forceActiveFocus(
Qt.TabFocusReason)
226 event.accepted =
true
234 property Flickable view: listItem.ListView.view || (listItem.parent ? (listItem.parent.ListView.view || (listItem.parent instanceof Flickable ? listItem.parent : null)) : null)
236 function viewHasPropertySwipeFilter():
bool {
237 return view && view.parent && view.parent.parent &&
"_swipeFilter" in view.parent.parent;
240 readonly
property QtObject swipeFilterItem: (viewHasPropertySwipeFilter() && view.parent.parent._swipeFilter) ? view.parent.parent._swipeFilter : null
242 readonly property bool edgeEnabled: swipeFilterItem ? swipeFilterItem.currentItem === listItem || swipeFilterItem.currentItem === listItem.parent : false
246 if (listItem.alwaysVisibleActions || !Kirigami.Settings.tabletMode) {
249 if (viewHasPropertySwipeFilter() && Kirigami.Settings.tabletMode && !internal.view.parent.parent._swipeFilter) {
250 const component =
Qt.createComponent(
Qt.resolvedUrl(
"../private/SwipeItemEventFilter.qml"));
251 internal.view.parent.parent._swipeFilter = component.createObject(internal.view.parent.parent);
258 target: Kirigami.Settings
259 function onTabletModeChanged() {
260 if (!internal.viewHasPropertySwipeFilter()) {
263 if (Kirigami.Settings.tabletMode) {
264 if (!internal.swipeFilterItem) {
265 const component =
Qt.createComponent(
Qt.resolvedUrl(
"../private/SwipeItemEventFilter.qml"));
266 listItem.ListView.view.parent.parent._swipeFilter = component.createObject(listItem.ListView.view.parent.parent);
270 if (listItem.ListView.view.parent.parent._swipeFilter) {
271 listItem.ListView.view.parent.parent._swipeFilter.destroy();
282 readonly
property int paddingOffset: (visible ? width : 0) + Kirigami.Units.smallSpacing
283 readonly property var theAlias: anchors
284 function validate(want, defaultValue) {
285 const expectedLeftPadding = () => listItem.padding * 2 + (listItem.mirrored ? overlayLoader.paddingOffset : 0)
286 const expectedRightPadding = () => listItem.padding * 2 + (listItem.mirrored ? 0 : overlayLoader.paddingOffset)
289 `Don
't override the leftPadding or rightPadding on a SwipeListItem!\n` +
290 `This makes it impossible for me to adjust my layout as I need to for various usecases.\n` +
291 `I'll
try to fix the mistake
for you, but you should
remove your overrides from your app
's code entirely.\n` +
292 `If I can't fix the paddings, I
'll fall back to a default layout, but it'll be slightly incorrect and lacks\n` +
293 `adaptations needed
for touch screens and
right-to-
left languages, among other things.`
295 if (listItem.leftPadding != expectedLeftPadding() || listItem.rightPadding != expectedRightPadding()) {
296 listItem.leftPadding =
Qt.binding(expectedLeftPadding)
297 listItem.rightPadding =
Qt.binding(expectedRightPadding)
298 console.warn(warningText)
305 right: validate(listItem.mirrored ? undefined : (contentItem ? contentItem.right : undefined), contentItem ? contentItem.right : undefined)
306 rightMargin: validate(-paddingOffset, 0)
307 left: validate(!listItem.mirrored ? undefined : (contentItem ? contentItem.left : undefined), undefined)
308 leftMargin: validate(-paddingOffset, 0)
310 bottom: parent.bottom
312 LayoutMirroring.enabled: false
315 z: contentItem ? contentItem.z + 1 : 0
316 width: item ? item.implicitWidth : actionsLayout.implicitWidth
317 active: !listItem.alwaysVisibleActions && Kirigami.Settings.tabletMode
318 visible: listItem.actionsVisible && opacity > 0
320 sourceComponent: handleComponent
321 opacity: listItem.alwaysVisibleActions || Kirigami.Settings.tabletMode || listItem.hovered ? 1 : 0
322 Behavior on opacity {
325 duration: Kirigami.Units.veryShortDuration
326 easing.type: Easing.InOutQuad
339 implicitWidth: Kirigami.Units.iconSizes.smallMedium
341 preventStealing:
true
342 readonly
property real openPosition: (listItem.width - width - listItem.leftPadding * 2)/listItem.width
343 property real startX: 0
344 property real lastPosition: 0
345 property bool openIntention
347 onPressed: mouse => {
348 startX = mapToItem(listItem, 0, 0).x;
350 onClicked: mouse => {
351 if (Math.abs(mapToItem(listItem, 0, 0).x - startX) >
Qt.styleHints.startDragDistance) {
354 if (listItem.mirrored) {
355 if (listItem.swipe.position < 0.5) {
356 slideAnim.to = openPosition
361 if (listItem.swipe.position > -0.5) {
362 slideAnim.to = -openPosition
369 onPositionChanged: mouse => {
370 const pos = mapToItem(listItem, mouse.x, mouse.y);
372 if (listItem.mirrored) {
373 listItem.swipe.position = Math.max(0, Math.min(openPosition, (pos.x / listItem.width)));
374 openIntention = listItem.swipe.position > lastPosition;
376 listItem.swipe.position = Math.min(0, Math.max(-openPosition, (pos.x / (listItem.width -listItem.rightPadding) - 1)));
377 openIntention = listItem.swipe.position < lastPosition;
379 lastPosition = listItem.swipe.position;
381 onReleased: mouse => {
382 if (listItem.mirrored) {
384 slideAnim.to = openPosition
390 slideAnim.to = -openPosition
401 selected: listItem.checked || (listItem.down && !listItem.checked && !listItem.sectionDelegate)
402 source: (listItem.mirrored ? (listItem.background.x < listItem.background.width/2 ?
"overflow-menu-right" :
"overflow-menu-left") : (listItem.background.x < -listItem.background.width/2 ?
"overflow-menu-right" :
"overflow-menu-left"))
406 id: swipeFilterConnection
408 target: internal.edgeEnabled ? internal.swipeFilterItem : null
409 function onPeekChanged() {
410 if (!listItem.actionsVisible) {
414 if (listItem.mirrored) {
415 listItem.swipe.position = Math.max(0, Math.min(dragButton.openPosition, internal.swipeFilterItem.peek));
416 dragButton.openIntention = listItem.swipe.position > dragButton.lastPosition;
419 listItem.swipe.position = Math.min(0, Math.max(-dragButton.openPosition, -internal.swipeFilterItem.peek));
420 dragButton.openIntention = listItem.swipe.position < dragButton.lastPosition;
423 dragButton.lastPosition = listItem.swipe.position;
425 function onPressed(mouse) {
426 if (internal.edgeEnabled) {
427 dragButton.pressed(mouse);
430 function onClicked(mouse) {
431 if (Math.abs(listItem.background.x) < Kirigami.Units.gridUnit && internal.edgeEnabled) {
432 dragButton.clicked(mouse);
435 function onReleased(mouse) {
436 if (internal.edgeEnabled) {
437 dragButton.released(mouse);
440 function onCurrentItemChanged() {
441 if (!internal.edgeEnabled) {
452 id: actionsBackgroundDelegate
457 readonly
property Item contentItem: swipeBackground
462 bottom: parent.bottom
465 color: parent.pressed ?
Qt.darker(Kirigami.Theme.backgroundColor, 1.1) :
Qt.darker(Kirigami.Theme.backgroundColor, 1.05)
466 x: listItem.mirrored ? listItem.background.x - width : (listItem.background.x + listItem.background.width)
467 width: listItem.mirrored ? parent.width - (parent.width - x) : parent.width - x
470 onTapped: listItem.swipe.
close()
474 visible: background.x != 0
484 visible: background.x != 0
487 bottom: parent.bottom
492 visible: listItem.swipe.position != 0
500 LayoutMirroring.enabled: listItem.mirrored
504 bottom: parent.bottom
505 rightMargin: Kirigami.
Units.smallSpacing
507 visible: parent !== listItem
508 parent: !listItem.alwaysVisibleActions && Kirigami.Settings.tabletMode
509 ? listItem.swipe.leftItem?.contentItem || listItem.swipe.rightItem?.contentItem || listItem
512 property bool hasVisibleActions: false
513 property int indexInListView: index ?? -1
515 function updateVisibleActions(definitelyVisible: bool) {
516 hasVisibleActions = definitelyVisible || listItem.actions.some(isActionVisible);
519 function isActionVisible(action: T.Action): bool {
520 return (action instanceof Kirigami.
Action) ? action.visible : true;
525 model: listItem.actions
527 delegate: QQC2.ToolButton {
528 required
property T.Action modelData
529 required
property int index
531 property bool tabbedFromDelegate:
false
534 display: T.AbstractButton.IconOnly
535 visible: actionsLayout.isActionVisible(action)
537 onVisibleChanged: actionsLayout.updateVisibleActions(visible);
538 Component.onCompleted: actionsLayout.updateVisibleActions(visible);
539 Component.onDestruction: actionsLayout.updateVisibleActions(visible);
541 QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
542 QQC2.ToolTip.visible: (Kirigami.Settings.tabletMode ? pressed : hovered) && QQC2.ToolTip.text.length > 0
543 QQC2.ToolTip.text: (action as Kirigami.
Action)?.tooltip ?? action?.text ??
""
550 Keys.onBacktabPressed: (
event) => {
551 if (tabbedFromDelegate) {
552 listItem.forceActiveFocus(
Qt.BacktabFocusReason)
554 event.accepted =
false
558 Keys.onPressed: (
event) => {
559 if ((
Qt.application.layoutDirection ==
Qt.LeftToRight &&
event.key ==
Qt.Key_Left) ||
560 (
Qt.application.layoutDirection ==
Qt.RightToLeft &&
event.key ==
Qt.Key_Right)) {
561 for (var target = index -1; target>=0; target--) {
562 if (target == -1 || actionsLayout.children[target].visible) {
567 listItem.forceActiveFocus(
Qt.BacktabFocusReason)
569 actionsLayout.children[target].tabbedFromDelegate = tabbedFromDelegate
570 actionsLayout.children[target].forceActiveFocus(
Qt.TabFocusReason)
572 event.accepted =
true
573 }
else if ((
Qt.application.layoutDirection ==
Qt.LeftToRight &&
event.key ==
Qt.Key_Right) ||
574 (
Qt.application.layoutDirection ==
Qt.RightToLeft &&
event.key ==
Qt.Key_Left)) {
576 for (var target = index +1; target<actionsRep.count; target++) {
577 if (actionsLayout.children[target].visible) {
581 if (target < (actionsRep.count)) {
582 actionsLayout.children[target].tabbedFromDelegate = tabbedFromDelegate
583 actionsLayout.children[target].forceActiveFocus(
Qt.TabFocusReason)
584 event.accepted =
true
589 Keys.onUpPressed: (
event) => {
590 if (actionsLayout.indexInListView >= 0) {
591 listItem.ListView.view.currentIndex = actionsLayout.indexInListView
593 event.accepted =
false
596 Keys.onDownPressed: (
event) => {
597 if (actionsLayout.indexInListView >= 0) {
598 listItem.ListView.view.currentIndex = actionsLayout.indexInListView
600 event.accepted =
false
603 onActiveFocusChanged: {
605 listItem.ListView.view.positionViewAtIndex(actionsLayout.indexInListView, ListView.Contain)
607 tabbedFromDelegate =
false
611 Accessible.name: text
612 Accessible.description: (action as Kirigami.Action)?.tooltip ??
""
619 right: listItem.alwaysVisibleActions || listItem.mirrored || !Kirigami.Settings.tabletMode ? null : actionsBackgroundDelegate
620 left: listItem.alwaysVisibleActions || listItem.mirrored && Kirigami.Settings.tabletMode ? actionsBackgroundDelegate : null
624 duration: Kirigami.Units.longDuration
625 easing.type: Easing.InOutQuad
626 target: listItem.swipe
628 from: listItem.swipe.position
color textColor
This property holds the color of the text in the item.
alias supportsMouseEvents
This property sets whether the item should emit signals related to mouse interaction.
bool separatorVisible
This property sets whether the separator is visible.
color activeBackgroundColor
This property holds the color of the background when the item is pressed or selected.
bool alwaysVisibleActions
This property sets whether actions behind this SwipeListItem will always be visible.
color activeTextColor
This property holds the color of the text when the item is pressed or selected.
bool alternatingBackground
This property sets whether instances of this list item will alternate between two colors,...
color alternateBackgroundColor
This property holds the background color to be used when background alternating is enabled.
alias containsMouse
This property tells whether the cursor is currently hovering over the item.
color backgroundColor
This property holds the background color of the list item.
alias overlayWidth
This property holds the width of the overlay.
bool sectionDelegate
This property sets whether this item is a section delegate.
bool actionsVisible
This property tells whether actions are visible and interactive.
listTAction actions
This property holds actions of the list item.
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
KEDUVOCDOCUMENT_EXPORT QStringList languages()
QTextStream & left(QTextStream &stream)
QTextStream & right(QTextStream &stream)