Skip to content

fix(editor): add hover and press states to color mark icons - #511

Open
tianming-1996 wants to merge 1 commit into
linuxdeepin:release/eaglefrom
tianming-1996:release/eagle
Open

fix(editor): add hover and press states to color mark icons#511
tianming-1996 wants to merge 1 commit into
linuxdeepin:release/eaglefrom
tianming-1996:release/eagle

Conversation

@tianming-1996

@tianming-1996 tianming-1996 commented Aug 7, 2026

Copy link
Copy Markdown

根因分析

颜色标记图标 ColorLabelsrc/widgets/ColorSelectWdg.h:53-63)仅实现 m_bSelected 一个状态,缺失 hover 和 press 交互状态:

  • 构造函数虽调用了 setMouseTracking(true),但未重写 enterEvent()/leaveEvent()
  • mousePressEvent() 直接选中,无 press 过渡反馈
  • paintEvent() 只绘制默认圆/选中圆环两态

修复方案

ColorLabel 增加 m_bHover/m_bPressed 状态变量,重写 enterEvent()/leaveEvent()/mousePressEvent()/mouseReleaseEvent()paintEvent() 三分支渲染:press 态颜色加深+微缩,hover 态外扩,normal 保持原有逻辑。选中信号改为 release 触发(与 Qt 按钮标准行为一致)。

改动安全评估

低风险。ColorLabelColorSelectWdg 中的私有控件,无外部引用。新增 hover/press 属纯叠加性视觉增强,sigColorClicked 信号语义不变(仅触发时机从 press 改为 release),不破坏 ColorSelectWdg 的互斥选中逻辑。

PMS: BUG-196825

Summary by Sourcery

Bug Fixes:

  • Add hover and pressed visual states to ColorLabel color markers so their interaction feedback matches user expectations and Qt button conventions.

@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.

Sorry @tianming-1996, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: tianming-1996

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

@sourcery-ai

sourcery-ai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds proper hover and press interaction states to ColorLabel in ColorSelectWdg, refactoring painting and mouse event handling so the color markers visually respond to hover/press and emit their selection signal on mouse release instead of press.

Sequence diagram for updated ColorLabel mouse interaction

sequenceDiagram
    actor User
    participant ColorLabel
    participant ColorSelectWdg

    User->>ColorLabel: enterEvent
    ColorLabel->>ColorLabel: m_bHover = true
    ColorLabel->>ColorLabel: update

    User->>ColorLabel: mousePressEvent (LeftButton)
    ColorLabel->>ColorLabel: m_bPressed = true
    ColorLabel->>ColorLabel: update

    User->>ColorLabel: mouseReleaseEvent (LeftButton)
    ColorLabel->>ColorLabel: m_bPressed = false
    ColorLabel->>ColorLabel: m_bSelected = true
    ColorLabel->>ColorLabel: update
    ColorLabel-->>ColorSelectWdg: sigColorClicked(m_bSelected, m_color)

    User->>ColorLabel: leaveEvent
    ColorLabel->>ColorLabel: m_bHover = false
    ColorLabel->>ColorLabel: m_bPressed = false
    ColorLabel->>ColorLabel: update
Loading

File-Level Changes

Change Details Files
Implement hover and press visual states for ColorLabel and adjust selection signaling to occur on mouse release.
  • Refactor paintEvent to branch on pressed, hover, and normal states with distinct circle geometry and color (pressed: inner circle shrunk and darkened; hover: slightly enlarged circle with outer glow; normal: previous small-circle-plus-ring logic).
  • Introduce m_bHover and m_bPressed state flags, updating them in new enterEvent, leaveEvent, mousePressEvent, and mouseReleaseEvent overrides, and triggering repaint via update().
  • Change selection activation from mousePressEvent to mouseReleaseEvent, ensuring the signal is emitted only when the left mouse button is released while still in the pressed state, and call base-class event handlers for proper propagation.
  • Add QEvent include and mark overridden event handlers with override in the header for clarity and correctness.
src/widgets/ColorSelectWdg.cpp
src/widgets/ColorSelectWdg.h

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

ColorLabel widget only implements selected/unselected visual states,
missing hover and press feedback. This adds enterEvent/leaveEvent for
hover highlighting and mousePressEvent/mouseReleaseEvent for press
animation, improving interaction experience.

为颜色标记图标增加悬停与按压交互状态。ColorLabel 原先仅有选中/未选中两种
视觉状态,缺少 hover 和 press 反馈。新增 enterEvent/leaveEvent 实现悬停
高亮,mousePressEvent/mouseReleaseEvent 实现按压动画。

