Add function to center a widget avoiding overflow

This commit is contained in:
Martchus 2021-03-24 14:42:56 +01:00
parent 55341a7305
commit 3da940fe5b
2 changed files with 52 additions and 7 deletions

View File

@ -114,17 +114,61 @@ QRect availableScreenGeometryAtPoint(const QPoint &point)
#endif
}
/// \cond
static QRect limitRect(QRect rect, const QRect &bounds)
{
if (rect.left() < bounds.left()) {
rect.setLeft(bounds.left());
}
if (rect.top() < bounds.top()) {
rect.setTop(bounds.top());
}
if (rect.right() > bounds.right()) {
rect.setRight(bounds.right());
}
if (rect.bottom() > bounds.bottom()) {
rect.setBottom(bounds.bottom());
}
return rect;
}
static bool centerWidgetInternal(QWidget *widget, const QWidget *parent, const QPoint *position, bool avoidOverflow)
{
const auto availableGeometry = parent ? parent->geometry() : availableScreenGeometryAtPoint(position ? *position : QCursor::pos());
const auto alignedRect = QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, widget->size(), availableGeometry);
if (!avoidOverflow) {
widget->setGeometry(alignedRect);
return false;
}
const auto limitedRect = limitRect(alignedRect, availableGeometry);
widget->setGeometry(limitedRect);
return alignedRect != limitedRect;
}
/// \endcond
/*!
* \brief Moves the specified \a widget in the middle of the (available) screen
* area or \a parent if specified.
*
* The screen containing the current cursor position is used unless \a position
* is specified.
* \brief Moves the specified \a widget to be centered within the (available) screen area or \a parent if specified.
* \remarks
* - The screen containing the current cursor position is used unless \a position is specified.
*/
void centerWidget(QWidget *widget, const QWidget *parent, const QPoint *position)
{
widget->setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, widget->size(),
parent ? parent->geometry() : availableScreenGeometryAtPoint(position ? *position : QCursor::pos())));
centerWidgetInternal(widget, parent, position, false);
}
/*!
* \brief Moves the specified \a widget to be centered within the (available) screen area or \a parent if specified.
* \returns Returns whether an overflow occurred.
* \remarks
* - If the widget overflows it is resized to take the whole available space in the dimention(s) that overflow. Note that
* this does *not* take the window frame into account. So if \a widget is a window it makes sense to show it using
* QWidget::showMaximized() to make it fill the entire screen to avoid clipped window frames. It makes also sense to
* assign a smaller size to avoid clipped window frames once the window is "de-maximized" again.
* - The screen containing the current cursor position is used unless \a position is specified.
*/
bool centerWidgetAvoidingOverflow(QWidget *widget, const QWidget *parent, const QPoint *position)
{
return centerWidgetInternal(widget, parent, position, true);
}
/*!

View File

@ -37,6 +37,7 @@ QT_UTILITIES_EXPORT const QString &dialogStyle();
#ifdef QT_UTILITIES_GUI_QTWIDGETS
QT_UTILITIES_EXPORT QRect availableScreenGeometryAtPoint(const QPoint &point);
QT_UTILITIES_EXPORT void centerWidget(QWidget *widget, const QWidget *parent = nullptr, const QPoint *position = nullptr);
QT_UTILITIES_EXPORT bool centerWidgetAvoidingOverflow(QWidget *widget, const QWidget *parent = nullptr, const QPoint *position = nullptr);
QT_UTILITIES_EXPORT void cornerWidget(QWidget *widget, const QPoint *position = nullptr);
QT_UTILITIES_EXPORT void makeHeading(QWidget *widget);
QT_UTILITIES_EXPORT void updateStyle(QWidget *widget);