@@ -16,91 +16,160 @@
1616
1717import QtQuick 2.4
1818import Ubuntu.Components 1.3
19+import Ubuntu.Layouts 1.0
1920import Unity.Application 0.1
21+import Unity.Indicators 0.1
22+import Utils 0.1
23+import Unity.ApplicationMenu 0.1
24+
25+import QtQuick.Window 2.2
26+// for indicator-keyboard
27+import AccountsService 0.1
28+import Unity.InputInfo 0.1
29+
30+import "../ApplicationMenus"
2031import "../Components"
2132import "../Components/PanelState"
2233import ".."
34+import "Indicators"
2335
2436Item {
2537 id: root
26− readonly property real panelHeight: indicatorArea.y + d.indicatorHeight
38+ readonly property real panelHeight: panelArea.y + minimizedPanelHeight
39+
40+ property real minimizedPanelHeight: units.gu(3)
41+ property real expandedPanelHeight: units.gu(7)
42+ property real indicatorMenuWidth: width
43+ property real applicationMenuWidth: width
44+
45+ property alias applicationMenus: __applicationMenus
2746 property alias indicators: __indicators
28− property alias callHint: __callHint
2947 property bool fullscreenMode: false
30− property real indicatorAreaShowProgress: 1.0
31− property bool locked: false
48+ property real panelAreaShowProgress: 1.0
49+ property bool greeterShown: false
50+
51+ property string mode: "staged"
3252
3353 MouseArea {
54+ id: backMouseEater
3455 anchors.fill: parent
3556 anchors.topMargin: panelHeight
36− visible: !indicators.fullyClosed
57+ visible: !indicators.fullyClosed || !applicationMenus.fullyClosed
3758 enabled: visible
38− onClicked: if (indicators.fullyOpened) indicators.hide();
3959 hoverEnabled: true // should also eat hover events, otherwise they will pass through
60+
61+ onClicked: {
62+ __applicationMenus.hide();
63+ __indicators.hide();
64+ }
4065 }
4166
4267 Binding {
4368 target: PanelState
4469 property: "panelHeight"
45− value: indicators.minimizedPanelHeight
70+ value: minimizedPanelHeight
71+ }
72+
73+ RegisteredApplicationMenuModel {
74+ id: registeredMenuModel
75+ persistentSurfaceId: PanelState.focusedPersistentSurfaceId
76+ }
77+
78+ QtObject {
79+ id: d
80+
81+ property bool revealControls: !greeterShown &&
82+ !applicationMenus.shown &&
83+ !indicators.shown &&
84+ (decorationMouseArea.containsMouse || menuBarLoader.menusRequested)
85+
86+ property bool showWindowDecorationControls: (revealControls && PanelState.decorationsVisible) ||
87+ PanelState.decorationsAlwaysVisible
88+
89+ property bool showPointerMenu: revealControls &&
90+ (PanelState.decorationsVisible || mode == "staged")
91+
92+ property bool enablePointerMenu: revealControls &&
93+ applicationMenus.available &&
94+ applicationMenus.model
95+
96+ property bool showTouchMenu: !greeterShown &&
97+ !showPointerMenu
98+
99+ property bool enableTouchMenus: showTouchMenu &&
100+ applicationMenus.available &&
101+ applicationMenus.model
46102 }
47103
48104 Item {
49− id: indicatorArea
50− objectName: "indicatorArea"
105+ id: panelArea
106+ objectName: "panelArea"
51107
52108 anchors.fill: parent
53109
54110 transform: Translate {
55111 y: indicators.state === "initial"
56− ? (1.0 - indicatorAreaShowProgress) * -d.indicatorHeight
112+ ? (1.0 - panelAreaShowProgress) * - minimizedPanelHeight
57113 : 0
58114 }
59115
60116 BorderImage {
61117 id: indicatorsDropShadow
62118 anchors {
63− fill: indicators
64− leftMargin: -units.gu(1)
65− bottomMargin: -units.gu(1)
119+ fill: __indicators
120+ margins: -units.gu(1)
121+ }
122+ visible: !__indicators.fullyClosed
123+ source: "graphics/rectangular_dropshadow.sci"
124+ }
125+
126+ BorderImage {
127+ id: appmenuDropShadow
128+ anchors {
129+ fill: __applicationMenus
130+ margins: -units.gu(1)
66131 }
67− visible: !indicators.fullyClosed
132+ visible: !__applicationMenus.fullyClosed
68133 source: "graphics/rectangular_dropshadow.sci"
69134 }
70135
71136 BorderImage {
72137 id: panelDropShadow
73138 anchors {
74− fill: indicatorAreaBackground
139+ fill: panelAreaBackground
75140 bottomMargin: -units.gu(1)
76141 }
77− visible: PanelState.dropShadow && !callHint.visible
142+ visible: PanelState.dropShadow
78143 source: "graphics/rectangular_dropshadow.sci"
79144 }
80145
81146 Rectangle {
82− id: indicatorAreaBackground
147+ id: panelAreaBackground
83148 color: callHint.visible ? theme.palette.normal.positive : theme.palette.normal.background
84149 anchors {
85150 top: parent.top
86151 left: parent.left
87152 right: parent.right
88153 }
89− height: indicators.minimizedPanelHeight
154+ height: minimizedPanelHeight
90155
91156 Behavior on color { ColorAnimation { duration: UbuntuAnimation.FastDuration } }
92157 }
93158
94159 MouseArea {
160+ id: decorationMouseArea
95161 objectName: "windowControlArea"
96162 anchors {
97− top: parent.top
98163 left: parent.left
99− right: indicators.left
164+ right: parent.right
165+ }
166+ height: minimizedPanelHeight
167+ hoverEnabled: !__indicators.shown
168+ onClicked: {
169+ if (callHint.visible) {
170+ callHint.showLiveCall();
171+ }
100172 }
101− height: indicators.minimizedPanelHeight
102− hoverEnabled: true
103− onClicked: if (callHint.visible) { callHint.showLiveCall(); }
104173
105174 onPressed: {
106175 if (!callHint.visible) {
@@ -109,29 +178,135 @@ Item {
109178 }
110179 }
111180
112− // WindowControlButtons inside the mouse area, otherwise QML doesn't grok nested hover events :/
113− // cf. https://bugreports.qt.io/browse/QTBUG-32909
114− WindowControlButtons {
115− id: windowControlButtons
116− objectName: "panelWindowControlButtons"
117− anchors {
118− left: parent.left
119− top: parent.top
181+ Row {
182+ anchors.fill: parent
183+ spacing: units.gu(2)
184+
185+ // WindowControlButtons inside the mouse area, otherwise QML doesn't grok nested hover events :/
186+ // cf. https://bugreports.qt.io/browse/QTBUG-32909
187+ WindowControlButtons {
188+ id: windowControlButtons
189+ objectName: "panelWindowControlButtons"
190+ height: indicators.minimizedPanelHeight
191+ opacity: d.showWindowDecorationControls ? 1 : 0
192+ visible: opacity != 0
193+ Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
194+
195+ active: PanelState.decorationsVisible || PanelState.decorationsAlwaysVisible
196+ windowIsMaximized: true
197+ onCloseClicked: PanelState.closeClicked()
198+ onMinimizeClicked: PanelState.minimizeClicked()
199+ onMaximizeClicked: PanelState.restoreClicked()
200+ closeButtonShown: PanelState.closeButtonShown
201+ }
202+
203+ Loader {
204+ id: menuBarLoader
205+ height: parent.height
206+ enabled: d.enablePointerMenu
207+ opacity: d.showPointerMenu ? 1 : 0
208+ visible: opacity != 0
209+ Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
210+ active: __applicationMenus.model
211+
212+ property bool menusRequested: menuBarLoader.item ? menuBarLoader.item.showRequested : false
213+
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
222+
223+ Connections {
224+ target: __applicationMenus
225+ onShownChanged: bar.dismiss();
226+ }
227+
228+ Connections {
229+ target: __indicators
230+ onShownChanged: bar.dismiss();
231+ }
232+ }
233+ }
234+ }
235+
236+ ActiveCallHint {
237+ id: callHint
238+ objectName: "callHint"
239+
240+ anchors.centerIn: parent
241+ height: minimizedPanelHeight
242+
243+ visible: active && indicators.state == "initial" && __applicationMenus.state == "initial"
244+ greeterShown: root.greeterShown
245+ }
246+ }
247+
248+ PanelMenu {
249+ id: __applicationMenus
250+
251+ model: registeredMenuModel.model
252+ width: root.applicationMenuWidth
253+ minimizedPanelHeight: root.minimizedPanelHeight
254+ expandedPanelHeight: root.expandedPanelHeight
255+ openedHeight: root.height
256+ alignment: Qt.AlignLeft
257+ enableHint: !callHint.active && !fullscreenMode
258+ showOnClick: false
259+ panelColor: panelAreaBackground.color
260+
261+ onShowTapped: {
262+ if (callHint.active) {
263+ callHint.showLiveCall();
264+ }
265+ }
266+
267+ showRowTitle: !expanded
268+ rowTitle: PanelState.title
269+ rowItemDelegate: ActionItem {
270+ id: actionItem
271+ property int ownIndex: index
272+ objectName: "appMenuItem"+index
273+
274+ width: _title.width + units.gu(2)
275+ height: parent.height
276+
277+ action: Action {
278+ text: model.label.replace("_", "&")
279+ }
280+
281+ Label {
282+ id: _title
283+ anchors.centerIn: parent
284+ text: actionItem.text
285+ horizontalAlignment: Text.AlignLeft
286+ color: enabled ? "white" : "#5d5d5d"
287+ }
288+ }
289+
290+ pageDelegate: PanelMenuPage {
291+ menuModel: __applicationMenus.model
292+ submenuIndex: modelIndex
293+
294+ factory: ApplicationMenuItemFactory {
295+ rootModel: __applicationMenus.model
120296 }
121− height: indicators.minimizedPanelHeight
297+ }
298+
299+ enabled: d.enableTouchMenus
300+ opacity: d.showTouchMenu ? 1 : 0
301+ visible: opacity != 0
302+ Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
122303
123− visible: ((PanelState.buttonsVisible && parent.containsMouse) || PanelState.buttonsAlwaysVisible)
124− && !root.locked && !callHint.visible
125− active: PanelState.buttonsVisible || PanelState.buttonsAlwaysVisible
126− windowIsMaximized: true
127− onCloseClicked: PanelState.closeClicked()
128− onMinimizeClicked: PanelState.minimizeClicked()
129− onMaximizeClicked: PanelState.restoreClicked()
130− closeButtonShown: PanelState.closeButtonShown
304+ onEnabledChanged: {
305+ if (!enabled) hide();
131306 }
132307 }
133308
134− IndicatorsMenu {
309+ PanelMenu {
135310 id: __indicators
136311 objectName: "indicators"
137312
@@ -139,72 +314,93 @@ Item {
139314 top: parent.top
140315 right: parent.right
141316 }
142−
143− shown: false
144− width: root.width - (windowControlButtons.visible ? windowControlButtons.width + titleLabel.width : 0)
145− minimizedPanelHeight: units.gu(3)
146− expandedPanelHeight: units.gu(7)
317+ width: root.indicatorMenuWidth
318+ minimizedPanelHeight: root.minimizedPanelHeight
319+ expandedPanelHeight: root.expandedPanelHeight
147320 openedHeight: root.height
148321
149− overFlowWidth: {
150− if (callHint.visible) {
151− return Math.max(root.width - (callHint.width + units.gu(2)), 0)
152− }
153− return root.width
154− }
322+ overFlowWidth: root.width
155323 enableHint: !callHint.active && !fullscreenMode
156324 showOnClick: !callHint.visible
157− panelColor: indicatorAreaBackground.color
325+ panelColor: panelAreaBackground.color
158326
159327 onShowTapped: {
160328 if (callHint.active) {
161329 callHint.showLiveCall();
162330 }
163331 }
164− }
165332
166− Label {
167− id: titleLabel
168− objectName: "windowDecorationTitle"
169− anchors {
170− left: parent.left
171− right: __indicators.left
172− top: parent.top
173− leftMargin: units.gu(1)
174− rightMargin: units.gu(1)
175− topMargin: units.gu(0.5)
176− bottomMargin: units.gu(0.5)
177− }
178− color: "white"
179− height: indicators.minimizedPanelHeight - anchors.topMargin - anchors.bottomMargin
180− opacity: !windowControlButtons.visible && !root.locked && !callHint.visible ? 1 : 0
181− visible: opacity != 0
182− verticalAlignment: Text.AlignVCenter
183− fontSize: "medium"
184− font.weight: PanelState.buttonsVisible ? Font.Light : Font.Medium
185− text: PanelState.title
186− elide: Text.ElideRight
187− maximumLineCount: 1
188− Behavior on opacity { UbuntuNumberAnimation {} }
189− }
333+ rowItemDelegate: IndicatorItem {
334+ id: indicatorItem
335+ objectName: identifier+"-panelItem"
190336
191− // TODO here would the Locally integrated menus come
337+ property int ownIndex: index
338+ property bool overflow: parent.width - x > __indicators.overFlowWidth
339+ property bool hidden: !expanded && (overflow || !indicatorVisible || hideSessionIndicator || hideKeyboardIndicator)
340+ // HACK for indicator-session
341+ readonly property bool hideSessionIndicator: identifier == "indicator-session" && Math.min(Screen.width, Screen.height) <= units.gu(60)
342+ // HACK for indicator-keyboard
343+ readonly property bool hideKeyboardIndicator: identifier == "indicator-keyboard" && (AccountsService.keymaps.length < 2 || keyboardsModel.count == 0)
192344
193− ActiveCallHint {
194− id: __callHint
195− anchors {
196− top: parent.top
197− left: parent.left
345+ height: parent.height
346+ expanded: indicators.expanded
347+ selected: ListView.isCurrentItem
348+
349+ identifier: model.identifier
350+ busName: indicatorProperties.busName
351+ actionsObjectPath: indicatorProperties.actionsObjectPath
352+ menuObjectPath: indicatorProperties.menuObjectPath
353+
354+ opacity: hidden ? 0.0 : 1.0
355+ Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
356+
357+ width: ((expanded || indicatorVisible) && !hideSessionIndicator && !hideKeyboardIndicator) ? implicitWidth : 0
358+
359+ Behavior on width { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
360+ }
361+
362+ pageDelegate: PanelMenuPage {
363+ objectName: modelData.identifier + "-page"
364+ submenuIndex: 0
365+
366+ menuModel: delegate.menuModel
367+
368+ factory: IndicatorMenuItemFactory {
369+ indicator: {
370+ var context = modelData.identifier;
371+ if (context && context.indexOf("fake-") === 0) {
372+ context = context.substring("fake-".length)
373+ }
374+ return context;
375+ }
376+ rootModel: delegate.menuModel
377+ }
378+
379+ IndicatorDelegate {
380+ id: delegate
381+ busName: modelData.indicatorProperties.busName
382+ actionsObjectPath: modelData.indicatorProperties.actionsObjectPath
383+ menuObjectPath: modelData.indicatorProperties.menuObjectPath
384+ }
385+ }
386+
387+ enabled: !applicationMenus.expanded
388+ opacity: !applicationMenus.expanded ? 1 : 0
389+ Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
390+
391+ onEnabledChanged: {
392+ if (!enabled) hide();
198393 }
199− height: indicators.minimizedPanelHeight
200− visible: active && indicators.state == "initial"
201394 }
202395 }
203396
204− QtObject {
205− id: d
206− objectName: "panelPriv"
207− readonly property real indicatorHeight: indicators.minimizedPanelHeight
397+ InputDeviceModel {
398+ id: keyboardsModel
399+ deviceFilter: InputInfo.Keyboard
400+ }
401+
402+ IndicatorsLight {
403+ id: indicatorLights
208404 }
209405
210406 states: [
@@ -212,7 +408,7 @@ Item {
212408 name: "onscreen" //fully opaque and visible at top edge of screen
213409 when: !fullscreenMode
214410 PropertyChanges {
215− target: indicatorArea;
411+ target: panelArea;
216412 anchors.topMargin: 0
217413 opacity: 1;
218414 }
@@ -221,25 +417,33 @@ Item {
221417 name: "offscreen" //pushed off screen
222418 when: fullscreenMode
223419 PropertyChanges {
224− target: indicatorArea;
225− anchors.topMargin: indicators.state === "initial" ? -d.indicatorHeight : 0
226− opacity: indicators.fullyClosed ? 0.0 : 1.0
420+ target: panelArea;
421+ anchors.topMargin: {
422+ if (indicators.state !== "initial") return 0;
423+ if (applicationMenus.state !== "initial") return 0;
424+ return -minimizedPanelHeight;
425+ }
426+ opacity: indicators.fullyClosed && applicationMenus.fullyClosed ? 0.0 : 1.0
227427 }
228428 PropertyChanges {
229429 target: indicators.showDragHandle;
230430 anchors.bottomMargin: -units.gu(1)
231431 }
432+ PropertyChanges {
433+ target: applicationMenus.showDragHandle;
434+ anchors.bottomMargin: -units.gu(1)
435+ }
232436 }
233437 ]
234438
235439 transitions: [
236440 Transition {
237441 to: "onscreen"
238− UbuntuNumberAnimation { target: indicatorArea; properties: "anchors.topMargin,opacity" }
442+ UbuntuNumberAnimation { target: panelArea; properties: "anchors.topMargin,opacity" }
239443 },
240444 Transition {
241445 to: "offscreen"
242− UbuntuNumberAnimation { target: indicatorArea; properties: "anchors.topMargin,opacity" }
446+ UbuntuNumberAnimation { target: panelArea; properties: "anchors.topMargin,opacity" }
243447 }
244448 ]
245449}