Skip to content

ToolButton: 深色模式 hover/pressed 毛玻璃效果 + checked 状态样式重构 - #672

Open
zqq-dora wants to merge 1 commit into
linuxdeepin:v25-flowstylefrom
zqq-dora:feat/toolbutton-dark-hover-pressed
Open

ToolButton: 深色模式 hover/pressed 毛玻璃效果 + checked 状态样式重构#672
zqq-dora wants to merge 1 commit into
linuxdeepin:v25-flowstylefrom
zqq-dora:feat/toolbutton-dark-hover-pressed

Conversation

@zqq-dora

@zqq-dora zqq-dora commented Aug 26, 2026

Copy link
Copy Markdown

ToolButton: 深色模式 hover/pressed 毛玻璃效果 + checked 状态样式重构

背景

ToolButton 在深色模式下的 hover/pressed 样式效果不理想:hover 时使用的是浅灰色 tint(rgba(1,1,1,0.15)),缺乏层次感和质感;checked 状态复用了 Button 的 accent 填充样式,视觉上与 ToolButton 的轻量风格不匹配。

本 PR 重新设计了 ToolButton 的深色模式 hover/pressed 样式,并重构了 checked 状态的独立样式。

修改内容

1. 深色模式 hover 效果(毛玻璃)

深色模式 hover 新增了背景模糊(backdrop blur)效果,模拟设计稿中的磨砂玻璃质感:

  • 背景模糊 radius: 15saturation: 100%
  • 背景色 rgba(20, 20, 20, 0.2) 半透明深色 tint
  • 顶部 1px 白色内阴影 rgba(255, 255, 255, 0.1)(高光)
  • 底部 1px 黑色内阴影 rgba(0, 0, 0, 0.5)(暗角)
  • 圆角 6px

模糊效果通过 D.InWindowBlur 实现,使用 D.ItemViewport 裁剪到圆角形状。模糊功能受平台限制(valid 属性门控),在不支持的平台仅显示 tint + 内阴影。

2. 深色模式 pressed 效果

深色模式 pressed 使用纯色 tint rgba(0, 0, 0, 0.15),不叠加模糊和内阴影,保持简洁。

3. checked 状态样式重构

checked 状态不再复用 Button 的 accent 填充样式,改为独立的 overlay chip 样式:

  • 背景:浅色模式 rgba(0, 0, 0, 0.1~0.15),深色模式 rgba(0, 0, 0, 0.3~0.35)
  • 文字/图标:统一使用 Highlight 强调色
  • 底部 1px 内阴影:浅色 rgba(0, 0, 0, 0.1),深色 rgba(0, 0, 0, 0.5)

4. InWindowBlur 组件增强

InWindowBlur.qml 新增 saturation 属性别名,暴露 MultiEffect 的饱和度参数,使 ToolButton 的深色 hover 可以设置 100% 饱和度。

涉及文件

文件 改动
qt6/src/qml/overridable/InWindowBlur.qml 新增 saturation 属性别名
qt6/src/qml/FlowStyle.qml toolButton QtObject 新增 radiuscheckedBackgroundcheckedTextcheckedShadowhoverBackground 属性
qt6/src/qml/ToolButton.qml 重构 textColorbackground 的 Binding 逻辑,新增深色 hover 毛玻璃和内阴影、checked 状态独立样式

已知限制

  • 背景模糊(backdrop blur)依赖平台 GPU 支持,在软件渲染或不支持 InWindowBlur 的环境下会降级为纯 tint + 内阴影(仅去掉模糊,视觉效果保持一致)
  • ButtonBox 有自己的 backgroundPanel 动画覆盖层,与本 PR 的 ToolButton hover 样式独立,不在本次修改范围内

Summary by Sourcery

Improve ToolButton state styling across themes with dark-mode frosted hover effects and a dedicated checked appearance.

New Features:

  • Add dark-mode frosted-glass hover styling for non-checked ToolButtons with a platform-aware blur fallback.
  • Expose saturation control through InWindowBlur for configurable backdrop effects.

Bug Fixes:

  • Improve the visual hierarchy of ToolButton hover and pressed states in dark mode.

