Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sync: from linuxdeepin/qt5integration #38

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,23 @@ function(dtk_add_plugin)
endfunction()

find_package(Dtk${VERSION_SUFFIX} REQUIRED COMPONENTS Widget)
cmake_dependent_option(ENABLE_QT_XDG_ICON_LOADER "Enable QtXdgIconLoader" ON "QT_VERSION_MAJOR EQUAL 5" OFF)

option(ENABLE_QT_XDG_ICON_LOADER "Enable QtXdgIconLoader" ON)
find_package(Qt${QT_VERSION_MAJOR}XdgIconLoader)
find_package(Qt${QT_VERSION_MAJOR}Xdg REQUIRED)
if (NOT Qt${QT_VERSION_MAJOR}XdgIconLoader_FOUND)
message(WARNING " Qt${QT_VERSION_MAJOR}XdgIconLoader Not Found, DISABLE QtXdgIconLoader !")
set (ENABLE_QT_XDG_ICON_LOADER OFF)
endif()

if(ENABLE_QT_XDG_ICON_LOADER)
find_package(Qt5XdgIconLoader REQUIRED)
find_package(Qt5Xdg REQUIRED)
set(QT_XDG_ICON_DEPS Qt5XdgIconLoader Qt5Xdg)
set(XDG_ICON_VERSION_MAJOR ${Qt5XdgIconLoader_VERSION_MAJOR})
set(QT_XDG_ICON_DEPS Qt${QT_VERSION_MAJOR}XdgIconLoader Qt${QT_VERSION_MAJOR}Xdg)

if("${QT_VERSION_MAJOR}" STREQUAL "5")
set(XDG_ICON_VERSION_MAJOR ${Qt5XdgIconLoader_VERSION_MAJOR})
elseif("${QT_VERSION_MAJOR}" STREQUAL "6")
set(XDG_ICON_VERSION_MAJOR ${Qt6XdgIconLoader_VERSION_MAJOR})
endif()
endif()

set(PLUGIN_OUTPUT_BASE_DIR ${CMAKE_BINARY_DIR}/plugins CACHE STRING "Plugin output base path")
Expand Down
4 changes: 3 additions & 1 deletion platformthemeplugin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS DBus Widgets)
set(QT_LIBS Qt${QT_VERSION_MAJOR}::DBus Qt${QT_VERSION_MAJOR}::Widgets)
if(QT_VERSION_MAJOR EQUAL 5)
find_package(Qt5X11Extras REQUIRED)
list(APPEND QT_LIBS Qt5::X11Extras ${QT_XDG_ICON_DEPS})
list(APPEND QT_LIBS Qt5::X11Extras)
if(QT_VERSION_MINOR GREATER_EQUAL 8) # Qt5.8
find_package(Qt5ThemeSupport REQUIRED)
list(APPEND QT_LIBS Qt5::ThemeSupportPrivate)
Expand All @@ -26,10 +26,12 @@ if(QT_VERSION_MAJOR EQUAL 5)
else()
list(APPEND QT_LIBS Qt6::GuiPrivate)
endif()

find_package(PkgConfig REQUIRED)
pkg_check_modules(Deps REQUIRED IMPORTED_TARGET mtdev x11)
if(ENABLE_QT_XDG_ICON_LOADER)
set(DEFS -DXDG_ICON_VERSION_MAR=${XDG_ICON_VERSION_MAJOR})
list(APPEND QT_LIBS ${QT_XDG_ICON_DEPS})
endif()
if(QT_VERSION_MAJOR EQUAL 5)
qt5_add_dbus_interface(DBUS_INTERFACES ${CMAKE_CURRENT_LIST_DIR}/xmls/com.deepin.filemanager.filedialog.xml filedialog_interface)
Expand Down
117 changes: 104 additions & 13 deletions styleplugins/chameleon/chameleonstyle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include <QBitmap>
#include <QTableView>
#include <QStyledItemDelegate>
#include <QVariantAnimation>
#include <DSpinBox>
#include <DTreeView>
#include <DIconButton>
Expand Down Expand Up @@ -122,6 +123,57 @@
#endif
}

