Commit 349db11a authored by Ingo Klöcker's avatar Ingo Klöcker
Browse files

Automatically adjust the height of the scroll area to its contents

If sizeAdjustPolicy is set to QAbstractScrollArea::AdjustToContents,
then the scroll area will (try to) adjust its height, so that the widget
in the scroll area is shown without vertical bar.

GnuPG-bug-id: 5969
parent d4d7bb80
......@@ -3,6 +3,8 @@
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB
SPDX-FileCopyrightText: 2022 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
......@@ -11,6 +13,8 @@
#include "scrollarea.h"
#include <QResizeEvent>
#include <QScreen>
#include <QScrollBar>
#include <QVBoxLayout>
......@@ -24,9 +28,28 @@ ScrollArea::ScrollArea(QWidget *parent)
new QVBoxLayout{w};
setWidget(w);
setWidgetResizable(true);
w->installEventFilter(this);
}
ScrollArea::~ScrollArea() = default;
ScrollArea::~ScrollArea()
{
widget()->removeEventFilter(this);
}
void ScrollArea::setMaximumAutoAdjustHeight(int maxHeight)
{
mMaximumAutoAdjustHeight = maxHeight;
}
int ScrollArea::maximumAutoAdjustHeight() const
{
if (mMaximumAutoAdjustHeight < 0) {
// if no height is set then use 2/3 of the desktop's height, i.e.
// the same as Qt uses for top-level widgets
return screen()->availableGeometry().height() * 2 / 3;
}
return mMaximumAutoAdjustHeight;
}
QSize ScrollArea::minimumSizeHint() const
{
......@@ -57,3 +80,17 @@ QSize ScrollArea::sizeHint() const
return sz;
}
bool ScrollArea::eventFilter(QObject *obj, QEvent *ev)
{
if (ev->type() == QEvent::Resize && obj == widget() && sizeAdjustPolicy() == AdjustToContents) {
const auto *const event = static_cast<QResizeEvent*>(ev);
if (event->size().height() > event->oldSize().height()) {
const auto currentViewportHeight = viewport()->height();
const auto wantedViewportHeight = std::min(event->size().height(), maximumAutoAdjustHeight());
if (currentViewportHeight < wantedViewportHeight) {
setMinimumHeight(height() - currentViewportHeight + wantedViewportHeight);
}
}
}
return QScrollArea::eventFilter(obj, ev);
}
......@@ -3,6 +3,8 @@
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB
SPDX-FileCopyrightText: 2022 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
......@@ -17,6 +19,10 @@ namespace Kleo
/**
* This class improves a few aspects of QScrollArea for usage by us, in
* particular, for vertically scrollable widgets.
*
* If sizeAdjustPolicy is set to QAbstractScrollArea::AdjustToContents,
* then the scroll area will (try to) adjust its size to the widget to avoid
* scroll bars as much as possible.
*/
class ScrollArea : public QScrollArea
{
......@@ -30,6 +36,19 @@ public:
explicit ScrollArea(QWidget *parent = nullptr);
~ScrollArea() override;
/**
* Sets the maximum height that the scroll area should automatically resize
* to to \p maxHeight. By default, or if \p maxHeight is negative, the
* scroll area will resize to at most 2/3 of the desktop's height.
*/
void setMaximumAutoAdjustHeight(int maxHeight);
/**
* Returns the maximum height that the scroll area will automatically resize
* to.
*/
int maximumAutoAdjustHeight() const;
/**
* Reimplemented to add the minimum size hint of the widget.
*/
......@@ -41,6 +60,12 @@ public:
* unless it is explicitly turned off.
*/
QSize sizeHint() const override;
private:
bool eventFilter(QObject *obj, QEvent *ev) override;
private:
int mMaximumAutoAdjustHeight = -1;
};
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment