Display richer status in capture connection window.

* This includes the capture progress bar that will appear, as well as
  better information about the active API.
This commit is contained in:
baldurk
2017-12-29 16:15:09 +00:00
parent 559656e0f6
commit 0fef1c0a44
3 changed files with 336 additions and 175 deletions
+88 -34
View File
@@ -23,6 +23,7 @@
******************************************************************************/
#include "LiveCapture.h"
#include <QDesktopServices>
#include <QMenu>
#include <QMetaProperty>
#include <QMouseEvent>
@@ -112,10 +113,20 @@ LiveCapture::LiveCapture(ICaptureContext &ctx, const QString &hostname, const QS
ui->preview->setMouseTracking(true);
setTitle(tr("Connecting.."));
ui->connectionStatus->setText(tr("Connecting.."));
setTitle(tr("Connecting"));
ui->connectionStatus->setText(tr("Connecting"));
ui->connectionIcon->setPixmap(Pixmaps::hourglass(ui->connectionIcon));
ui->apiIcon->setVisible(false);
ui->triggerCapture->setEnabled(false);
ui->queueCap->setEnabled(false);
ui->target->setText(QString());
ui->captureProgressLabel->setVisible(false);
ui->captureProgress->setVisible(false);
ui->captures->setItemDelegate(new NameEditOnlyDelegate(this));
{
@@ -566,6 +577,41 @@ bool LiveCapture::checkAllowDelete()
return (res == QMessageBox::Yes);
}
void LiveCapture::updateAPIStatus()
{
QString apiStatus;
bool nonpresenting = false;
// add any fully working APIs first in the list.
for(QString api : m_APIs.keys())
{
if(m_APIs[api].supported && m_APIs[api].presenting)
apiStatus += lit(", <b>%1</b>").arg(api);
}
// then add any problem APIs
for(QString api : m_APIs.keys())
{
if(!m_APIs[api].supported)
{
apiStatus += tr(", %1 (Unsupported)").arg(api);
}
else if(!m_APIs[api].presenting)
{
apiStatus += tr(", %1 (Not Presenting)").arg(api);
nonpresenting = true;
}
}
// remove the redundant starting ", "
apiStatus.remove(0, 2);
ui->apiStatus->setText(apiStatus);
ui->apiIcon->setVisible(nonpresenting);
}
QString LiveCapture::MakeText(Capture *cap)
{
QString text = cap->name;
@@ -818,6 +864,11 @@ void LiveCapture::on_previewSplit_splitterMoved(int pos, int index)
m_IgnorePreviewToggle = false;
}
void LiveCapture::on_apiIcon_clicked(QMouseEvent *event)
{
QDesktopServices::openUrl(QUrl(lit("https://renderdoc.org/docs/in_application_api.html")));
}
void LiveCapture::captures_keyPress(QKeyEvent *e)
{
if(e->key() == Qt::Key_Delete)
@@ -1018,7 +1069,7 @@ void LiveCapture::connectionThreadEntry()
{
GUIInvoke::call([this]() {
setTitle(tr("Connection failed"));
ui->connectionStatus->setText(tr("Connection failed"));
ui->connectionStatus->setText(tr("Failed"));
ui->connectionIcon->setPixmap(Pixmaps::del(ui->connectionIcon));
connectionClosed();
@@ -1028,25 +1079,16 @@ void LiveCapture::connectionThreadEntry()
}
GUIInvoke::call([this]() {
QString api = QString::fromUtf8(m_Connection->GetAPI());
if(api.isEmpty())
api = tr("No API detected");
QString target = QString::fromUtf8(m_Connection->GetTarget());
uint32_t pid = m_Connection->GetPID();
if(pid == 0)
{
ui->connectionStatus->setText(tr("Connection established to %1 (%2)").arg(target).arg(api));
setTitle(target);
}
else
{
ui->connectionStatus->setText(
tr("Connection established to %1 [PID %2] (%3)").arg(target).arg(pid).arg(api));
QString target = QString::fromUtf8(m_Connection->GetTarget());
if(pid)
setTitle(QFormatStr("%1 [PID %2]").arg(target).arg(pid));
}
else
setTitle(target);
ui->target->setText(windowTitle());
ui->connectionIcon->setPixmap(Pixmaps::connect(ui->connectionIcon));
ui->connectionStatus->setText(tr("Established"));
});
while(m_Connection && m_Connection->Connected())
@@ -1095,28 +1137,37 @@ void LiveCapture::connectionThreadEntry()
bool presenting = msg.apiUse.presenting;
bool supported = msg.apiUse.supported;
GUIInvoke::call([this, api, presenting, supported]() {
QString target = QString::fromUtf8(m_Connection->GetTarget());
uint32_t pid = m_Connection->GetPID();
m_APIs[api] = APIStatus(presenting, supported);
if(pid == 0)
if(presenting && supported)
{
ui->connectionStatus->setText(tr("Connection established to %1 (%2)").arg(target).arg(api));
setTitle(target);
ui->triggerCapture->setEnabled(true);
ui->queueCap->setEnabled(true);
}
else
{
ui->connectionStatus->setText(
tr("Connection established to %1 [PID %2] (%3)").arg(target).arg(pid).arg(api));
setTitle(QFormatStr("%1 [PID %2]").arg(target).arg(pid));
}
ui->connectionIcon->setPixmap(Pixmaps::connect(ui->connectionIcon));
updateAPIStatus();
});
}
if(msg.type == TargetControlMessageType::CaptureProgress)
{
float progress = msg.capProgress;
GUIInvoke::call([this, progress]() {});
GUIInvoke::call([this, progress]() {
if(progress >= 0.0f && progress < 1.0f)
{
ui->captureProgressLabel->setVisible(true);
ui->captureProgress->setVisible(true);
ui->captureProgress->setMaximum(1000);
ui->captureProgress->setValue(1000 * progress);
}
else
{
ui->captureProgressLabel->setVisible(false);
ui->captureProgress->setVisible(false);
}
});
}
if(msg.type == TargetControlMessageType::NewCapture)
@@ -1143,7 +1194,7 @@ void LiveCapture::connectionThreadEntry()
uint32_t capID = msg.newCapture.captureId;
QString path = msg.newCapture.path;
GUIInvoke::call([=]() { captureCopied(capID, path); });
GUIInvoke::call([this, capID, path]() { captureCopied(capID, path); });
}
if(msg.type == TargetControlMessageType::NewChild)
@@ -1163,7 +1214,7 @@ void LiveCapture::connectionThreadEntry()
}
GUIInvoke::call([this]() {
ui->connectionStatus->setText(tr("Connection closed"));
ui->connectionStatus->setText(tr("Closed"));
ui->connectionIcon->setPixmap(Pixmaps::disconnect(ui->connectionIcon));
ui->numFrames->setEnabled(false);
@@ -1172,6 +1223,9 @@ void LiveCapture::connectionThreadEntry()
ui->triggerCapture->setEnabled(false);
ui->queueCap->setEnabled(false);
ui->apiStatus->setText(tr("None"));
ui->apiIcon->setVisible(false);
connectionClosed();
});
}
+12
View File
@@ -72,6 +72,7 @@ private slots:
void on_triggerCapture_clicked();
void on_queueCap_clicked();
void on_previewSplit_splitterMoved(int pos, int index);
void on_apiIcon_clicked(QMouseEvent *event);
// manual slots
void captures_keyPress(QKeyEvent *e);
@@ -116,12 +117,22 @@ private:
bool added = false;
};
struct APIStatus
{
APIStatus() = default;
APIStatus(bool p, bool s) : presenting(p), supported(s) {}
bool presenting = false;
bool supported = false;
};
Capture *GetCapture(QListWidgetItem *item);
void AddCapture(QListWidgetItem *item, Capture *cap);
QString MakeText(Capture *cap);
QImage MakeThumb(const QImage &screenshot);
void updateAPIStatus();
void connectionThreadEntry();
void captureCopied(uint32_t ID, const QString &localPath);
void captureAdded(uint32_t ID, const QString &executable, const QString &api,
@@ -177,4 +188,5 @@ private:
QMutex m_ChildrenLock;
QList<ChildProcess> m_Children;
QMap<QString, APIStatus> m_APIs;
};
+236 -141
View File
@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>749</width>
<width>680</width>
<height>483</height>
</rect>
</property>
@@ -27,19 +27,13 @@
<number>3</number>
</property>
<item>
<widget class="QFrame" name="connectionFrame">
<widget class="QFrame" name="frame_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
@@ -54,158 +48,259 @@
<number>0</number>
</property>
<item>
<widget class="QLabel" name="connectionIcon">
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../../Resources/resources.qrc">:/hourglass.png</pixmap>
<widget class="QGroupBox" name="statusGroup">
<property name="title">
<string>Status</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Target:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="apiStatus">
<property name="text">
<string>None</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="connectionStatus">
<property name="text">
<string>Connecting</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="target">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="captureProgressLabel">
<property name="text">
<string>Capture in Progress:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="connectionStatusLabel">
<property name="text">
<string>Connection Status:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="apiStatusLabel">
<property name="text">
<string>API:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="connectionIcon">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../../Resources/resources.qrc">:/hourglass.png</pixmap>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="RDLabel" name="apiIcon">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="toolTip">
<string>&lt;p&gt;An API in use is not presenting to a window. This commonly means the API rendering is happening to off-screen targets and either nothing is displayed, or the results are displayed using some other mechanism.&lt;/p&gt;
&lt;p&gt;Without the boundary of a frame, RenderDoc cannot capture by default since it can't tell where to start and stop.&lt;/p&gt;
&lt;p&gt;You can use RenderDoc's In-application API to manually provide markers about where to start and stop the frame capture.&lt;/p&gt;
&lt;p&gt;Click on the icon for more information about this API.&lt;/p&gt;</string>
</property>
<property name="pixmap">
<pixmap resource="../../Resources/resources.qrc">:/information.png</pixmap>
</property>
</widget>
</item>
<item row="4" column="0" colspan="3">
<widget class="QProgressBar" name="captureProgress">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="connectionStatus">
<property name="text">
<string>Connecting...</string>
<widget class="QGroupBox" name="toolsGroup">
<property name="title">
<string>Tools</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="2" colspan="3">
<widget class="QDoubleSpinBox" name="captureFrame">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="decimals">
<number>0</number>
</property>
<property name="maximum">
<double>10000.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QPushButton" name="queueCap">
<property name="text">
<string>Queue Capture</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QDoubleSpinBox" name="captureDelay">
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="suffix">
<string> secs</string>
</property>
<property name="decimals">
<number>0</number>
</property>
<property name="maximum">
<double>120.000000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QDoubleSpinBox" name="numFrames">
<property name="minimumSize">
<size>
<width>45</width>
<height>0</height>
</size>
</property>
<property name="decimals">
<number>0</number>
</property>
<property name="minimum">
<double>1.000000000000000</double>
</property>
<property name="maximum">
<double>4.000000000000000</double>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="capDelayLabel">
<property name="text">
<string>Capture Delay</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="numFramesLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string># Frames:</string>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QPushButton" name="triggerCapture">
<property name="text">
<string>Trigger Capture</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="capFrameLabel">
<property name="text">
<string>Capture Frame #</string>
</property>
</widget>
</item>
<item row="2" column="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="connectionSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="toolsGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Tools</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="4">
<widget class="QPushButton" name="queueCap">
<property name="text">
<string>Queue Capture</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="captureDelay">
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="suffix">
<string> secs</string>
</property>
<property name="decimals">
<number>0</number>
</property>
<property name="maximum">
<double>120.000000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QDoubleSpinBox" name="numFrames">
<property name="minimumSize">
<size>
<width>45</width>
<height>0</height>
</size>
</property>
<property name="decimals">
<number>0</number>
</property>
<property name="minimum">
<double>1.000000000000000</double>
</property>
<property name="maximum">
<double>4.000000000000000</double>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="capDelayLabel">
<property name="text">
<string>Capture Delay</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="numFramesLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string># Frames:</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QPushButton" name="triggerCapture">
<property name="text">
<string>Trigger Capture</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="capFrameLabel">
<property name="text">
<string>Capture Frame #</string>
</property>
</widget>
</item>
<item row="0" column="5">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<width>75</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1" colspan="3">
<widget class="QDoubleSpinBox" name="captureFrame">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="decimals">
<number>0</number>
</property>
<property name="maximum">
<double>10000.000000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>