diff --git a/README.md b/README.md index 8f9b31a19ffe649c32a1d8e4db8fc5affa61ba23..c09064a91ca70c61d418550db5013f8e6410a630 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Kiran桌面qt5平台一体化插件,其中包含QPlatformTheme插件,QStyle插 ## 编译安装 ```shell -# yum install cmake gcc-c++ qt5-linguist qt5-qtbase-devel qt5-qtbase-private-devel qt5-qtx11extras-devel kiran-qdbusxml2cpp kiran-log-qt5-devel qt5-qtsvg-devel gsettings-qt-devel +# yum install cmake gcc-c++ qt5-linguist qt5-qtbase-devel qt5-qtbase-private-devel qt5-qtx11extras-devel kiran-qdbusxml2cpp kiran-log-qt5-devel qt5-qtsvg-devel gsettings-qt-devel kiran-cc-daemon-devel qt5-qtbase-static # mkdir # cd build && cmake -DCMAKE_INSTALL_PREFIX=/usr .. # make diff --git a/lib/theme/define.h b/lib/theme/define.h index da7c73f8caa5108b8b843326bd17b44ba78e0a3a..9ee9900422831622307a73f9d7b19ffd1b1a4a11 100644 --- a/lib/theme/define.h +++ b/lib/theme/define.h @@ -41,13 +41,6 @@ enum Corner }; Q_DECLARE_FLAGS(Corners, Corner) -enum PaletteType -{ - PALETTE_LIGHT, - PALETTE_DARK, - PALETTE_LAST -}; - #define KIRAN_STYLE_PROPERTY_BUTTON_TYPE "_kiran_button_type" } // namespace Kiran diff --git a/lib/theme/palette-private.h b/lib/theme/palette-private.h index d220480ff30ea930ebb96225b7ae133d1881d926..8a51b826df12f3d4b44d04269e6b377eefc366e0 100644 --- a/lib/theme/palette-private.h +++ b/lib/theme/palette-private.h @@ -1,14 +1,14 @@ /** - * Copyright (c) 2023 ~ 2024 KylinSec Co., Ltd. + * Copyright (c) 2023 ~ 2024 KylinSec Co., Ltd. * kiranwidgets-qt5 is licensed under Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: - * http://license.coscl.org.cn/MulanPSL2 - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, - * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, - * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - * + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * * Author: tangjie02 */ @@ -27,7 +27,7 @@ class PalettePrivate : public QObject public: explicit PalettePrivate(Palette* qptr); - ~PalettePrivate() override = default;; + ~PalettePrivate() override = default; void setBaseColors(const Palette::BaseColors& baseColors); void setColorFactor(const Palette::ColorFactor& colorFactor); diff --git a/lib/theme/palette.cpp b/lib/theme/palette.cpp index 6130d02cff8447774d657fa02870a490f0dea5e0..cc7e7b0fcdd38db680f81f94d7a2a31af2dc0cdb 100644 --- a/lib/theme/palette.cpp +++ b/lib/theme/palette.cpp @@ -1,14 +1,14 @@ /** - * Copyright (c) 2023 ~ 2024 KylinSec Co., Ltd. + * Copyright (c) 2023 ~ 2024 KylinSec Co., Ltd. * kiranwidgets-qt5 is licensed under Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: - * http://license.coscl.org.cn/MulanPSL2 - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, - * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, - * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - * + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * * Author: tangjie02 */ @@ -24,23 +24,23 @@ namespace Kiran namespace Theme { // 定义内置的基础颜色,只包含浅色和深色 -Palette::BaseColors g_lightBaseColors = {.baseBackground = QColor(232, 232, 232), // #E8E8E8 - .baseForeground = QColor(34, 34, 34), // #222222 - .widgetBackground = QColor(239, 239, 239), // #EFEFEF - .widgetBorder = QColor(204, 204, 204), // #CCCCCC - .widgetSelection = QColor(0, 162, 255), // #00A2FF - .widgetMain = QColor(46, 179, 255), // #2EB3FF - .widgetWarning = QColor(250, 73, 73), // #FA4949 - .containerBackground = QColor(255, 255, 255)};// #FFFFFF - -Palette::BaseColors g_darkBaseColors = {.baseBackground = QColor(34, 34, 34), // #222222 - .baseForeground = QColor(255, 255, 255), // #FFFFFF - .widgetBackground = QColor(57, 57, 57), // #393939 - .widgetBorder = QColor(69, 69, 69), // #454545 - .widgetSelection = QColor(0, 162, 255), // #00A2FF - .widgetMain = QColor(46, 179, 255), // #2EB3FF - .widgetWarning = QColor(250, 73, 73), // #FA4949 - .containerBackground = QColor(45, 45, 45)};// #2d2d2d +Palette::BaseColors g_lightBaseColors = {.baseBackground = QColor(232, 232, 232), // #E8E8E8 + .baseForeground = QColor(34, 34, 34), // #222222 + .widgetBackground = QColor(239, 239, 239), // #EFEFEF + .widgetBorder = QColor(204, 204, 204), // #CCCCCC + .widgetSelection = QColor(0, 162, 255), // #00A2FF + .widgetMain = QColor(46, 179, 255), // #2EB3FF + .widgetWarning = QColor(250, 73, 73), // #FA4949 + .containerBackground = QColor(255, 255, 255)}; // #FFFFFF + +Palette::BaseColors g_darkBaseColors = {.baseBackground = QColor(34, 34, 34), // #222222 + .baseForeground = QColor(255, 255, 255), // #FFFFFF + .widgetBackground = QColor(57, 57, 57), // #393939 + .widgetBorder = QColor(69, 69, 69), // #454545 + .widgetSelection = QColor(0, 162, 255), // #00A2FF + .widgetMain = QColor(46, 179, 255), // #2EB3FF + .widgetWarning = QColor(250, 73, 73), // #FA4949 + .containerBackground = QColor(45, 45, 45)}; // #2d2d2d // 颜色计算因子 Palette::ColorFactor g_colorFactor = {.widgetHover = 0.9, .widgetSunken = 0.8, @@ -228,6 +228,7 @@ void Palette::setBaseColors(const BaseColors& baseColors) Q_D(Palette); d->setBaseColors(baseColors); + emit baseColorsChanged(); } const Palette::BaseColors& Palette::getBaseColors() @@ -295,8 +296,8 @@ void Palette::polish(QPalette& qPalette) for (auto colorGroupInter = colorGroupInfo.begin(); colorGroupInter != colorGroupInfo.end(); ++colorGroupInter) { qPalette.setColor(colorGroupInter.key(), - colorRoleInter.key(), - this->getColor(colorGroupInter.value(), colorRoleInter.value())); + colorRoleInter.key(), + this->getColor(colorGroupInter.value(), colorRoleInter.value())); } } } diff --git a/lib/theme/palette.h b/lib/theme/palette.h index 617c3507a51483ac6cea9be3e3bfeaf976fbf0aa..2fc2732ad5823107c6d59d1b7ddbe4db11be1617 100644 --- a/lib/theme/palette.h +++ b/lib/theme/palette.h @@ -1,14 +1,14 @@ /** - * Copyright (c) 2023 ~ 2024 KylinSec Co., Ltd. + * Copyright (c) 2023 ~ 2024 KylinSec Co., Ltd. * kiranwidgets-qt5 is licensed under Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: - * http://license.coscl.org.cn/MulanPSL2 - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, - * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, - * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - * + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * * Author: tangjie02 */ @@ -114,7 +114,7 @@ public: public: explicit Palette(QObject* parent = nullptr); - ~Palette() override = default;; + ~Palette() override = default; static Palette* getDefault(); @@ -129,6 +129,10 @@ public: void polish(QPalette& palette); +signals: + // 当基础颜色发生变化时发送该信号 + void baseColorsChanged(); + private: uint32_t styleState2ColorGroups(QStyle::State styleState); diff --git a/lib/theme/style-helper.cpp b/lib/theme/style-helper.cpp index 2a788b64c860193de21ff4702ed9a5e2c7507289..55528b76e65497874f483bedb820ebe291611958 100644 --- a/lib/theme/style-helper.cpp +++ b/lib/theme/style-helper.cpp @@ -3,43 +3,58 @@ // #include "style-helper.h" +#include "palette.h" -//extern Kiran::Theme::Palette::BaseColors g_lightBaseColors; -//extern Kiran::Theme::Palette::BaseColors g_darkBaseColors; +namespace Kiran +{ +namespace Theme +{ -Kiran::Theme::Palette::BaseColors g_lightBaseColors = {.baseBackground = QColor(232, 232, 232), // #E8E8E8 - .baseForeground = QColor(34, 34, 34), // #222222 - .widgetBackground = QColor(239, 239, 239), // #EFEFEF - .widgetBorder = QColor(204, 204, 204), // #CCCCCC - .widgetSelection = QColor(0, 162, 255), // #00A2FF - .widgetMain = QColor(46, 179, 255), // #2EB3FF - .widgetWarning = QColor(250, 73, 73)}; // #FA4949 +extern Kiran::Theme::Palette::BaseColors g_lightBaseColors; +extern Kiran::Theme::Palette::BaseColors g_darkBaseColors; -Kiran::Theme::Palette::BaseColors g_darkBaseColors = {.baseBackground = QColor(34, 34, 34), // #222222 - .baseForeground = QColor(255, 255, 255), // #FFFFFF - .widgetBackground = QColor(57, 57, 57), // #393939 - .widgetBorder = QColor(69, 69, 69), // #454545 - .widgetSelection = QColor(0, 162, 255), // #00A2FF - .widgetMain = QColor(46, 179, 255), // #2EB3FF - .widgetWarning = QColor(250, 73, 73)}; // #FA4949 +StyleHelper::StyleHelper() = default; +StyleHelper::~StyleHelper() = default; -namespace Kiran +StyleHelper* StyleHelper::m_instance = nullptr; +StyleHelper* StyleHelper::getDefault() { -namespace Theme + if (!StyleHelper::m_instance) + { + StyleHelper::m_instance = new StyleHelper(); + } + return StyleHelper::m_instance; +} + +PaletteType StyleHelper::paletteType() { -StyleHelper::StyleHelper() -= default; -StyleHelper::~StyleHelper()= default; + auto baseColors = DEFAULT_PALETTE()->getBaseColors(); + if (baseColors.baseBackground == g_lightBaseColors.baseBackground) + { + return PaletteType::PALETTE_LIGHT; + } + else if (baseColors.baseBackground == g_darkBaseColors.baseBackground) + { + return PaletteType::PALETTE_DARK; + } + else + { + return PaletteType::PALETTE_DARK; + } +} -void StyleHelper::doChangeTheme(Kiran::PaletteType paletteType) +void StyleHelper::doChangeTheme(PaletteType paletteType) { Palette::BaseColors baseColors; - if (paletteType == PaletteType::PALETTE_LIGHT) { + if (paletteType == PaletteType::PALETTE_LIGHT) + { baseColors = g_lightBaseColors; - } else if (paletteType == PaletteType::PALETTE_DARK) { + } + else if (paletteType == PaletteType::PALETTE_DARK) + { baseColors = g_darkBaseColors; } DEFAULT_PALETTE()->setBaseColors(baseColors); } -} // namespace Theme -} // namespace Kiran +} // namespace Theme +} // namespace Kiran diff --git a/lib/theme/style-helper.h b/lib/theme/style-helper.h index 67513545e45622218d8237fab1d9e7a868ebeaa2..d2a8e65447023b6be798fc5e8bdc2b91b14dddf6 100644 --- a/lib/theme/style-helper.h +++ b/lib/theme/style-helper.h @@ -1,19 +1,32 @@ #pragma once -#include "lib/theme/palette.h" -#include "lib/theme/define.h" - +#define DEFAULT_STYLE_HELPER StyleHelper::getDefault namespace Kiran { namespace Theme { + +enum PaletteType +{ + PALETTE_LIGHT, + PALETTE_DARK, + PALETTE_LAST +}; + class StyleHelper { public: explicit StyleHelper(); ~StyleHelper(); - static void doChangeTheme(Kiran::PaletteType paletteType); + + static StyleHelper* getDefault(); + + static PaletteType paletteType(); + static void doChangeTheme(PaletteType paletteType); + +private: + static StyleHelper* m_instance; }; -} // namespace Theme -} // namespace Kiran \ No newline at end of file +} // namespace Theme +} // namespace Kiran \ No newline at end of file diff --git a/lib/theme/style.cpp b/lib/theme/style.cpp index 990648989945f0236caf0f8115788e62f4411169..fc15ecc9d8ccd65a4da6573082ac42de4e2b4fee 100644 --- a/lib/theme/style.cpp +++ b/lib/theme/style.cpp @@ -41,7 +41,7 @@ #include "lib/theme/style-private.h" #include "render-helper.h" -#if 0 +#if 1 //调试用 QDebug operator<<(QDebug dbg, const QColor &color) { @@ -274,14 +274,17 @@ StylePrivate::ButtonType StylePrivate::getButtonType(const QPushButton *btn) { ButtonType buttonType = BUTTON_Normal; - QVariant var = btn->property(KIRAN_STYLE_PROPERTY_BUTTON_TYPE); - if (var.isValid()) + if(btn) { - bool toInt = false; - auto temp = static_cast(var.toInt(&toInt)); - if (toInt) + QVariant var = btn->property(KIRAN_STYLE_PROPERTY_BUTTON_TYPE); + if (var.isValid()) { - buttonType = temp; + bool toInt = false; + auto temp = static_cast(var.toInt(&toInt)); + if (toInt) + { + buttonType = temp; + } } } @@ -561,7 +564,16 @@ void Style::drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption * switch (element) { case PE_Frame: - this->drawPEFrame(option, painter, widget); + if (widget && widget->inherits("QComboBoxPrivateContainer")) + { + QStyleOption copy = *option; + copy.state |= State_Raised; + this->drawPrimitive(PE_PanelMenu, ©, painter, widget); + } + else + { + this->drawPEFrame(option, painter, widget); + } break; // case PE_FrameFocusRect: // this->drawPEFrameFocusRect(option, painter, widget); @@ -634,6 +646,9 @@ void Style::drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption * case PE_IndicatorToolBarHandle: this->drawPEIndicatorToolBarHandle(option, painter, widget); break; + case PE_PanelMenu: + this->drawPEPanelMenu(option, painter, widget); + break; // case PE_PanelItemViewRow: // this->drawPanelItemViewRow(option, painter, widget); // break; @@ -835,6 +850,13 @@ void Style::drawControl(QStyle::ControlElement element, const QStyleOption *opti case CE_MenuBarEmptyArea: this->drawControlMenuBarEmptyArea(option, painter, widget); break; + case CE_MenuItem: + //针对QCombobox下拉框绘制菜单项 + if (qobject_cast(widget) || (option->styleObject && option->styleObject->property("_q_isComboBoxPopupItem").toBool())) + { + this->drawControlMenuItem(option, painter, widget); + } + break; // 不绘制的控件元素集合 case CE_ToolBar: break; @@ -1816,6 +1838,12 @@ void Style::drawCCComboBox(const QStyleOptionComplex *option, QPainter *painter, else { auto backgroundColor = Palette::getDefault()->getColor(option->state, Palette::WIDGET); + //combobox在选中状态时,背景颜色需设置为ACTIVE状态下的颜色 + if(option->state & QStyle::State_Selected) + { + backgroundColor = Palette::getDefault()->getColor(Palette::ACTIVE, Palette::WIDGET); + } + auto borderColor = Palette::getDefault()->getColor(option->state, Palette::BORDER); RenderHelper::renderFrame(painter, option->rect, 1, 4, backgroundColor, borderColor); } @@ -2553,6 +2581,56 @@ void Style::drawControlMenuBarEmptyArea(const QStyleOption *option, QPainter *pa painter->fillRect(option->rect, background); } +void Style::drawControlMenuItem(const QStyleOption* option, QPainter* painter, const QWidget* widget) const +{ + const auto menuItemOption(qstyleoption_cast(option)); + RETURN_IF_FALSE(menuItemOption); + + painter->save(); + + int alignment = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine; + + if (!this->styleHint(QStyle::SH_UnderlineShortcut, option, widget)) + { + alignment |= Qt::TextHideMnemonic; + } + alignment |= Qt::AlignLeft; + + const bool enabled(menuItemOption->state & QStyle::State_Enabled); + const bool mouseOver((menuItemOption->state & QStyle::State_MouseOver) && enabled); + const bool sunken((menuItemOption->state & QStyle::State_Sunken) && enabled); + const bool selected((menuItemOption->state & QStyle::State_Selected) && enabled); + + if (selected || mouseOver || sunken) { + // 设置背景颜色 + auto backgroundColor = Palette::getDefault()->getBaseColors().widgetMain; + painter->fillRect(menuItemOption->rect, backgroundColor); + } + + //绘制文字 + if(!menuItemOption->text.isEmpty()) + { + auto itemTextRect = menuItemOption->rect.adjusted(Metrics::ComboBox_FrameWidth, 0, -1, 0); + this->drawItemText(painter,itemTextRect, alignment, menuItemOption->palette, enabled, menuItemOption->text, QPalette::ButtonText); + painter->restore(); + } +} + +void Style::drawPEPanelMenu(const QStyleOption* option, QPainter* painter, const QWidget* widget) const +{ + const auto panelMenuOption(qstyleoption_cast(option)); + RETURN_IF_FALSE(panelMenuOption); + + if (widget && widget->inherits("QComboBoxPrivateContainer")) + { + painter->save(); + auto bgColor = Palette::getDefault()->getBaseColors().widgetMain; //与combobox菜单项颜色一致 + auto borderColor = Palette::getDefault()->getColor(option->state, Palette::BORDER); + painter->fillRect(option->rect, bgColor); + painter->restore(); + } +} + QSize Style::progressBarSizeFromContents(const QStyleOption *option, const QSize &contentSize, const QWidget *widget) const { const auto progressBarOption(qstyleoption_cast(option)); diff --git a/lib/theme/style.h b/lib/theme/style.h index 987f3f3573414803bebc4d419652f720fe6bf87d..af2178127a307401694bc5a27a0a1c53406c6b27 100644 --- a/lib/theme/style.h +++ b/lib/theme/style.h @@ -113,6 +113,8 @@ private: // menu void drawControlMenuBarItem(const QStyleOption* option, QPainter* painter, const QWidget* widget) const; void drawControlMenuBarEmptyArea(const QStyleOption* option, QPainter* painter, const QWidget* widget) const; + void drawControlMenuItem(const QStyleOption* option, QPainter* painter, const QWidget* widget) const; + void drawPEPanelMenu(const QStyleOption* option, QPainter* painter, const QWidget* widget) const; // progressbar QSize progressBarSizeFromContents(const QStyleOption* option, const QSize& contentSize, const QWidget* widget) const;