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/sidebar.h | |
| parent | efa49ca6d23530b5e1ececccea4a2dc0bbe3406b (diff) | |
Sidebar improvements
Diffstat (limited to 'ui/sidebar.h')
| -rw-r--r-- | ui/sidebar.h | 347 |
1 files changed, 107 insertions, 240 deletions
diff --git a/ui/sidebar.h b/ui/sidebar.h index 4f8825ed..59bf4d34 100644 --- a/ui/sidebar.h +++ b/ui/sidebar.h @@ -1,288 +1,155 @@ #pragma once -#include <QtWidgets/QWidget> -#include <QtWidgets/QLabel> -#include <QtWidgets/QStackedWidget> #include <QtWidgets/QSplitter> -#include <QtGui/QPicture> #include <QtCore/QSettings> -#include "theme.h" +#include "sidebarwidget.h" +#include "sidebarcontainer.h" +#include "sidebaricons.h" +#include "splitter.h" -class SidebarEntry; -class MainWindow; -class ContextMenuManager; -class SplitPaneWidget; - -/*! - - \defgroup sidebar Sidebar - \ingroup uiapi -*/ - -/*! - \ingroup sidebar -*/ -struct SidebarIcon -{ - QImage original; - QImage active; - QImage inactive; - - static SidebarIcon generate(const QImage& src); -}; - -/*! - \ingroup sidebar -*/ -class BINARYNINJAUIAPI SidebarWidget : public QWidget -{ - Q_OBJECT - - protected: - QString m_title; - UIActionHandler m_actionHandler; - ContextMenuManager* m_contextMenuManager = nullptr; - Menu* m_menu = nullptr; - - QTimer* m_updateTimer = nullptr; - - public: - SidebarWidget(const QString& title); - ~SidebarWidget() { closing(); } - const QString& title() const { return m_title; } - - void enableRefreshTimer(int interval); - void setRefreshQuiesce(bool enable); - virtual void notifyRefresh() {}; - - virtual void notifyFontChanged() {} - virtual void notifyOffsetChanged(uint64_t /*offset*/) {} - virtual void notifyThemeChanged(); - virtual void notifyViewChanged(ViewFrame* /*frame*/) {} - virtual void notifyViewLocationChanged(View* /*view*/, const ViewLocation& /*viewLocation*/) {} - virtual void focus(); - virtual void closing() {} - - virtual QWidget* headerWidget() { return nullptr; } -}; - -/*! - \ingroup sidebar -*/ -class BINARYNINJAUIAPI SidebarWidgetAndHeader : public QWidget -{ - Q_OBJECT - SidebarWidget* m_widget; - QWidget* m_header; - ViewFrame* m_frame; - - public: - SidebarWidgetAndHeader(SidebarWidget* widget, ViewFrame* frame); - - SidebarWidget* widget() const { return m_widget; } - QWidget* header() const { return m_header; } - ViewFrame* viewFrame() const { return m_frame; } - - void updateTheme(); - void updateFonts(); -}; - -/*! - \ingroup sidebar -*/ -class BINARYNINJAUIAPI SidebarHeaderTitle : public QLabel -{ - Q_OBJECT - - public: - SidebarHeaderTitle(const QString& name); -}; +class ViewFrame; /*! \ingroup sidebar */ -class BINARYNINJAUIAPI SidebarHeader : public QWidget +struct BINARYNINJAUIAPI SidebarMetrics { - Q_OBJECT - - public: - SidebarHeader(const QString& name, QWidget* rightSide = nullptr); + int iconWidth, iconHeight; + int paddingX, paddingY; + int separatorPadding; + int iconTotalWidth, iconTotalHeight; + int dragIconPadding; + int dropIconPadding; }; /*! \ingroup sidebar */ -class BINARYNINJAUIAPI SidebarInvalidContextWidget : public SidebarWidget +class BINARYNINJAUIAPI Sidebar : public QObject { Q_OBJECT - public: - SidebarInvalidContextWidget(const QString& title); - - private Q_SLOTS: - void openFile(); -}; - -/*! - \ingroup sidebar -*/ -class BINARYNINJAUIAPI SidebarWidgetType -{ - SidebarIcon m_icon; - QString m_name; - - public: - SidebarWidgetType(const QImage& icon, const QString& name); - virtual ~SidebarWidgetType() {} - - const SidebarIcon& icon() const { return m_icon; } - const QString& name() const { return m_name; } + struct SavedTypeOrderingInfo + { + QString typeName; + bool isDefaultArea; + }; - virtual bool isInReferenceArea() const { return false; } - virtual bool viewSensitive() const { return true; } - virtual SidebarWidget* createWidget(ViewFrame* frame, BinaryViewRef data) = 0; - virtual SidebarWidget* createInvalidContextWidget(); + SidebarIconsWidget* m_left; + SidebarIconsWidget* m_right; + Splitter* m_parentSideSplitter = nullptr; + Splitter* m_parentExtendedSideSplitter = nullptr; + Splitter* m_parentBottomSplitter = nullptr; + Splitter* m_parentBottomSeparatorSplitter = nullptr; - void updateTheme(); -}; - -class ViewFrame; + SplitPaneWidget* m_panes = nullptr; + ViewFrame* m_frame = nullptr; + QString m_dataType; + BinaryViewRef m_data; -/*! - \ingroup sidebar -*/ -struct SidebarWidgetContainerState -{ - SidebarWidgetType* contentWidgetType; - SidebarWidgetType* referenceWidgetType; - QList<int> contentSplitterSizes; - QList<int> parentSplitterSizes; -}; + std::map<SplitPaneWidget*, std::map<QString, QVariantMap>> m_priorParentSideSplitterSizes; + std::map<SplitPaneWidget*, std::map<QString, QVariantMap>> m_priorParentExtendedSideSplitterSizes; + std::map<SplitPaneWidget*, std::map<QString, QVariantMap>> m_priorParentBottomSplitterSizes; + std::map<SplitPaneWidget*, std::map<QString, QVariantMap>> m_priorParentBottomSeparatorSplitterSizes; + std::map<SplitPaneWidget*, std::map<ViewFrame*, std::map<QString, std::pair<View*, ViewLocation>>>> + m_currentViewLocation; + std::set<SidebarWidgetType*> m_toggledWidgets; -/*! - \ingroup sidebar -*/ -class BINARYNINJAUIAPI SidebarWidgetContainer : public QWidget -{ - Q_OBJECT + static std::map<SidebarWidgetLocation, std::vector<SidebarWidgetType*>> m_types; + static std::map<SidebarWidgetLocation, std::vector<SavedTypeOrderingInfo>> m_savedTypeOrdering; + static std::set<Sidebar*> m_instances; + static std::set<SidebarWidgetType*> m_defaultTypes; + static std::optional<SidebarMetrics> m_metrics; - QSplitter* m_parentSplitter = nullptr; - QSplitter* m_contentSplitter; - QStackedWidget* m_contentStackedWidget; - QStackedWidget* m_referenceStackedWidget; - SplitPaneWidget* m_panes; - ViewFrame* m_frame; - QString m_dataType; - BinaryViewRef m_data; - SidebarWidgetType* m_contentActive = nullptr; - SidebarWidgetType* m_lastContentActive = nullptr; - SidebarWidgetType* m_referenceActive = nullptr; - SidebarWidgetType* m_pendingReferenceType = nullptr; - std::map<ViewFrame*, std::map<QString, std::map<SidebarWidgetType*, SidebarWidgetAndHeader*>>> m_widgets; - std::map<SplitPaneWidget*, std::map<QString, std::pair<SidebarWidgetType*, SidebarWidgetType*>>> m_priorWidgets; - std::map<SplitPaneWidget*, std::map<QString, QList<int>>> m_priorContentSplitterSizes; - std::map<SplitPaneWidget*, std::map<QString, QList<int>>> m_priorParentSplitterSizes; - std::optional<QList<int>> m_pendingContentSplitterSizes; - std::optional<QList<int>> m_pendingParentSplitterSizes; - std::map<ViewFrame*, std::map<QString, std::pair<View*, ViewLocation>>> m_currentViewLocation; +private Q_SLOTS: + void containerUpdated(); - void activateWidgetForType(SidebarWidgetType* type); - void deactivateWidgetForType(SidebarWidgetType* type); +public: + Sidebar(QWidget* parent); + virtual ~Sidebar(); - static QVariant sizesToVariant(const QList<int>& sizes); - static std::optional<QList<int>> variantToSizes(const QVariant& variant); + SidebarIconsWidget* left() const { return m_left; } + SidebarIconsWidget* right() const { return m_right; } + static SidebarWidgetLocation locationForType(SidebarWidgetType* type); + static SidebarLocation sideForLocation(SidebarWidgetLocation location); + static SidebarContainerLocation containerLocationForWidgetLocation(SidebarWidgetLocation location); + SidebarWidgetContainer* containerForLocation(SidebarWidgetLocation location) const; + static Qt::Orientation primaryOrientationForLocation(SidebarWidgetLocation location); + void forAllContainers(const std::function<void(SidebarWidgetContainer*)>& func) const; - public: - SidebarWidgetContainer(); + void setSplitters(Splitter* sideSplitter, Splitter* extendedSideSplitter, Splitter* bottomSplitter, + Splitter* bottomSeparatorSplitter); - void setSplitter(QSplitter* splitter); void setActiveContext(SplitPaneWidget* panes, ViewFrame* frame, const QString& dataType, BinaryViewRef data); void destroyContext(ViewFrame* frame); void destroyContext(SplitPaneWidget* panes); + void moveContextToContainer(SplitPaneWidget* panes, Sidebar* target); - bool isContentActive() const { return m_contentActive != nullptr; } - bool isActive(SidebarWidgetType* type) const { return m_contentActive == type || m_referenceActive == type; } - void activate(SidebarWidgetType* type); - void deactivate(SidebarWidgetType* type); + SplitPaneWidget* currentPanes(SidebarWidgetType* type = nullptr) const; + ViewFrame* currentFrame(SidebarWidgetType* type = nullptr) const; + const QString& currentDataType(SidebarWidgetType* type = nullptr) const; + BinaryViewRef currentData(SidebarWidgetType* type = nullptr) const; + std::optional<std::pair<View*, ViewLocation>> currentViewLocation() const; SidebarWidget* widget(SidebarWidgetType* type); SidebarWidget* widget(const QString& name); + SidebarWidgetAndHeader* widgetAndHeader(SidebarWidgetType* type); + SidebarWidgetAndHeader* widgetAndHeader(const QString& name); - virtual QSize sizeHint() const override; - - void updateTheme(); - void updateFonts(); - - void setDefaultReferenceType(SidebarWidgetType* type); - - void saveSizes(const QSettings& settings, const QString& windowStateName); - void saveState(const QSettings& settings, const QString& windowStateName); - void restoreSizes(const QSettings& settings, const QString& windowStateName); - void restoreState(const QSettings& settings, const QString& windowStateName); - - void updateViewLocation(View* view, const ViewLocation& viewLocation); - void viewChanged(); - - void toggleSidebar(); - - void moveContextToContainer( - SplitPaneWidget* panes, const std::vector<ViewFrame*>& frames, SidebarWidgetContainer* target); - - Q_SIGNALS: - void showContents(); - void hideContents(); -}; - -/*! - \ingroup sidebar -*/ -class BINARYNINJAUIAPI Sidebar : public QWidget -{ - Q_OBJECT - - SidebarWidgetType* m_hoverItem = nullptr; - SidebarWidgetContainer* m_currentContainer = nullptr; - - static std::vector<SidebarWidgetType*> m_contentTypes; - static std::vector<SidebarWidgetType*> m_referenceTypes; - static SidebarWidgetType* m_defaultContentType; - static SidebarWidgetType* m_defaultReferenceType; - - protected: - virtual void paintEvent(QPaintEvent* event) override; - virtual void mouseMoveEvent(QMouseEvent* event) override; - virtual void mousePressEvent(QMouseEvent* event) override; - virtual void leaveEvent(QEvent* event) override; - - public: - Sidebar(); - - SidebarWidgetContainer* container() const { return m_currentContainer; } - void setContainer(SidebarWidgetContainer* container); - void setActiveContext(SplitPaneWidget* panes, ViewFrame* frame, const QString& dataType, BinaryViewRef data); - - SidebarWidget* widget(SidebarWidgetType* type); - SidebarWidget* widget(const QString& name); + void addWidget(SidebarWidgetType* type, SidebarWidget* widget, bool canClose = false); + void addWidget(const QString& name, SidebarWidget* widget, bool canClose = false); + void removeWidget(SidebarWidgetType* type, SidebarWidget* widget); + void removeWidget(const QString& typeName, SidebarWidget* widget); + SidebarWidget* widgetWithTitle(SidebarWidgetType* type, const QString& title) const; + SidebarWidget* widgetWithTitle(const QString& typeName, const QString& title) const; + bool hasWidgetWithTitle(SidebarWidgetType* type, const QString& title) const; + bool hasWidgetWithTitle(const QString& typeName, const QString& title) const; + void focusWidgetWithTitle(SidebarWidgetType* type, const QString& title); + void focusWidgetWithTitle(const QString& typeName, const QString& title); void activate(SidebarWidgetType* type); void activate(const QString& name); + void activateDefaultTypes(); void deactivate(SidebarWidgetType* type); void deactivate(const QString& name); + void focus(SidebarWidgetType* type); + void focus(const QString& name); + void toggle(SidebarWidgetType* type); + void toggle(const QString& name); + bool isActive(SidebarWidgetType* type) const; + bool isActive(const QString& name) const; + bool isContentActive() const; + bool isSideContentActive() const; + bool isBottomContentActive() const; void updateTheme(); void updateFonts(); void toggleSidebar(); + void updateViewLocation(View* view, const ViewLocation& viewLocation); + void viewChanged(); + + void saveState(QSettings& settings, const QString& windowStateName, bool globalStateOnly = false); + QVariant saveActiveState(); + void restoreState(const QSettings& settings, const QString& windowStateName, bool globalStateOnly = false); + bool restoreActiveState(const QVariant& state); + static void addSidebarWidgetType(SidebarWidgetType* type); + static void moveSidebarWidgetType(SidebarWidgetType* type, SidebarWidgetLocation newLocation, size_t newIndex); static SidebarWidgetType* typeFromName(const QString& name); - static const std::vector<SidebarWidgetType*>& contentTypes() { return m_contentTypes; } - static const std::vector<SidebarWidgetType*>& referenceTypes() { return m_referenceTypes; } + static bool isTypeRegistered(const QString& name); + static std::vector<SidebarWidgetType*> types(); + static const std::vector<SidebarWidgetType*>& typesForLocation(SidebarWidgetLocation location); + static std::vector<SidebarWidgetType*> typesForContainerLocation(SidebarContainerLocation location); + static void initSavedTypeOrdering(); + static void saveTypeOrdering(); + + static SidebarMetrics metrics(); + static void refreshMetrics(); - static SidebarWidgetType* defaultContentType() { return m_defaultContentType; } - static SidebarWidgetType* defaultReferenceType() { return m_defaultReferenceType; } - static void setDefaultContentType(SidebarWidgetType* type) { m_defaultContentType = type; } - static void setDefaultReferenceType(SidebarWidgetType* type) { m_defaultReferenceType = type; } + static std::set<SidebarWidgetType*> defaultTypes() { return m_defaultTypes; } + static void setDefaultTypes(const std::set<SidebarWidgetType*>& types) { m_defaultTypes = types; } static Sidebar* current() { @@ -296,7 +163,7 @@ class BINARYNINJAUIAPI Sidebar : public QWidget static T* widget(SidebarWidgetType* type) { Sidebar* sidebar = current(); - if (!type || !sidebar || !sidebar->container() || !sidebar->container()->isActive(type)) + if (!type || !sidebar || !sidebar->isActive(type)) return (T*)nullptr; QWidget* widget = sidebar->widget(type); if (!widget) @@ -314,7 +181,7 @@ class BINARYNINJAUIAPI Sidebar : public QWidget static T* activateWidget(SidebarWidgetType* type) { Sidebar* sidebar = current(); - if (!type || !sidebar || !sidebar->container()) + if (!type || !sidebar) return (T*)nullptr; sidebar->activate(type); QWidget* widget = sidebar->widget(type); @@ -397,7 +264,7 @@ class BINARYNINJAUIAPI Sidebar : public QWidget if (!type || !ctxt.context) return (T*)nullptr; Sidebar* sidebar = ctxt.context->sidebar(); - if (!sidebar->container() || !sidebar->container()->isActive(type)) + if (!sidebar->isActive(type)) return (T*)nullptr; QWidget* widget = sidebar->widget(type); if (!widget) @@ -447,7 +314,7 @@ class BINARYNINJAUIAPI Sidebar : public QWidget if (!type || !ctxt.context) return false; Sidebar* sidebar = ctxt.context->sidebar(); - if (!sidebar->container() || !sidebar->container()->isActive(type)) + if (!sidebar->isActive(type)) return false; QWidget* widget = sidebar->widget(type); if (!widget) |