Enhancements:

  • Refactor checked ToolButtons into a dedicated subtle overlay-chip style with accent-colored content and inset shadows.
  • Centralize ToolButton state palettes, radius, and background styling in FlowStyle.

@deepin-ci-robot

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: zqq-dora

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@deepin-ci-robot

Copy link
Copy Markdown
Contributor

Hi @zqq-dora. Thanks for your PR. 😃

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

CLA Assistant Lite bot:

如果你是以企业贡献者的身份进行提交,请联系我们签署企业贡献者许可协议
If you submit as corporate contributor, please contact us to sign our Corporate Contributor License Agreement

感谢您的提交,我们非常感谢。 像许多开源项目一样,在接受您的贡献之前,我们要求您签署我们的个人贡献者许可协议。 您只需发布与以下格式相同的评论即可签署个人贡献者许可协议
Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Individual Contributor License Agreement before we can accept your contribution. You can sign the Individual Contributor License Agreement by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA.

You can retrigger this bot by commenting recheck in this Pull Request

@deepin-ci-robot

Copy link
Copy Markdown
Contributor

Hi @zqq-dora. Thanks for your PR.

I'm waiting for a linuxdeepin member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@sourcery-ai

sourcery-ai Bot commented Aug 26, 2026

Copy link
Copy Markdown

Reviewer's Guide

本 PR 通过新增 ToolButton 专用主题调色板和状态绑定,彻底分离 checked 样式与通用 Button accent 填充,并利用平台能力门控的 InWindowBlur、圆角裁剪及内阴影实现深色 hover 毛玻璃效果;同时扩展 InWindowBlur 的 saturation 配置。

Sequence diagram for ToolButton state-dependent overlays

sequenceDiagram
    participant User
    participant ToolButton
    participant ColorSelector
    participant ButtonPanel
    participant InWindowBlur
    participant ItemViewport
    participant BoxInsetShadow

    User->>ToolButton: hover or press
    ToolButton->>ColorSelector: controlState
    ColorSelector-->>ButtonPanel: HoveredState or PressedState
    alt dark theme hover
        ButtonPanel->>InWindowBlur: radius and saturation
        InWindowBlur->>ItemViewport: clip hoverBlur.content to radius
        InWindowBlur-->>ButtonPanel: blur when valid
        ButtonPanel->>BoxInsetShadow: show top highlight and bottom shadow
    else non-checked hover or press
        ButtonPanel-->>ToolButton: apply hoverBackground
    end
    alt checked
        ToolButton-->>ButtonPanel: apply checkedBackground
        ToolButton-->>ToolButton: apply checkedText
        ButtonPanel->>BoxInsetShadow: apply checkedShadow
    end
Loading

File-Level Changes

Change Details Files
集中扩展 ToolButton 的主题配置,为 checked、hover 和 pressed 状态提供独立的颜色、阴影及圆角参数。
  • 新增 checked overlay、Highlight 文本色、底部内阴影和 hover/pressed 背景调色板。
  • 将 ToolButton 的圆角统一纳入样式配置。
qt6/src/qml/FlowStyle.qml
重构 ToolButton 的状态渲染,使 checked 状态采用轻量 overlay chip,并为深色 hover 增加可降级的毛玻璃和内阴影效果。
  • 通过状态条件 Binding 分离 checked 与非 checked 的背景、可见性和文本色逻辑。
  • 使用 InWindowBlur、ItemViewport 和两层 BoxInsetShadow 实现深色 hover 的模糊、高光及暗角效果。
  • 为 checked chip 添加 Highlight 内容色和底部内阴影,并保持 pressed 状态使用纯色覆盖。
qt6/src/qml/ToolButton.qml
扩展窗口内模糊组件对 MultiEffect 饱和度参数的暴露能力。
  • 新增 saturation 属性别名,供 ToolButton 配置 100% 饱和度。
qt6/src/qml/overridable/InWindowBlur.qml
调整 FlowStyle.qml 的结构布局,将既有样式对象从原位置移除并重新归入文件末尾区域。
  • 检查被移动的 submenu、panel、delegate、indicator、bar、progress、slider 等样式对象是否完整保留及作用域未变。
