forked from qt-creator/qt-creator
EffectMaker: Fix popup geometry
Effect Maker preview and node combo box popups will now stay within the screen boundaries of the screen the parent combo box belongs to. Fixes: QDS-10512 Change-Id: Ibbfb706499c4b17e27ff5ae471fef8bb9f7384cb Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -23,18 +23,48 @@ StudioControls.ComboBox {
|
||||
|
||||
required property Item mainRoot
|
||||
|
||||
readonly property int popupHeight: Math.min(800, row.height + 2)
|
||||
|
||||
function calculateWindowGeometry() {
|
||||
var globalPos = EffectMakerBackend.rootView.globalPos(mainRoot.mapFromItem(root, 0, 0))
|
||||
var screenRect = EffectMakerBackend.rootView.screenRect();
|
||||
|
||||
window.width = row.width + 2 // 2: scrollView left and right 1px margins
|
||||
|
||||
var newX = globalPos.x + root.width - window.width
|
||||
if (newX < screenRect.x)
|
||||
newX = globalPos.x
|
||||
|
||||
var newY = Math.min(screenRect.y + screenRect.height,
|
||||
Math.max(screenRect.y, globalPos.y + root.height - 1))
|
||||
|
||||
// Check if we have more space above or below the control, and put control on that side,
|
||||
// unless we have enough room for maximum size popup under the control
|
||||
var newHeight
|
||||
var screenY = newY - screenRect.y
|
||||
if (screenRect.height - screenY > screenY || screenRect.height - screenY > root.popupHeight) {
|
||||
newHeight = Math.min(root.popupHeight, screenRect.height - screenY)
|
||||
} else {
|
||||
newHeight = Math.min(root.popupHeight, screenY - root.height)
|
||||
newY = newY - newHeight - root.height + 1
|
||||
}
|
||||
|
||||
window.height = newHeight
|
||||
window.x = newX
|
||||
window.y = newY
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: root.popup
|
||||
|
||||
function onAboutToShow() {
|
||||
var a = mainRoot.mapToGlobal(0, 0)
|
||||
var b = root.mapToItem(mainRoot, 0, 0)
|
||||
|
||||
window.x = a.x + b.x + root.width - window.width
|
||||
window.y = a.y + b.y + root.height - 1
|
||||
root.calculateWindowGeometry()
|
||||
|
||||
window.show()
|
||||
window.requestActivate()
|
||||
|
||||
// Geometry can get corrupted by first show after screen change, so recalc it
|
||||
root.calculateWindowGeometry()
|
||||
}
|
||||
|
||||
function onAboutToHide() {
|
||||
@@ -45,8 +75,6 @@ StudioControls.ComboBox {
|
||||
Window {
|
||||
id: window
|
||||
|
||||
width: row.width + 2 // 2: scrollView left and right 1px margins
|
||||
height: Math.min(800, Math.min(row.height + 2, Screen.height - y - 40)) // 40: some bottom margin to cover OS bottom toolbar
|
||||
flags: Qt.Dialog | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint
|
||||
|
||||
onActiveFocusItemChanged: {
|
||||
@@ -67,16 +95,6 @@ StudioControls.ComboBox {
|
||||
Row {
|
||||
id: row
|
||||
|
||||
onWidthChanged: {
|
||||
// Needed to update on first window showing, as row.width only gets
|
||||
// correct value after the window is shown, so first showing is off
|
||||
|
||||
var a = mainRoot.mapToGlobal(0, 0)
|
||||
var b = root.mapToItem(mainRoot, 0, 0)
|
||||
|
||||
window.x = a.x + b.x + root.width - row.width
|
||||
}
|
||||
|
||||
padding: 10
|
||||
spacing: 10
|
||||
|
||||
|
@@ -30,18 +30,48 @@ StudioControls.ComboBox {
|
||||
"images/preview4.png"]
|
||||
property string selectedImage: images[0]
|
||||
|
||||
readonly property int popupHeight: Math.min(800, col.height + 2)
|
||||
|
||||
function calculateWindowGeometry() {
|
||||
var globalPos = EffectMakerBackend.rootView.globalPos(mainRoot.mapFromItem(root, 0, 0))
|
||||
var screenRect = EffectMakerBackend.rootView.screenRect();
|
||||
|
||||
window.width = col.width + 2 // 2: scrollView left and right 1px margins
|
||||
|
||||
var newX = globalPos.x + root.width - window.width
|
||||
if (newX < screenRect.x)
|
||||
newX = globalPos.x
|
||||
|
||||
var newY = Math.min(screenRect.y + screenRect.height,
|
||||
Math.max(screenRect.y, globalPos.y + root.height - 1))
|
||||
|
||||
// Check if we have more space above or below the control, and put control on that side,
|
||||
// unless we have enough room for maximum size popup under the control
|
||||
var newHeight
|
||||
var screenY = newY - screenRect.y
|
||||
if (screenRect.height - screenY > screenY || screenRect.height - screenY > root.popupHeight) {
|
||||
newHeight = Math.min(root.popupHeight, screenRect.height - screenY)
|
||||
} else {
|
||||
newHeight = Math.min(root.popupHeight, screenY - root.height)
|
||||
newY = newY - newHeight - root.height + 1
|
||||
}
|
||||
|
||||
window.height = newHeight
|
||||
window.x = newX
|
||||
window.y = newY
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: root.popup
|
||||
|
||||
function onAboutToShow() {
|
||||
var a = mainRoot.mapToGlobal(0, 0)
|
||||
var b = root.mapToItem(mainRoot, 0, 0)
|
||||
|
||||
window.x = a.x + b.x + root.width - window.width
|
||||
window.y = a.y + b.y + root.height - 1
|
||||
root.calculateWindowGeometry()
|
||||
|
||||
window.show()
|
||||
window.requestActivate()
|
||||
|
||||
// Geometry can get corrupted by first show after screen change, so recalc it
|
||||
root.calculateWindowGeometry()
|
||||
}
|
||||
|
||||
function onAboutToHide() {
|
||||
@@ -65,8 +95,6 @@ StudioControls.ComboBox {
|
||||
Window {
|
||||
id: window
|
||||
|
||||
width: col.width + 2 // 2: scrollView left and right 1px margins
|
||||
height: Math.min(800, Math.min(col.height + 2, Screen.height - y - 40)) // 40: some bottom margin to cover OS bottom toolbar
|
||||
flags: Qt.Dialog | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint
|
||||
|
||||
onActiveFocusItemChanged: {
|
||||
@@ -88,16 +116,6 @@ StudioControls.ComboBox {
|
||||
Column {
|
||||
id: col
|
||||
|
||||
onWidthChanged: {
|
||||
// Needed to update on first window showing, as row.width only gets
|
||||
// correct value after the window is shown, so first showing is off
|
||||
|
||||
var a = mainRoot.mapToGlobal(0, 0)
|
||||
var b = root.mapToItem(mainRoot, 0, 0)
|
||||
|
||||
window.x = a.x + b.x + root.width - col.width
|
||||
}
|
||||
|
||||
padding: 10
|
||||
spacing: 10
|
||||
|
||||
|
@@ -119,6 +119,20 @@ void EffectMakerWidget::focusSection(int section)
|
||||
Q_UNUSED(section)
|
||||
}
|
||||
|
||||
QRect EffectMakerWidget::screenRect() const
|
||||
{
|
||||
if (m_quickWidget && m_quickWidget->screen())
|
||||
return m_quickWidget->screen()->availableGeometry();
|
||||
return {};
|
||||
}
|
||||
|
||||
QPoint EffectMakerWidget::globalPos(const QPoint &point) const
|
||||
{
|
||||
if (m_quickWidget)
|
||||
return m_quickWidget->mapToGlobal(point);
|
||||
return point;
|
||||
}
|
||||
|
||||
QSize EffectMakerWidget::sizeHint() const
|
||||
{
|
||||
return {420, 420};
|
||||
|
@@ -41,6 +41,8 @@ public:
|
||||
|
||||
Q_INVOKABLE void addEffectNode(const QString &nodeQenPath);
|
||||
Q_INVOKABLE void focusSection(int section);
|
||||
Q_INVOKABLE QRect screenRect() const;
|
||||
Q_INVOKABLE QPoint globalPos(const QPoint &point) const;
|
||||
|
||||
QSize sizeHint() const override;
|
||||
|
||||
|
Reference in New Issue
Block a user