diff options
| author | Rusty Wagner <rusty.wagner@gmail.com> | 2024-01-12 10:11:19 -0700 |
|---|---|---|
| committer | Rusty Wagner <rusty.wagner@gmail.com> | 2024-02-05 13:42:52 -0500 |
| commit | 97ac519092fc87e27c49ab21aafb41b77f40dc03 (patch) | |
| tree | 33d1a72b835a73c25868cb170106f865d9d54430 /ui/splitter.h | |
| parent | efa49ca6d23530b5e1ececccea4a2dc0bbe3406b (diff) | |
Sidebar improvements
Diffstat (limited to 'ui/splitter.h')
| -rw-r--r-- | ui/splitter.h | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/ui/splitter.h b/ui/splitter.h new file mode 100644 index 00000000..089de444 --- /dev/null +++ b/ui/splitter.h @@ -0,0 +1,123 @@ +#pragma once + +#include <QtWidgets/QWidget> +#include <QtCore/QSettings> +#include <vector> +#include <set> +#include <map> +#include "uicontext.h" + +/*! + \defgroup splitter Splitter + \ingroup uiapi +*/ + +/*! + \ingroup splitter +*/ +enum SplitterWidgetSizingStyle +{ + RelativeWidgetSize, + WidgetSizeInPoints +}; + +/*! + \ingroup splitter +*/ +struct BINARYNINJAUIAPI SplitterWidgetSizing +{ + SplitterWidgetSizingStyle style; + float referenceSize; + bool isDefault; + float requestedSize; + QString group; + + static SplitterWidgetSizing relativeSize(float relativeSize = 1, const QString& group = QString()); + static SplitterWidgetSizing pointSize(int size); + + QVariantMap serialize() const; + static std::optional<SplitterWidgetSizing> deserialize(const QVariantMap& value); +}; + +/*! + \ingroup splitter +*/ +struct BINARYNINJAUIAPI SplitterWidget +{ + QString key; + QWidget* widget; + bool visible; + SplitterWidgetSizing sizing; + int actualSize, minimumSize; +}; + +/*! + \ingroup splitter +*/ +class BINARYNINJAUIAPI Splitter: public QWidget +{ + Q_OBJECT + + struct SplitterDragInfo + { + size_t left, right; + int offset; + }; + + struct GroupInfo + { + QString group; + std::set<SplitterWidget*> widgets; + SplitterWidgetSizing sizing; + int actualSize, minimumSize; + }; + + Qt::Orientation m_orientation; + int m_handleSize; + + std::vector<SplitterWidget> m_widgets; + std::map<QString, SplitterWidgetSizing> m_sizing; + std::map<QString, SplitterWidgetSizing> m_groupSizing; + + std::optional<size_t> m_handleHover; + std::optional<SplitterDragInfo> m_handleDrag; + + bool m_updatingLayout = false; + +public: + Splitter(Qt::Orientation orientation); + + void addWidget(const QString& key, QWidget* widget, const SplitterWidgetSizing& defaultSize); + void insertWidget(const QString& key, size_t index, QWidget* widget, const SplitterWidgetSizing& defaultSize); + void addRelativeSizeGroup(const QString& group, float relativeSize); + + QVariantMap saveState(); + void saveState(QSettings& settings, const QString& stateName); + void restoreState(const QVariantMap& state); + void restoreState(const QSettings& settings, const QString& stateName); + void resetToDefault(); + +protected: + virtual void paintEvent(QPaintEvent* event) override; + virtual void mousePressEvent(QMouseEvent* event) override; + virtual void mouseMoveEvent(QMouseEvent* event) override; + virtual void mouseReleaseEvent(QMouseEvent* event) override; + virtual void leaveEvent(QEvent* event) override; + virtual void resizeEvent(QResizeEvent* event) override; + virtual void childEvent(QChildEvent* event) override; + virtual bool event(QEvent* event) override; + +private: + void forAllSplitterHandles(const std::function<void(size_t leftIdx, size_t rightIdx, int pos)>& func); + void processLayout(const std::function<int(int availablePointSize)>& processPointSizeWidgets, + const std::function<void(int availableWidgetSize)>& processRelativeSizeWidgets); + void getWidgetsForSizingStyle(SplitterWidgetSizingStyle style, + std::set<SplitterWidget*>& widgets, std::vector<GroupInfo>& groups); + void regenerateLayoutForRelativeSizedWidgets( + std::set<SplitterWidget*> widgets, std::vector<GroupInfo> groups, int availableSize); + void regenerateLayout(); + void calculateRequestedSizesForRelativeSizedWidgets( + const std::set<SplitterWidget*>& widgets, const std::vector<GroupInfo>& groups, int availableSize); + void calculateRequestedSizesForActualLayout(); + void updateWidgetPositions(); +}; |
