From 3f5a9114831146b2845ddce8277cac809651d975 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 19 Nov 2020 14:30:22 +0000 Subject: [PATCH] Refactor CustomPaintWidget to handle widget recreation internally * This allows us to expose to to python as a easy-to-use "replay output ready" widget. --- qrenderdoc/Code/CaptureContext.cpp | 2 +- qrenderdoc/Code/Interface/Extensions.h | 61 ++++++ qrenderdoc/Code/MiniQtHelper.cpp | 47 +++++ qrenderdoc/Code/MiniQtHelper.h | 6 + qrenderdoc/Widgets/CustomPaintWidget.cpp | 226 +++++++++++++++++------ qrenderdoc/Widgets/CustomPaintWidget.h | 93 ++++++---- qrenderdoc/Widgets/ResourcePreview.cpp | 15 +- qrenderdoc/Widgets/ResourcePreview.h | 2 +- qrenderdoc/Windows/BufferViewer.cpp | 36 +--- qrenderdoc/Windows/BufferViewer.h | 5 - qrenderdoc/Windows/PythonShell.cpp | 18 ++ qrenderdoc/Windows/TextureViewer.cpp | 60 ++---- qrenderdoc/Windows/TextureViewer.h | 1 - 13 files changed, 384 insertions(+), 188 deletions(-) diff --git a/qrenderdoc/Code/CaptureContext.cpp b/qrenderdoc/Code/CaptureContext.cpp index db3604dbe..6868f8713 100644 --- a/qrenderdoc/Code/CaptureContext.cpp +++ b/qrenderdoc/Code/CaptureContext.cpp @@ -1315,7 +1315,7 @@ void CaptureContext::CloseCapture() for(ICaptureViewer *viewer : capviewers) { - if(viewer) + if(viewer && m_CaptureViewers.contains(viewer)) viewer->OnCaptureClosed(); } diff --git a/qrenderdoc/Code/Interface/Extensions.h b/qrenderdoc/Code/Interface/Extensions.h index d8b6dbcf8..ea844c8ca 100644 --- a/qrenderdoc/Code/Interface/Extensions.h +++ b/qrenderdoc/Code/Interface/Extensions.h @@ -620,6 +620,67 @@ The widget needs to be added to a parent to become part of a panel or window. )"); virtual QWidget *CreateLabel() = 0; + DOCUMENT(R"(Create a widget suitable for rendering to with a :class:`renderdoc.ReplayOutput`. This +widget takes care of painting on demand and recreating the internal display widget when necessary, +however this means you must use :meth:`GetWidgetWindowingData` to retrieve the windowing data for +creating the output as well as call :meth:`SetWidgetReplayOutput` to notify the widget of the +current output. + +:return: The handle to the newly created widget. +:rtype: ``QWidget`` +)"); + virtual QWidget *CreateOutputRenderingWidget() = 0; + + DOCUMENT(R"(Return the opaque pointer of windowing data suitable for passing to +:meth:`~renderdoc.ReplayController.CreateOutput` or other functions that expect windowing data. + +If the widget is not a output rendering widget created with :meth:`CreateOutputRenderingWidget` this +function will fail and return an invalid set of windowing data. + +It's important to note that the windowing data is not valid forever, so this function should be +called as close to where you call :meth:`~renderdoc.ReplayController.CreateOutput` as possible. +Also don't fetch windowing data unless you are going to create an output, because this function will +cause the widget to go into an undefined state unless an output is created to render onto it. + +.. note:: + This function must be called on the main UI thread. + +:param QWidget window: The widget to create windowing data for. +:return: The windowing data. +:rtype: ~renderdoc.WindowingData +)"); + virtual WindowingData GetWidgetWindowingData(QWidget *widget) = 0; + + DOCUMENT(R"(Set the current output for a widget. This only affects output rendering widgets. If +another type of widget is passed nothing will happen. + +Passing ``None`` as the output will reset the widget and make it display the default background +until another output is set. + +When a capture is closed and all outputs are destroyed, the widget will automatically unset the +output so there is no need to do that manually. + +:param QWidget widget: The widget to set the output for. +:param ~renderdoc.ReplayOutput output: The new output to set, or ``None`` to unset any previous + output. +)"); + virtual void SetWidgetReplayOutput(QWidget *widget, IReplayOutput *output) = 0; + + DOCUMENT(R"(Set the default backkground color for a rendering widget. This background color is +used when no output is currently configured, e.g. when a capture is closed. + +For all other widget types this has no effect. + +To disable the background color pass negative values for the components, this will cause a default +checkerboard to be rendered instead. This is the default behaviour when a widget is created. + +:param QWidget widget: The widget to set the background color of. +:param float red: The red component of the color, in the range ``0.0 - 1.0``. +:param float green: The green component of the color, in the range ``0.0 - 1.0``. +:param float blue: The blue component of the color, in the range ``0.0 - 1.0``. +)"); + virtual void SetWidgetBackgroundColor(QWidget *widget, float red, float green, float blue) = 0; + DOCUMENT(R"(Create a checkbox widget which can be toggled between unchecked and checked. When created the checkbox is unchecked. diff --git a/qrenderdoc/Code/MiniQtHelper.cpp b/qrenderdoc/Code/MiniQtHelper.cpp index 28ce51f9a..9c836911c 100644 --- a/qrenderdoc/Code/MiniQtHelper.cpp +++ b/qrenderdoc/Code/MiniQtHelper.cpp @@ -36,6 +36,7 @@ #include "Code/QRDUtils.h" #include "Code/pyrenderdoc/PythonContext.h" #include "Widgets/CollapseGroupBox.h" +#include "Widgets/CustomPaintWidget.h" #include "Widgets/Extended/RDDoubleSpinBox.h" #include "Widgets/Extended/RDLabel.h" #include "Widgets/Extended/RDLineEdit.h" @@ -419,6 +420,52 @@ QWidget *MiniQtHelper::CreateLabel() return new RDLabel(); } +QWidget *MiniQtHelper::CreateOutputRenderingWidget() +{ + CustomPaintWidget *widget = new CustomPaintWidget(NULL); + widget->SetContext(m_Ctx); + return widget; +} + +WindowingData MiniQtHelper::GetWidgetWindowingData(QWidget *widget) +{ + if(!widget) + return {}; + + CustomPaintWidget *paintWidget = qobject_cast(widget); + + if(paintWidget) + return paintWidget->GetWidgetWindowingData(); + + return {}; +} + +void MiniQtHelper::SetWidgetReplayOutput(QWidget *widget, IReplayOutput *output) +{ + if(!widget) + return; + + CustomPaintWidget *paintWidget = qobject_cast(widget); + + if(paintWidget) + paintWidget->SetOutput(output); +} + +void MiniQtHelper::SetWidgetBackgroundColor(QWidget *widget, float red, float green, float blue) +{ + if(!widget) + return; + + CustomPaintWidget *paintWidget = qobject_cast(widget); + + if(paintWidget) + paintWidget->SetBackCol(red < 0.0 || green < 0.0 || blue < 0.0 + ? QColor() + : QColor::fromRgb(qMin(red * 255, 255), + qMin(green * 255, 255), + qMin(blue * 255, 255))); +} + QWidget *MiniQtHelper::CreateCheckbox(WidgetCallback changed) { QCheckBox *w = new QCheckBox(); diff --git a/qrenderdoc/Code/MiniQtHelper.h b/qrenderdoc/Code/MiniQtHelper.h index ca8e219b1..272090cf2 100644 --- a/qrenderdoc/Code/MiniQtHelper.h +++ b/qrenderdoc/Code/MiniQtHelper.h @@ -83,6 +83,12 @@ public: QWidget *CreateLabel() override; + QWidget *CreateOutputRenderingWidget() override; + + WindowingData GetWidgetWindowingData(QWidget *widget) override; + void SetWidgetReplayOutput(QWidget *widget, IReplayOutput *output) override; + void SetWidgetBackgroundColor(QWidget *widget, float red, float green, float blue) override; + QWidget *CreateCheckbox(WidgetCallback changed) override; QWidget *CreateRadiobox(WidgetCallback changed) override; diff --git a/qrenderdoc/Widgets/CustomPaintWidget.cpp b/qrenderdoc/Widgets/CustomPaintWidget.cpp index 96ce33a78..c92221547 100644 --- a/qrenderdoc/Widgets/CustomPaintWidget.cpp +++ b/qrenderdoc/Widgets/CustomPaintWidget.cpp @@ -27,55 +27,192 @@ #include #include #include +#include #include "Code/Interface/QRDInterface.h" +CustomPaintWidgetInternal::CustomPaintWidgetInternal(CustomPaintWidget &parentCustom, bool rendering) + : m_Custom(parentCustom), m_Rendering(rendering) +{ + setAttribute(Qt::WA_OpaquePaintEvent); + setMouseTracking(true); + if(m_Rendering) + setAttribute(Qt::WA_PaintOnScreen); +} + +CustomPaintWidgetInternal::~CustomPaintWidgetInternal() +{ +} + CustomPaintWidget::CustomPaintWidget(QWidget *parent) : QWidget(parent) { - m_Ctx = NULL; - m_Output = NULL; - setAttribute(Qt::WA_OpaquePaintEvent); - setMouseTracking(true); m_Tag = QFormatStr("custompaint%1").arg((uintptr_t) this); -} -CustomPaintWidget::CustomPaintWidget(ICaptureContext *c, QWidget *parent) : QWidget(parent) -{ - m_Ctx = c; - m_Output = NULL; setAttribute(Qt::WA_OpaquePaintEvent); - if(c) - setAttribute(Qt::WA_PaintOnScreen); - setMouseTracking(true); - m_Tag = QFormatStr("custompaint%1").arg((uintptr_t) this); + setAttribute(Qt::WA_PaintOnScreen); + + m_Dark = Formatter::DarkCheckerColor(); + m_Light = Formatter::LightCheckerColor(); + + QVBoxLayout *l = new QVBoxLayout(this); + l->setContentsMargins(0, 0, 0, 0); + l->setSpacing(0); + setLayout(l); + + RecreateInternalWidget(); } CustomPaintWidget::~CustomPaintWidget() { + if(m_Ctx) + m_Ctx->RemoveCaptureViewer(this); } -void CustomPaintWidget::mousePressEvent(QMouseEvent *e) +void CustomPaintWidget::SetContext(ICaptureContext &ctx) { - emit clicked(e); + if(m_Ctx) + m_Ctx->RemoveCaptureViewer(this); + + m_Ctx = &ctx; + m_Ctx->AddCaptureViewer(this); + + RecreateInternalWidget(); } -void CustomPaintWidget::mouseDoubleClickEvent(QMouseEvent *event) +void CustomPaintWidget::OnCaptureLoaded() { - emit(doubleClicked(event)); + RecreateInternalWidget(); } -void CustomPaintWidget::mouseMoveEvent(QMouseEvent *e) +void CustomPaintWidget::OnCaptureClosed() { - emit mouseMove(e); + // forget any output we used to have + SetOutput(NULL); } -void CustomPaintWidget::wheelEvent(QWheelEvent *e) +void CustomPaintWidget::OnSelectedEventChanged(uint32_t eventId) { - emit mouseWheel(e); + // nothing, we only care about capture loaded/closed events } -void CustomPaintWidget::resizeEvent(QResizeEvent *e) +void CustomPaintWidget::OnEventChanged(uint32_t eventId) { - emit resize(e); + // nothing, we only care about capture loaded/closed events +} + +void CustomPaintWidget::update() +{ + m_Internal->update(); + QWidget::update(); +} + +WindowingData CustomPaintWidget::GetWidgetWindowingData() +{ + // switch to rendering here and recreate the widget, so we have an updated winId for the windowing + // data + m_Rendering = true; + RecreateInternalWidget(); + return m_Ctx->CreateWindowingData(m_Internal); +} + +void CustomPaintWidget::SetOutput(IReplayOutput *out) +{ + m_Output = out; + m_Rendering = (out != NULL); + + RecreateInternalWidget(); +} + +void CustomPaintWidget::RecreateInternalWidget() +{ + if(!GUIInvoke::onUIThread()) + { + GUIInvoke::call(this, [this]() { RecreateInternalWidget(); }); + return; + } + + // if no capture is loaded, we're not rendering anymore. + m_Rendering = m_Rendering && m_Ctx && m_Ctx->IsCaptureLoaded(); + + // we need to recreate the widget if it's not matching out rendering state. + if(m_Internal == NULL || m_Rendering != m_Internal->IsRendering()) + { + delete m_Internal; + m_Internal = new CustomPaintWidgetInternal(*this, m_Rendering); + + layout()->addWidget(m_Internal); + } +} + +void CustomPaintWidget::changeEvent(QEvent *event) +{ + if(event->type() == QEvent::PaletteChange || event->type() == QEvent::StyleChange) + { + m_Dark = Formatter::DarkCheckerColor(); + m_Light = Formatter::LightCheckerColor(); + update(); + } +} + +void CustomPaintWidget::renderInternal(QPaintEvent *e) +{ + if(m_Ctx && m_Output) + { + QPointer me(this); + m_Ctx->Replay().AsyncInvoke(m_Tag, [me](IReplayController *r) { + if(me && me->m_Output) + me->m_Output->Display(); + }); + } +} + +void CustomPaintWidget::paintInternal(QPaintEvent *e) +{ + if(m_BackCol.isValid()) + { + QPainter p(m_Internal); + p.fillRect(rect(), m_BackCol); + } + else + { + int numX = (int)ceil((float)rect().width() / 64.0f); + int numY = (int)ceil((float)rect().height() / 64.0f); + + QPainter p(m_Internal); + for(int x = 0; x < numX; x++) + { + for(int y = 0; y < numY; y++) + { + QColor &col = ((x % 2) == (y % 2)) ? m_Dark : m_Light; + + p.fillRect(QRect(x * 64, y * 64, 64, 64), col); + } + } + } +} + +void CustomPaintWidgetInternal::mousePressEvent(QMouseEvent *e) +{ + emit m_Custom.clicked(e); +} + +void CustomPaintWidgetInternal::mouseDoubleClickEvent(QMouseEvent *event) +{ + emit m_Custom.doubleClicked(event); +} + +void CustomPaintWidgetInternal::mouseMoveEvent(QMouseEvent *e) +{ + emit m_Custom.mouseMove(e); +} + +void CustomPaintWidgetInternal::wheelEvent(QWheelEvent *e) +{ + emit m_Custom.mouseWheel(e); +} + +void CustomPaintWidgetInternal::resizeEvent(QResizeEvent *e) +{ + emit m_Custom.resize(e); } void CustomPaintWidget::keyPressEvent(QKeyEvent *e) @@ -90,44 +227,21 @@ void CustomPaintWidget::keyReleaseEvent(QKeyEvent *e) void CustomPaintWidget::paintEvent(QPaintEvent *e) { - if(m_Ctx) - { - if(m_Output != NULL) - { - QPointer me(this); - m_Ctx->Replay().AsyncInvoke(m_Tag, [me](IReplayController *r) { - if(me && me->m_Output) - me->m_Output->Display(); - }); - } - } - else if(m_Dark == m_Light) - { - QPainter p(this); - p.fillRect(rect(), m_Dark); - } + // don't paint this widget +} + +void CustomPaintWidgetInternal::paintEvent(QPaintEvent *e) +{ + if(m_Rendering) + m_Custom.renderInternal(e); else - { - int numX = (int)ceil((float)rect().width() / 64.0f); - int numY = (int)ceil((float)rect().height() / 64.0f); - - QPainter p(this); - for(int x = 0; x < numX; x++) - { - for(int y = 0; y < numY; y++) - { - QColor &col = ((x % 2) == (y % 2)) ? m_Dark : m_Light; - - p.fillRect(QRect(x * 64, y * 64, 64, 64), col); - } - } - } + m_Custom.paintInternal(e); } #if defined(RENDERDOC_PLATFORM_APPLE) -bool CustomPaintWidget::event(QEvent *e) +bool CustomPaintWidgetInternal::event(QEvent *e) { - if(m_Ctx && e->type() == QEvent::UpdateRequest) + if(m_Rendering && e->type() == QEvent::UpdateRequest) paintEvent(NULL); return QWidget::event(e); } diff --git a/qrenderdoc/Widgets/CustomPaintWidget.h b/qrenderdoc/Widgets/CustomPaintWidget.h index 6db176621..155c0e5b3 100644 --- a/qrenderdoc/Widgets/CustomPaintWidget.h +++ b/qrenderdoc/Widgets/CustomPaintWidget.h @@ -25,32 +25,61 @@ #pragma once #include +#include "Code/Interface/QRDInterface.h" -struct IReplayOutput; -struct ICaptureContext; +class CustomPaintWidget; -class CustomPaintWidget : public QWidget +// this is the internal widget that gets recreated +class CustomPaintWidgetInternal : public QWidget +{ +private: + Q_OBJECT + + CustomPaintWidget &m_Custom; + bool m_Rendering = false; + +public: + explicit CustomPaintWidgetInternal(CustomPaintWidget &parentCustom, bool rendering); + ~CustomPaintWidgetInternal(); + + bool IsRendering() const { return m_Rendering; } +protected: + void mousePressEvent(QMouseEvent *e) override; + void mouseDoubleClickEvent(QMouseEvent *event) override; + void mouseMoveEvent(QMouseEvent *e) override; + void wheelEvent(QWheelEvent *e) override; + void resizeEvent(QResizeEvent *e) override; + +#if defined(RENDERDOC_PLATFORM_APPLE) + bool event(QEvent *event) override; +#endif + + void paintEvent(QPaintEvent *e) override; + QPaintEngine *paintEngine() const override { return m_Rendering ? NULL : QWidget::paintEngine(); } +}; + +// this is the public-facing widget which is persistent and contains & recreates the internal widget +class CustomPaintWidget : public QWidget, ICaptureViewer { private: Q_OBJECT public: explicit CustomPaintWidget(QWidget *parent = 0); - explicit CustomPaintWidget(ICaptureContext *c, QWidget *parent = 0); ~CustomPaintWidget(); - // this is needed to solve a chicken-and-egg problem. We need to recreate the widget - // whenever we go from custom rendering to painting (e.g. capture loaded or closed). But - // we need the widget to have been recreated before we create the output, so we can - // pass in the winId. - // So we go by whether or not we have a CaptureContext * and go on faith that the - // output will be set before any painting work has to happen. - void setOutput(IReplayOutput *out) { m_Output = out; } - void setColours(QColor dark, QColor light) - { - m_Dark = dark; - m_Light = light; - } + void SetContext(ICaptureContext &ctx); + // ICaptureViewer + void OnCaptureLoaded() override; + void OnCaptureClosed() override; + void OnSelectedEventChanged(uint32_t eventId) override; + void OnEventChanged(uint32_t eventId) override; + + void update(); + + WindowingData GetWidgetWindowingData(); + void SetOutput(IReplayOutput *out); + void SetBackCol(QColor col) { m_BackCol = col; } signals: void clicked(QMouseEvent *e); void doubleClicked(QMouseEvent *e); @@ -61,26 +90,26 @@ signals: void keyRelease(QKeyEvent *e); private: - void mousePressEvent(QMouseEvent *e) override; - void mouseDoubleClickEvent(QMouseEvent *event) override; - void mouseMoveEvent(QMouseEvent *e) override; - void wheelEvent(QWheelEvent *e) override; - void resizeEvent(QResizeEvent *e) override; + void changeEvent(QEvent *event) override; void keyPressEvent(QKeyEvent *e) override; void keyReleaseEvent(QKeyEvent *e) override; - -public slots: - -protected: -#if defined(RENDERDOC_PLATFORM_APPLE) - bool event(QEvent *event) override; -#endif - void paintEvent(QPaintEvent *e) override; - QPaintEngine *paintEngine() const override { return m_Ctx ? NULL : QWidget::paintEngine(); } - ICaptureContext *m_Ctx; - IReplayOutput *m_Output; + + QPaintEngine *paintEngine() const override { return NULL; } + friend class CustomPaintWidgetInternal; + + CustomPaintWidgetInternal *m_Internal = NULL; + + bool m_Rendering = false; + + void RecreateInternalWidget(); + void renderInternal(QPaintEvent *e); + void paintInternal(QPaintEvent *e); + + ICaptureContext *m_Ctx = NULL; + IReplayOutput *m_Output = NULL; QString m_Tag; QColor m_Dark; QColor m_Light; + QColor m_BackCol; }; diff --git a/qrenderdoc/Widgets/ResourcePreview.cpp b/qrenderdoc/Widgets/ResourcePreview.cpp index 8f1d058ff..b0b79bebe 100644 --- a/qrenderdoc/Widgets/ResourcePreview.cpp +++ b/qrenderdoc/Widgets/ResourcePreview.cpp @@ -32,15 +32,8 @@ ResourcePreview::ResourcePreview(ICaptureContext &c, IReplayOutput *output, QWid { ui->setupUi(this); - CustomPaintWidget *thumb = new CustomPaintWidget(&c, this); - thumb->setOutput(output); - thumb->setObjectName(ui->thumbnail->objectName()); - thumb->setSizePolicy(ui->thumbnail->sizePolicy()); - thumb->setMinimumSize(QSize(0, 0)); - - delete ui->thumbnail; - ui->thumbnail = thumb; - ui->gridLayout->addWidget(ui->thumbnail, 0, 0, 1, 2); + ui->thumbnail->SetContext(c); + ui->thumbnail->SetOutput(output); setBackgroundRole(QPalette::Background); setForegroundRole(QPalette::Highlight); @@ -119,7 +112,7 @@ void ResourcePreview::changeEvent(QEvent *event) setSelected(m_Selected); } -QWidget *ResourcePreview::thumbWidget() +WindowingData ResourcePreview::GetWidgetWindowingData() { - return ui->thumbnail; + return ui->thumbnail->GetWidgetWindowingData(); } diff --git a/qrenderdoc/Widgets/ResourcePreview.h b/qrenderdoc/Widgets/ResourcePreview.h index c11a0dcb1..1fa97aefa 100644 --- a/qrenderdoc/Widgets/ResourcePreview.h +++ b/qrenderdoc/Widgets/ResourcePreview.h @@ -53,7 +53,7 @@ public: void clickEvent(QMouseEvent *e); void doubleClickEvent(QMouseEvent *e); - QWidget *thumbWidget(); + WindowingData GetWidgetWindowingData(); void setActive(bool b) { diff --git a/qrenderdoc/Windows/BufferViewer.cpp b/qrenderdoc/Windows/BufferViewer.cpp index 67083e725..ed0c46d63 100644 --- a/qrenderdoc/Windows/BufferViewer.cpp +++ b/qrenderdoc/Windows/BufferViewer.cpp @@ -1918,6 +1918,8 @@ BufferViewer::BufferViewer(ICaptureContext &ctx, bool meshview, QWidget *parent) { ui->setupUi(this); + ui->render->SetContext(m_Ctx); + byteRangeStart = (RDSpinBox64 *)ui->byteRangeStart; byteRangeLength = (RDSpinBox64 *)ui->byteRangeLength; @@ -2381,12 +2383,12 @@ void BufferViewer::OnCaptureLoaded() if(!m_MeshView) return; - WindowingData winData = m_Ctx.CreateWindowingData(ui->render); + WindowingData winData = ui->render->GetWidgetWindowingData(); m_Ctx.Replay().BlockInvoke([winData, this](IReplayController *r) { m_Output = r->CreateOutput(winData, ReplayOutputType::Mesh); - ui->render->setOutput(m_Output); + ui->render->SetOutput(m_Output); RT_UpdateAndDisplay(r); }); @@ -3603,21 +3605,6 @@ void BufferViewer::Reset() m_BBoxes.clear(); - ICaptureContext *ctx = &m_Ctx; - - // while a capture is loaded, pass NULL into the widget - if(!m_Ctx.IsCaptureLoaded()) - ctx = NULL; - - { - CustomPaintWidget *render = new CustomPaintWidget(ctx, this); - render->setObjectName(ui->render->objectName()); - render->setSizePolicy(ui->render->sizePolicy()); - delete ui->render; - ui->render = render; - ui->renderContainerGridLayout->addWidget(ui->render, 1, 1, 1, 1); - } - QObject::connect(ui->render, &CustomPaintWidget::mouseMove, this, &BufferViewer::render_mouseMove); QObject::connect(ui->render, &CustomPaintWidget::clicked, this, &BufferViewer::render_clicked); QObject::connect(ui->render, &CustomPaintWidget::keyPress, this, &BufferViewer::render_keyPress); @@ -3625,12 +3612,6 @@ void BufferViewer::Reset() &BufferViewer::render_keyRelease); QObject::connect(ui->render, &CustomPaintWidget::mouseWheel, this, &BufferViewer::render_mouseWheel); - updateCheckerboardColours(); -} - -void BufferViewer::updateCheckerboardColours() -{ - ui->render->setColours(Formatter::DarkCheckerColor(), Formatter::LightCheckerColor()); } void BufferViewer::ClearModels() @@ -4238,15 +4219,6 @@ void BufferViewer::debugVertex() m_Ctx.AddDockWindow(s->Widget(), DockReference::AddTo, this); } -void BufferViewer::changeEvent(QEvent *event) -{ - if(event->type() == QEvent::PaletteChange || event->type() == QEvent::StyleChange) - { - updateCheckerboardColours(); - ui->render->update(); - } -} - void BufferViewer::SyncViews(RDTableView *primary, bool selection, bool scroll) { if(!ui->syncViews->isChecked()) diff --git a/qrenderdoc/Windows/BufferViewer.h b/qrenderdoc/Windows/BufferViewer.h index 29ee9a63f..e466bc433 100644 --- a/qrenderdoc/Windows/BufferViewer.h +++ b/qrenderdoc/Windows/BufferViewer.h @@ -134,9 +134,6 @@ private slots: void exportData(const BufferExport ¶ms); void debugVertex(); -protected: - void changeEvent(QEvent *event) override; - private: bool eventFilter(QObject *watched, QEvent *event) override; Ui::BufferViewer *ui; @@ -247,8 +244,6 @@ private: void Reset(); - void updateCheckerboardColours(); - void ClearModels(); void UI_CalculateMeshFormats(); diff --git a/qrenderdoc/Windows/PythonShell.cpp b/qrenderdoc/Windows/PythonShell.cpp index a75416044..f0e58b4c6 100644 --- a/qrenderdoc/Windows/PythonShell.cpp +++ b/qrenderdoc/Windows/PythonShell.cpp @@ -207,6 +207,24 @@ struct MiniQtInvoker : ObjectForwarder } QWidget *CreateLabel() { return InvokeRetFunction(&IMiniQtHelper::CreateLabel); } + QWidget *CreateOutputRenderingWidget() + { + return InvokeRetFunction(&IMiniQtHelper::CreateOutputRenderingWidget); + } + WindowingData GetWidgetWindowingData(QWidget *widget) + { + return InvokeRetFunction(&IMiniQtHelper::GetWidgetWindowingData, widget); + } + + void SetWidgetReplayOutput(QWidget *widget, IReplayOutput *output) + { + InvokeVoidFunction(&IMiniQtHelper::SetWidgetReplayOutput, widget, output); + } + + void SetWidgetBackgroundColor(QWidget *widget, float red, float green, float blue) + { + InvokeVoidFunction(&IMiniQtHelper::SetWidgetBackgroundColor, widget, red, green, blue); + } QWidget *CreateCheckbox(WidgetCallback changed) { return InvokeRetFunction(&IMiniQtHelper::CreateCheckbox, changed); diff --git a/qrenderdoc/Windows/TextureViewer.cpp b/qrenderdoc/Windows/TextureViewer.cpp index a9b16f13a..4ddb6b806 100644 --- a/qrenderdoc/Windows/TextureViewer.cpp +++ b/qrenderdoc/Windows/TextureViewer.cpp @@ -450,6 +450,9 @@ TextureViewer::TextureViewer(ICaptureContext &ctx, QWidget *parent) { ui->setupUi(this); + ui->render->SetContext(m_Ctx); + ui->pixelContext->SetContext(m_Ctx); + ui->textureList->setFont(Formatter::PreferredFont()); ui->textureListFilter->setFont(Formatter::PreferredFont()); ui->rangeBlack->setFont(Formatter::PreferredFont()); @@ -677,15 +680,6 @@ void TextureViewer::showEvent(QShowEvent *event) HighlightUsage(); } -void TextureViewer::changeEvent(QEvent *event) -{ - if(event->type() == QEvent::PaletteChange || event->type() == QEvent::StyleChange) - { - updateBackgroundColors(); - ui->render->update(); - } -} - void TextureViewer::HighlightUsage() { TextureDescription *texptr = GetCurrentTexture(); @@ -2231,7 +2225,7 @@ void TextureViewer::InitResourcePreview(ResourcePreview *prev, BoundResource res prev->setResourceName(fullname); - WindowingData winData = m_Ctx.CreateWindowingData(prev->thumbWidget()); + WindowingData winData = prev->GetWidgetWindowingData(); prev->setProperty("f", QVariant::fromValue(follow)); prev->setSlotName(slotName); @@ -2262,7 +2256,7 @@ void TextureViewer::InitResourcePreview(ResourcePreview *prev, BoundResource res prev->setActive(true); prev->setSelected(true); - WindowingData winData = m_Ctx.CreateWindowingData(prev->thumbWidget()); + WindowingData winData = prev->GetWidgetWindowingData(); m_Ctx.Replay().AsyncInvoke([this, winData](IReplayController *) { m_Output->AddThumbnail(winData, ResourceId(), {0, 0, ~0U}, CompType::Typeless); }); @@ -2743,30 +2737,6 @@ void TextureViewer::on_renderVScroll_valueChanged(int position) void TextureViewer::UI_RecreatePanels() { - ICaptureContext *ctx = &m_Ctx; - - // while a capture is loaded, pass NULL into the widget - if(!m_Ctx.IsCaptureLoaded()) - ctx = NULL; - - { - CustomPaintWidget *render = new CustomPaintWidget(ctx, ui->renderContainer); - render->setObjectName(ui->render->objectName()); - render->setSizePolicy(ui->render->sizePolicy()); - delete ui->render; - ui->render = render; - ui->gridLayout->addWidget(render, 1, 0, 1, 1); - } - - { - CustomPaintWidget *pixelContext = new CustomPaintWidget(ctx, ui->pixelContextLayout); - pixelContext->setObjectName(ui->pixelContext->objectName()); - pixelContext->setSizePolicy(ui->pixelContext->sizePolicy()); - delete ui->pixelContext; - ui->pixelContext = pixelContext; - ui->pixelcontextgrid->addWidget(pixelContext, 0, 0, 1, 2); - } - updateBackgroundColors(); QObject::connect(ui->render, &CustomPaintWidget::clicked, this, &TextureViewer::render_mouseClick); @@ -2782,24 +2752,16 @@ void TextureViewer::UI_RecreatePanels() void TextureViewer::updateBackgroundColors() { - if(backCol.isValid()) - { - ui->render->setColours(backCol, backCol); - ui->pixelContext->setColours(backCol, backCol); - } - else - { - ui->render->setColours(Formatter::DarkCheckerColor(), Formatter::LightCheckerColor()); - ui->pixelContext->setColours(Formatter::DarkCheckerColor(), Formatter::LightCheckerColor()); - } + ui->render->SetBackCol(backCol); + ui->pixelContext->SetBackCol(backCol); } void TextureViewer::OnCaptureLoaded() { Reset(); - WindowingData renderData = m_Ctx.CreateWindowingData(ui->render); - WindowingData contextData = m_Ctx.CreateWindowingData(ui->pixelContext); + WindowingData renderData = ui->render->GetWidgetWindowingData(); + WindowingData contextData = ui->pixelContext->GetWidgetWindowingData(); ui->saveTex->setEnabled(true); ui->locationGoto->setEnabled(true); @@ -2820,8 +2782,8 @@ void TextureViewer::OnCaptureLoaded() m_Output->SetPixelContext(contextData); - ui->render->setOutput(m_Output); - ui->pixelContext->setOutput(m_Output); + ui->render->SetOutput(m_Output); + ui->pixelContext->SetOutput(m_Output); RT_UpdateAndDisplay(r); diff --git a/qrenderdoc/Windows/TextureViewer.h b/qrenderdoc/Windows/TextureViewer.h index 061cf9378..41c7637bb 100644 --- a/qrenderdoc/Windows/TextureViewer.h +++ b/qrenderdoc/Windows/TextureViewer.h @@ -227,7 +227,6 @@ private slots: protected: void enterEvent(QEvent *event) override; void showEvent(QShowEvent *event) override; - void changeEvent(QEvent *event) override; private: void RT_FetchCurrentPixel(IReplayController *r, uint32_t x, uint32_t y, PixelValue &pickValue,