Add work in progress timeline bar

* Has an EID scale bar along the top, and simple zoom/pan, but nothing
  else.
This commit is contained in:
baldurk
2017-07-13 18:44:41 +01:00
parent df9f72b857
commit d3d1bcd136
10 changed files with 504 additions and 14 deletions
+24
View File
@@ -46,6 +46,7 @@
#include "Windows/ShaderViewer.h"
#include "Windows/StatisticsViewer.h"
#include "Windows/TextureViewer.h"
#include "Windows/TimelineBar.h"
#include "QRDUtils.h"
CaptureContext::CaptureContext(QString paramFilename, QString remoteHost, uint32_t remoteIdent,
@@ -728,6 +729,18 @@ IStatisticsViewer *CaptureContext::GetStatisticsViewer()
return m_StatisticsViewer;
}
ITimelineBar *CaptureContext::GetTimelineBar()
{
if(m_TimelineBar)
return m_TimelineBar;
m_TimelineBar = new TimelineBar(*this, m_MainWindow);
m_TimelineBar->setObjectName(lit("timelineBar"));
setupDockWindow(m_TimelineBar);
return m_TimelineBar;
}
IPythonShell *CaptureContext::GetPythonShell()
{
if(m_PythonShell)
@@ -780,6 +793,11 @@ void CaptureContext::ShowStatisticsViewer()
m_MainWindow->showStatisticsViewer();
}
void CaptureContext::ShowTimelineBar()
{
m_MainWindow->showTimelineBar();
}
void CaptureContext::ShowPythonShell()
{
m_MainWindow->showPythonShell();
@@ -878,6 +896,10 @@ QWidget *CaptureContext::CreateBuiltinWindow(const QString &objectName)
{
return GetStatisticsViewer()->Widget();
}
else if(objectName == lit("timelineBar"))
{
return GetTimelineBar()->Widget();
}
else if(objectName == lit("pythonShell"))
{
return GetPythonShell()->Widget();
@@ -904,6 +926,8 @@ void CaptureContext::BuiltinWindowClosed(QWidget *window)
m_DebugMessageView = NULL;
else if(m_StatisticsViewer && m_StatisticsViewer->Widget() == window)
m_StatisticsViewer = NULL;
else if(m_TimelineBar && m_TimelineBar->Widget() == window)
m_TimelineBar = NULL;
else if(m_PythonShell && m_PythonShell->Widget() == window)
m_PythonShell = NULL;
else
+5
View File
@@ -46,6 +46,7 @@ class TextureViewer;
class CaptureDialog;
class DebugMessageView;
class StatisticsViewer;
class TimelineBar;
class PythonShell;
QString ConfigFilePath(const QString &filename);
@@ -131,6 +132,7 @@ public:
ICaptureDialog *GetCaptureDialog() override;
IDebugMessageView *GetDebugMessageView() override;
IStatisticsViewer *GetStatisticsViewer() override;
ITimelineBar *GetTimelineBar() override;
IPythonShell *GetPythonShell() override;
bool HasEventBrowser() override { return m_EventBrowser != NULL; }
@@ -141,6 +143,7 @@ public:
bool HasCaptureDialog() override { return m_CaptureDialog != NULL; }
bool HasDebugMessageView() override { return m_DebugMessageView != NULL; }
bool HasStatisticsViewer() override { return m_StatisticsViewer != NULL; }
bool HasTimelineBar() override { return m_TimelineBar != NULL; }
bool HasPythonShell() override { return m_PythonShell != NULL; }
void ShowEventBrowser() override;
void ShowAPIInspector() override;
@@ -150,6 +153,7 @@ public:
void ShowCaptureDialog() override;
void ShowDebugMessageView() override;
void ShowStatisticsViewer() override;
void ShowTimelineBar() override;
void ShowPythonShell() override;
IShaderViewer *EditShader(bool customShader, const QString &entryPoint, const QStringMap &files,
@@ -271,5 +275,6 @@ private:
CaptureDialog *m_CaptureDialog = NULL;
DebugMessageView *m_DebugMessageView = NULL;
StatisticsViewer *m_StatisticsViewer = NULL;
TimelineBar *m_TimelineBar = NULL;
PythonShell *m_PythonShell = NULL;
};
+68 -14
View File
@@ -104,7 +104,8 @@ struct IMainWindow
typedef std::function<void()> ShortcutCallback;
DOCUMENT(
"Retrieves the QWidget for this :class:`MainWindow` if PySide2 is available, or ``None``.");
"Retrieves the QWidget for this :class:`MainWindow` if PySide2 is available, or otherwise a "
"unique opaque pointer that can be passed to RenderDoc functions expecting a QWidget.");
virtual QWidget *Widget() = 0;
DOCUMENT(R"(Register a callback for a particular key shortcut.
@@ -138,7 +139,8 @@ DOCUMENT("The event browser window.");
struct IEventBrowser
{
DOCUMENT(
"Retrieves the QWidget for this :class:`EventBrowser` if PySide2 is available, or ``None``.");
"Retrieves the QWidget for this :class:`EventBrowser` if PySide2 is available, or otherwise "
"unique opaque pointer that can be passed to RenderDoc functions expecting a QWidget.");
virtual QWidget *Widget() = 0;
DOCUMENT("Updates the duration column if the selected time unit changes.");
@@ -155,7 +157,8 @@ DOCUMENT("The API inspector window.");
struct IAPIInspector
{
DOCUMENT(
"Retrieves the QWidget for this :class:`APIInspector` if PySide2 is available, or ``None``.");
"Retrieves the QWidget for this :class:`APIInspector` if PySide2 is available, or otherwise "
"unique opaque pointer that can be passed to RenderDoc functions expecting a QWidget.");
virtual QWidget *Widget() = 0;
DOCUMENT("Refresh the current API view - useful if callstacks are now available.");
@@ -173,7 +176,8 @@ struct IPipelineStateViewer
{
DOCUMENT(
"Retrieves the QWidget for this :class:`PipelineStateViewer` if PySide2 is available, or "
"``None``.");
"otherwise unique opaque pointer that can be passed to RenderDoc functions expecting a "
"QWidget.");
virtual QWidget *Widget() = 0;
DOCUMENT(R"(Prompt the user to save the binary form of the given shader to disk.
@@ -194,7 +198,8 @@ struct ITextureViewer
{
DOCUMENT(
"Retrieves the QWidget for this :class:`TextureViewer` if PySide2 is available, or "
"``None``.");
"otherwise unique opaque pointer that can be passed to RenderDoc functions expecting a "
"QWidget.");
virtual QWidget *Widget() = 0;
DOCUMENT(R"(Open a texture view, optionally raising this window to the foreground.
@@ -221,7 +226,8 @@ DOCUMENT("The buffer viewer window, either a raw buffer or the geometry pipeline
struct IBufferViewer
{
DOCUMENT(
"Retrieves the QWidget for this :class:`BufferViewer` if PySide2 is available, or ``None``.");
"Retrieves the QWidget for this :class:`BufferViewer` if PySide2 is available, or otherwise "
"unique opaque pointer that can be passed to RenderDoc functions expecting a QWidget.");
virtual QWidget *Widget() = 0;
DOCUMENT(R"(Scroll to the given row in the given stage's data.
@@ -262,7 +268,8 @@ struct ICaptureDialog
{
DOCUMENT(
"Retrieves the QWidget for this :class:`CaptureDialog` if PySide2 is available, or "
"``None``.");
"otherwise unique opaque pointer that can be passed to RenderDoc functions expecting a "
"QWidget.");
virtual QWidget *Widget() = 0;
DOCUMENT(R"(Determines if the window is in inject or launch mode.
@@ -344,7 +351,8 @@ struct IDebugMessageView
{
DOCUMENT(
"Retrieves the QWidget for this :class:`DebugMessageView` if PySide2 is available, or "
"``None``.");
"otherwise unique opaque pointer that can be passed to RenderDoc functions expecting a "
"QWidget.");
virtual QWidget *Widget() = 0;
protected:
@@ -359,7 +367,8 @@ struct IStatisticsViewer
{
DOCUMENT(
"Retrieves the QWidget for this :class:`StatisticsViewer` if PySide2 is available, or "
"``None``.");
"otherwise unique opaque pointer that can be passed to RenderDoc functions expecting a "
"QWidget.");
virtual QWidget *Widget() = 0;
protected:
@@ -367,14 +376,40 @@ protected:
~IStatisticsViewer() = default;
};
DOCUMENT("The timeline bar.");
struct ITimelineBar
{
DOCUMENT(
"Retrieves the QWidget for this :class:`TimelineBar` if PySide2 is available, or otherwise "
"unique opaque pointer that can be passed to RenderDoc functions expecting a QWidget.");
virtual QWidget *Widget() = 0;
DOCUMENT(R"(Highlights the frame usage of the specified resource.
:param ~renderdoc.ResourceId id: The ID of the resource to highlight.
)");
virtual void HighlightResourceUsage(ResourceId id) = 0;
DOCUMENT(R"(Highlights the modifications in a frame of a given resource.
:param ~renderdoc.ResourceId id: The ID of the resource that is being modified.
:param list history: A list of :class:`~renderdoc.PixelModification` events to display.
)");
virtual void HighlightHistory(ResourceId id, const QList<PixelModification> &history) = 0;
protected:
ITimelineBar() = default;
~ITimelineBar() = default;
};
DECLARE_REFLECTION_STRUCT(IStatisticsViewer);
DOCUMENT("The interactive python shell.");
struct IPythonShell
{
DOCUMENT(
"Retrieves the QWidget for this :class:`PythonShell` if PySide2 is available, or "
"``None``.");
"Retrieves the QWidget for this :class:`PythonShell` if PySide2 is available, or otherwise "
"unique opaque pointer that can be passed to RenderDoc functions expecting a QWidget.");
virtual QWidget *Widget() = 0;
protected:
@@ -410,7 +445,8 @@ struct IShaderViewer
typedef std::function<void(ICaptureContext *ctx)> CloseCallback;
DOCUMENT(
"Retrieves the QWidget for this :class:`ShaderViewer` if PySide2 is available, or ``None``.");
"Retrieves the QWidget for this :class:`ShaderViewer` if PySide2 is available, or otherwise "
"unique opaque pointer that can be passed to RenderDoc functions expecting a QWidget.");
virtual QWidget *Widget() = 0;
DOCUMENT(R"(Retrieves the current step in the debugging.
@@ -451,7 +487,8 @@ struct IConstantBufferPreviewer
{
DOCUMENT(
"Retrieves the QWidget for this :class:`ConstantBufferPreviewer` if PySide2 is available, or "
"``None``.");
"otherwise unique opaque pointer that can be passed to RenderDoc functions expecting a "
"QWidget.");
virtual QWidget *Widget() = 0;
protected:
@@ -466,7 +503,8 @@ struct IPixelHistoryView
{
DOCUMENT(
"Retrieves the QWidget for this :class:`PixelHistoryView` if PySide2 is available, or "
"``None``.");
"otherwise unique opaque pointer that can be passed to RenderDoc functions expecting a "
"QWidget.");
virtual QWidget *Widget() = 0;
DOCUMENT(R"(Set the history displayed in this window.
@@ -1082,6 +1120,13 @@ as well as messages generated during replay and analysis.
)");
virtual IStatisticsViewer *GetStatisticsViewer() = 0;
DOCUMENT(R"(Retrieve the current singleton :class:`TimelineBar`.
:return: The current window, which is created (but not shown) it there wasn't one open.
:rtype: TimelineBar
)");
virtual ITimelineBar *GetTimelineBar() = 0;
DOCUMENT(R"(Retrieve the current singleton :class:`PythonShell`.
:return: The current window, which is created (but not shown) it there wasn't one open.
@@ -1145,6 +1190,13 @@ as well as messages generated during replay and analysis.
)");
virtual bool HasStatisticsViewer() = 0;
DOCUMENT(R"(Check if there is a current :class:`TimelineBar` open.
:return: ``True`` if there is a window open.
:rtype: ``bool``
)");
virtual bool HasTimelineBar() = 0;
DOCUMENT(R"(Check if there is a current :class:`PythonShell` open.
:return: ``True`` if there is a window open.
@@ -1170,6 +1222,8 @@ as well as messages generated during replay and analysis.
DOCUMENT(
"Raise the current :class:`StatisticsViewer`, showing it in the default place if needed.");
virtual void ShowStatisticsViewer() = 0;
DOCUMENT("Raise the current :class:`TimelineBar`, showing it in the default place if needed.");
virtual void ShowTimelineBar() = 0;
DOCUMENT("Raise the current :class:`PythonShell`, showing it in the default place if needed.");
virtual void ShowPythonShell() = 0;
+12
View File
@@ -1486,6 +1486,18 @@ void MainWindow::on_action_Statistics_Viewer_triggered()
ui->toolWindowManager->addToolWindow(stats, mainToolArea());
}
void MainWindow::on_action_Timeline_triggered()
{
QWidget *stats = m_Ctx.GetTimelineBar()->Widget();
if(ui->toolWindowManager->toolWindows().contains(stats))
ToolWindowManager::raiseToolWindow(stats);
else
ui->toolWindowManager->addToolWindow(
stats,
ToolWindowManager::AreaReference(ToolWindowManager::TopWindowSide, mainToolArea().area()));
}
void MainWindow::on_action_Python_Shell_triggered()
{
QWidget *py = m_Ctx.GetPythonShell()->Widget();
+2
View File
@@ -92,6 +92,7 @@ public:
void showCaptureDialog() { on_action_Launch_Application_triggered(); }
void showDebugMessageView() { on_action_Errors_and_Warnings_triggered(); }
void showStatisticsViewer() { on_action_Statistics_Viewer_triggered(); }
void showTimelineBar() { on_action_Timeline_triggered(); }
void showPythonShell() { on_action_Python_Shell_triggered(); }
private slots:
// automatic slots
@@ -108,6 +109,7 @@ private slots:
void on_action_Launch_Application_triggered();
void on_action_Errors_and_Warnings_triggered();
void on_action_Statistics_Viewer_triggered();
void on_action_Timeline_triggered();
void on_action_Python_Shell_triggered();
void on_action_Inject_into_Process_triggered();
void on_action_Resolve_Symbols_triggered();
+9
View File
@@ -201,6 +201,10 @@ struct CaptureContextInvoker : ICaptureContext
{
return InvokeRetFunction<IStatisticsViewer *>(&ICaptureContext::GetStatisticsViewer);
}
virtual ITimelineBar *GetTimelineBar() override
{
return InvokeRetFunction<ITimelineBar *>(&ICaptureContext::GetTimelineBar);
}
virtual IPythonShell *GetPythonShell() override
{
return InvokeRetFunction<IPythonShell *>(&ICaptureContext::GetPythonShell);
@@ -237,6 +241,10 @@ struct CaptureContextInvoker : ICaptureContext
{
return InvokeRetFunction<bool>(&ICaptureContext::HasStatisticsViewer);
}
virtual bool HasTimelineBar() override
{
return InvokeRetFunction<bool>(&ICaptureContext::HasTimelineBar);
}
virtual bool HasPythonShell() override
{
return InvokeRetFunction<bool>(&ICaptureContext::HasPythonShell);
@@ -271,6 +279,7 @@ struct CaptureContextInvoker : ICaptureContext
{
InvokeVoidFunction(&ICaptureContext::ShowStatisticsViewer);
}
virtual void ShowTimelineBar() override { InvokeVoidFunction(&ICaptureContext::ShowTimelineBar); }
virtual void ShowPythonShell() override { InvokeVoidFunction(&ICaptureContext::ShowPythonShell); }
virtual IShaderViewer *EditShader(bool customShader, const QString &entryPoint,
const QStringMap &files, IShaderViewer::SaveCallback saveCallback,
+293
View File
@@ -0,0 +1,293 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2017 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "TimelineBar.h"
#include <QMouseEvent>
#include <QPainter>
#include <QScrollBar>
#include <QWheelEvent>
TimelineBar::TimelineBar(ICaptureContext &ctx, QWidget *parent)
: QAbstractScrollArea(parent), m_Ctx(ctx)
{
m_Ctx.AddLogViewer(this);
setMouseTracking(true);
setFrameShape(NoFrame);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
QObject::connect(horizontalScrollBar(), &QScrollBar::valueChanged,
[this](int value) { m_pan = -value; });
setWindowTitle(tr("Timeline"));
}
TimelineBar::~TimelineBar()
{
m_Ctx.BuiltinWindowClosed(this);
m_Ctx.RemoveLogViewer(this);
}
void TimelineBar::HighlightResourceUsage(ResourceId id)
{
}
void TimelineBar::HighlightHistory(ResourceId id, const QList<PixelModification> &history)
{
}
void TimelineBar::OnLogfileClosed()
{
setWindowTitle(tr("Timeline"));
m_Events.clear();
}
void TimelineBar::OnLogfileLoaded()
{
setWindowTitle(tr("Timeline - Frame #%1").arg(m_Ctx.FrameInfo().frameNumber));
addEvents(m_Ctx.CurDrawcalls());
m_zoom = 1.0;
m_pan = 0.0;
m_lastPos = QPointF();
layout();
}
void TimelineBar::OnEventChanged(uint32_t eventID)
{
}
QSize TimelineBar::minimumSizeHint() const
{
return QSize(margin * 4 + borderWidth * 2 + 100, margin * 4 + borderWidth * 2 + 40);
}
void TimelineBar::resizeEvent(QResizeEvent *e)
{
layout();
}
void TimelineBar::layout()
{
QFontMetrics fm(Formatter::PreferredFont());
// outer margin + border + inner margin + width of title + scale bar text advance
m_leftCoord = margin + borderWidth + margin + fm.width(scaleTitle) + fm.height();
m_totalSize = viewport()->width() - m_leftCoord - margin - borderWidth - margin;
uint32_t maxEID = m_Events.isEmpty() ? 0 : m_Events.back();
int stepSize = 1;
int stepMagnitude = 1;
m_scaleLabelWidth = fm.width(QString::number(maxEID)) + fm.height();
m_scaleLabelStep = stepSize * stepMagnitude;
qreal virtualSize = m_totalSize * m_zoom;
while(virtualSize > 0 && (maxEID / m_scaleLabelStep) * m_scaleLabelWidth > virtualSize)
{
// increment 1, 2, 5, 10, 20, 50, 100, ...
if(stepSize == 1)
{
stepSize = 2;
}
else if(stepSize == 2)
{
stepSize = 5;
}
else if(stepSize == 5)
{
stepSize = 1;
stepMagnitude *= 10;
}
m_scaleLabelStep = stepSize * stepMagnitude;
}
int numLabels = maxEID / m_scaleLabelStep + 1;
m_scaleLabelWidth = virtualSize / numLabels;
horizontalScrollBar()->setRange(0, virtualSize - m_totalSize);
horizontalScrollBar()->setSingleStep(m_scaleLabelWidth);
horizontalScrollBar()->setPageStep(m_totalSize);
horizontalScrollBar()->setValue(-m_pan);
viewport()->update();
}
void TimelineBar::mousePressEvent(QMouseEvent *e)
{
m_lastPos = e->localPos();
}
void TimelineBar::mouseReleaseEvent(QMouseEvent *e)
{
}
void TimelineBar::mouseMoveEvent(QMouseEvent *e)
{
if(e->buttons() == Qt::LeftButton)
{
qreal delta = e->localPos().x() - m_lastPos.x();
m_pan += delta;
m_pan = qBound(-m_totalSize * (m_zoom - 1.0), m_pan, 0.0);
m_lastPos = e->localPos();
layout();
}
}
void TimelineBar::wheelEvent(QWheelEvent *e)
{
float mod = (1.0 + e->delta() / 2500.0f);
qreal prevZoom = m_zoom;
m_zoom = qMax(1.0, m_zoom * mod);
qreal zoomDelta = (m_zoom / prevZoom);
// adjust the pan so that it's still in bounds, and so the zoom acts centred on the mouse
qreal newPan = m_pan;
newPan -= (e->x() - m_leftCoord);
newPan = newPan * zoomDelta;
newPan += (e->x() - m_leftCoord);
m_pan = qBound(-m_totalSize * (m_zoom - 1.0), newPan, 0.0);
e->accept();
layout();
}
void TimelineBar::paintEvent(QPaintEvent *e)
{
QPainter p(viewport());
p.setFont(font());
p.setRenderHint(QPainter::Antialiasing);
p.setRenderHint(QPainter::HighQualityAntialiasing);
QRectF r = viewport()->rect();
p.fillRect(r, palette().brush(QPalette::Window));
r = r.marginsRemoved(QMarginsF(margin, margin, margin, margin));
p.fillRect(r, palette().brush(QPalette::Text));
r = r.marginsRemoved(QMarginsF(borderWidth, borderWidth, borderWidth, borderWidth));
p.fillRect(r, palette().brush(QPalette::Base));
QTextOption to;
to.setWrapMode(QTextOption::NoWrap);
to.setAlignment(Qt::AlignLeft | Qt::AlignTop);
QRectF scaleRect = r;
scaleRect.setHeight(qMin(scaleRect.height(), p.fontMetrics().height() + margin * 2));
p.setPen(QPen(palette().brush(QPalette::Text), 0.0));
p.drawLine(scaleRect.bottomLeft() + QPointF(0, 0.5), scaleRect.bottomRight() + QPointF(0, 0.5));
scaleRect = scaleRect.marginsRemoved(QMargins(margin, margin, margin, margin));
QString text = scaleTitle;
p.drawText(scaleRect, text, to);
scaleRect.setLeft(scaleRect.left() + p.fontMetrics().width(text) + scaleRect.height());
if(!m_Ctx.LogLoaded())
return;
p.setClipRect(scaleRect);
scaleRect.setLeft(scaleRect.left() + m_pan);
uint32_t maxEID = m_Events.isEmpty() ? 0 : m_Events.back();
to.setAlignment(Qt::AlignCenter | Qt::AlignTop);
p.setFont(Formatter::PreferredFont());
for(uint32_t i = 0; i <= maxEID; i += m_scaleLabelStep)
{
if(scaleRect.left() + m_scaleLabelWidth >= 0)
{
QRectF labelRect = scaleRect;
labelRect.setWidth(m_scaleLabelWidth);
p.drawText(labelRect, QString::number(i), to);
}
scaleRect.setLeft(scaleRect.left() + m_scaleLabelWidth);
if(scaleRect.width() <= 0)
break;
}
p.setClipRect(viewport()->rect());
}
uint32_t TimelineBar::eventAt(qreal x)
{
if(m_Events.isEmpty())
return 0;
// pan x
x -= m_pan;
// normalise x between 0 and 1, left to right of bar area.
x -= m_leftCoord;
x /= m_totalSize;
// apply zoom factor
x /= m_zoom;
// x = 0 is the left side of EID 0, x = 1 is the right side of the last EID
return uint32_t(x * (m_Events.back() + 1));
}
void TimelineBar::addEvents(const rdctype::array<DrawcallDescription> &curDraws)
{
for(const DrawcallDescription &d : curDraws)
{
addEvents(d.children);
if(!(d.flags & (DrawFlags::SetMarker | DrawFlags::PushMarker)) || (d.flags & DrawFlags::APICalls))
m_Events.push_back(d.eventID);
}
}
+81
View File
@@ -0,0 +1,81 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2017 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#pragma once
#include <QAbstractScrollArea>
#include "Code/CaptureContext.h"
class TimelineBar : public QAbstractScrollArea, public ITimelineBar, public ILogViewer
{
Q_OBJECT
public:
explicit TimelineBar(ICaptureContext &ctx, QWidget *parent = 0);
~TimelineBar();
QSize minimumSizeHint() const override;
// IStatisticsViewer
QWidget *Widget() override { return this; }
void HighlightResourceUsage(ResourceId id) override;
void HighlightHistory(ResourceId id, const QList<PixelModification> &history) override;
// ILogViewerForm
void OnLogfileLoaded() override;
void OnLogfileClosed() override;
void OnSelectedEventChanged(uint32_t eventID) override {}
void OnEventChanged(uint32_t eventID) override;
protected:
void mousePressEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override;
void wheelEvent(QWheelEvent *e) override;
void paintEvent(QPaintEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
private:
ICaptureContext &m_Ctx;
QVector<uint32_t> m_Events;
const qreal margin = 2.0;
const qreal borderWidth = 1.0;
const QString scaleTitle = lit("EID:");
qreal m_leftCoord = 0;
qreal m_totalSize = 0;
int m_scaleLabelStep = 0;
qreal m_scaleLabelWidth = 0;
qreal m_zoom = 1.0;
qreal m_pan = 0.0;
QPointF m_lastPos;
void layout();
uint32_t eventAt(qreal x);
void addEvents(const rdctype::array<DrawcallDescription> &curDraws);
};
+2
View File
@@ -200,6 +200,7 @@ SOURCES += Code/qrenderdoc.cpp \
Widgets/Extended/RDTableView.cpp \
Windows/DebugMessageView.cpp \
Windows/StatisticsViewer.cpp \
Windows/TimelineBar.cpp \
Windows/Dialogs/SettingsDialog.cpp \
Windows/Dialogs/OrderedListEditor.cpp \
Widgets/Extended/RDTableWidget.cpp \
@@ -260,6 +261,7 @@ HEADERS += Code/CaptureContext.h \
Widgets/Extended/RDTableView.h \
Windows/DebugMessageView.h \
Windows/StatisticsViewer.h \
Windows/TimelineBar.h \
Windows/Dialogs/SettingsDialog.h \
Windows/Dialogs/OrderedListEditor.h \
Widgets/Extended/RDTableWidget.h \
+8
View File
@@ -626,6 +626,7 @@
<ClCompile Include="$(IntDir)generated\moc_PythonShell.cpp" />
<ClCompile Include="$(IntDir)generated\moc_PixelHistoryView.cpp" />
<ClCompile Include="$(IntDir)generated\moc_StatisticsViewer.cpp" />
<ClCompile Include="$(IntDir)generated\moc_TimelineBar.cpp" />
<ClCompile Include="$(IntDir)generated\moc_SuggestRemoteDialog.cpp" />
<ClCompile Include="$(IntDir)generated\moc_TextureGoto.cpp" />
<ClCompile Include="$(IntDir)generated\moc_TextureSaveDialog.cpp" />
@@ -701,6 +702,7 @@
<ClCompile Include="Windows\PythonShell.cpp" />
<ClCompile Include="Windows\PixelHistoryView.cpp" />
<ClCompile Include="Windows\StatisticsViewer.cpp" />
<ClCompile Include="Windows\TimelineBar.cpp" />
<ClCompile Include="Windows\TextureViewer.cpp" />
<ClCompile Include="3rdparty\toolwindowmanager\ToolWindowManager.cpp">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
@@ -1175,6 +1177,12 @@
<Message>MOC %(Filename).h</Message>
<Outputs>$(IntDir)generated\moc_%(Filename).cpp</Outputs>
</CustomBuild>
<CustomBuild Include="Windows\TimelineBar.h">
<AdditionalInputs>%(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs)</AdditionalInputs>
<Command>$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I$(ProjectDir) -I$(SolutionDir)\renderdoc\api\replay -I$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015 -I$(ProjectDir)3rdparty\qt\$(Platform)\include -I$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets -I$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui -I$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore %(Fullpath) -o $(IntDir)generated\moc_%(Filename).cpp</Command>
<Message>MOC %(Filename).h</Message>
<Outputs>$(IntDir)generated\moc_%(Filename).cpp</Outputs>
</CustomBuild>
<CustomBuild Include="Windows\StatisticsViewer.h">
<AdditionalInputs>%(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs)</AdditionalInputs>
<Command>$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I$(ProjectDir) -I$(SolutionDir)\renderdoc\api\replay -I$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015 -I$(ProjectDir)3rdparty\qt\$(Platform)\include -I$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets -I$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui -I$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore %(Fullpath) -o $(IntDir)generated\moc_%(Filename).cpp</Command>