on fe9d37e help sign in
unity8/qml/Panel/Panel.qml
446 lines 16 kB history raw
1/*
2 * Copyright (C) 2013-2017 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
17import QtQuick 2.4
18import Ubuntu.Components 1.3
19import Ubuntu.Layouts 1.0
20import Unity.Application 0.1
21import Unity.Indicators 0.1
22import Utils 0.1
23import Unity.ApplicationMenu 0.1
25import QtQuick.Window 2.2
27import "../ApplicationMenus"
28import "../Components"
29import "../Components/PanelState"
30import ".."
31import "Indicators"
33Item {
34 id: root
35 readonly property real panelHeight: panelArea.y + minimizedPanelHeight
37 property real minimizedPanelHeight: units.gu(3)
38 property real expandedPanelHeight: units.gu(7)
39 property real indicatorMenuWidth: width
40 property real applicationMenuWidth: width
42 property alias applicationMenus: __applicationMenus
43 property alias indicators: __indicators
44 property bool fullscreenMode: false
45 property real panelAreaShowProgress: 1.0
46 property bool greeterShown: false
47 property bool hasKeyboard: false
49 property string mode: "staged"
51 MouseArea {
52 id: backMouseEater
53 anchors.fill: parent
54 anchors.topMargin: panelHeight
55 visible: !indicators.fullyClosed || !applicationMenus.fullyClosed
56 enabled: visible
57 hoverEnabled: true // should also eat hover events, otherwise they will pass through
59 onClicked: {
60 __applicationMenus.hide();
61 __indicators.hide();
62 }
63 }
65 Binding {
66 target: PanelState
67 property: "panelHeight"
68 value: minimizedPanelHeight
69 }
71 RegisteredApplicationMenuModel {
72 id: registeredMenuModel
73 persistentSurfaceId: PanelState.focusedPersistentSurfaceId
74 }
76 QtObject {
77 id: d
79 property bool revealControls: !greeterShown &&
80 !applicationMenus.shown &&
81 !indicators.shown &&
82 (decorationMouseArea.containsMouse || menuBarLoader.menusRequested)
84 property bool showWindowDecorationControls: (revealControls && PanelState.decorationsVisible) ||
85 PanelState.decorationsAlwaysVisible
87 property bool showPointerMenu: revealControls && enablePointerMenu &&
88 (PanelState.decorationsVisible || mode == "staged")
90 property bool enablePointerMenu: applicationMenus.available &&
91 applicationMenus.model
93 property bool showTouchMenu: !greeterShown &&
94 !showPointerMenu &&
95 !showWindowDecorationControls
97 property bool enableTouchMenus: showTouchMenu &&
98 applicationMenus.available &&
99 applicationMenus.model
100 }
102 Item {
103 id: panelArea
104 objectName: "panelArea"
106 anchors.fill: parent
108 transform: Translate {
109 y: indicators.state === "initial"
110 ? (1.0 - panelAreaShowProgress) * - minimizedPanelHeight
111 : 0
112 }
114 BorderImage {
115 id: indicatorsDropShadow
116 anchors {
117 fill: __indicators
118 margins: -units.gu(1)
119 }
120 visible: !__indicators.fullyClosed
121 source: "graphics/rectangular_dropshadow.sci"
122 }
124 BorderImage {
125 id: appmenuDropShadow
126 anchors {
127 fill: __applicationMenus
128 margins: -units.gu(1)
129 }
130 visible: !__applicationMenus.fullyClosed
131 source: "graphics/rectangular_dropshadow.sci"
132 }
134 BorderImage {
135 id: panelDropShadow
136 anchors {
137 fill: panelAreaBackground
138 bottomMargin: -units.gu(1)
139 }
140 visible: PanelState.dropShadow
141 source: "graphics/rectangular_dropshadow.sci"
142 }
144 Rectangle {
145 id: panelAreaBackground
146 color: callHint.visible ? theme.palette.normal.positive : theme.palette.normal.background
147 anchors {
148 top: parent.top
149 left: parent.left
150 right: parent.right
151 }
152 height: minimizedPanelHeight
154 Behavior on color { ColorAnimation { duration: UbuntuAnimation.FastDuration } }
155 }
157 MouseArea {
158 id: decorationMouseArea
159 objectName: "windowControlArea"
160 anchors {
161 left: parent.left
162 right: parent.right
163 }
164 height: minimizedPanelHeight
165 hoverEnabled: !__indicators.shown
166 onClicked: {
167 if (callHint.visible) {
168 callHint.showLiveCall();
169 }
170 }
172 onPressed: {
173 if (!callHint.visible) {
174 // let it fall through to the window decoration of the maximized window behind, if any
175 mouse.accepted = false;
176 }
177 }
179 Row {
180 anchors.fill: parent
181 spacing: units.gu(2)
183 // WindowControlButtons inside the mouse area, otherwise QML doesn't grok nested hover events :/
184 // cf. https://bugreports.qt.io/browse/QTBUG-32909
185 WindowControlButtons {
186 id: windowControlButtons
187 objectName: "panelWindowControlButtons"
188 height: indicators.minimizedPanelHeight
189 opacity: d.showWindowDecorationControls ? 1 : 0
190 visible: opacity != 0
191 Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
193 active: PanelState.decorationsVisible || PanelState.decorationsAlwaysVisible
194 windowIsMaximized: true
195 onCloseClicked: PanelState.closeClicked()
196 onMinimizeClicked: PanelState.minimizeClicked()
197 onMaximizeClicked: PanelState.restoreClicked()
198 closeButtonShown: PanelState.closeButtonShown
199 }
201 Loader {
202 id: menuBarLoader
203 height: parent.height
204 enabled: d.enablePointerMenu
205 opacity: d.showPointerMenu ? 1 : 0
206 visible: opacity != 0
207 Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
208 active: d.showPointerMenu && !callHint.visible
210 width: parent.width - windowControlButtons.width - units.gu(2) - __indicators.barWidth
212 property bool menusRequested: menuBarLoader.item ? menuBarLoader.item.showRequested : false
214 sourceComponent: MenuBar {
215 id: bar
216 objectName: "menuBar"
217 anchors.left: parent.left
218 anchors.margins: units.gu(1)
219 height: menuBarLoader.height
220 enableKeyFilter: valid && PanelState.decorationsVisible
221 unityMenuModel: __applicationMenus.model
223 Connections {
224 target: __applicationMenus
225 onShownChanged: bar.dismiss();
226 }
228 Connections {
229 target: __indicators
230 onShownChanged: bar.dismiss();
231 }
233 onDoubleClicked: PanelState.restoreClicked()
234 }
235 }
236 }
238 ActiveCallHint {
239 id: callHint
240 objectName: "callHint"
242 anchors.centerIn: parent
243 height: minimizedPanelHeight
245 visible: active && indicators.state == "initial" && __applicationMenus.state == "initial"
246 greeterShown: root.greeterShown
247 }
248 }
250 PanelMenu {
251 id: __applicationMenus
253 model: registeredMenuModel.model
254 width: root.applicationMenuWidth
255 minimizedPanelHeight: root.minimizedPanelHeight
256 expandedPanelHeight: root.expandedPanelHeight
257 openedHeight: root.height
258 alignment: Qt.AlignLeft
259 enableHint: !callHint.active && !fullscreenMode
260 showOnClick: false
261 panelColor: panelAreaBackground.color
263 onShowTapped: {
264 if (callHint.active) {
265 callHint.showLiveCall();
266 }
267 }
269 showRowTitle: !expanded
270 rowTitle: PanelState.title
271 rowItemDelegate: ActionItem {
272 id: actionItem
273 property int ownIndex: index
274 objectName: "appMenuItem"+index
276 width: _title.width + units.gu(2)
277 height: parent.height
279 action: Action {
280 text: model.label.replace("_", "&")
281 }
283 Label {
284 id: _title
285 anchors.centerIn: parent
286 text: actionItem.text
287 horizontalAlignment: Text.AlignLeft
288 color: enabled ? theme.palette.normal.backgroundText : theme.palette.disabled.backgroundText
289 }
290 }
292 pageDelegate: PanelMenuPage {
293 menuModel: __applicationMenus.model
294 submenuIndex: modelIndex
296 factory: ApplicationMenuItemFactory {
297 rootModel: __applicationMenus.model
298 }
299 }
301 enabled: d.enableTouchMenus
302 opacity: d.showTouchMenu ? 1 : 0
303 visible: opacity != 0
304 Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
306 onEnabledChanged: {
307 if (!enabled) hide();
308 }
309 }
311 PanelMenu {
312 id: __indicators
313 objectName: "indicators"
315 anchors {
316 top: parent.top
317 right: parent.right
318 }
319 width: root.indicatorMenuWidth
320 minimizedPanelHeight: root.minimizedPanelHeight
321 expandedPanelHeight: root.expandedPanelHeight
322 openedHeight: root.height
324 overFlowWidth: root.width
325 enableHint: !callHint.active && !fullscreenMode
326 showOnClick: !callHint.visible
327 panelColor: panelAreaBackground.color
329 onShowTapped: {
330 if (callHint.active) {
331 callHint.showLiveCall();
332 }
333 }
335 rowItemDelegate: IndicatorItem {
336 id: indicatorItem
337 objectName: identifier+"-panelItem"
339 property int ownIndex: index
340 readonly property bool overflow: parent.width - x > __indicators.overFlowWidth
341 readonly property bool hidden: !expanded && (overflow || !indicatorVisible || hideSessionIndicator || hideKeyboardIndicator)
342 // HACK for indicator-session
343 readonly property bool hideSessionIndicator: identifier == "indicator-session" && Math.min(Screen.width, Screen.height) <= units.gu(60)
344 // HACK for indicator-keyboard
345 readonly property bool hideKeyboardIndicator: identifier == "indicator-keyboard" && !hasKeyboard
347 height: parent.height
348 expanded: indicators.expanded
349 selected: ListView.isCurrentItem
351 identifier: model.identifier
352 busName: indicatorProperties.busName
353 actionsObjectPath: indicatorProperties.actionsObjectPath
354 menuObjectPath: indicatorProperties.menuObjectPath
356 opacity: hidden ? 0.0 : 1.0
357 Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
359 width: ((expanded || indicatorVisible) && !hideSessionIndicator && !hideKeyboardIndicator) ? implicitWidth : 0
361 Behavior on width { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
362 }
364 pageDelegate: PanelMenuPage {
365 objectName: modelData.identifier + "-page"
366 submenuIndex: 0
368 menuModel: delegate.menuModel
370 factory: IndicatorMenuItemFactory {
371 indicator: {
372 var context = modelData.identifier;
373 if (context && context.indexOf("fake-") === 0) {
374 context = context.substring("fake-".length)
375 }
376 return context;
377 }
378 rootModel: delegate.menuModel
379 }
381 IndicatorDelegate {
382 id: delegate
383 busName: modelData.indicatorProperties.busName
384 actionsObjectPath: modelData.indicatorProperties.actionsObjectPath
385 menuObjectPath: modelData.indicatorProperties.menuObjectPath
386 }
387 }
389 enabled: !applicationMenus.expanded
390 opacity: !callHint.visible && !applicationMenus.expanded ? 1 : 0
391 Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
393 onEnabledChanged: {
394 if (!enabled) hide();
395 }
396 }
397 }
399 IndicatorsLight {
400 id: indicatorLights
401 }
403 states: [
404 State {
405 name: "onscreen" //fully opaque and visible at top edge of screen
406 when: !fullscreenMode
407 PropertyChanges {
408 target: panelArea;
409 anchors.topMargin: 0
410 opacity: 1;
411 }
412 },
413 State {
414 name: "offscreen" //pushed off screen
415 when: fullscreenMode
416 PropertyChanges {
417 target: panelArea;
418 anchors.topMargin: {
419 if (indicators.state !== "initial") return 0;
420 if (applicationMenus.state !== "initial") return 0;
421 return -minimizedPanelHeight;
422 }
423 opacity: indicators.fullyClosed && applicationMenus.fullyClosed ? 0.0 : 1.0
424 }
425 PropertyChanges {
426 target: indicators.showDragHandle;
427 anchors.bottomMargin: -units.gu(1)
428 }
429 PropertyChanges {
430 target: applicationMenus.showDragHandle;
431 anchors.bottomMargin: -units.gu(1)
432 }
433 }
434 ]
436 transitions: [
437 Transition {
438 to: "onscreen"
439 UbuntuNumberAnimation { target: panelArea; properties: "anchors.topMargin,opacity" }
440 },
441 Transition {
442 to: "offscreen"
443 UbuntuNumberAnimation { target: panelArea; properties: "anchors.topMargin,opacity" }
444 }
445 ]