qt6/src/qml/FlowStyle.qml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 3 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="qt6/src/qml/FlowStyle.qml" line_range="822-823" />
<code_context>
         // the highlight color of main menu item, when submenu is opened.
</code_context>
<issue_to_address>
**issue (bug_risk):** FlowStyle.qml ends with an incomplete `property D.Palette submenuOpenedItemHigh` declaration after deleting the remainder of the style object. QML parsing fails, so the style module cannot be loaded and every component importing `DS.Style` fails to instantiate.

**Suggested fix:** Restore the deleted FlowStyle contents and complete the `submenuOpenedItemHighlight` declaration and closing braces.
</issue_to_address>

### Comment 2
<location path="qt6/src/qml/FlowStyle.qml" line_range="822-823" />
<code_context>
         // the highlight color of main menu item, when submenu is opened.
</code_context>
<issue_to_address>
**issue (broader_impact):** The change removes the existing style objects after the toolButton section, including `highlightPanel`, `behindWindowBlur`, `arrowRectangleBlur`, `itemDelegate`, `scrollBar`, `progressBar`, `titleBar`, and related properties that remain referenced by QML components. Those references resolve to undefined style objects at runtime even if the truncated FlowStyle declaration is repaired.

**Triggers:** When any component using one of the removed DS.Style properties is loaded.

**Suggested fix:** Keep all unrelated FlowStyle properties and only add the new toolButton properties.
</issue_to_address>

### Comment 3
<location path="qt6/src/qml/ToolButton.qml" line_range="205" />
<code_context>
+            visible: control.checked
+            z: D.DTK.AboveOrder
+            cornerRadius: buttonPanel.radius
+            shadowColor: control.D.ColorSelector.checkedShadow
+            shadowOffsetX: 0
+            shadowOffsetY: -1
</code_context>
<issue_to_address>
**issue (bug_risk):** `D.ColorSelector` exposes palette colors using the `...Color` naming convention, but the checked shadow is read as `control.D.ColorSelector.checkedShadow`. That attached property is undefined, so the checked chip's `shadowColor` does not receive the configured palette color and can produce an invalid binding/runtime warning.

**Triggers:** When a ToolButton is checked and the checked shadow is evaluated.

**Suggested fix:** Use the ColorSelector-exposed checked shadow color property, such as `control.D.ColorSelector.checkedShadowColor`, or bind directly to the `checkedShadow` palette through a supported selector API.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread qt6/src/qml/FlowStyle.qml Outdated
Comment thread qt6/src/qml/FlowStyle.qml Outdated
Comment thread qt6/src/qml/ToolButton.qml
@hudeng-go

Copy link
Copy Markdown

/ok-to-test

Comment thread qt6/src/qml/FlowStyle.qml
Comment thread qt6/src/qml/ToolButton.qml
Comment thread qt6/src/qml/FlowStyle.qml Outdated
@zqq-dora

zqq-dora commented Sep 3, 2026

Copy link
Copy Markdown
Author

关于内阴影在 QWidget 端的实现问题,已在 dtkwidget 中新增了 DDrawUtils::drawInsetShadow(),接口与现有的 drawShadow() 平行,使用同样的 qt_blurImage 做内阴影渲染,可以在 QWidget 的 ToolButton 样式中调用以实现一致的视觉效果。

dtkwidget PR: linuxdeepin/dtkwidget#779

关于性能问题,深色 hover 的模糊和内阴影只在鼠标悬停时触发(__darkHover 条件门控),且 ToolButton 通常只有少量同时显示,实际开销可控。在不支持 InWindowBlur 的平台上会自动降级为纯 tint + 内阴影,不会触发模糊。

另外,之前的两个问题也已修复:

  1. FlowStyle.qml 被误删的样式对象已全部恢复
  2. hoverBackground 已改名为 background,利用 Palette 内建的状态切换机制,不再手动判断 controlState

@18202781743

Copy link
Copy Markdown
Contributor

这一个pr只需要一个commit,

@deepin-ci-robot

Copy link
Copy Markdown
Contributor

