Launcher: create popup windows on demand
This avoids some flickering issues on macOS, and reduces resource use generally.
This commit is contained in:
parent
cf8ec5998e
commit
ffbbe54cbc
3 changed files with 168 additions and 159 deletions
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue