Skip to content

Commit 4193ec2

Browse files
52cybdeepin-bot[bot]
authored andcommitted
fix: refactor popup width calculation into reusable AutoSizingComboBox
Extract the duplicated popup width calculation logic from DisplayMain into a reusable QML component, AutoSizingComboBox. This improves code maintainability and ensures consistent behavior across all ComboBoxes that require dynamic popup sizing. Log: Optimized combobox popup width for display settings Influence: 1. Verify resolution combobox dropdown width adapts to content 2. Verify refresh rate combobox dropdown width adapts to content 3. Test with various screen resolutions and refresh rate options 4. Ensure no regression in existing combobox functionality 5. Test with long and short text items to verify minimum width handling feat: 将弹窗宽度计算逻辑重构为可复用的 AutoSizingComboBox 组件 从 DisplayMain 中提取重复的弹窗宽度计算逻辑到可复用的 QML 组件 AutoSizingComboBox 中,提高代码可维护性,确保所有需要动态弹窗大小的 ComboBox 行为一致。 Log: 优化显示设置中的下拉框弹窗宽度 Influence: 1. 验证分辨率下拉框弹窗宽度自适应内容 2. 验证刷新率下拉框弹窗宽度自适应内容 3. 测试不同屏幕分辨率和刷新率选项 4. 确保现有下拉框功能无回归问题 5. 测试长文本和短文本项,验证最小宽度处理 PMS: BUG-366553
1 parent e3971f8 commit 4193ec2

2 files changed

Lines changed: 88 additions & 26 deletions

File tree

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd.
2+
//
3+
// SPDX-License-Identifier: LGPL-3.0-or-later
4+
5+
import QtQuick
6+
import org.deepin.dtk 1.0
7+
import org.deepin.dtk.style 1.0 as DS
8+
9+
10+
// AutoSizingComboBox — ComboBox 封装,自动适配下拉面板宽度
11+
ComboBox {
12+
id: control
13+
14+
property real _popupContentWidth: 0
15+
16+
TextMetrics {
17+
id: _textMetrics
18+
font: control.font
19+
}
20+
21+
/**
22+
* 文本像素宽度之外的额外填充总和(最坏情况:当前选中项 checked=true 时 indicator 可见)
23+
*
24+
* T.MenuItem 内容布局(对 checked 项,indicator 显式时):
25+
* ┌──────────────────────────────────────────────────────────┐
26+
* │ leftPadding(6) │ indicator(14) │ spacing(6) │ contentItem(IconLabel) │ rightPadding(6) │
27+
* └──────────────────────────────────────────────────────────┘
28+
*
29+
* Style 常量来源(dtkdeclarative/qt6/src/qml/FlowStyle.qml):
30+
* DS.Style.popup.margin = 10 Popup contentItem 边距
31+
* DS.Style.control.padding = 6 MenuItem 外 padding
32+
* DS.Style.control.spacing = 6 Indicator 与 contentItem 间距
33+
* DS.Style.menu.item.iconSize.width = 14 Indicator(checkmark)宽度
34+
* DS.Style.menu.item.contentPadding = 30 IconLabel 左 padding
35+
*/
36+
37+
readonly property real _textExtraPadding: DS.Style.menu.item.contentPadding // 30
38+
+ DS.Style.control.padding * 2 // 12
39+
+ DS.Style.popup.margin * 2 // 20
40+
+ DS.Style.menu.item.iconSize.width // 14 (indicator)
41+
+ DS.Style.control.spacing // 6 (indicator spacing)
42+
// = 82
43+
44+
function _updatePopupWidth() {
45+
var m = model
46+
if (!m) {
47+
_popupContentWidth = 0
48+
return
49+
}
50+
51+
var count = typeof m.count === 'number' ? m.count
52+
: (typeof m.length === 'number' ? m.length : 0)
53+
if (count <= 0) {
54+
_popupContentWidth = 0
55+
return
56+
}
57+
58+
var usesGet = typeof m.get === 'function'
59+
60+
var maxWidth = 0
61+
for (var i = 0; i < count; ++i) {
62+
var item = usesGet ? m.get(i) : m[i]
63+
if (!item) {
64+
continue
65+
}
66+
67+
var text = textRole ? item[textRole] : item.text
68+
if (text === undefined || text === "") {
69+
continue
70+
}
71+
72+
_textMetrics.text = String(text)
73+
var w = _textMetrics.width + _textExtraPadding
74+
if (w > maxWidth) {
75+
maxWidth = w
76+
}
77+
}
78+
_popupContentWidth = maxWidth
79+
}
80+
81+
onModelChanged: _updatePopupWidth()
82+
onFontChanged: _updatePopupWidth()
83+
Component.onCompleted: _updatePopupWidth()
84+
85+
popup.implicitWidth: Math.max(_popupContentWidth, width)
86+
}

src/plugin-display/qml/DisplayMain.qml

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -710,16 +710,14 @@ DccObject {
710710
displayName: qsTr("Resolution") // 分辨率
711711
weight: 20
712712
pageType: DccObject.Editor
713-
page: ComboBox {
713+
page: AutoSizingComboBox {
714714
id: resolutionComboBox
715715
flat: true
716716
enabled: !(root.isExtendMode && dccData.isConcatScreenMode)
717717
model: root.getResolutionModel(screen.resolutionList, screen.bestResolution)
718718
textRole: "text"
719719
valueRole: "value"
720720

721-
property real popupContentWidth: 0
722-
723721
function indexOfSize(model, currentSize) {
724722
for (var i = 0; i < model.length; i++) {
725723
let v = model[i]
@@ -730,28 +728,6 @@ DccObject {
730728
return -1
731729
}
732730

733-
TextMetrics {
734-
id: resolutionTextMetrics
735-
font: resolutionComboBox.font
736-
}
737-
738-
function updatePopupWidth() {
739-
var maxWidth = 0
740-
for (var i = 0; i < model.length; i++) {
741-
resolutionTextMetrics.text = model[i].text
742-
var itemWidth = resolutionTextMetrics.width + 80
743-
if (itemWidth > maxWidth) {
744-
maxWidth = itemWidth
745-
}
746-
}
747-
popupContentWidth = maxWidth
748-
}
749-
750-
Component.onCompleted: updatePopupWidth()
751-
onModelChanged: updatePopupWidth()
752-
753-
popup.width: Math.max(popupContentWidth, width)
754-
755731
currentIndex: indexOfSize(model, screen.currentResolution)
756732
onActivated: {
757733
if (screen.currentResolution === currentValue) {
@@ -856,7 +832,7 @@ DccObject {
856832
displayName: qsTr("Refresh Rate") // 刷新率
857833
weight: 40
858834
pageType: DccObject.Editor
859-
page: ComboBox {
835+
page: AutoSizingComboBox {
860836
flat: true
861837
enabled: !(root.isExtendMode && dccData.isConcatScreenMode)
862838
textRole: "text"

0 commit comments

Comments
 (0)