Details
-
Bug
-
Resolution: Fixed
-
P2: Important
-
6.6.2, 6.7.0 Beta3
-
931e67f54 (dev), 7ef4989a5 (6.8), fb668f64b (6.7)
Description
Code
This code generalizes https://doc.qt.io/Boot2Qt/b2qt-customization.html#switching-between-portrait-and-landscape-views to study how to rotate GUIs that contain Popups.
It looks like calculations relating to the top and left edges are fine, but calculations relating to the bottom and right edges are not.
import QtQuick import QtQuick.Controls.Basic Window { id: window width: 400 height: 250 color: "beige" visible: true contentItem.rotation: rotate ? 90 : 0 Overlay.overlay.anchors.fill: btn_rotateOverlay.checked ? container : window.contentItem property bool rotate: btn_rotateContainer.checked property int virtualWidth: rotate ? window.height : window.width property int virtualHeight: rotate ? window.width : window.height Item { // From https://doc.qt.io/Boot2Qt/b2qt-customization.html#switching-between-portrait-and-landscape-views id: container width: window.virtualWidth height: window.virtualHeight anchors.centerIn: parent Column { anchors.centerIn: parent Button { id: btn_rotateContainer text: "Rotate Container" checkable: true } Button { id: btn_rotateOverlay text: "Rotate Overlay" checkable: true } Button { text: "Popup" onClicked: popup.open() } Row { ToolButton { text: "L" onClicked: drawer_left.open() } ToolButton { text: "T" onClicked: drawer_top.open() } ToolButton { text: "R" onClicked: drawer_right.open() } ToolButton { text: "B" onClicked: drawer_bottom.open() } } } Popup { id: popup width: parent.width/2 height: parent.height/2 anchors.centerIn: parent dim: true Text { text: "This way up" } Overlay.modeless: Rectangle { color: "#AA0000FF" } } ComboBox { model: ["Alpha", "Bravo", "Charlie"] } ComboBox { model: ["Alpha", "Bravo", "Charlie"] anchors.bottom: parent.bottom } Drawer { id: drawer_left Text { anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right text: "Left Drawer" } edge: Qt.LeftEdge width: 100 height: window.virtualHeight } Drawer { id: drawer_right Text { anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left text: "Right Drawer" } edge: Qt.RightEdge width: 100 height: window.virtualHeight } Drawer { id: drawer_top Text { anchors.horizontalCenter: parent.horizontalCenter anchors.bottom: parent.bottom text: "Top Drawer" } edge: Qt.TopEdge width: window.virtualWidth height: 100 } Drawer { id: drawer_bottom Text { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top text: "Bottom Drawer" } edge: Qt.BottomEdge width: window.virtualWidth height: 100 } } }
Steps to reproduce
- Build and run this code
- Open the Popup, 2 ComboBoxes, and 4 Drawers
- Enable "Rotate Container" (but not "Rotate Overlay") and repeat Step #2
- Enable both "Rotate Container" and "Rotate Overlay" and repeat Step #2
Outcomes
- If we rotate the container only without rotating the Overlay: The dimmers, ComboBox drop-downs, and Drawers are all positioned/sized incorrectly.
- If we rotate both the container and the Overlay:
- The dimmers, top ComboBox drop-down, and top+left Drawers are now positioned/sized correctly.
- However, the bottom ComboBox drop-down and the right+bottom Drawers are still wrong.
(see attached diagram for an overview)
Analysis
These outcomes shows that the Popup positioning calculations are partially based on the Overlay. However, other parts (namely the calculations that try to keep the Popups within the right/bottom bounds) are based on the Window geometry instead. All calculations should be based on the same reference.
// QQuickPopupPositioner::reposition() const QMarginsF margins = p->getMargins(); QRectF bounds(qMax<qreal>(0.0, margins.left()), qMax<qreal>(0.0, margins.top()), p->window->width() - qMax<qreal>(0.0, margins.left()) - qMax<qreal>(0.0, margins.right()), p->window->height() - qMax<qreal>(0.0, margins.top()) - qMax<qreal>(0.0, margins.bottom()));
https://github.com/qt/qtdeclarative/blob/v6.7.0-beta3/src/quicktemplates/qquickdrawer.cpp
// QQuickDrawerPositioner::reposition() switch (drawer->edge()) { case Qt::LeftEdge: popupItem->setX((position - 1.0) * popupItem->width()); break; case Qt::RightEdge: popupItem->setX(window->width() - position * popupItem->width()); break; case Qt::TopEdge: popupItem->setY((position - 1.0) * popupItem->height()); break; case Qt::BottomEdge: popupItem->setY(window->height() - position * popupItem->height()); break; }
Other observations
The fix for QTBUG-80910 (which was picked back to Qt 6.6) now takes the rotation into account and allows Drawers to be dragged in from the correct rotated edge. This fix is not too useful if the Drawer is positioned iscorrectly.
Also, we could exploit QTBUG-123114 to "fix" the calculations for the bottom ComboBox...
contentOrientation: rotate ? Qt.LandscapeOrientation : Qt.PrimaryOrientation
...but two wrongs don't make a right. This hack also has no effect on the bottom/right Drawers.
Attachments
Issue Links
- resulted from
-
QTBUG-80910 Drawer item does not support rotation
- Closed
For Gerrit Dashboard: QTBUG-122963 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
547039,7 | Popup/Drawer: Reposition based on Overlay geometry instead of Window geometry | dev | qt/qtdeclarative | Status: MERGED | +2 | 0 |
574592,2 | Popup/Drawer: Reposition based on Overlay geometry instead of Window geometry | 6.8 | qt/qtdeclarative | Status: MERGED | +2 | 0 |
574645,2 | Popup/Drawer: Reposition based on Overlay geometry instead of Window geometry | 6.7 | qt/qtdeclarative | Status: MERGED | +2 | 0 |