1
0
Fork 0

Launcher: create popup windows on demand

This avoids some flickering issues on macOS, and reduces resource use 
generally.
This commit is contained in:
James Turner 2020-03-17 11:14:11 +00:00
parent cf8ec5998e
commit ffbbe54cbc
3 changed files with 168 additions and 159 deletions

View file

@ -92,10 +92,9 @@ Rectangle {
screenPos = _launcher.mapToGlobal(title, Qt.point(0, 0))
}
popupFrame.x = screenPos.x;
popupFrame.y = screenPos.y;
popupFrame.show()
tracker.window = popupFrame
var pop = popup.createObject(root, {x:screenPos.x, y:screenPos.y })
tracker.window = pop;
pop.show();
}
}
@ -108,59 +107,63 @@ Rectangle {
id: tracker
}
Window {
id: popupFrame
Component {
id: popup
width: root.width
flags: Qt.Popup
height: choicesColumn.childrenRect.height
color: "white"
Window {
id: popupFrame
Rectangle {
border.width: 1
border.color: Style.minorFrameColor
anchors.fill: parent
}
width: root.width
flags: Qt.Popup
height: choicesColumn.childrenRect.height
color: "white"
Column {
id: choicesColumn
Rectangle {
border.width: 1
border.color: Style.minorFrameColor
anchors.fill: parent
}
Repeater {
// would prefer the model to be conditional on visiblity,
// but this trips up the Window sizing on Linux (Ubuntu at
// least) and we get a mis-aligned origin
model: aircraftInfo.variantNames
Column {
id: choicesColumn
delegate: Item {
width: popupFrame.width
height: choiceText.implicitHeight
Repeater {
// would prefer the model to be conditional on visiblity,
// but this trips up the Window sizing on Linux (Ubuntu at
// least) and we get a mis-aligned origin
model: aircraftInfo.variantNames
Text {
id: choiceText
text: modelData
delegate: Item {
width: popupFrame.width
height: choiceText.implicitHeight
// allow override the size in case the title size is enormous
font.pixelSize: (popupFontPixelSize > 0) ? popupFontPixelSize : title.font.pixelSize
Text {
id: choiceText
text: modelData
color: choiceArea.containsMouse ? Style.themeColor : Style.baseTextColor
anchors {
left: parent.left
right: parent.right
margins: 4
// allow override the size in case the title size is enormous
font.pixelSize: (root.popupFontPixelSize > 0) ? root.popupFontPixelSize : title.font.pixelSize
color: choiceArea.containsMouse ? Style.themeColor : Style.baseTextColor
anchors {
left: parent.left
right: parent.right
margins: 4
}
}
}
MouseArea {
id: choiceArea
hoverEnabled: true
anchors.fill: parent
onClicked: {
popupFrame.hide()
root.selected(model.index)
MouseArea {
id: choiceArea
hoverEnabled: true
anchors.fill: parent
onClicked: {
popupFrame.close()
root.selected(model.index)
}
}
}
} // of delegate Item
} // of Repeater
}
} // of popup frame
} // of delegate Item
} // of Repeater
}
} // of popup frame
} // of popup component
}

View file

@ -37,11 +37,12 @@ Item {
hoverEnabled: root.enabled
enabled: root.enabled
onClicked: {
var screenPos = _launcher.mapToGlobal(button, Qt.point(-popupFrame.width, 0))
popupFrame.x = screenPos.x;
popupFrame.y = screenPos.y;
popupFrame.visible = true
tracker.window = popupFrame
var pop = popup.createObject(root)
var screenPos = _launcher.mapToGlobal(button, Qt.point(-pop.width, 0))
pop.y = screenPos.y;
pop.x = screenPos.x;
tracker.window = pop;
pop.show();
}
}
}
@ -50,51 +51,54 @@ Item {
id: tracker
}
Window {
id: popupFrame
Component {
id: popup
flags: Qt.Popup
height: choicesColumn.childrenRect.height + Style.margin * 2
width: choicesColumn.childrenRect.width + Style.margin * 2
visible: false
color: "white"
Window {
id: popupFrame
Rectangle {
border.width: 1
border.color: Style.minorFrameColor
anchors.fill: parent
}
flags: Qt.Popup
height: choicesColumn.childrenRect.height + Style.margin * 2
width: choicesColumn.childrenRect.width + Style.margin * 2
color: "white"
// text repeater
Column {
id: choicesColumn
spacing: Style.margin
x: Style.margin
y: Style.margin
Rectangle {
border.width: 1
border.color: Style.minorFrameColor
anchors.fill: parent
}
Repeater {
id: choicesRepeater
model: root.model
delegate:
StyledText {
id: choiceText
// text repeater
Column {
id: choicesColumn
spacing: Style.margin
x: Style.margin
y: Style.margin
// Taken from TableViewItemDelegateLoader.qml to follow QML role conventions
text: model && model.hasOwnProperty(displayRole) ? model[displayRole] // Qml ListModel and QAbstractItemModel
: modelData && modelData.hasOwnProperty(displayRole) ? modelData[displayRole] // QObjectList / QObject
: modelData != undefined ? modelData : "" // Models without role
height: implicitHeight + Style.margin
Repeater {
id: choicesRepeater
model: root.model
delegate:
StyledText {
id: choiceText
MouseArea {
width: popupFrame.width // full width of the popup
height: parent.height
onClicked: {
popupFrame.visible = false
root.selected(model.index);
// Taken from TableViewItemDelegateLoader.qml to follow QML role conventions
text: model && model.hasOwnProperty(displayRole) ? model[displayRole] // Qml ListModel and QAbstractItemModel
: modelData && modelData.hasOwnProperty(displayRole) ? modelData[displayRole] // QObjectList / QObject
: modelData != undefined ? modelData : "" // Models without role
height: implicitHeight + Style.margin
MouseArea {
width: popupFrame.width // full width of the popup
height: parent.height
onClicked: {
root.selected(model.index);
popupFrame.close()
}
}
}
} // of Text delegate
} // text repeater
} // text column
} // of popup Window
} // of Text delegate
} // text repeater
} // text column
} // of popup Window
}
}