Log: 为颜色标记图标增加悬停与按压交互状态
PMS: BUG-196825
Influence: 右键菜单颜色标记子菜单的颜色图标现在有 hover/press 视觉反馈,
不影响已有标记和清除功能。
@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

★ 总体评分:98分

■ 【总体评价】

代码实现了ColorLabel控件的悬停与按压视觉反馈,交互逻辑规范且无安全隐患
逻辑完全正确,代码规范良好,仅因存在极少量绘制代码重复扣2分

■ 【详细分析】

  • 1.语法逻辑(完全正确)✓

代码在头文件中正确添加了override关键字,确保了虚函数重写的安全性。状态切换逻辑严密,在leaveEvent中同时重置了m_bHover和m_bPressed状态,防止鼠标移出后状态残留。mouseReleaseEvent中通过判断e->button() == Qt::LeftButton && m_bPressed确保了只有在控件内完成按下并释放左键时才触发选中信号,完美修复了原代码在mousePressEvent中直接触发导致的交互不符合规范的问题。
建议:保持当前的实现方式,无需额外修改。

  • 2.代码质量(良好)✓

代码命名符合DTK风格规范,新增的m_bHover和m_bPressed变量使用了明确的前缀和类型标识。注释清晰,准确描述了Normal、Hover、Press三种状态下的视觉表现意图。格式化上修复了原代码中操作符周围缺少空格的问题。
潜在问题:在paintEvent的m_bPressed和m_bHover分支中,绘制选中状态圆环的代码高度重复。
建议:将绘制选中圆环的逻辑提取为一个私有辅助函数,如drawSelectedRing,以提升代码可维护性。

  • 3.代码性能(高效)✓

paintEvent中每次重绘都会重新构造QPainterPath对象并进行路径相减运算。由于ColorLabel是一个轻量级的二维图形控件,涉及的仅仅是几个椭圆路径的生成与填充,计算复杂度极低,不会引起任何可感知的性能瓶颈或卡顿。
建议:无需进行性能优化,保持当前的直接绘制方式即可。

  • 4.代码安全(存在0个安全漏洞)✓

漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个
本次修改纯粹涉及Qt本地图形绘制与基础鼠标事件处理,未引入任何网络请求、文件读写、命令执行或外部数据解析逻辑,完全不存在命令注入、缓冲区溢出等安全攻击面。
建议:继续保持安全的编码习惯,在后续扩展功能时注意对外部输入的校验。

■ 【改进建议代码示例】

// src/widgets/ColorSelectWdg.h
class ColorLabel : public DWidget
{
    // ... 其他代码保持不变
private:
    void drawSelectedRing(QPainter &painter, const QRect &r, int innerDistance);
    // ... 其他代码保持不变
};

// src/widgets/ColorSelectWdg.cpp
void ColorLabel::drawSelectedRing(QPainter &painter, const QRect &r, int innerDistance)
{
    if (!m_bSelected) return;
    QPainterPath ring;
    ring.addEllipse(r.adjusted(innerDistance, innerDistance, -innerDistance, -innerDistance));
    QPainterPath outerPath;
    outerPath.addEllipse(r);
    ring = outerPath - ring;
    painter.fillPath(ring, m_color);
}

void ColorLabel::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)

    int distance = 2;
    QRect r = rect();

    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::Qt4CompatiblePainting);

    if (m_bPressed) {
        QRectF pressedRect = r.adjusted(distance, distance, -distance, -distance);
        QPainterPath pressedPath;
        pressedPath.addEllipse(pressedRect);
        painter.fillPath(pressedPath, m_color.darker(130));
        drawSelectedRing(painter, r, distance / 2);
    } else if (m_bHover) {
        QRectF hoverRect = r.adjusted(distance, distance, -distance, -distance);
        QPainterPath hoverPath;
        hoverPath.addEllipse(hoverRect);
        painter.fillPath(hoverPath, m_color);
        drawSelectedRing(painter, r, distance);
    } else {
        QPainterPath bigCircle;
        bigCircle.addEllipse(r);

        QPainterPath smallCircle;
        smallCircle.addEllipse(r.adjusted(2 * distance, 2 * distance, -2 * distance, -2 * distance));

        painter.fillPath(smallCircle, m_color);
        drawSelectedRing(painter, r, distance);
    }

    painter.end();
}

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants