File indexing completed on 2024-12-22 05:16:04
0001 /* 0002 SPDX-FileCopyrightText: 2022 Janet Blackquill <uhhadd@gmail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #include "maskmousearea.h" 0008 #include <QQuickItemGrabResult> 0009 0010 struct MaskMouseArea::Private { 0011 QImage maskImage; 0012 bool containsMouse = false; 0013 }; 0014 0015 MaskMouseArea::MaskMouseArea(QQuickItem *parent) 0016 : QQuickItem(parent) 0017 , d(new Private) 0018 { 0019 setAcceptHoverEvents(true); 0020 setAcceptedMouseButtons(Qt::AllButtons); 0021 updateMask(); 0022 connect(this, &QQuickItem::parentChanged, this, &MaskMouseArea::updateMask); 0023 } 0024 0025 MaskMouseArea::~MaskMouseArea() 0026 { 0027 } 0028 0029 void MaskMouseArea::updateMask() 0030 { 0031 if (parentItem() == nullptr || parentItem()->height() < 1) { 0032 return; 0033 } 0034 0035 auto result = parentItem()->grabToImage(); 0036 connect( 0037 result.get(), 0038 &QQuickItemGrabResult::ready, 0039 this, 0040 [result, this] { 0041 d->maskImage = result->image(); 0042 }, 0043 Qt::SingleShotConnection /* Otherwise leak */); 0044 } 0045 0046 void MaskMouseArea::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) 0047 { 0048 Q_UNUSED(newGeometry) 0049 Q_UNUSED(oldGeometry) 0050 0051 updateMask(); 0052 } 0053 0054 bool MaskMouseArea::contains(const QPointF &point) const 0055 { 0056 if (!QQuickItem::contains(point) || d->maskImage.isNull()) { 0057 return false; 0058 } 0059 0060 QPoint rounded = point.toPoint(); 0061 const int x = rounded.x(), y = rounded.y(); 0062 0063 if (x < 0 || x >= d->maskImage.width()) { 0064 return false; 0065 } 0066 if (y < 0 || y >= d->maskImage.height()) { 0067 return false; 0068 } 0069 0070 return d->maskImage.pixel(x, y) != 0; 0071 } 0072 0073 void MaskMouseArea::mousePressEvent(QMouseEvent *event) 0074 { 0075 event->accept(); 0076 } 0077 0078 void MaskMouseArea::mouseReleaseEvent(QMouseEvent *event) 0079 { 0080 if (!contains(event->position())) { 0081 return; 0082 } 0083 0084 Q_EMIT tapped(); 0085 } 0086 0087 void MaskMouseArea::hoverEnterEvent(QHoverEvent *event) 0088 { 0089 Q_UNUSED(event) 0090 d->containsMouse = true; 0091 Q_EMIT hoveredChanged(); 0092 } 0093 0094 void MaskMouseArea::hoverLeaveEvent(QHoverEvent *event) 0095 { 0096 Q_UNUSED(event) 0097 d->containsMouse = false; 0098 Q_EMIT hoveredChanged(); 0099 } 0100 0101 bool MaskMouseArea::hovered() const 0102 { 0103 return d->containsMouse; 0104 }