deepin pr auto review

🤖 AI 代码审查报告

总体评分: 98 分 (通过阈值: 70分)

Pass


📊 总体评价

项目 结果
项目名称 linuxdeepin/dtkdeclarative
PR 地址 #672
PR 标题 ToolButton: 深色模式 hover/pressed 毛玻璃效果 + checked 状态样式重构
作者 zqq-dora
分支 feat/toolbutton-dark-hover-pressed → v25-flowstyle
修改文件 FlowStyle.qml, ToolButton.qml, InWindowBlur.qml
变更统计 +175 / -14
审查结论 代码审查通过
评分详情 代码质量优秀,实现与PR描述的目标一致。无安全漏洞,语法逻辑正确,性能合理。仅在代码质量和性能维度有极少量优化空间。

📝 代码目的分析

本 PR 旨在重新设计 ToolButton 的深色模式 hover/pressed 样式,并重构 checked 状态的独立样式:

  1. 深色模式 hover 新增背景模糊(backdrop blur)效果,模拟磨砂玻璃质感
  2. 深色模式 pressed 使用纯色 tint,保持简洁
  3. checked 状态不再复用 Button 的 accent 填充样式,改为独立的 overlay chip 样式
  4. InWindowBlur 组件新增 saturation 属性别名

代码实现与上述目的完全一致,设计思路清晰,实现合理。


🔍 详细分析

1. 语法逻辑(25/25)✓ "语法正确,逻辑清晰"

语法正确,逻辑清晰

潜在问题:
✅ 未发现明显问题

分析详情:

  • QML 语法正确,所有属性定义、Binding 对象、组件嵌套均符合 QML 规范
  • 无内存泄漏风险:QML 通过父子所有权关系自动管理内存,InWindowBlur、BoxInsetShadow 作为 buttonPanel 的子元素会随父元素自动释放
  • 边界条件处理完善:
    • InWindowBlur 通过 hoverBlur.valid 门控平台支持检测,不支持时自动降级为纯 tint + 内阴影
    • __darkHover 属性正确组合三个条件(非 checked + 深色主题 + hovered 状态),互斥逻辑严密
    • 多个 Binding 对象使用 !control.checkedcontrol.checked 互斥条件,不会产生绑定冲突
  • 状态转换逻辑正确:normal → hover → pressed 各状态的颜色、可见性、模糊效果切换合理

2. 代码质量(24/25)✓ "代码结构清晰,注释完整"

代码结构清晰,注释完整

潜在问题:

  1. qt6/src/qml/ToolButton.qml,约155-175行,buttonPanel (ButtonPanel background) 中两个 BoxInsetShadow 元素(白色顶部高光和黑色底部暗角)结构高度相似,仅 shadowColorshadowOffsetY 不同。虽然 QML 声明式风格中这种写法可接受,但可考虑进一步简化以提升可维护性。

建议:

  1. 建议在 textColor 属性变更处添加简短注释说明为何移除 D.DTK.hasAnimation 分支判断,帮助后续维护者理解设计决策。当前注释主要描述新行为,缺少对旧行为变更的说明。

分析详情:

  • 注释完整性:优秀。每个新增属性和关键逻辑都有详细注释,解释设计决策和技术原因
  • 代码重复:轻微。两个 BoxInsetShadow 结构相似但参数不同,属 QML 常见模式
  • 结构合理性:良好。FlowStyle.qml 中的属性组织清晰,ToolButton.qml 中的组件层次合理
  • 调试信息:无残留调试代码

3. 代码性能(19/20)✓ "性能良好,资源使用合理"

性能良好,资源使用合理

潜在问题:

  1. qt6/src/qml/ToolButton.qml,约130-145行,buttonPanel (InWindowBlur) 中 InWindowBlur 组件作为 buttonPanel 的子元素始终被实例化,即使在浅色模式或非 hover 状态下。虽然 visible 属性正确控制了渲染,但 QML 对象本身仍占用内存。对于大量 ToolButton 实例的场景,可能存在轻微内存开销。