View file

@ -101,6 +101,15 @@ FocusScope {
}
}
function showUnitsMenu()
{
var screenPos = _launcher.mapToGlobal(editFrame, Qt.point(0, editFrame.height))
var pop = popup.createObject(root, {x:screenPos.x, y:screenPos.y })
tracker.window = pop;
pop.show();
}
Component.onCompleted: {
// ensure any initial value is accepted by our mode.
// this stops people passing in completely wrong quantities
@ -196,7 +205,7 @@ FocusScope {
anchors.left: parent.left
anchors.margins: Style.margin
text: visible ? units.shortText : ""
onClicked: unitSelectionPopup.show()
onClicked: root.showUnitsMenu()
clickable: (units.numChoices > 1)
}
@ -251,7 +260,7 @@ FocusScope {
anchors.baseline: edit.baseline
anchors.right: upDownArea.left
text: visible ? units.shortText : ""
onClicked: unitSelectionPopup.show()
onClicked: root.showUnitsMenu();
clickable: (units.numChoices > 1)
}
@ -324,76 +333,69 @@ FocusScope {
id: tracker
}
Window {
id: unitSelectionPopup
visible: false
flags: Qt.Popup
color: "white"
height: choicesColumn.childrenRect.height + Style.margin * 2
width: choicesColumn.width + Style.margin * 2
Component {
id: popup
Window {
id: unitSelectionPopup
flags: Qt.Popup
color: "white"
height: choicesColumn.childrenRect.height + Style.margin * 2
width: choicesColumn.width + Style.margin * 2
function show()
{
var screenPos = _launcher.mapToGlobal(editFrame, Qt.point(0, editFrame.height))
unitSelectionPopup.x = screenPos.x;
unitSelectionPopup.y = screenPos.y;
unitSelectionPopup.visible = true
tracker.window = unitSelectionPopup
}
Rectangle {
border.width: 1
border.color: Style.minorFrameColor
anchors.fill: parent
}
// choice layout column
Column {
id: choicesColumn
spacing: Style.margin
x: Style.margin
y: Style.margin
width: menuWidth
function calculateMenuWidth()
{
var minWidth = 0;
for (var i = 0; i < choicesRepeater.count; i++) {
minWidth = Math.max(minWidth, choicesRepeater.itemAt(i).implicitWidth);
}
return minWidth;
Rectangle {
border.width: 1
border.color: Style.minorFrameColor
anchors.fill: parent
}
readonly property int menuWidth: calculateMenuWidth()
// choice layout column
Column {
id: choicesColumn
spacing: Style.margin
x: Style.margin
y: Style.margin
width: menuWidth
// main item repeater
Repeater {
id: choicesRepeater
model: units
delegate:
Text {
id: choiceText
readonly property bool selected: units.selectedIndex === model.index
text: model.longName
height: implicitHeight + Style.margin
font.pixelSize: Style.baseFontPixelSize
color: choiceArea.containsMouse ? Style.themeColor : Style.baseTextColor
function calculateMenuWidth()
{
var minWidth = 0;
for (var i = 0; i < choicesRepeater.count; i++) {
minWidth = Math.max(minWidth, choicesRepeater.itemAt(i).implicitWidth);
}
return minWidth;
}
MouseArea {
id: choiceArea
width: unitSelectionPopup.width // full width of the popup
height: parent.height
hoverEnabled: true
readonly property int menuWidth: calculateMenuWidth()
onClicked: {
root.changeToUnits(model.index);
unitSelectionPopup.visible = false;
// main item repeater
Repeater {
id: choicesRepeater
model: units
delegate:
Text {
id: choiceText
readonly property bool selected: units.selectedIndex === model.index
text: model.longName
height: implicitHeight + Style.margin
font.pixelSize: Style.baseFontPixelSize
color: choiceArea.containsMouse ? Style.themeColor : Style.baseTextColor
MouseArea {
id: choiceArea
width: unitSelectionPopup.width // full width of the popup
height: parent.height
hoverEnabled: true
onClicked: {
root.changeToUnits(model.index);
unitSelectionPopup.close();
}
}
}
} // of Text delegate
} // text repeater
} // text column
}
} // of Text delegate
} // text repeater
} // text column
}
} // of popup component
}