18
18
import QtQuick.Layouts 1.1
19
import QtQuick.Window 2.2
20
19
import Ubuntu.Components 1.3
21
20
import Ubuntu.Components.ListItems 1.3 as ListItems
22
21
import "../Components"
22
import "../Components/PanelState"
27
28
backgroundColor: theme.palette.normal.overlay
30
signal childActivated()
32
// true for submenus that need to show on the other side of their parent
33
// if they don't fit when growing right
34
property bool substractWidth: false
36
property bool selectFirstOnCountChange: true
38
property real desiredX
40
var dummy = visible; // force recalc when shown/hidden
41
var parentTopLeft = parent.mapToItem(null, 0, 0);
42
var farX = ApplicationMenusLimits.screenWidth;
43
if (parentTopLeft.x + width + desiredX <= farX) {
49
return farX - parentTopLeft.x - width;
54
property real desiredY
56
var dummy = visible; // force recalc when shown/hidden
57
var parentTopLeft = parent.mapToItem(null, 0, 0);
58
var bottomY = ApplicationMenusLimits.screenHeight;
59
if (parentTopLeft.y + height + desiredY <= bottomY) {
62
return bottomY - parentTopLeft.y - height;
29
66
property alias unityMenuModel: repeater.model
64
101
readonly property int currentIndex: currentItem ? currentItem.__ownIndex : -1
66
103
property real __minimumWidth: units.gu(20)
67
property real __maximumWidth: Screen.width * 0.7
104
property real __maximumWidth: ApplicationMenusLimits.screenWidth * 0.7
68
105
property real __minimumHeight: units.gu(2)
69
property real __maximumHeight: Screen.height * 0.7
106
property real __maximumHeight: ApplicationMenusLimits.screenHeight - PanelState.panelHeight
71
108
signal dismissAll()
176
226
contentHeight: menuColumn.height
177
227
interactive: height < contentHeight
230
id: submenuHoverTimer
231
interval: 225 // GTK MENU_POPUP_DELAY, Qt SH_Menu_SubMenuPopupDelay in QCommonStyle is 256
232
onTriggered: d.currentItem.item.trigger();
180
236
anchors.fill: parent
181
237
hoverEnabled: true
182
propagateComposedEvents: true // propogate events so we send clicks to children.
183
238
z: 1 // on top so we override any other hovers
184
239
onEntered: updateCurrentItemFromPosition(Qt.point(mouseX, mouseY))
185
240
onPositionChanged: updateCurrentItemFromPosition(Qt.point(mouse.x, mouse.y))
190
245
if (!d.hoveredItem || !d.currentItem ||
191
246
!d.hoveredItem.contains(Qt.point(pos.x - d.currentItem.x, pos.y - d.currentItem.y))) {
247
submenuHoverTimer.stop();
192
249
d.hoveredItem = menuColumn.childAt(pos.x, pos.y)
193
250
if (!d.hoveredItem || !d.hoveredItem.enabled)
195
252
d.currentItem = d.hoveredItem;
254
if (!d.currentItem.__isSeparator && d.currentItem.item.hasSubmenu && d.currentItem.item.enabled) {
255
submenuHoverTimer.start();
261
var pos = mapToItem(listView.contentItem, mouse.x, mouse.y);
262
var clickedItem = menuColumn.childAt(pos.x, pos.y);
263
if (clickedItem.enabled && !clickedItem.__isSeparator) {
264
clickedItem.item.trigger();
282
id: separatorComponent
283
ListItems.ThinDivider {
284
// Parent will be loader
285
objectName: parent.objectName + "-separator"
286
implicitHeight: units.dp(2)
291
id: menuItemComponent
293
// Parent will be loader
295
menuData: parent.__menuData
296
objectName: parent.objectName + "-actionItem"
298
width: MathUtils.clamp(implicitWidth, d.__minimumWidth, d.__maximumWidth)
300
action.onTriggered: {
301
submenuHoverTimer.stop();
303
d.currentItem = parent;
307
root.unityMenuModel.aboutToShow(__ownIndex);
308
var model = root.unityMenuModel.submenu(__ownIndex);
309
popup = submenuComponent.createObject(focusScope, {
310
objectName: parent.objectName + "-",
311
unityMenuModel: model,
312
substractWidth: true,
313
desiredX: Qt.binding(function() { return root.width }),
314
desiredY: Qt.binding(function() {
315
var dummy = listView.contentY; // force a recalc on contentY change.
316
return mapToItem(container, 0, y).y;
319
popup.retreat.connect(function() {
322
menuItem.forceActiveFocus();
324
popup.childActivated.connect(function() {
327
root.childActivated();
329
} else if (!popup.visible) {
330
root.unityMenuModel.aboutToShow(__ownIndex);
331
popup.visible = true;
332
popup.item.selectFirstIndex();
335
root.unityMenuModel.activate(__ownIndex);
336
root.childActivated();
342
onCurrentIndexChanged: {
343
if (popup && d.currentIndex != __ownIndex) {
344
popup.visible = false;
367
if (root.selectFirstOnCountChange && !d.currentItem && count > 0) {
368
root.selectFirstIndex();
224
374
objectName: root.objectName + "-item" + __ownIndex
376
property Item popup: null
377
property var __menuData: model
226
378
property int __ownIndex: index
227
379
property bool __isSeparator: model.isSeparator
235
387
return menuItemComponent;
238
property Item popup: null
240
390
Layout.fillWidth: true
243
id: menuItemComponent
247
objectName: loader.objectName + "-actionItem"
249
width: MathUtils.clamp(implicitWidth, d.__minimumWidth, d.__maximumWidth)
251
action.onTriggered: {
252
d.currentItem = loader;
256
var model = root.unityMenuModel.submenu(__ownIndex);
257
popup = submenuComponent.createObject(focusScope, {
258
objectName: loader.objectName + "-",
259
unityMenuModel: model,
260
x: Qt.binding(function() { return root.width }),
261
y: Qt.binding(function() {
262
var dummy = listView.contentY; // force a recalc on contentY change.
263
return mapToItem(container, 0, y).y;
267
popup.visible = true;
269
popup.retreat.connect(function() {
272
menuItem.forceActiveFocus();
275
root.unityMenuModel.activate(__ownIndex);
281
onCurrentIndexChanged: {
282
if (popup && d.currentIndex != __ownIndex) {
283
popup.visible = false;
297
id: separatorComponent
298
ListItems.ThinDivider {
299
objectName: loader.objectName + "-separator"
300
implicitHeight: units.dp(2)
375
474
id: submenuLoader
376
475
source: "MenuPopup.qml"
477
property real desiredX
478
property real desiredY
479
property bool substractWidth
378
480
property var unityMenuModel: null
383
property: "unityMenuModel"
384
value: submenuLoader.unityMenuModel
389
property: "objectName"
390
value: submenuLoader.objectName + "menu"
482
signal childActivated()
485
item.unityMenuModel = Qt.binding(function() { return submenuLoader.unityMenuModel; });
486
item.objectName = Qt.binding(function() { return submenuLoader.objectName + "menu"; });
487
item.desiredX = Qt.binding(function() { return submenuLoader.desiredX; });
488
item.desiredY = Qt.binding(function() { return submenuLoader.desiredY; });
489
item.substractWidth = Qt.binding(function() { return submenuLoader.substractWidth; });
393
492
Keys.onLeftPressed: retreat()
395
Component.onCompleted: item.select(0);
396
onVisibleChanged: if (visible) { item.select(0); }
496
onChildActivated: childActivated();