diff --git a/src/Gui/QuantitySpinBox.cpp b/src/Gui/QuantitySpinBox.cpp index 98749a06b0..b7febd34e6 100644 --- a/src/Gui/QuantitySpinBox.cpp +++ b/src/Gui/QuantitySpinBox.cpp @@ -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); } diff --git a/src/Gui/SpinBox.cpp b/src/Gui/SpinBox.cpp index ca0bae7f60..89287b4f54 100644 --- a/src/Gui/SpinBox.cpp +++ b/src/Gui/SpinBox.cpp @@ -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) diff --git a/src/Gui/Widgets.cpp b/src/Gui/Widgets.cpp index 7bf54da9e9..72920e3ac7 100644 --- a/src/Gui/Widgets.cpp +++ b/src/Gui/Widgets.cpp @@ -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" diff --git a/src/Gui/Widgets.h b/src/Gui/Widgets.h index f086c28f91..34bfe251fe 100644 --- a/src/Gui/Widgets.h +++ b/src/Gui/Widgets.h @@ -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 diff --git a/src/Gui/propertyeditor/PropertyItem.cpp b/src/Gui/propertyeditor/PropertyItem.cpp index 7e0098a46c..c90b4870a6 100644 --- a/src/Gui/propertyeditor/PropertyItem.cpp +++ b/src/Gui/propertyeditor/PropertyItem.cpp @@ -1645,6 +1645,7 @@ void VectorListWidget::buttonClicked() setValue(data); }); + Gui::adjustDialogPosition(dlg); dlg->exec(); }