Core: Fix 'Expression' and 'Vector' editor outhanging the screen (#22426)

* Core: Fix Expression dialog outhanging main window

Expression dialog is now fully shown inside main window, even if opened from model panel positioned on right side. If Model panel is outside main window, dialog is opened over this panel.

* Core: Fix Vectors dialog outhanging main window

Vectors dialog is now fully shown inside main window, even if opened from model panel positioned on right side. If Model panel is outside main window, dialog is opened over this panel.

* Core: Simplify 'adjustDialogPosition()'

Change suggested and authored by @hyarion
This commit is contained in:
Krzysztof
2025-08-07 19:22:28 +02:00
committed by GitHub
parent b63110b9b5
commit f5a5fb6411
5 changed files with 65 additions and 0 deletions

View File

@@ -52,6 +52,7 @@
#include "Command.h"
#include "Dialogs/DlgExpressionInput.h"
#include "Tools.h"
#include "Widgets.h"
using namespace Gui;
@@ -618,6 +619,7 @@ void QuantitySpinBox::openFormulaDialog()
QPoint pos = mapToGlobal(QPoint(0,0));
box->move(pos-box->expressionPosition());
box->setExpressionInputSize(width(), height());
Gui::adjustDialogPosition(box);
Q_EMIT showFormulaDialog(true);
}

View File

@@ -40,6 +40,7 @@
#include "Command.h"
#include "Dialogs/DlgExpressionInput.h"
#include "QuantitySpinBox_p.h"
#include "Widgets.h"
using namespace Gui;
@@ -206,6 +207,7 @@ void ExpressionSpinBox::openFormulaDialog()
QPoint pos = spinbox->mapToGlobal(QPoint(0,0));
box->move(pos-box->expressionPosition());
box->setExpressionInputSize(spinbox->width(), spinbox->height());
Gui::adjustDialogPosition(box);
}
bool ExpressionSpinBox::handleKeyEvent(const QString& text)

View File

@@ -55,6 +55,7 @@
#include "QuantitySpinBox_p.h"
#include "Tools.h"
#include "Dialogs/ui_DlgTreeWidget.h"
#include "MainWindow.h"
using namespace Gui;
using namespace App;
@@ -1606,6 +1607,7 @@ void ExpLineEdit::openFormulaDialog()
QPoint pos = mapToGlobal(QPoint(0,0));
box->move(pos-box->expressionPosition());
box->setExpressionInputSize(width(), height());
Gui::adjustDialogPosition(box);
}
void ExpLineEdit::finishFormulaDialog()
@@ -1663,5 +1665,54 @@ bool ButtonGroup::exclusive() const
return _exclusive;
}
namespace Gui {
void adjustDialogPosition(QDialog* dialog) {
if (!dialog) {
return;
}
const MainWindow* mw = getMainWindow();
if (!mw) {
return;
}
dialog->adjustSize(); // ensure correct size
const QRect mainWindowRect{ mw->mapToGlobal(QPoint(0, 0)), mw->size() };
const QRect dialogRect{ dialog->frameGeometry() };
const bool isFullyInside = mainWindowRect.contains(dialogRect);
if (isFullyInside) {
return;
}
const bool isCompletelyOutside = !mainWindowRect.intersects(dialogRect);
if (isCompletelyOutside) {
return;
}
const int margin = 5;
const QRect availableArea = mainWindowRect.adjusted(
margin, margin, -margin, -margin
);
QPoint adjustedTopLeft = dialogRect.topLeft();
adjustedTopLeft.setX(std::clamp(
adjustedTopLeft.x(),
availableArea.left(),
availableArea.right() - dialogRect.width()
));
adjustedTopLeft.setY(std::clamp(
adjustedTopLeft.y(),
availableArea.top(),
availableArea.bottom() - dialogRect.height()
));
dialog->move(adjustedTopLeft);
}
}
#include "moc_Widgets.cpp"

View File

@@ -613,6 +613,15 @@ private:
bool _exclusive;
};
/**
* Adjusts the position of the given dialog to ensure it remains within the bounds of the main window.
* This helps prevent dialogs from appearing partially or fully off-screen relative to the main application window.
*
* This function shall be invoked after the dialog has been shown (using show()) or its position or size has changed.
* Exception: If the dialog is modal, this function should be called before the dialog is called with exec().
*/
void adjustDialogPosition(QDialog* dialog);
} // namespace Gui
#endif // GUI_WIDGETS_H

View File

@@ -1645,6 +1645,7 @@ void VectorListWidget::buttonClicked()
setValue(data);
});
Gui::adjustDialogPosition(dlg);
dlg->exec();
}