ChameleonMovementAnimation::ChameleonMovementAnimation(QWidget *targetWidget)
: QVariantAnimation(targetWidget)
{
setDuration(150);

connect(this, &QVariantAnimation::valueChanged, targetWidget, [this] (const QVariant &value) {
if (!isRuning())
return;

const auto rect = value.toRect();
Q_ASSERT(!m_currentRect.isEmpty());
this->targetWidget()->update(m_currentRect.united(rect));
m_currentRect = rect;
});
connect(this, &QVariantAnimation::finished, targetWidget, [this] {
Q_ASSERT(m_currentRect == m_targetRect);
// 确保动画结束后有一帧的刷新,因为在菜单的动画过程中会修改菜单文字的 opacity
// 对opacity的修改会根据是否处于动画状态进行判断,因此要确保动画结束后刷新它
this->targetWidget()->update(m_currentRect);
});
}

QWidget *ChameleonMovementAnimation::targetWidget() const
{
return qobject_cast<QWidget*>(parent());
}

void ChameleonMovementAnimation::setTargetRect(const QRect &rect)
{
if (m_targetRect == rect)
return;

m_lastTargetRect = m_targetRect;
m_targetRect = rect;

if (m_currentRect.isEmpty())
m_currentRect = m_lastTargetRect;

// 当目标绘制区域改变时,说明当前正在进行的动画过期了,应该重新开始动画
stop();
setStartValue(m_currentRect);
setEndValue(rect);

if (!m_currentRect.isEmpty()) {
start();
} else {
// 这种情况说明不需要进行动画,往往发生在首次显示,这时候应该直接绘制到目标区域
m_currentRect = rect;
}
}

ChameleonStyle::ChameleonStyle()
: DStyle()
{
Expand Down Expand Up @@ -2757,7 +2809,7 @@
return true;
}

void ChameleonStyle::drawMenuItemBackground(const QStyleOption *option, QPainter *painter, QStyleOptionMenuItem::MenuItemType type) const
ChameleonMovementAnimation *ChameleonStyle::drawMenuItemBackground(const QStyleOption *option, QPainter *painter, QStyleOptionMenuItem::MenuItemType type) const
{
QBrush color;
bool selected = (option->state & QStyle::State_Enabled) && option->state & QStyle::State_Selected;
Expand All @@ -2766,7 +2818,7 @@
painter->setPen(Qt::NoPen);
painter->setBrush(getColor(option, QPalette::Highlight));
painter->drawRect(option->rect);
return;
return nullptr;
}

// 清理旧的阴影
Expand All @@ -2791,8 +2843,6 @@
}

if (selected) {
color = option->palette.highlight();

// draw shadow
if (type == QStyleOptionMenuItem::Normal) {
if (option->styleObject) {
Expand All @@ -2807,9 +2857,7 @@
}
}
}

painter->fillRect(option->rect, color);
} else {
} else do {
color = option->palette.window().color();

if (color.color().isValid() && color.color().alpha() != 0) {
Expand Down Expand Up @@ -2846,14 +2894,14 @@
}

if (!option->styleObject)
return;
break;

// 为上一个item绘制阴影
const QRect shadow = option->styleObject->property("_d_menu_shadow_rect").toRect();

// 判断阴影rect是否在自己的区域
if (!option->rect.contains(shadow.center()))
return;
break;

static QColor shadow_color;
static QPixmap shadow_pixmap;
Expand All @@ -2870,11 +2918,47 @@
if (!shadow_pixmap.isNull()) {
if (QMenu *menu = qobject_cast<QMenu *>(option->styleObject)) {
if (!menu->geometry().contains(QCursor::pos()))
return;
break;
}
painter->drawPixmap(shadow, shadow_pixmap);
}
} while (false);

{ // 无论如何都尝试绘制,因为可能有动画存在
color = option->palette.highlight();

QWidget *animationTargetWidget = qobject_cast<QWidget*>(option->styleObject);
if (!option->styleObject)
animationTargetWidget = dynamic_cast<QWidget*>(painter->device());

ChameleonMovementAnimation *animation = nullptr;

if (animationTargetWidget) {
animation = animationTargetWidget->findChild<ChameleonMovementAnimation*>("_d_menu_select_animation",
Qt::FindDirectChildrenOnly);
if (!animation) {
animation = new ChameleonMovementAnimation(animationTargetWidget);
animation->setObjectName("_d_menu_select_animation");
}

if (selected)
animation->setTargetRect(option->rect);
}

if (animation && animation->isRuning()) {
auto opacity = painter->opacity();
// 一些状态为 disable 的 menu item 在绘制时会修改不透明度,这里暂时改回1.0。
painter->setOpacity(1.0);
painter->fillRect(animation->currentRect(), color);
painter->setOpacity(opacity);

return animation;
} else if (selected) {
painter->fillRect(option->rect, color);
}
}

