summaryrefslogtreecommitdiff
path: root/ui/sidebar.h
diff options
context:
space:
mode:
authorRusty Wagner <rusty.wagner@gmail.com>2024-01-12 10:11:19 -0700
committerRusty Wagner <rusty.wagner@gmail.com>2024-02-05 13:42:52 -0500
commit97ac519092fc87e27c49ab21aafb41b77f40dc03 (patch)
tree33d1a72b835a73c25868cb170106f865d9d54430 /ui/sidebar.h
parentefa49ca6d23530b5e1ececccea4a2dc0bbe3406b (diff)
Sidebar improvements
Diffstat (limited to 'ui/sidebar.h')
-rw-r--r--ui/sidebar.h347
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)