diff --git a/src/widgets/capture_overlay_widget.cpp b/src/widgets/capture_overlay_widget.cpp index 1faa8e5..797dcf4 100644 --- a/src/widgets/capture_overlay_widget.cpp +++ b/src/widgets/capture_overlay_widget.cpp @@ -613,6 +613,20 @@ void CaptureOverlayWidget::mouseReleaseEvent(QMouseEvent *event) setCursor(m_selection.cursorShape()); if (m_selection.hasSelection()) { refreshCanvasForSelection(false); + if (m_defaultAction == CaptureAction::Sticky || m_defaultAction == CaptureAction::Save) { + const CaptureAction action = m_defaultAction; + if (m_magnifier) { + m_magnifier->hide(); + } + update(); + event->accept(); + QTimer::singleShot(0, this, [this, action]() { + if (isVisible() && m_selection.hasSelection()) { + performAction(action); + } + }); + return; + } updateToolbarGeometry(); m_toolbar->show(); m_toolbar->raise(); @@ -1162,3 +1176,5 @@ QString CaptureOverlayWidget::defaultSaveFilePath() const .arg(QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd_HHmmss"))); return QDir(baseDir).filePath(fileName); } + + diff --git a/src/widgets/sticky_canvas_widget.cpp b/src/widgets/sticky_canvas_widget.cpp index 6d69e88..26b3b58 100644 --- a/src/widgets/sticky_canvas_widget.cpp +++ b/src/widgets/sticky_canvas_widget.cpp @@ -51,6 +51,16 @@ void StickyCanvasWidget::setViewScale(qreal scale) update(); } +void StickyCanvasWidget::setContentOpacity(qreal opacity) +{ + const qreal next = qBound(0.05, opacity, 1.0); + if (qFuzzyCompare(m_contentOpacity, next)) { + return; + } + m_contentOpacity = next; + update(); +} + void StickyCanvasWidget::setActiveShapeType(Shapeype type) { m_shapeType = type; @@ -180,6 +190,9 @@ void StickyCanvasWidget::paintEvent(QPaintEvent *event) Q_UNUSED(event); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); + + painter.save(); + painter.setOpacity(m_contentOpacity); if (m_backgroundVisible) { painter.fillRect(rect(), Qt::white); } @@ -188,7 +201,6 @@ void StickyCanvasWidget::paintEvent(QPaintEvent *event) painter.drawImage(rect(), m_backgroundImage); } - painter.save(); painter.scale(m_viewScale, m_viewScale); for (Shape *shape : m_shapes) { if (shape) { @@ -311,3 +323,5 @@ void StickyCanvasWidget::clearShapes() qDeleteAll(m_shapes); m_shapes.clear(); } + + diff --git a/src/widgets/sticky_canvas_widget.h b/src/widgets/sticky_canvas_widget.h index 56f7bf9..3a26384 100644 --- a/src/widgets/sticky_canvas_widget.h +++ b/src/widgets/sticky_canvas_widget.h @@ -21,6 +21,7 @@ public: void setBackgroundImage(const QImage &image); void setBackgroundVisible(bool visible); void setViewScale(qreal scale); + void setContentOpacity(qreal opacity); void setActiveShapeType(Shapeype type); void setPenColor(const QColor &color); void setPenSize(int size); @@ -67,7 +68,9 @@ private: bool m_drawingEnabled = false; bool m_draggingShape = false; qreal m_viewScale = 1.0; + qreal m_contentOpacity = 1.0; QPoint m_startPoint; }; #endif // STICKY_CANVAS_WIDGET_H + diff --git a/src/widgets/sticky_pin_widget.cpp b/src/widgets/sticky_pin_widget.cpp index a55fb2c..4d50d73 100644 --- a/src/widgets/sticky_pin_widget.cpp +++ b/src/widgets/sticky_pin_widget.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -28,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -73,6 +75,18 @@ qreal monitorScaleForPoint(const QPoint &physicalPoint) return 1.0; } +bool isAltWheelActive(const QWheelEvent *event) +{ + if (event && event->modifiers().testFlag(Qt::AltModifier)) { + return true; + } +#ifdef Q_OS_WIN + return (GetAsyncKeyState(VK_MENU) & 0x8000) != 0; +#else + return QGuiApplication::keyboardModifiers().testFlag(Qt::AltModifier); +#endif +} + QPoint physicalOffsetForLogicalPoint(const QPoint &logicalPoint, const QPoint &referencePhysicalPoint) { #ifdef Q_OS_WIN @@ -280,6 +294,7 @@ StickyPinWidget::StickyPinWidget(const QString &imageUrl, m_canvas = new StickyCanvasWidget(this); m_canvas->setBackgroundImage(m_image); m_canvas->setViewScale(m_zoomFactor); + m_canvas->setContentOpacity(m_contentOpacity); m_canvas->setPenColor(m_currentPenColor); m_canvas->setPenSize(m_currentPenSize); m_canvas->setActiveShapeType(PEN); @@ -494,7 +509,7 @@ StickyPinWidget::StickyPinWidget(const QString &imageUrl, connect(m_aiLoadingTimer, &QTimer::timeout, this, [this]() { m_aiLoadingFrame = (m_aiLoadingFrame + 1) % 12; updateAiLoadingIcon(); - update(contentRect()); + update(); }); auto setupButton = [](QToolButton *button, const QString &tooltip) { @@ -607,6 +622,20 @@ StickyPinWidget::StickyPinWidget(const QString &imageUrl, }); connect(m_closeButton, &QToolButton::clicked, this, &QWidget::close); + const auto wheelAwareWidgets = findChildren(); + for (QWidget *child : wheelAwareWidgets) { + if (!child) { + continue; + } + if (child == m_visionResultWidget) { + continue; + } + if (m_visionResultWidget && m_visionResultWidget->isAncestorOf(child)) { + continue; + } + child->installEventFilter(this); + } + updateLayoutAndSize(); if (!m_colorButtons.isEmpty()) { m_colorButtons.first()->setChecked(true); @@ -639,17 +668,18 @@ void StickyPinWidget::paintEvent(QPaintEvent *event) painter.fillRect(rect(), Qt::transparent); const QRect imageRect = contentRect(); + const qreal contentOpacity = qBound(0.05, m_contentOpacity, 1.0); if (m_shadowVisible) { for (int i = 10; i >= 1; --i) { - const int alpha = 3 + i * 2; + const int alpha = qRound((3 + i * 2) * contentOpacity); painter.setPen(Qt::NoPen); painter.setBrush(QColor(47, 143, 255, alpha)); painter.drawRoundedRect(imageRect.adjusted(-i, -i, i, i), 8, 8); } } - painter.setPen(QPen(QColor(120, 182, 255, 80), 1)); - painter.setBrush(Qt::white); + painter.setPen(QPen(QColor(120, 182, 255, qRound(80 * contentOpacity)), 1)); + painter.setBrush(QColor(255, 255, 255, qRound(255 * contentOpacity))); painter.drawRoundedRect(imageRect, 4, 4); painter.setBrush(Qt::NoBrush); @@ -870,17 +900,72 @@ void StickyPinWidget::mousePressEvent(QMouseEvent *event) QWidget::mousePressEvent(event); } +bool StickyPinWidget::eventFilter(QObject *watched, QEvent *event) +{ + if (watched && event && event->type() == QEvent::Wheel) { + auto *wheelEvent = static_cast(event); + if (isAltOpacityAdjustActive(wheelEvent) && handleWheelInteraction(wheelEvent)) { + return true; + } + } + return QWidget::eventFilter(watched, event); +} + void StickyPinWidget::wheelEvent(QWheelEvent *event) { + if (handleWheelInteraction(event)) { + return; + } + QWidget::wheelEvent(event); +} + +bool StickyPinWidget::handleWheelInteraction(QWheelEvent *event) +{ + if (!event) { + return false; + } + const QPoint angleDelta = event->angleDelta(); - if (angleDelta.y() == 0) { - QWidget::wheelEvent(event); + const int primaryDelta = (angleDelta.y() != 0) ? angleDelta.y() : angleDelta.x(); + const bool altActive = isAltOpacityAdjustActive(event); + if (primaryDelta == 0) { + return false; + } + + if (altActive) { + const qreal delta = primaryDelta > 0 ? 0.05 : -0.05; + const qreal nextOpacity = qBound(0.05, m_contentOpacity + delta, 1.0); + setContentOpacity(nextOpacity); + QToolTip::showText(event->globalPosition().toPoint(), + tr("透明度 %1%").arg(qRound(nextOpacity * 100)), + this); + event->accept(); + return true; + } + + const qreal step = primaryDelta > 0 ? 1.1 : 0.9; + setZoomFactor(m_zoomFactor * step); + event->accept(); + return true; +} + +bool StickyPinWidget::isAltOpacityAdjustActive(const QWheelEvent *event) const +{ + return isAltWheelActive(event); +} + +void StickyPinWidget::setContentOpacity(qreal value) +{ + const qreal next = qBound(0.05, value, 1.0); + if (qFuzzyCompare(m_contentOpacity, next)) { return; } - const qreal step = angleDelta.y() > 0 ? 1.1 : 0.9; - setZoomFactor(m_zoomFactor * step); - event->accept(); + m_contentOpacity = next; + if (m_canvas) { + m_canvas->setContentOpacity(next); + } + update(); } void StickyPinWidget::setZoomFactor(qreal value) @@ -896,6 +981,7 @@ void StickyPinWidget::setZoomFactor(qreal value) if (m_canvas) { m_canvas->setViewScale(m_zoomFactor); m_canvas->setBackgroundImage(m_image); + m_canvas->setContentOpacity(m_contentOpacity); } updateLayoutAndSize(); update(); @@ -1003,7 +1089,7 @@ void StickyPinWidget::setAiLoading(bool loading) if (m_aiLoadingTimer) { m_aiLoadingTimer->start(); } - update(contentRect()); + update(); return; } @@ -1013,7 +1099,7 @@ void StickyPinWidget::setAiLoading(bool loading) if (m_aiButton) { m_aiButton->setIcon(QIcon(QStringLiteral(":/resource/img/lc_chat.svg"))); } - update(contentRect()); + update(); } void StickyPinWidget::updateAiLoadingIcon() @@ -1264,3 +1350,5 @@ int StickyPinWidget::toolbarWidth() const { return 32 * 16 + 52 + 2 * 16 + 12; } + + diff --git a/src/widgets/sticky_pin_widget.h b/src/widgets/sticky_pin_widget.h index 71e54a4..a1d064d 100644 --- a/src/widgets/sticky_pin_widget.h +++ b/src/widgets/sticky_pin_widget.h @@ -42,6 +42,7 @@ protected: void contextMenuEvent(QContextMenuEvent *event) override; void mousePressEvent(QMouseEvent *event) override; void wheelEvent(QWheelEvent *event) override; + bool eventFilter(QObject *watched, QEvent *event) override; private: void setActiveTool(Shapeype type, QToolButton *activeButton); @@ -49,6 +50,9 @@ private: void updateToolOptionsPanel(); void updateLayoutAndSize(); QToolButton *currentActiveToolButton() const; + bool handleWheelInteraction(QWheelEvent *event); + bool isAltOpacityAdjustActive(const QWheelEvent *event) const; + void setContentOpacity(qreal value); void setZoomFactor(qreal value); void openAiEditor(); void openVisionWindow(); @@ -122,8 +126,10 @@ private: bool m_aiLoading = false; int m_aiLoadingFrame = 0; qreal m_zoomFactor = 1.0; + qreal m_contentOpacity = 1.0; QTimer *m_aiLoadingTimer = nullptr; bool m_released = false; }; #endif // STICKY_PIN_WIDGET_H +