return nullptr;
}

void ChameleonStyle::drawMenuItemRedPoint(const QStyleOptionMenuItem *option, QPainter *painter, const QWidget *widget) const
Expand Down Expand Up @@ -2955,7 +3039,7 @@
bool sunken = menuItem->state & State_Sunken;

//绘制背景
drawMenuItemBackground(option, painter, menuItem->menuItemType);
auto animation = drawMenuItemBackground(option, painter, menuItem->menuItemType);

//绘制分段
if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
Expand All @@ -2972,8 +3056,15 @@
return true;
}

const bool useHighlightedText = selected && !animation;
if (!useHighlightedText && selected) {
// 在动画中时,selected item 的文字颜色不会使用 HighlightedText,当动画结束后会立即
// 变为 HighlightedText,会显得比较突然,因此使用不透明度对文本等内容进行过渡
painter->setOpacity(1.0 - animation->progress());
}

//绘制选择框
bool ignoreCheckMark = false;

Check warning on line 3067 in styleplugins/chameleon/chameleonstyle.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Condition '!ignoreCheckMark' is always true

int frameRadius = DStyle::pixelMetric(PM_FrameRadius); //打钩矩形的左侧距离item的左边缘; 也是 打钩矩形的右侧距离 图文内容的左边缘
int smallIconSize = proxy()->pixelMetric(PM_ButtonIconSize, option, widget);//打钩的宽度
Expand All @@ -2990,7 +3081,7 @@
checkRect.moveCenter(QPoint(checkRect.left() + smallIconSize / 2, menuItem->rect.center().y()));
painter->setRenderHint(QPainter::Antialiasing);

if (selected)
if (useHighlightedText)
painter->setPen(getColor(option, QPalette::HighlightedText));
else
painter->setPen(getColor(option, QPalette::BrightText));
Expand All @@ -3010,7 +3101,7 @@

}

if (selected) {
if (useHighlightedText) {
painter->setPen(getColor(option, QPalette::HighlightedText));
} else {
if ((option->state & QStyle::State_Enabled)) {
Expand Down
30 changes: 29 additions & 1 deletion styleplugins/chameleon/chameleonstyle.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define CHAMELEONSTYLE_H

#include <DStyle>
#include <QVariantAnimation>

DWIDGET_USE_NAMESPACE

Expand All @@ -18,6 +19,33 @@ class DStyleOptionButtonBoxButton;
DWIDGET_END_NAMESPACE

namespace chameleon {
class ChameleonMovementAnimation : public QVariantAnimation
{
Q_OBJECT

public:
explicit ChameleonMovementAnimation(QWidget *targetWidget);

inline QRect currentRect() const {
return m_currentRect;
}

inline bool isRuning() const {
return state() == QVariantAnimation::Running;
}

inline float progress() const {
return float(currentLoopTime()) / duration();
}

QWidget *targetWidget() const;
void setTargetRect(const QRect &rect);

private:
QRect m_currentRect;
QRect m_targetRect;
QRect m_lastTargetRect;
};

class ChameleonStyle : public DStyle
{
Expand Down Expand Up @@ -67,7 +95,7 @@ class ChameleonStyle : public DStyle
bool drawSpinBox(const QStyleOptionSpinBox *opt, QPainter *p, const QWidget *w) const;
void updateSpinBoxButtonState(const QStyleOptionSpinBox *opt, QStyleOptionButton& button, bool isActive, bool isEnabled) const;
bool drawMenuBarItem(const QStyleOptionMenuItem *option, QRect &rect, QPainter *painter, const QWidget *widget) const;
void drawMenuItemBackground(const QStyleOption *option, QPainter *painter, QStyleOptionMenuItem::MenuItemType type) const;
ChameleonMovementAnimation *drawMenuItemBackground(const QStyleOption *option, QPainter *painter, QStyleOptionMenuItem::MenuItemType type) const;
bool drawMenuItem(const QStyleOptionMenuItem *option, QPainter *painter, const QWidget *widget) const;
bool drawTabBar(QPainter *painter ,const QStyleOptionTab *tab, const QWidget *widget) const;
bool drawTabBarLabel(QPainter *painter ,const QStyleOptionTab *tab, const QWidget *widget) const;
Expand Down
Loading