File indexing completed on 2024-12-29 05:06:05
0001 // SPDX-FileCopyrightText: 2019 Marco Martin <mart@kde.org> 0002 // SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org> 0003 // SPDX-License-Identifier: LGPL-2.0-or-later 0004 0005 #include "widgetcontainer.h" 0006 0007 #include <QCursor> 0008 #include <QGuiApplication> 0009 #include <QStyleHints> 0010 0011 WidgetContainer::WidgetContainer(QQuickItem *parent) 0012 : QQuickItem(parent) 0013 , m_pressAndHoldTimer{new QTimer{this}} 0014 { 0015 m_pressAndHoldTimer->setInterval(QGuiApplication::styleHints()->mousePressAndHoldInterval()); 0016 m_pressAndHoldTimer->setSingleShot(true); 0017 connect(m_pressAndHoldTimer, &QTimer::timeout, this, &WidgetContainer::startPressAndHold); 0018 0019 setFiltersChildMouseEvents(true); 0020 setFlags(QQuickItem::ItemIsFocusScope); 0021 setActiveFocusOnTab(true); 0022 setAcceptedMouseButtons(Qt::LeftButton); 0023 0024 connect(this, &WidgetContainer::activeFocusChanged, this, &WidgetContainer::onActiveFocusChanged); 0025 } 0026 0027 bool WidgetContainer::editMode() const 0028 { 0029 return m_editMode; 0030 } 0031 0032 void WidgetContainer::setEditMode(bool editMode) 0033 { 0034 if (m_editMode != editMode) { 0035 m_editMode = editMode; 0036 0037 if (m_editMode) { 0038 setZ(1); 0039 0040 if (m_pressed) { 0041 // sendUngrabRecursive(m_contentItem); 0042 QMouseEvent ev(QEvent::MouseButtonPress, mapFromScene(m_mouseDownPosition), m_mouseDownPosition, QPointF(), Qt::LeftButton, {}, {}); 0043 ev.setExclusiveGrabber(ev.point(0), this); 0044 QCoreApplication::sendEvent(this, &ev); 0045 } 0046 0047 } else { 0048 setZ(0); 0049 } 0050 0051 Q_EMIT editModeChanged(); 0052 } 0053 } 0054 0055 bool WidgetContainer::childMouseEventFilter(QQuickItem *item, QEvent *event) 0056 { 0057 switch (event->type()) { 0058 case QEvent::MouseButtonPress: { 0059 QMouseEvent *me = static_cast<QMouseEvent *>(event); 0060 if (me->buttons() & Qt::LeftButton) { 0061 mousePressEvent(me); 0062 } 0063 break; 0064 } 0065 case QEvent::MouseMove: { 0066 QMouseEvent *me = static_cast<QMouseEvent *>(event); 0067 mouseMoveEvent(me); 0068 break; 0069 } 0070 case QEvent::MouseButtonRelease: { 0071 QMouseEvent *me = static_cast<QMouseEvent *>(event); 0072 mouseReleaseEvent(me); 0073 break; 0074 } 0075 case QEvent::UngrabMouse: 0076 mouseUngrabEvent(); 0077 break; 0078 default: 0079 break; 0080 } 0081 0082 return QQuickItem::childMouseEventFilter(item, event); 0083 } 0084 0085 void WidgetContainer::mousePressEvent(QMouseEvent *event) 0086 { 0087 forceActiveFocus(Qt::MouseFocusReason); 0088 0089 m_pressed = true; 0090 m_pressAndHoldTimer->start(); 0091 m_mouseDownPosition = event->scenePosition(); 0092 event->accept(); 0093 } 0094 0095 void WidgetContainer::mouseMoveEvent(QMouseEvent *event) 0096 { 0097 if (!m_editMode && QPointF(event->scenePosition() - m_mouseDownPosition).manhattanLength() >= QGuiApplication::styleHints()->startDragDistance()) { 0098 m_pressAndHoldTimer->stop(); 0099 } 0100 0101 QQuickItem::mouseMoveEvent(event); 0102 } 0103 0104 void WidgetContainer::mouseReleaseEvent(QMouseEvent *event) 0105 { 0106 Q_EMIT pressReleased(); 0107 0108 m_pressAndHoldTimer->stop(); 0109 m_pressed = false; 0110 0111 event->accept(); 0112 } 0113 0114 void WidgetContainer::mouseUngrabEvent() 0115 { 0116 m_pressAndHoldTimer->stop(); 0117 m_pressed = false; 0118 } 0119 0120 void WidgetContainer::startPressAndHold() 0121 { 0122 setEditMode(true); 0123 Q_EMIT startEditMode(m_mouseDownPosition); 0124 } 0125 0126 void WidgetContainer::onActiveFocusChanged(bool activeFocus) 0127 { 0128 if (!activeFocus) { 0129 setEditMode(false); 0130 } 0131 }