From 322120ba8f73170c991b8bc28d5cb0b663f8923f Mon Sep 17 00:00:00 2001 From: Ali Kianian Date: Tue, 3 Sep 2024 15:02:50 +0300 Subject: [PATCH] QmlDesigner: Highlight the camera view action on the menu Fixes: QDS-13492 Change-Id: I828570d372822c854e6d388bdef0ecaf501bdb7a Reviewed-by: Mahmoud Badri Reviewed-by: Miikka Heikkinen --- .../edit3d/cameraviewwidgetaction.cpp | 42 +++++++++-- .../edit3d/cameraviewwidgetaction.h | 19 +++++ src/plugins/qmldesignerbase/CMakeLists.txt | 2 +- .../qmldesignerbase/studio/studiostyle.cpp | 72 +++++++++++++++++-- 4 files changed, 122 insertions(+), 13 deletions(-) diff --git a/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.cpp b/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.cpp index 8f9e025dc0a..7b56190e686 100644 --- a/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.cpp +++ b/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.cpp @@ -5,8 +5,6 @@ #include #include -#include - namespace QmlDesigner { struct CameraActionsModel::DataItem @@ -29,19 +27,22 @@ const QList CameraActionsModel::m_data{ CameraViewWidgetAction::CameraViewWidgetAction(QObject *parent) : QWidgetAction(parent) { - QComboBox *defaultComboBox = new QComboBox(); + ComboBoxAction *defaultComboBox = new ComboBoxAction(); CameraActionsModel *comboBoxModel = new CameraActionsModel(defaultComboBox); defaultComboBox->setModel(comboBoxModel); setDefaultWidget(defaultComboBox); + connect(defaultComboBox, &QComboBox::currentIndexChanged, this, [this] { emit currentModeChanged(currentMode()); }); + + connect(defaultComboBox, &ComboBoxAction::hovered, this, &CameraViewWidgetAction::onWidgetHovered); } QString CameraViewWidgetAction::currentMode() const { - QComboBox *defaultComboBox = qobject_cast(defaultWidget()); + ComboBoxAction *defaultComboBox = qobject_cast(defaultWidget()); QTC_ASSERT(defaultComboBox, return "CameraOff"); return defaultComboBox->currentData(CameraActionsModel::ModeRole).toString(); @@ -49,24 +50,33 @@ QString CameraViewWidgetAction::currentMode() const void CameraViewWidgetAction::setMode(const QString &mode) { - QComboBox *defaultComboBox = qobject_cast(defaultWidget()); + ComboBoxAction *defaultComboBox = qobject_cast(defaultWidget()); QTC_ASSERT(defaultComboBox, return); defaultComboBox->setCurrentIndex(CameraActionsModel::modeIndex(mode)); } QWidget *CameraViewWidgetAction::createWidget(QWidget *parent) { - QComboBox *defaultComboBox = qobject_cast(defaultWidget()); + ComboBoxAction *defaultComboBox = qobject_cast(defaultWidget()); QTC_ASSERT(defaultComboBox, return nullptr); - QComboBox *newComboBox = new QComboBox(parent); + ComboBoxAction *newComboBox = new ComboBoxAction(parent); newComboBox->setModel(defaultComboBox->model()); connect(defaultComboBox, &QComboBox::currentIndexChanged, newComboBox, &QComboBox::setCurrentIndex); connect(newComboBox, &QComboBox::currentIndexChanged, defaultComboBox, &QComboBox::setCurrentIndex); newComboBox->setCurrentIndex(defaultComboBox->currentIndex()); + + connect(newComboBox, &ComboBoxAction::hovered, this, &CameraViewWidgetAction::onWidgetHovered); + newComboBox->setProperty("_qdss_hoverFrame", true); + return newComboBox; } +void CameraViewWidgetAction::onWidgetHovered() +{ + activate(Hover); +} + CameraActionsModel::CameraActionsModel(QObject *parent) : QAbstractListModel(parent) {} @@ -102,4 +112,22 @@ int CameraActionsModel::modeIndex(const QString &mode) return std::max(0, idx); } +ComboBoxAction::ComboBoxAction(QWidget *parent) + : QComboBox(parent) +{ + setMouseTracking(true); +} + +void ComboBoxAction::enterEvent(QEnterEvent *event) +{ + QComboBox::enterEvent(event); + emit hovered(); +} + +void ComboBoxAction::moveEvent(QMoveEvent *event) +{ + QComboBox::moveEvent(event); + emit hovered(); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.h b/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.h index e368a41b032..f017f8e478e 100644 --- a/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.h +++ b/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.h @@ -3,6 +3,7 @@ #pragma once #include +#include #include #include @@ -20,6 +21,9 @@ public: protected: QWidget *createWidget(QWidget *parent) override; +private slots: + void onWidgetHovered(); + signals: void currentModeChanged(QString); }; @@ -43,4 +47,19 @@ private: static const QList m_data; }; +class ComboBoxAction : public QComboBox +{ + Q_OBJECT + +public: + explicit ComboBoxAction(QWidget *parent = nullptr); + +protected: + void enterEvent(QEnterEvent *event) override; + void moveEvent(QMoveEvent *event) override; + +signals: + void hovered(); +}; + } // namespace QmlDesigner diff --git a/src/plugins/qmldesignerbase/CMakeLists.txt b/src/plugins/qmldesignerbase/CMakeLists.txt index e5d06b7d14d..aa1a89da4b3 100644 --- a/src/plugins/qmldesignerbase/CMakeLists.txt +++ b/src/plugins/qmldesignerbase/CMakeLists.txt @@ -19,7 +19,7 @@ add_qtc_library(QmlDesignerSettings STATIC add_qtc_plugin(QmlDesignerBase CONDITION TARGET Qt::QuickWidgets - DEPENDS Qt::Core Qt::QuickWidgets + DEPENDS Qt::Core Qt::QuickWidgets Qt::GuiPrivate PLUGIN_DEPENDS Core ProjectExplorer QtSupport PUBLIC_INCLUDES settings SOURCES diff --git a/src/plugins/qmldesignerbase/studio/studiostyle.cpp b/src/plugins/qmldesignerbase/studio/studiostyle.cpp index 8bb92ccc88c..a828dcf1880 100644 --- a/src/plugins/qmldesignerbase/studio/studiostyle.cpp +++ b/src/plugins/qmldesignerbase/studio/studiostyle.cpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include #define ANIMATE_SCROLLBARS QT_CONFIG(animation) using namespace Utils; @@ -109,6 +111,17 @@ bool isQmlEditorMenu(const QWidget *widget) return false; } +bool hasHoverFrame(const QStyleOption *option) +{ + return option->styleObject && option->styleObject->property("_qdss_hoverFrame").toBool(); +} + +bool isHovered(const QStyleOption *option) +{ + return option->state + && option->state.testFlags({QStyle::State_Enabled, QStyle::State_MouseOver}); +} + inline QPixmap getPixmapFromIcon( const QIcon &icon, const QSize &size, bool enabled, bool active, bool checked) { @@ -135,6 +148,37 @@ inline QRect expandScrollRect(const QRect &ref, } } +namespace FusionStyleHelper { +bool isMacSystemPalette(const QPalette &pal) +{ + if (!Utils::HostOsInfo::isMacHost()) + return false; + + const QPalette *themePalette = QGuiApplicationPrivate::platformTheme()->palette(); + return themePalette + && themePalette->color(QPalette::Normal, QPalette::Highlight) + == pal.color(QPalette::Normal, QPalette::Highlight) + && themePalette->color(QPalette::Normal, QPalette::HighlightedText) + == pal.color(QPalette::Normal, QPalette::HighlightedText); +} + +QColor highlight(const QPalette &pal) +{ + if (isMacSystemPalette(pal)) + return QColor(60, 140, 230); + return pal.color(QPalette::Highlight); +} + +QColor highlightedOutline(const QPalette &pal) +{ + QColor highlightedOutline = highlight(pal).darker(125); + if (highlightedOutline.value() > 160) + highlightedOutline.setHsl(highlightedOutline.hue(), highlightedOutline.saturation(), 160); + return highlightedOutline; +} + +} // namespace FusionStyleHelper + } // namespace StudioStyle::StudioStyle(QStyle *style) @@ -192,10 +236,20 @@ void StudioStyle::drawPrimitive( Super::drawPrimitive(element, option, painter, widget); break; - case PE_PanelButtonCommand: - if (!isQmlEditorMenu(widget)) - Super::drawPrimitive(element, option, painter, widget); - break; + case PE_PanelButtonCommand: { + if (isQmlEditorMenu(widget)) + break; + + if (hasHoverFrame(option) && isHovered(option)) { + painter->save(); + painter->setPen(FusionStyleHelper::highlightedOutline(option->palette)); + painter->setBrush(Qt::NoBrush); + painter->drawRect(QRectF(option->rect).adjusted(0.5, 0.5, -0.5, -0.5)); + painter->restore(); + break; + } + Super::drawPrimitive(element, option, painter, widget); + } break; case PE_FrameDefaultButton: { if (const auto button = qstyleoption_cast(option)) { bool enabled = button->state & QStyle::State_Enabled; @@ -594,7 +648,15 @@ void StudioStyle::drawComplexControl( } } break; case CC_ComboBox: { - painter->fillRect(option->rect, standardPalette().brush(QPalette::ColorRole::Base)); + if (hasHoverFrame(option)) { + if (isHovered(option)) { + painter->fillRect( + QRectF(option->rect).adjusted(0.5, 0.5, -0.5, -0.5), + FusionStyleHelper::highlight(option->palette)); + } + } else { + painter->fillRect(option->rect, standardPalette().brush(QPalette::ColorRole::Base)); + } Super::drawComplexControl(control, option, painter, widget); } break;