Changeset View
Changeset View
Standalone View
Standalone View
applets/taskmanager/package/contents/ui/GroupDialog.qml
Show All 29 Lines | 29 | PlasmaCore.Dialog { | |||
---|---|---|---|---|---|
30 | id: groupDialog | 30 | id: groupDialog | ||
31 | visible: false | 31 | visible: false | ||
32 | 32 | | |||
33 | type: PlasmaCore.Dialog.PopupMenu | 33 | type: PlasmaCore.Dialog.PopupMenu | ||
34 | flags: Qt.WindowStaysOnTopHint | 34 | flags: Qt.WindowStaysOnTopHint | ||
35 | hideOnWindowDeactivate: true | 35 | hideOnWindowDeactivate: true | ||
36 | location: plasmoid.location | 36 | location: plasmoid.location | ||
37 | 37 | | |||
38 | property int preferredWidth: Screen.width / (3 * Screen.devicePixelRatio) | 38 | readonly property int preferredWidth: Screen.width / (3 * Screen.devicePixelRatio) | ||
39 | property int preferredHeight: Screen.height / (2 * Screen.devicePixelRatio) | 39 | readonly property int preferredHeight: Screen.height / (2 * Screen.devicePixelRatio) | ||
40 | property int contentWidth: scrollArea.overflowing ? mainItem.width - (units.smallSpacing * 3) : mainItem.width | 40 | readonly property int contentWidth: scrollArea.overflowing ? mainItem.width - (units.smallSpacing * 3) : mainItem.width | ||
41 | property TextMetrics textMetrics: TextMetrics {} | 41 | readonly property TextMetrics textMetrics: TextMetrics {} | ||
42 | property alias overflowing: scrollArea.overflowing | 42 | property alias overflowing: scrollArea.overflowing | ||
43 | property alias activeTask: focusActiveTaskTimer.targetIndex | 43 | property alias activeTask: focusActiveTaskTimer.targetIndex | ||
44 | property var _oldAppletStatus: PlasmaCore.Types.UnknownStatus | ||||
44 | 45 | | |||
45 | function selectTask(task) { | 46 | function selectTask(task) { | ||
46 | if (!task) { | 47 | if (!task) { | ||
47 | return; | 48 | return; | ||
48 | } | 49 | } | ||
49 | 50 | | |||
50 | task.forceActiveFocus(); | 51 | task.forceActiveFocus(); | ||
51 | scrollArea.ensureItemVisible(task); | 52 | scrollArea.ensureItemVisible(task); | ||
52 | } | 53 | } | ||
53 | 54 | | |||
54 | mainItem: PlasmaExtras.ScrollArea { | 55 | mainItem: MouseHandler { | ||
55 | id: scrollArea | | |||
56 | | ||||
57 | property bool overflowing: (viewport.height < contentItem.height) | | |||
58 | | ||||
59 | horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff | | |||
60 | | ||||
61 | function ensureItemVisible(item) { | | |||
62 | var itemTop = item.y; | | |||
63 | var itemBottom = (item.y + item.height); | | |||
64 | | ||||
65 | if (itemTop < flickableItem.contentY) { | | |||
66 | flickableItem.contentY = itemTop; | | |||
67 | } | | |||
68 | | ||||
69 | if ((itemBottom - flickableItem.contentY) > viewport.height) { | | |||
70 | flickableItem.contentY = Math.abs(viewport.height - itemBottom); | | |||
71 | } | | |||
72 | } | | |||
73 | | ||||
74 | MouseHandler { | | |||
75 | id: mouseHandler | 56 | id: mouseHandler | ||
76 | 57 | | |||
77 | width: parent.width | | |||
78 | height: (groupRepeater.count * (LayoutManager.verticalMargins() | | |||
79 | + Math.max(theme.mSize(theme.defaultFont).height, units.iconSizes.medium))) | | |||
80 | | ||||
81 | target: taskList | 58 | target: taskList | ||
82 | handleWheelEvents: !scrollArea.overflowing | 59 | handleWheelEvents: !scrollArea.overflowing | ||
83 | 60 | | |||
84 | Timer { | 61 | Timer { | ||
85 | id: focusActiveTaskTimer | 62 | id: focusActiveTaskTimer | ||
86 | 63 | | |||
87 | property var targetIndex: null | 64 | property var targetIndex: null | ||
88 | 65 | | |||
Show All 12 Lines | 77 | if (task.modelIndex() == targetIndex) { | |||
101 | selectTask(task); | 78 | selectTask(task); | ||
102 | return; | 79 | return; | ||
103 | } | 80 | } | ||
104 | } | 81 | } | ||
105 | } | 82 | } | ||
106 | } | 83 | } | ||
107 | } | 84 | } | ||
108 | 85 | | |||
86 | PlasmaExtras.ScrollArea { | ||||
87 | id: scrollArea | ||||
88 | | ||||
89 | anchors.fill: parent | ||||
90 | | ||||
91 | readonly property bool overflowing: (viewport.height < contentItem.height) | ||||
92 | | ||||
93 | horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff | ||||
94 | | ||||
95 | function ensureItemVisible(item) { | ||||
96 | var itemTop = item.y; | ||||
97 | var itemBottom = (item.y + item.height); | ||||
98 | | ||||
99 | if (itemTop < flickableItem.contentY) { | ||||
100 | flickableItem.contentY = itemTop; | ||||
101 | } | ||||
102 | | ||||
103 | if ((itemBottom - flickableItem.contentY) > viewport.height) { | ||||
104 | flickableItem.contentY = Math.abs(viewport.height - itemBottom); | ||||
105 | } | ||||
106 | } | ||||
107 | | ||||
109 | TaskList { | 108 | TaskList { | ||
110 | id: taskList | 109 | id: taskList | ||
111 | 110 | | |||
112 | anchors.fill: parent | 111 | width: parent.width | ||
113 | 112 | | |||
114 | add: Transition { | 113 | add: Transition { | ||
115 | // We trigger a null-interval timer in the first add | 114 | // We trigger a null-interval timer in the first add | ||
116 | // transition after setting the model so onTriggered | 115 | // transition after setting the model so onTriggered | ||
117 | // will run after the Flow has positioned items. | 116 | // will run after the Flow has positioned items. | ||
118 | 117 | | |||
119 | ScriptAction { | 118 | ScriptAction { | ||
120 | script: { | 119 | script: { | ||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Line(s) | 180 | VisualDataModel { | |||
184 | delegate: Task { | 183 | delegate: Task { | ||
185 | visible: true | 184 | visible: true | ||
186 | inPopup: true | 185 | inPopup: true | ||
187 | } | 186 | } | ||
188 | } | 187 | } | ||
189 | ] | 188 | ] | ||
190 | 189 | | |||
191 | onVisualParentChanged: { | 190 | onVisualParentChanged: { | ||
192 | if (!visualParent) { | 191 | if (visible && visualParent) { | ||
192 | attachModel(); | ||||
193 | } else { | ||||
193 | visible = false; | 194 | visible = false; | ||
194 | } | 195 | } | ||
195 | } | 196 | } | ||
196 | 197 | | |||
197 | onVisibleChanged: { | 198 | onVisibleChanged: { | ||
198 | if (visible && visualParent) { | 199 | if (visible && visualParent) { | ||
199 | groupFilter.model = tasksModel; | 200 | _oldAppletStatus = plasmoid.status; | ||
200 | groupFilter.rootIndex = groupFilter.modelIndex(visualParent.itemIndex); | 201 | plasmoid.status = PlasmaCore.Types.RequiresAttentionStatus; | ||
201 | 202 | | |||
202 | groupRepeater.aboutToPopulate = true; | 203 | attachModel(); | ||
203 | groupRepeater.model = groupFilter; | | |||
204 | 204 | | |||
205 | mainItem.forceActiveFocus(); | 205 | groupDialog.requestActivate(); | ||
206 | mouseHandler.forceActiveFocus(); | ||||
206 | } else { | 207 | } else { | ||
208 | plasmoid.status = _oldAppletStatus; | ||||
207 | visualParent = null; | 209 | visualParent = null; | ||
208 | groupRepeater.model = undefined; | 210 | groupRepeater.model = undefined; | ||
209 | groupFilter.model = undefined; | 211 | groupFilter.model = undefined; | ||
210 | groupFilter.rootIndex = undefined; | 212 | groupFilter.rootIndex = undefined; | ||
211 | } | 213 | } | ||
212 | } | 214 | } | ||
213 | 215 | | |||
216 | function attachModel() { | ||||
217 | if (!visualParent) { | ||||
218 | return; | ||||
219 | } | ||||
220 | | ||||
221 | if (!groupFilter.model) { | ||||
222 | groupFilter.model = tasksModel; | ||||
223 | } | ||||
224 | | ||||
225 | groupRepeater.aboutToPopulate = true; | ||||
226 | | ||||
227 | groupFilter.rootIndex = tasksModel.makeModelIndex(visualParent.itemIndex); | ||||
228 | | ||||
229 | if (!groupRepeater.model) { | ||||
230 | groupRepeater.model = groupFilter; | ||||
231 | } | ||||
232 | } | ||||
233 | | ||||
214 | function updateSize() { | 234 | function updateSize() { | ||
215 | if (!visible || !visualParent) { | 235 | if (!visible) { | ||
216 | return; | 236 | return; | ||
217 | } | 237 | } | ||
218 | 238 | | |||
219 | if (!groupRepeater.count) { | 239 | if (!visualParent) { | ||
220 | visible = false; | 240 | visible = false; | ||
221 | } else { | 241 | return; | ||
242 | } | ||||
243 | | ||||
244 | if (!visualParent.childCount) { | ||||
245 | visible = false; | ||||
246 | // Setting VisualDataModel.rootIndex drops groupRepeater.count to 0 | ||||
247 | // before the actual row count. updateSize is therefore invoked twice; | ||||
248 | // only update size once the repeater count matches the model role. | ||||
249 | } else if (visualParent.childCount == groupRepeater.count) { | ||||
222 | var task; | 250 | var task; | ||
223 | var maxWidth = 0; | 251 | var maxWidth = 0; | ||
224 | var maxHeight = 0; | 252 | var maxHeight = 0; | ||
225 | 253 | | |||
226 | backend.cancelHighlightWindows(); | 254 | backend.cancelHighlightWindows(); | ||
227 | 255 | | |||
228 | for (var i = 0; i < taskList.children.length - 1; ++i) { | 256 | for (var i = 0; i < taskList.children.length - 1; ++i) { | ||
229 | task = taskList.children[i]; | 257 | task = taskList.children[i]; | ||
230 | 258 | | |||
231 | textMetrics.text = task.labelText; | 259 | textMetrics.text = task.labelText; | ||
232 | var textWidth = textMetrics.boundingRect.width; | 260 | var textWidth = textMetrics.boundingRect.width; | ||
233 | 261 | | |||
234 | if (textWidth > maxWidth) { | 262 | if (textWidth > maxWidth) { | ||
235 | maxWidth = textWidth; | 263 | maxWidth = textWidth; | ||
236 | } | 264 | } | ||
237 | 265 | | |||
238 | task.labelTextChanged.connect(updateSize); | 266 | task.labelTextChanged.connect(updateSize); | ||
239 | } | 267 | } | ||
240 | 268 | | |||
241 | maxWidth += LayoutManager.horizontalMargins() + units.iconSizes.medium + 2 * units.smallSpacing; | | |||
242 | maxHeight = groupRepeater.count * (LayoutManager.verticalMargins() + Math.max(theme.mSize(theme.defaultFont).height, units.iconSizes.medium)); | 269 | maxHeight = groupRepeater.count * (LayoutManager.verticalMargins() + Math.max(theme.mSize(theme.defaultFont).height, units.iconSizes.medium)); | ||
243 | 270 | | |||
271 | maxWidth += LayoutManager.horizontalMargins() + units.iconSizes.medium + 2 * units.smallSpacing; | ||||
272 | | ||||
273 | // Add horizontal space for scrollbar if needed. | ||||
274 | // FIXME TODO HACK: Use actuall scrollbar width instead of a good guess. | ||||
275 | if (maxHeight > preferredHeight) { | ||||
276 | maxWidth += (units.smallSpacing * 3); | ||||
277 | } | ||||
278 | | ||||
244 | mainItem.height = Math.min(preferredHeight, maxHeight); | 279 | mainItem.height = Math.min(preferredHeight, maxHeight); | ||
245 | mainItem.width = Math.min(preferredWidth, (tasks.vertical ? Math.max(maxWidth, tasks.width) : Math.min(maxWidth, tasks.width))); | 280 | mainItem.width = Math.min(preferredWidth, (tasks.vertical ? Math.max(maxWidth, tasks.width) : Math.min(maxWidth, tasks.width))); | ||
246 | } | 281 | } | ||
247 | } | 282 | } | ||
248 | } | 283 | } |