建议:

  1. 可考虑使用 Loader 延迟加载 InWindowBlur,仅在首次进入深色 hover 状态时创建。但当前实现已通过 visible 门控,实际影响可忽略。

分析详情:

  • 算法复杂度:不适用(UI 样式代码,无算法逻辑)
  • 系统调用:无频繁系统调用
  • 资源释放:QML 自动管理,无资源泄漏风险
  • 缓存策略:属性绑定自动缓存,无不必要的重复计算
  • 所有昂贵的操作(模糊渲染、阴影渲染)均通过 visible 属性正确门控

4. 代码安全(30/30)✓ "存在0个安全漏洞"

存在0个安全漏洞

漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个

安全漏洞详情:
✅ 未发现安全漏洞

分析详情:

  • 无用户输入处理:本 PR 为纯 UI 样式代码,不涉及用户输入
  • 无网络操作:无 API 调用、无网络请求
  • 无文件系统访问:无文件读写操作
  • 无命令执行:无 system/exec 调用
  • 无 SQL 查询:无数据库操作
  • 无硬编码密钥:无敏感信息
  • 无缓冲区操作:无 C/C++ 层面的内存操作
  • 颜色值使用 Qt.rgba() 标准方式,无注入风险

📋 修改文件清单

文件 变更类型 行数变化 说明
qt6/src/qml/FlowStyle.qml 修改 +86 toolButton QtObject 新增 radius、checkedBackground、checkedText、checkedShadow、background 属性
qt6/src/qml/ToolButton.qml 修改 +99/-14 重构 textColor 和 background Binding 逻辑,新增深色 hover 毛玻璃和内阴影、checked 状态独立样式
qt6/src/qml/overridable/InWindowBlur.qml 修改 +1 新增 saturation 属性别名

💡 改进建议

  1. BoxInsetShadow 简化(ToolButton.qml 约155-175行):两个深色 hover BoxInsetShadow 元素可考虑通过属性绑定差异化 shadowColorshadowOffsetY,减少重复配置
  2. InWindowBlur 延迟加载(ToolButton.qml 约130-145行):可考虑使用 Loader 在首次需要时创建 InWindowBlur,减少非必要时的内存占用
  3. textColor 变更注释(ToolButton.qml 约13行):建议补充说明移除 D.DTK.hasAnimation 分支的原因

本报告由 AI 代码审查工具自动生成

Comment thread qt6/src/qml/ToolButton.qml
Comment thread qt6/src/qml/ToolButton.qml Outdated
Binding on visible {
when: D.DTK.hasAnimation
value: control.hovered && !control.checked
when: control.checked

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when: D.DTK.hasAnimation
value: control.hovered && !control.checked
这个逻辑不需要了么?如果直接为true,直接绑定就好了,应该不需要这个Binding,

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里我已经删掉了。ButtonPanel 默认的 visible 逻辑本身就覆盖了 button.checked,checked 态仍然会正常显示,所以这个额外的 Binding 确实是冗余的。

@18202781743

Copy link
Copy Markdown
Contributor

需要修下ci报错的问题,

- 深色 hover: backdrop blur(radius=15, saturation=100%) + rgba(20,20,20,0.2) tint + 白色顶部/黑色底部内阴影
- 深色 pressed: rgba(0,0,0,0.15) 纯色 tint
- checked 状态: 独立 overlay chip 样式(checkedBackground/checkedText/checkedShadow)
- InWindowBlur: 新增 saturation 属性别名
- FlowStyle toolButton: 新增 radius/checkedBackground/checkedText/checkedShadow/background
- textColor 改为统一使用 toolButton.checkedText,不再按 hasAnimation 切换旧 checkedButton 文本样式
- 移除冗余的 checked visible Binding,复用 ButtonPanel 默认可见性
- 更新 ToolButton SPDX 版权年份到 2026
@zqq-dora
zqq-dora force-pushed the feat/toolbutton-dark-hover-pressed branch from 00a3b43 to 2f31602 Compare September 4, 2026 02:43
@zqq-dora

zqq-dora commented Sep 4, 2026

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA.

@zqq-dora

zqq-dora commented Sep 4, 2026

Copy link
Copy Markdown
Author

recheck

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants