1 /* 2 * stackedwidgets.h - classes implementing stacked widgets 3 * Program: kalarm 4 * SPDX-FileCopyrightText: 2008-2021 David Jarvie <djarvie@kde.org> 5 * 6 * SPDX-License-Identifier: GPL-2.0-or-later 7 */ 8 9 #pragma once 10 11 #include <QStackedWidget> 12 #include <QVector> 13 #include <QScrollArea> 14 class QDialog; 15 16 /** 17 * A QStackedWidget, whose size hint is that of the largest widget in the stack. 18 * 19 * @author David Jarvie <djarvie@kde.org> 20 */ 21 class StackedWidget : public QStackedWidget 22 { 23 public: 24 /** Constructor. 25 * @param parent The parent object of this widget. 26 */ 27 explicit StackedWidget(QWidget* parent = nullptr) QStackedWidget(parent)28 : QStackedWidget(parent) {} 29 QSize sizeHint() const override; 30 QSize minimumSizeHint() const override; 31 }; 32 33 template <class T> class StackedGroupT; 34 35 /** 36 * A widget contained in a stack, whose minimum size hint is that of the largest 37 * widget in the stack. This class works together with StackedGroup. 38 * 39 * @author David Jarvie <djarvie@kde.org> 40 */ 41 template <class T> 42 class StackedGroupWidgetT : public T 43 { 44 public: 45 /** Constructor. 46 * @param parent The parent object of this widget. 47 * @param group The stack group to insert this widget into. 48 */ 49 explicit StackedGroupWidgetT(StackedGroupT<T>* group, QWidget* parent = nullptr) T(parent)50 : T(parent), 51 mGroup(group) 52 { 53 mGroup->addWidget(this); 54 } ~StackedGroupWidgetT()55 ~StackedGroupWidgetT() override { mGroup->removeWidget(this); } sizeHint()56 QSize sizeHint() const override { return minimumSizeHint(); } minimumSizeHint()57 QSize minimumSizeHint() const override { return mGroup->minimumSizeHint(); } 58 59 private: 60 StackedGroupT<T>* mGroup; 61 }; 62 63 /** 64 * A group of stacked widgets whose minimum size hints are all equal to the 65 * largest widget's minimum size hint. 66 * 67 * It is inherited from QObject solely to ensure automatic deletion when its 68 * parent widget is deleted. 69 * 70 * @author David Jarvie <djarvie@kde.org> 71 */ 72 template <class T> 73 class StackedGroupT : public QObject 74 { 75 public: QObject(parent)76 explicit StackedGroupT(QObject* parent = nullptr) : QObject(parent) {} addWidget(StackedGroupWidgetT<T> * w)77 void addWidget(StackedGroupWidgetT<T>* w) { mWidgets += w; } removeWidget(StackedGroupWidgetT<T> * w)78 void removeWidget(StackedGroupWidgetT<T>* w) { mWidgets.removeAll(w); } 79 virtual QSize minimumSizeHint() const; 80 81 protected: 82 QVector<StackedGroupWidgetT<T>*> mWidgets; 83 }; 84 85 template <class T> minimumSizeHint()86QSize StackedGroupT<T>::minimumSizeHint() const 87 { 88 QSize sz; 89 for (const auto& w : mWidgets) 90 sz = sz.expandedTo(w->T::minimumSizeHint()); 91 return sz; 92 } 93 94 /** A non-scrollable stacked widget. */ 95 using StackedGroupWidget = StackedGroupWidgetT<QWidget>; 96 /** A group of non-scrollable stacked widgets. */ 97 using StackedGroup = StackedGroupT<QWidget>; 98 99 100 class StackedScrollGroup; 101 102 /** 103 * A stacked widget which becomes scrollable when necessary to fit the height 104 * of the screen. 105 * 106 * @author David Jarvie <djarvie@kde.org> 107 */ 108 class StackedScrollWidget : public StackedGroupWidgetT<QScrollArea> 109 { 110 public: 111 explicit StackedScrollWidget(StackedScrollGroup* group, QWidget* parent = nullptr); widget()112 QWidget* widget() const { return viewport()->findChild<QWidget*>(); } 113 }; 114 115 /** 116 * A group of stacked widgets which individually become scrollable when necessary 117 * to fit the height of the screen. 118 * 119 * @author David Jarvie <djarvie@kde.org> 120 */ 121 class StackedScrollGroup : public StackedGroupT<QScrollArea> 122 { 123 public: 124 StackedScrollGroup(QDialog*, QObject* tabParent); 125 QSize minimumSizeHint() const override; heightReduction()126 int heightReduction() const { return mHeightReduction; } 127 QSize adjustSize(bool force = false); setSized()128 void setSized() { mSized = true; } sized()129 bool sized() const { return mSized; } 130 131 private: 132 QSize maxMinimumSizeHint() const; 133 134 QDialog* mDialog; 135 int mMinHeight {-1}; 136 int mHeightReduction {0}; 137 bool mSized {false}; 138 }; 139 140 141 // vim: et sw=4: 142