Allow registering window, panel and context menu items with callbacks

This commit is contained in:
baldurk committed 2018-10-23 14:23:12 +01:00
1 parent 67fc971cd9
commit 94dfb9890b
24 files changed
+963 -67

No files matched your search

+301 -1
View File
@@ -35,6 +35,7 @@
#include <QProgressDialog>
#include <QRegularExpression>
#include <QTimer>
#include "Code/Resources.h"
#include "Code/pyrenderdoc/PythonContext.h"
#include "Windows/APIInspector.h"
#include "Windows/BufferViewer.h"
@@ -348,10 +349,309 @@ bool CaptureContext::LoadExtension(rdcstr name)
}
});
m_MainWindow->CleanMenus();
for(QAction *a : m_MainWindow->GetMenuActions())
CleanMenu(a);
m_RegisteredMenuItems.removeAll(NULL);
return ret;
}
void CaptureContext::RegisterWindowMenu(WindowMenu base, const rdcarray<rdcstr> &submenus,
ExtensionCallback callback)
{
if(base == WindowMenu::Unknown)
{
qCritical() << "Can't register menu for WindowMenu::Unknown";
return;
}
if(submenus.isEmpty())
{
qCritical() << "Empty list of submenus";
return;
}
if(base == WindowMenu::NewMenu && submenus.count() == 1)
{
qCritical() << "Need at least two items in submenus for WindowMenu::NewMenu";
return;
}
QMenu *menu = m_MainWindow->GetBaseMenu(base, submenus[0]);
if(!menu)
{
qCritical() << "Couldn't get base menu";
return;
}
std::function<void()> slotcallback = [this, callback]() { callback(this, {}); };
// if it's a new menu, GetBaseMenu already did the work, so skip the 0th element of submenus
if(base == WindowMenu::NewMenu)
{
rdcarray<rdcstr> items = submenus;
items.erase(0);
AddSortedMenuItem(menu, false, items, slotcallback);
}
else
{
AddSortedMenuItem(menu, false, submenus, slotcallback);
}
}
void CaptureContext::RegisterPanelMenu(PanelMenu base, const rdcarray<rdcstr> &submenus,
ExtensionCallback callback)
{
if(base == PanelMenu::Unknown)
{
qCritical() << "Can't register menu for PanelMenu::Unknown";
return;
}
RegisteredMenuItem *item = new RegisteredMenuItem();
item->panel = base;
item->submenus = submenus;
item->callback = callback;
m_RegisteredMenuItems.push_back(item);
m_PendingExtensionObjects.push_back(item);
}
void CaptureContext::RegisterContextMenu(ContextMenu base, const rdcarray<rdcstr> &submenus,
ExtensionCallback callback)
{
if(base == ContextMenu::Unknown)
{
qCritical() << "Can't register menu for ContextMenu::Unknown";
return;
}
RegisteredMenuItem *item = new RegisteredMenuItem();
item->context = base;
item->submenus = submenus;
item->callback = callback;
m_RegisteredMenuItems.push_back(item);
m_PendingExtensionObjects.push_back(item);
}
void CaptureContext::MenuDisplaying(ContextMenu contextMenu, QMenu *menu,
const ExtensionCallbackData &data)
{
ContextMenu contextMenuAlt = contextMenu;
switch(contextMenu)
{
case ContextMenu::MeshPreview_GSOutVertex:
case ContextMenu::MeshPreview_VSInVertex:
case ContextMenu::MeshPreview_VSOutVertex:
contextMenuAlt = ContextMenu::MeshPreview_Vertex;
break;
case ContextMenu::TextureViewer_InputThumbnail:
case ContextMenu::TextureViewer_OutputThumbnail:
contextMenuAlt = ContextMenu::TextureViewer_Thumbnail;
break;
}
for(RegisteredMenuItem *item : m_RegisteredMenuItems)
{
if(item->context == contextMenu || item->context == contextMenuAlt)
{
AddSortedMenuItem(menu, true, item->submenus, [this, item, data]() {
rdcarray<rdcpair<rdcstr, PyObject *>> args;
PythonContext::ConvertPyArgs(data, args);
item->callback(this, args);
PythonContext::FreePyArgs(args);
});
}
}
}
void CaptureContext::MenuDisplaying(PanelMenu panelMenu, QWidget *extensionButton,
const ExtensionCallbackData &data)
{
QMenu contextMenu(m_MainWindow);
for(RegisteredMenuItem *item : m_RegisteredMenuItems)
{
if(item->panel == panelMenu)
{
AddSortedMenuItem(&contextMenu, false, item->submenus, [this, item, data]() {
rdcarray<rdcpair<rdcstr, PyObject *>> args;
PythonContext::ConvertPyArgs(data, args);
item->callback(this, args);
PythonContext::FreePyArgs(args);
});
}
}
QAction emptyAction(tr("No extension commands configured"), m_MainWindow);
if(contextMenu.isEmpty())
{
contextMenu.addAction(&emptyAction);
QObject::connect(&emptyAction, &QAction::triggered,
[this]() { m_MainWindow->showExtensionManager(); });
}
RDDialog::show(&contextMenu, extensionButton->mapToGlobal(extensionButton->rect().bottomLeft()));
}
void CaptureContext::AddSortedMenuItem(QMenu *menu, bool rootMenu, const rdcarray<rdcstr> &items,
std::function<void()> callback)
{
QAction *beforeAction = NULL;
bool addIcon = rootMenu;
// if we're inserting into a pre-existing menu, try to find an __examples__ action which tells us
// where
// to be inserting
{
QList<QAction *> children = menu->actions();
int idx = 0;
for(; idx < children.count(); idx++)
{
if(children[idx]->text() == lit("__extensions__"))
break;
}
// if we found it, set beforeAction
if(idx < children.count())
{
// search back to find the right place alphabetically to place this, if there are existing
// menus
for(; idx > 0;)
{
// if the previous child is a separator, break, there are no more previous menus
if(children[idx - 1]->isSeparator())
break;
// if we should be sorted before the previous child, move backwards
if(children[idx - 1]->text() > items[0])
{
idx--;
continue;
}
// if we found the right place, break
break;
}
beforeAction = children[idx];
addIcon = true;
}
}
for(int i = 0; i < items.count() - 1; i++)
{
QList<QAction *> children = menu->actions();
bool found = false;
// see if this submenu already exists, if so just iterate down to it
for(QAction *a : children)
{
if(a->text() == items[i])
{
menu = a->menu();
found = true;
break;
}
}
if(found)
{
addIcon = false;
beforeAction = NULL;
continue;
}
// create the new submenu
QMenu *submenu = new QMenu(items[i], m_MainWindow);
// if we don't have a beforeAction, find where to insert this to keep alphabetical order.
if(!beforeAction)
{
for(QAction *a : children)
{
if(submenu->menuAction()->text() < a->text())
{
beforeAction = a;
break;
}
}
}
if(beforeAction)
menu->insertMenu(beforeAction, submenu);
else
menu->addMenu(submenu);
if(addIcon)
submenu->setIcon(Icons::plugin());
addIcon = false;
beforeAction = NULL;
menu = submenu;
}
QAction *action = new QAction(m_MainWindow);
action->setText(items.back());
QObject::connect(action, &QAction::triggered, callback);
if(!beforeAction)
{
QList<QAction *> children = menu->actions();
for(QAction *a : children)
{
if(action->text() < a->text())
{
beforeAction = a;
break;
}
}
}
if(beforeAction)
menu->insertAction(beforeAction, action);
else
menu->addAction(action);
if(addIcon)
action->setIcon(Icons::plugin());
m_PendingExtensionObjects.push_back(action);
}
void CaptureContext::CleanMenu(QAction *action)
{
QMenu *menu = action->menu();
// if this isn't a menu, nothing to do - return
if(!menu)
return;
// first clean all our children
for(QAction *a : menu->actions())
CleanMenu(a);
// if we no longer have any children in this menu, delete it.
if(menu->actions().isEmpty())
delete menu;
}
void CaptureContext::LoadCapture(const rdcstr &captureFile, const rdcstr &origFilename,
bool temporary, bool local)
{
+17
View File
@@ -72,6 +72,17 @@ public:
bool IsExtensionLoaded(rdcstr name) override;
bool LoadExtension(rdcstr name) override;
void RegisterWindowMenu(WindowMenu base, const rdcarray<rdcstr> &submenus,
ExtensionCallback callback) override;
void RegisterPanelMenu(PanelMenu base, const rdcarray<rdcstr> &submenus,
ExtensionCallback callback) override;
void RegisterContextMenu(ContextMenu base, const rdcarray<rdcstr> &submenus,
ExtensionCallback callback) override;
void MenuDisplaying(ContextMenu contextMenu, QMenu *menu,
const ExtensionCallbackData &data) override;
void MenuDisplaying(PanelMenu panelMenu, QWidget *extensionButton,
const ExtensionCallbackData &data) override;
//////////////////////////////////////////////////////////////////////////////
// Control functions
@@ -277,6 +288,10 @@ private:
void LoadCaptureThreaded(const QString &captureFile, const QString &origFilename, bool temporary,
bool local);
void AddSortedMenuItem(QMenu *menu, bool rootMenu, const rdcarray<rdcstr> &items,
std::function<void()> callback);
void CleanMenu(QAction *action);
uint32_t m_SelectedEventID = 0;
uint32_t m_EventID = 0;
@@ -341,6 +356,8 @@ private:
QList<QObject *> m_PendingExtensionObjects;
QMap<rdcstr, QList<QObject *>> m_ExtensionObjects;
QList<QPointer<RegisteredMenuItem>> m_RegisteredMenuItems;
// Windows
MainWindow *m_MainWindow = NULL;
EventBrowser *m_EventBrowser = NULL;
+182 -5
View File
@@ -29,6 +29,7 @@
// this is pre-declared as an opaque type as we only support converting to QWidget* via PySide
class QWidget;
class QMenu;
// we only support QVariant as an 'internal' interface, it's not exposed to python. However we need
// to use it in constructors/operators so conditionally compile it rather than split small structs
@@ -64,6 +65,13 @@ class QWidget;
#include "PersistantConfig.h"
#include "RemoteHost.h"
#ifdef RENDERDOC_QT_COMPAT
typedef rdcarray<rdcpair<rdcstr, QVariant> > ExtensionCallbackData;
#define make_pyarg make_rdcpair<rdcstr, QVariant>
#endif
struct ICaptureContext;
DOCUMENT("Contains all of the settings that control how to capture an executable.");
@@ -1022,6 +1030,111 @@ protected:
DECLARE_REFLECTION_STRUCT(IRGPInterop);
DOCUMENT(R"(Specifies the base menu to add a menu item into.
.. data:: File
The menu item will be in a section between Open/Save/Close captures and Import/Export.
.. data:: Window
The menu item will be in a new section at the end of the menu.
.. data:: Tools
The menu item will be added to a new section above Settings.
.. data:: NewMenu
The menu item will be a root menu, placed between Tools and Help.
.. data:: Help
The menu item will be added after the error reporting item.
)");
enum class WindowMenu
{
Unknown,
File,
Window,
Tools,
NewMenu,
Help,
};
DOCUMENT(R"(Specifies the panel to add a menu item into.
.. data:: EventBrowser
The :class:`EventBrowser`.
.. data:: PipelineStateViewer
The :class:`PipelineStateViewer`.
.. data:: MeshPreview
The mesh previewing :class:`BufferViewer`.
.. data:: TextureViewer
The :class:`TextureViewer`.
)");
enum class PanelMenu
{
Unknown,
EventBrowser,
PipelineStateViewer,
MeshPreview,
TextureViewer,
};
DOCUMENT(R"(Specifies the panel to add a menu item into.
.. data:: EventBrowser_Event
Adds the item to the context menu for events in the :class:`EventBrowser`.
.. data:: MeshPreview_Vertex
Adds the item to the context menu for all vertices in the mesh previewing :class:`BufferViewer`.
.. data:: MeshPreview_VSInVertex
Adds the item to the context menu for vertex inputs in the mesh previewing :class:`BufferViewer`.
.. data:: MeshPreview_VSOutVertex
Adds the item to the context menu for VS output in the mesh previewing :class:`BufferViewer`.
.. data:: MeshPreview_GSOutVertex
Adds the item to the context menu for GS/Tess output in the mesh previewing :class:`BufferViewer`.
.. data:: TextureViewer_Thumbnail
Adds the item to the context menu for all thumbnails in the :class:`TextureViewer`.
.. data:: TextureViewer_InputThumbnail
Adds the item to the context menu for input thumbnails in the :class:`TextureViewer`.
.. data:: TextureViewer_OutputThumbnail
Adds the item to the context menu for output thumbnails in the :class:`TextureViewer`.
)");
enum class ContextMenu
{
Unknown,
EventBrowser_Event,
MeshPreview_Vertex,
MeshPreview_VSInVertex,
MeshPreview_VSOutVertex,
MeshPreview_GSOutVertex,
TextureViewer_Thumbnail,
TextureViewer_InputThumbnail,
TextureViewer_OutputThumbnail,
};
DOCUMENT("The metadata for an extension.");
struct ExtensionMetadata
@@ -1081,10 +1194,12 @@ struct ExtensionMetadata
DECLARE_REFLECTION_STRUCT(ExtensionMetadata);
typedef struct _object PyObject;
DOCUMENT(R"(A manager for listing available and active extensions, as well as the interface for
extensions to register hooks and additional functionality.
.. function:: ExtensionCallback(context)
.. function:: ExtensionCallback(context, data)
Not a member function - the signature for any ``ExtensionCallback`` callbacks.
@@ -1092,10 +1207,13 @@ extensions to register hooks and additional functionality.
was registered.
:param CaptureContext context: The current capture context.
:param dict data: Additional data for the call, as a dictionary with string keys.
Context-dependent based on what generated the callback
)");
struct IExtensionManager
{
typedef std::function<void(ICaptureContext *ctx)> ExtensionCallback;
typedef std::function<void(ICaptureContext *ctx, const rdcarray<rdcpair<rdcstr, PyObject *> > &data)>
ExtensionCallback;
DOCUMENT(R"(Retrieve a list of installed extensions.
@@ -1118,6 +1236,65 @@ struct IExtensionManager
)");
virtual bool LoadExtension(rdcstr name) = 0;
DOCUMENT(R"(Register a new menu item in the main window's menus for an extension.
.. note:
The intermediate submenu items will be created as needed, there's no need to register each item
in the hierarchy. Registering a menu item and then registering a child is undefined, and the item
with a child may not receive callbacks at the correct times.
:param WindowMenu base: The base menu to add the item to.
:param list submenus: A list of strings containing the submenus to add before the item. The last
string will be the name of the menu item itself. Must contain at least one entry, or two entries
if ``base`` is :data:`WindowMenu.NewMenu`.
:param callback: The function to callback when the menu item is selected.
:type method: :func:`ExtensionCallback`
)");
virtual void RegisterWindowMenu(WindowMenu base, const rdcarray<rdcstr> &submenus,
ExtensionCallback callback) = 0;
DOCUMENT(R"(Register a menu item in a panel for an extension.
.. note:
The intermediate submenu items will be created as needed, there's no need to register each item
in the hierarchy. Registering a menu item and then registering a child is undefined, and the item
with a child may not receive callbacks at the correct times.
:param PanelMenu base: The panel to add the item to.
:param list submenus: A list of strings containing the submenus to add before the item. The last
string will be the name of the menu item itself. Must contain at least one entry.
:param callback: The function to callback when the menu item is selected.
:type method: :func:`ExtensionCallback`
)");
virtual void RegisterPanelMenu(PanelMenu base, const rdcarray<rdcstr> &submenus,
ExtensionCallback callback) = 0;
DOCUMENT(R"(Register a context menu item in a panel for an extension.
.. note:
The intermediate submenu items will be created as needed, there's no need to register each item
in the hierarchy. Registering a menu item and then registering a child is undefined, and the item
with a child may not receive callbacks at the correct times.
:param ContextMenu base: The panel to add the item to.
:param list submenus: A list of strings containing the submenus to add before the item. The last
string will be the name of the menu item itself. Must contain at least one entry.
:param callback: The function to callback when the menu item is selected.
:type method: :func:`ExtensionCallback`
)");
virtual void RegisterContextMenu(ContextMenu base, const rdcarray<rdcstr> &submenus,
ExtensionCallback callback) = 0;
#if !defined(SWIG) && !defined(SWIG_GENERATED)
// not exposed to SWIG, only used internally. For when a menu is displayed dynamically in a panel,
// this function is called to add any relevant menu items. Doing this almost immediate-mode GUI
// style avoids complex retained state that has to be refreshed each time a panel is created.
virtual void MenuDisplaying(ContextMenu contextMenu, QMenu *menu,
const ExtensionCallbackData &data) = 0;
virtual void MenuDisplaying(PanelMenu panelMenu, QWidget *extensionButton,
const ExtensionCallbackData &data) = 0;
#endif
protected:
DOCUMENT("");
IExtensionManager() = default;
@@ -1616,7 +1793,7 @@ If no bookmark exists, this function will do nothing.
DOCUMENT(R"(Retrieve the current singleton :class:`EventBrowser`.
:return: The current window, which is created (but not shown) it there wasn't one open.
:rtype: EventBrowser
:rtype: ~qrenderdoc.EventBrowser
)");
virtual IEventBrowser *GetEventBrowser() = 0;
@@ -1630,7 +1807,7 @@ If no bookmark exists, this function will do nothing.
DOCUMENT(R"(Retrieve the current singleton :class:`TextureViewer`.
:return: The current window, which is created (but not shown) it there wasn't one open.
:rtype: TextureViewer
:rtype: ~qrenderdoc.TextureViewer
)");
virtual ITextureViewer *GetTextureViewer() = 0;
@@ -1644,7 +1821,7 @@ If no bookmark exists, this function will do nothing.
DOCUMENT(R"(Retrieve the current singleton :class:`PipelineStateViewer`.
:return: The current window, which is created (but not shown) it there wasn't one open.
:rtype: PipelineStateViewer
:rtype: ~qrenderdoc.PipelineStateViewer
)");
virtual IPipelineStateViewer *GetPipelineViewer() = 0;
+11
View File
@@ -315,6 +315,17 @@ public:
void detach() { setProcessState(QProcess::NotRunning); }
};
class RegisteredMenuItem : public QObject
{
private:
Q_OBJECT
public:
ContextMenu context;
PanelMenu panel;
rdcarray<rdcstr> submenus;
IExtensionManager::ExtensionCallback callback;
};
class QFileFilterModel : public QSortFilterProxyModel
{
Q_OBJECT
@@ -74,6 +74,7 @@ bool CheckQtInterface();
// defined in SWIG-generated renderdoc_python.cpp
extern "C" PyObject *PyInit_renderdoc(void);
extern "C" PyObject *PassObjectToPython(const char *type, void *obj);
extern "C" PyObject *PassNewObjectToPython(const char *type, void *obj);
// this one is in qrenderdoc_python.cpp
extern "C" PyObject *PyInit_qrenderdoc(void);
extern "C" PyObject *WrapBareQWidget(QWidget *);
@@ -642,6 +643,70 @@ bool PythonContext::LoadExtension(ICaptureContext &ctx, const rdcstr &extension)
return ext != NULL;
}
void PythonContext::ConvertPyArgs(const ExtensionCallbackData &data,
rdcarray<rdcpair<rdcstr, PyObject *>> &args)
{
PyGILState_STATE gil = PyGILState_Ensure();
args.resize(data.size());
for(size_t i = 0; i < data.size(); i++)
{
rdcpair<rdcstr, PyObject *> &a = args[i];
a.first = data[i].first;
// convert QVariant to python object
const QVariant &in = data[i].second;
PyObject *&out = a.second;
// coverity[mixed_enums]
QMetaType::Type type = (QMetaType::Type)in.type();
switch(type)
{
case QMetaType::Bool: out = PyBool_FromLong(in.toBool()); break;
case QMetaType::Short:
case QMetaType::Long:
case QMetaType::Int: out = PyLong_FromLong(in.toInt()); break;
case QMetaType::UShort:
case QMetaType::ULong:
case QMetaType::UInt: out = PyLong_FromUnsignedLong(in.toUInt()); break;
case QMetaType::LongLong: out = PyLong_FromLongLong(in.toLongLong()); break;
case QMetaType::ULongLong: out = PyLong_FromUnsignedLongLong(in.toULongLong()); break;
case QMetaType::Float: out = PyFloat_FromDouble(in.toFloat()); break;
case QMetaType::Double: out = PyFloat_FromDouble(in.toDouble()); break;
case QMetaType::QString: out = PyUnicode_FromString(in.toString().toUtf8().data()); break;
default: break;
}
if(!out)
{
// try various other types
if(in.userType() == qMetaTypeId<ResourceId>())
out = PassNewObjectToPython("ResourceId *", new ResourceId(in.value<ResourceId>()));
}
if(!out)
{
qCritical() << "Couldn't convert" << in << "to python object";
out = Py_None;
Py_XINCREF(out);
}
}
PyGILState_Release(gil);
}
void PythonContext::FreePyArgs(rdcarray<rdcpair<rdcstr, PyObject *>> &args)
{
PyGILState_STATE gil = PyGILState_Ensure();
for(rdcpair<rdcstr, PyObject *> &a : args)
{
Py_XDECREF(a.second);
}
PyGILState_Release(gil);
}
QString PythonContext::versionString()
{
return QFormatStr("%1.%2.%3").arg(PY_MAJOR_VERSION).arg(PY_MINOR_VERSION).arg(PY_MICRO_VERSION);
+9
View File
@@ -332,6 +332,15 @@ PyObject *PassObjectToPython(const char *type, void *obj)
return SWIG_InternalNewPointerObj(obj, t, 0);
}
PyObject *PassNewObjectToPython(const char *type, void *obj)
{
swig_type_info *t = SWIG_TypeQuery(type);
if(t == NULL)
return NULL;
return SWIG_InternalNewPointerObj(obj, t, SWIG_POINTER_OWN);
}
%}
///////////////////////////////////////////////////////////////////////////////////////////
+33
View File
@@ -1132,6 +1132,15 @@ BufferViewer::BufferViewer(ICaptureContext &ctx, bool meshview, QWidget *parent)
QObject::connect(ui->matrixType, OverloadedSlot<int>::of(&QComboBox::currentIndexChanged),
[this](int) { camGuess_changed(0.0); });
{
QMenu *extensionsMenu = new QMenu(this);
QObject::connect(extensionsMenu, &QMenu::aboutToShow, [this, extensionsMenu]() {
extensionsMenu->clear();
m_Ctx.Extensions().MenuDisplaying(PanelMenu::MeshPreview, ui->extensions, {});
});
}
Reset();
m_Ctx.AddCaptureViewer(this);
@@ -1328,6 +1337,30 @@ void BufferViewer::stageRowMenu(MeshDataStage stage, QMenu *menu, const QPoint &
menu->addAction(m_ExportBytes);
menu->popup(m_CurView->viewport()->mapToGlobal(pos));
ContextMenu contextMenu = ContextMenu::MeshPreview_VSInVertex;
if(stage == MeshDataStage::VSOut)
contextMenu = ContextMenu::MeshPreview_VSOutVertex;
else if(stage == MeshDataStage::GSOut)
contextMenu = ContextMenu::MeshPreview_GSOutVertex;
QModelIndex idx = m_CurView->selectionModel()->currentIndex();
ExtensionCallbackData callbackdata = {make_pyarg("stage", (uint32_t)stage)};
if(idx.isValid())
{
uint32_t vertid =
m_CurView->model()->data(m_CurView->model()->index(idx.row(), 0), Qt::DisplayRole).toUInt();
uint32_t index =
m_CurView->model()->data(m_CurView->model()->index(idx.row(), 1), Qt::DisplayRole).toUInt();
callbackdata.push_back(make_pyarg("vertex", vertid));
callbackdata.push_back(make_pyarg("index", index));
}
m_Ctx.Extensions().MenuDisplaying(contextMenu, menu, callbackdata);
}
BufferViewer::~BufferViewer()
+11
View File
@@ -752,6 +752,17 @@
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="extensions">
<property name="icon">
<iconset resource="../Resources/resources.qrc">
<normaloff>:/plugin.png</normaloff>:/plugin.png</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="Line" name="offsetLine">
<property name="orientation">
+14
View File
@@ -189,6 +189,15 @@ EventBrowser::EventBrowser(ICaptureContext &ctx, QWidget *parent)
QObject::connect(ui->events->header(), &QHeaderView::customContextMenuRequested, this,
&EventBrowser::events_contextMenu);
{
QMenu *extensionsMenu = new QMenu(this);
QObject::connect(extensionsMenu, &QMenu::aboutToShow, [this, extensionsMenu]() {
extensionsMenu->clear();
m_Ctx.Extensions().MenuDisplaying(PanelMenu::EventBrowser, ui->extensions, {});
});
}
OnCaptureClosed();
m_redPalette = palette();
@@ -1009,6 +1018,11 @@ void EventBrowser::events_contextMenu(const QPoint &pos)
[this, rgp]() { rgp->SelectRGPEvent(m_Ctx.CurEvent()); });
}
contextMenu.addSeparator();
m_Ctx.Extensions().MenuDisplaying(ContextMenu::EventBrowser_Event, &contextMenu,
{{"eventId", m_Ctx.CurEvent()}});
RDDialog::show(&contextMenu, ui->events->viewport()->mapToGlobal(pos));
}
+11
View File
@@ -191,6 +191,17 @@
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="extensions">
<property name="icon">
<iconset resource="../Resources/resources.qrc">
<normaloff>:/plugin.png</normaloff>:/plugin.png</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
+43
View File
@@ -389,6 +389,13 @@ MainWindow::MainWindow(ICaptureContext &ctx) : QMainWindow(NULL), ui(new Ui::Mai
if(a->menu())
actions.append(a->menu()->actions());
}
// hide the dummy extension markers. They shouldn't be visible, they're just there so the code can
// easily find where to insert new extension menu items.
ui->extension_dummy_File->setVisible(false);
ui->extension_dummy_Window->setVisible(false);
ui->extension_dummy_Tools->setVisible(false);
ui->extension_dummy_Help->setVisible(false);
}
MainWindow::~MainWindow()
@@ -1324,6 +1331,42 @@ void MainWindow::LiveCaptureClosed(LiveCapture *live)
m_LiveCaptures.removeOne(live);
}
QMenu *MainWindow::GetBaseMenu(WindowMenu base, rdcstr name)
{
switch(base)
{
case WindowMenu::File: return ui->menu_File;
case WindowMenu::Window: return ui->menu_Window;
case WindowMenu::Tools: return ui->menu_Tools;
case WindowMenu::Help: return ui->menu_Help;
case WindowMenu::NewMenu: break;
default: return NULL;
}
// new menu. See if we have one for name already. If not, create a new one and add it to the menu
// bar.
for(QAction *m : ui->menuBar->actions())
{
// if it has an object name it's a built-in, ignore it.
if(!m->objectName().isEmpty())
continue;
if(m->text() == name)
return m->menu();
}
// no existing menu, add a new one
QMenu *menu = new QMenu(name, this);
menu->setIcon(Icons::plugin());
ui->menuBar->insertMenu(ui->menu_Help->menuAction(), menu);
return menu;
}
QList<QAction *> MainWindow::GetMenuActions()
{
return ui->menuBar->actions();
}
ToolWindowManager *MainWindow::mainToolManager()
{
return ui->toolWindowManager;
+4
View File
@@ -89,6 +89,9 @@ public:
void ShowLiveCapture(LiveCapture *live);
void LiveCaptureClosed(LiveCapture *live);
QMenu *GetBaseMenu(WindowMenu base, rdcstr name);
QList<QAction *> GetMenuActions();
void showEventBrowser() { on_action_Event_Browser_triggered(); }
void showAPIInspector() { on_action_API_Inspector_triggered(); }
void showMeshPreview() { on_action_Mesh_Output_triggered(); }
@@ -102,6 +105,7 @@ public:
void showPythonShell() { on_action_Python_Shell_triggered(); }
void showPerformanceCounterViewer() { on_action_Counter_Viewer_triggered(); }
void showResourceInspector() { on_action_Resource_Inspector_triggered(); }
void showExtensionManager() { on_action_Manage_Extensions_triggered(); }
void PopulateRecentCaptureFiles();
void PopulateRecentCaptureSettings();
void PopulateReportedBugs();
+28
View File
@@ -56,6 +56,8 @@
<addaction name="action_Create_RGP_Profile"/>
<addaction name="action_Open_RGP_Profile"/>
<addaction name="separator"/>
<addaction name="extension_dummy_Tools"/>
<addaction name="separator"/>
<addaction name="action_Settings"/>
<addaction name="action_Manage_Extensions"/>
<addaction name="action_Manage_Remote_Servers"/>
@@ -104,6 +106,8 @@
<addaction name="action_Save_Capture_As"/>
<addaction name="action_Close_Capture"/>
<addaction name="separator"/>
<addaction name="extension_dummy_File"/>
<addaction name="separator"/>
<addaction name="menu_Import_From"/>
<addaction name="menu_Export_As"/>
<addaction name="separator"/>
@@ -159,6 +163,8 @@
<addaction name="action_Counter_Viewer"/>
<addaction name="action_Resource_Inspector"/>
<addaction name="action_Comments"/>
<addaction name="separator"/>
<addaction name="extension_dummy_Window"/>
</widget>
<widget class="QMenu" name="menu_Help">
<property name="title">
@@ -178,6 +184,8 @@
<addaction name="action_Send_Error_Report"/>
<addaction name="menu_Reported_Bugs"/>
<addaction name="separator"/>
<addaction name="extension_dummy_Help"/>
<addaction name="separator"/>
<addaction name="action_Check_for_Updates"/>
<addaction name="separator"/>
<addaction name="action_Source_on_GitHub"/>
@@ -467,6 +475,26 @@
<string>Open RGP Profile</string>
</property>
</action>
<action name="extension_dummy_Tools">
<property name="text">
<string notr="true">__extensions__</string>
</property>
</action>
<action name="extension_dummy_Help">
<property name="text">
<string notr="true">__extensions__</string>
</property>
</action>
<action name="extension_dummy_Window">
<property name="text">
<string notr="true">__extensions__</string>
</property>
</action>
<action name="extension_dummy_File">
<property name="text">
<string notr="true">__extensions__</string>
</property>
</action>
<action name="action_Manage_Extensions">
<property name="text">
<string>Manage Extensions</string>
@@ -24,6 +24,7 @@
#include "D3D11PipelineStateViewer.h"
#include <float.h>
#include <QMenu>
#include <QMouseEvent>
#include <QScrollBar>
#include <QXmlStreamWriter>
@@ -171,6 +172,15 @@ D3D11PipelineStateViewer::D3D11PipelineStateViewer(ICaptureContext &ctx,
QObject::connect(cbuffer, &RDTreeWidget::itemActivated, this,
&D3D11PipelineStateViewer::cbuffer_itemActivated);
{
QMenu *extensionsMenu = new QMenu(this);
QObject::connect(extensionsMenu, &QMenu::aboutToShow, [this, extensionsMenu]() {
extensionsMenu->clear();
m_Ctx.Extensions().MenuDisplaying(PanelMenu::PipelineStateViewer, ui->extensions, {});
});
}
addGridLines(ui->rasterizerGridLayout, palette().color(QPalette::WindowText));
addGridLines(ui->blendStateGridLayout, palette().color(QPalette::WindowText));
addGridLines(ui->depthStateGridLayout, palette().color(QPalette::WindowText));
@@ -53,7 +53,7 @@
<item>
<widget class="QLabel" name="controlsLabel">
<property name="text">
<string>Display Controls</string>
<string>Controls</string>
</property>
<property name="margin">
<number>4</number>
@@ -136,6 +136,23 @@
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="extensions">
<property name="text">
<string>Extensions</string>
</property>
<property name="icon">
<iconset resource="../../Resources/resources.qrc">
<normaloff>:/plugin.png</normaloff>:/plugin.png</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
@@ -202,8 +219,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1000</width>
<height>576</height>
<width>454</width>
<height>245</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_3">
@@ -646,7 +663,7 @@
<normaloff>:/page_white_edit.png</normaloff>:/page_white_edit.png</iconset>
</property>
<property name="popupMode">
<enum>QToolButton::MenuButtonPopup</enum>
<enum>QToolButton::MenuButtonPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
@@ -708,8 +725,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1000</width>
<height>527</height>
<width>101</width>
<height>344</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_10">
@@ -1036,7 +1053,7 @@
<normaloff>:/page_white_edit.png</normaloff>:/page_white_edit.png</iconset>
</property>
<property name="popupMode">
<enum>QToolButton::MenuButtonPopup</enum>
<enum>QToolButton::MenuButtonPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
@@ -1095,8 +1112,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1000</width>
<height>527</height>
<width>101</width>
<height>344</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_11">
@@ -1423,7 +1440,7 @@
<normaloff>:/page_white_edit.png</normaloff>:/page_white_edit.png</iconset>
</property>
<property name="popupMode">
<enum>QToolButton::MenuButtonPopup</enum>
<enum>QToolButton::MenuButtonPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
@@ -1482,8 +1499,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1000</width>
<height>527</height>
<width>101</width>
<height>344</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_12">
@@ -1810,7 +1827,7 @@
<normaloff>:/page_white_edit.png</normaloff>:/page_white_edit.png</iconset>
</property>
<property name="popupMode">
<enum>QToolButton::MenuButtonPopup</enum>
<enum>QToolButton::MenuButtonPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
@@ -1869,8 +1886,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1000</width>
<height>527</height>
<width>101</width>
<height>430</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_13">
@@ -2868,7 +2885,7 @@
<normaloff>:/page_white_edit.png</normaloff>:/page_white_edit.png</iconset>
</property>
<property name="popupMode">
<enum>QToolButton::MenuButtonPopup</enum>
<enum>QToolButton::MenuButtonPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
@@ -2927,8 +2944,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1000</width>
<height>527</height>
<width>101</width>
<height>344</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_14">
@@ -3204,8 +3221,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1000</width>
<height>576</height>
<width>829</width>
<height>311</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_9">
@@ -4474,16 +4491,16 @@
</layout>
</widget>
<customwidgets>
<customwidget>
<class>RDLabel</class>
<extends>QLabel</extends>
<header>Widgets/Extended/RDLabel.h</header>
</customwidget>
<customwidget>
<class>RDTreeWidget</class>
<extends>QTreeView</extends>
<header>Widgets/Extended/RDTreeWidget.h</header>
</customwidget>
<customwidget>
<class>RDLabel</class>
<extends>QLabel</extends>
<header>Widgets/Extended/RDLabel.h</header>
</customwidget>
<customwidget>
<class>PipelineFlowChart</class>
<extends>QFrame</extends>
@@ -24,6 +24,7 @@
#include "D3D12PipelineStateViewer.h"
#include <float.h>
#include <QMenu>
#include <QMouseEvent>
#include <QScrollBar>
#include <QXmlStreamWriter>
@@ -211,6 +212,15 @@ D3D12PipelineStateViewer::D3D12PipelineStateViewer(ICaptureContext &ctx,
QObject::connect(cbuffer, &RDTreeWidget::itemActivated, this,
&D3D12PipelineStateViewer::cbuffer_itemActivated);
{
QMenu *extensionsMenu = new QMenu(this);
QObject::connect(extensionsMenu, &QMenu::aboutToShow, [this, extensionsMenu]() {
extensionsMenu->clear();
m_Ctx.Extensions().MenuDisplaying(PanelMenu::PipelineStateViewer, ui->extensions, {});
});
}
addGridLines(ui->rasterizerGridLayout, palette().color(QPalette::WindowText));
addGridLines(ui->blendStateGridLayout, palette().color(QPalette::WindowText));
addGridLines(ui->depthStateGridLayout, palette().color(QPalette::WindowText));
@@ -53,7 +53,7 @@
<item>
<widget class="QLabel" name="controlsLabel">
<property name="text">
<string>Display Controls</string>
<string>Controls</string>
</property>
<property name="margin">
<number>4</number>
@@ -136,6 +136,23 @@
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="extensions">
<property name="text">
<string>Extensions</string>
</property>
<property name="icon">
<iconset resource="../../Resources/resources.qrc">
<normaloff>:/plugin.png</normaloff>:/plugin.png</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
@@ -549,9 +566,9 @@
<property name="icon">
<iconset resource="../../Resources/resources.qrc">
<normaloff>:/page_white_edit.png</normaloff>:/page_white_edit.png</iconset>
</property>
</property>
<property name="popupMode">
<enum>QToolButton::MenuButtonPopup</enum>
<enum>QToolButton::MenuButtonPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
@@ -945,7 +962,7 @@
<normaloff>:/page_white_edit.png</normaloff>:/page_white_edit.png</iconset>
</property>
<property name="popupMode">
<enum>QToolButton::MenuButtonPopup</enum>
<enum>QToolButton::MenuButtonPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
@@ -1237,6 +1254,12 @@
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
@@ -1333,7 +1356,7 @@
<normaloff>:/page_white_edit.png</normaloff>:/page_white_edit.png</iconset>
</property>
<property name="popupMode">
<enum>QToolButton::MenuButtonPopup</enum>
<enum>QToolButton::MenuButtonPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
@@ -1625,6 +1648,12 @@
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
@@ -1721,7 +1750,7 @@
<normaloff>:/page_white_edit.png</normaloff>:/page_white_edit.png</iconset>
</property>
<property name="popupMode">
<enum>QToolButton::MenuButtonPopup</enum>
<enum>QToolButton::MenuButtonPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
@@ -2065,6 +2094,12 @@
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
@@ -2708,7 +2743,7 @@
<normaloff>:/page_white_edit.png</normaloff>:/page_white_edit.png</iconset>
</property>
<property name="popupMode">
<enum>QToolButton::MenuButtonPopup</enum>
<enum>QToolButton::MenuButtonPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
@@ -3000,6 +3035,12 @@
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
@@ -3764,7 +3805,7 @@
<normaloff>:/page_white_edit.png</normaloff>:/page_white_edit.png</iconset>
</property>
<property name="popupMode">
<enum>QToolButton::MenuButtonPopup</enum>
<enum>QToolButton::MenuButtonPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
@@ -4132,6 +4173,12 @@
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
@@ -24,6 +24,7 @@
#include "GLPipelineStateViewer.h"
#include <float.h>
#include <QMenu>
#include <QMouseEvent>
#include <QScrollBar>
#include <QXmlStreamWriter>
@@ -168,6 +169,15 @@ GLPipelineStateViewer::GLPipelineStateViewer(ICaptureContext &ctx, PipelineState
QObject::connect(res, &RDTreeWidget::itemActivated, this,
&GLPipelineStateViewer::resource_itemActivated);
{
QMenu *extensionsMenu = new QMenu(this);
QObject::connect(extensionsMenu, &QMenu::aboutToShow, [this, extensionsMenu]() {
extensionsMenu->clear();
m_Ctx.Extensions().MenuDisplaying(PanelMenu::PipelineStateViewer, ui->extensions, {});
});
}
addGridLines(ui->rasterizerGridLayout, palette().color(QPalette::WindowText));
addGridLines(ui->MSAAGridLayout, palette().color(QPalette::WindowText));
addGridLines(ui->blendStateGridLayout, palette().color(QPalette::WindowText));
@@ -53,7 +53,7 @@
<item>
<widget class="QLabel" name="controlsLabel">
<property name="text">
<string>Display Controls</string>
<string>Controls</string>
</property>
<property name="margin">
<number>4</number>
@@ -136,6 +136,23 @@
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="extensions">
<property name="text">
<string>Extensions</string>
</property>
<property name="icon">
<iconset resource="../../Resources/resources.qrc">
<normaloff>:/plugin.png</normaloff>:/plugin.png</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
@@ -671,8 +688,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>883</width>
<height>552</height>
<width>116</width>
<height>430</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_16">
@@ -1125,8 +1142,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>883</width>
<height>552</height>
<width>116</width>
<height>430</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_15">
@@ -1579,8 +1596,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>883</width>
<height>552</height>
<width>116</width>
<height>430</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_14">
@@ -2033,8 +2050,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>883</width>
<height>552</height>
<width>117</width>
<height>544</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_13">
@@ -3465,8 +3482,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>883</width>
<height>552</height>
<width>116</width>
<height>430</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_12">
@@ -3794,8 +3811,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>883</width>
<height>601</height>
<width>488</width>
<height>311</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_4">
@@ -4426,8 +4443,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>883</width>
<height>552</height>
<width>116</width>
<height>430</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_11">
@@ -4730,16 +4747,16 @@
</layout>
</widget>
<customwidgets>
<customwidget>
<class>RDLabel</class>
<extends>QLabel</extends>
<header>Widgets/Extended/RDLabel.h</header>
</customwidget>
<customwidget>
<class>RDTreeWidget</class>
<extends>QTreeView</extends>
<header>Widgets/Extended/RDTreeWidget.h</header>
</customwidget>
<customwidget>
<class>RDLabel</class>
<extends>QLabel</extends>
<header>Widgets/Extended/RDLabel.h</header>
</customwidget>
<customwidget>
<class>PipelineFlowChart</class>
<extends>QFrame</extends>
@@ -24,6 +24,7 @@
#include "VulkanPipelineStateViewer.h"
#include <float.h>
#include <QMenu>
#include <QMouseEvent>
#include <QScrollBar>
#include <QXmlStreamWriter>
@@ -163,6 +164,15 @@ VulkanPipelineStateViewer::VulkanPipelineStateViewer(ICaptureContext &ctx,
QObject::connect(ubo, &RDTreeWidget::itemActivated, this,
&VulkanPipelineStateViewer::ubo_itemActivated);
{
QMenu *extensionsMenu = new QMenu(this);
QObject::connect(extensionsMenu, &QMenu::aboutToShow, [this, extensionsMenu]() {
extensionsMenu->clear();
m_Ctx.Extensions().MenuDisplaying(PanelMenu::PipelineStateViewer, ui->extensions, {});
});
}
addGridLines(ui->rasterizerGridLayout, palette().color(QPalette::WindowText));
addGridLines(ui->MSAAGridLayout, palette().color(QPalette::WindowText));
addGridLines(ui->blendStateGridLayout, palette().color(QPalette::WindowText));
@@ -53,7 +53,7 @@
<item>
<widget class="QLabel" name="controlsLabel">
<property name="text">
<string>Display Controls</string>
<string>Controls</string>
</property>
<property name="margin">
<number>4</number>
@@ -136,6 +136,23 @@
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="extensions">
<property name="text">
<string>Extensions</string>
</property>
<property name="icon">
<iconset resource="../../Resources/resources.qrc">
<normaloff>:/plugin.png</normaloff>:/plugin.png</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
+28 -4
View File
@@ -540,6 +540,15 @@ TextureViewer::TextureViewer(ICaptureContext &ctx, QWidget *parent)
&TextureViewer::channelsWidget_mouseClicked);
}
{
QMenu *extensionsMenu = new QMenu(this);
QObject::connect(extensionsMenu, &QMenu::aboutToShow, [this, extensionsMenu]() {
extensionsMenu->clear();
m_Ctx.Extensions().MenuDisplaying(PanelMenu::TextureViewer, ui->extensions, {});
});
}
QWidget *renderContainer = ui->renderContainer;
ui->dockarea->addToolWindow(ui->renderContainer, ToolWindowManager::EmptySpace);
@@ -1885,7 +1894,8 @@ void TextureViewer::AddResourceUsageEntry(QMenu &menu, uint32_t start, uint32_t
menu.addAction(item);
}
void TextureViewer::OpenResourceContextMenu(ResourceId id, const rdcarray<EventUsage> &usage)
void TextureViewer::OpenResourceContextMenu(ResourceId id, bool input,
const rdcarray<EventUsage> &usage)
{
QMenu contextMenu(this);
@@ -1920,6 +1930,12 @@ void TextureViewer::OpenResourceContextMenu(ResourceId id, const rdcarray<EventU
contextMenu.addSeparator();
contextMenu.addAction(&openLockedTab);
contextMenu.addAction(&openResourceInspector);
contextMenu.addSeparator();
m_Ctx.Extensions().MenuDisplaying(input ? ContextMenu::TextureViewer_InputThumbnail
: ContextMenu::TextureViewer_OutputThumbnail,
&contextMenu, {{"resourceId", id}});
contextMenu.addSeparator();
contextMenu.addAction(&usageTitle);
@@ -1943,6 +1959,11 @@ void TextureViewer::OpenResourceContextMenu(ResourceId id, const rdcarray<EventU
}
else
{
contextMenu.addSeparator();
m_Ctx.Extensions().MenuDisplaying(input ? ContextMenu::TextureViewer_InputThumbnail
: ContextMenu::TextureViewer_OutputThumbnail,
&contextMenu, {});
RDDialog::show(&contextMenu, QCursor::pos());
}
}
@@ -2154,16 +2175,19 @@ void TextureViewer::thumb_clicked(QMouseEvent *e)
rdcarray<EventUsage> empty;
bool input = follow.Type == FollowType::ReadOnly;
if(id == ResourceId())
{
OpenResourceContextMenu(id, empty);
OpenResourceContextMenu(id, input, empty);
}
else
{
m_Ctx.Replay().AsyncInvoke([this, id](IReplayController *r) {
m_Ctx.Replay().AsyncInvoke([this, id, input](IReplayController *r) {
rdcarray<EventUsage> usage = r->GetUsage(id);
GUIInvoke::call(this, [this, id, usage]() { OpenResourceContextMenu(id, usage); });
GUIInvoke::call(this,
[this, id, input, usage]() { OpenResourceContextMenu(id, input, usage); });
});
}
}
+1 -1
View File
@@ -248,7 +248,7 @@ private:
int &prevIndex, bool copy, bool rw);
void AddResourceUsageEntry(QMenu &menu, uint32_t start, uint32_t end, ResourceUsage usage);
void OpenResourceContextMenu(ResourceId id, const rdcarray<EventUsage> &usage);
void OpenResourceContextMenu(ResourceId id, bool input, const rdcarray<EventUsage> &usage);
void AutoFitRange();
void rangePoint_Update();
+13 -2
View File
@@ -227,7 +227,7 @@
<widget class="QFrame" name="overlayToolbar">
<property name="geometry">
<rect>
<x>490</x>
<x>530</x>
<y>40</y>
<width>129</width>
<height>32</height>
@@ -418,7 +418,7 @@
<rect>
<x>330</x>
<y>40</y>
<width>149</width>
<width>181</width>
<height>32</height>
</rect>
</property>
@@ -539,6 +539,17 @@
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="extensions">
<property name="icon">
<iconset resource="../Resources/resources.qrc">
<normaloff>:/plugin.png</normaloff>:/plugin.png</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QFrame" name="subresourceToolbar">