From 97ac519092fc87e27c49ab21aafb41b77f40dc03 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Fri, 12 Jan 2024 10:11:19 -0700 Subject: Sidebar improvements --- ui/splitter.h | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 ui/splitter.h (limited to 'ui/splitter.h') 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 +#include +#include +#include +#include +#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 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 widgets; + SplitterWidgetSizing sizing; + int actualSize, minimumSize; + }; + + Qt::Orientation m_orientation; + int m_handleSize; + + std::vector m_widgets; + std::map m_sizing; + std::map m_groupSizing; + + std::optional m_handleHover; + std::optional 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& func); + void processLayout(const std::function& processPointSizeWidgets, + const std::function& processRelativeSizeWidgets); + void getWidgetsForSizingStyle(SplitterWidgetSizingStyle style, + std::set& widgets, std::vector& groups); + void regenerateLayoutForRelativeSizedWidgets( + std::set widgets, std::vector groups, int availableSize); + void regenerateLayout(); + void calculateRequestedSizesForRelativeSizedWidgets( + const std::set& widgets, const std::vector& groups, int availableSize); + void calculateRequestedSizesForActualLayout(); + void updateWidgetPositions(); +}; -- cgit v1.3.1