mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-27 08:24:39 -07:00
[Client] Show latency in status bar and server tab indicator (#7154)
* [Client] Show live connection latency in the status bar Add a permanent status-bar label fed by ConnectionController's pingStatsUpdated: shows the latest round-trip time, hides while disconnected or without samples, and carries a tooltip with Last/Median/95th percentile/Maximum over the rolling sample window (mirrored into the accessible description). The server tab gets the same stats as its tooltip. Took 2 minutes Took 2 minutes Took 1 minute Took 48 seconds Took 25 seconds Took 4 minutes * [Client] Graph connection latency history in the status bar Add LatencyGraphWidget, a size-agnostic bar sparkline over the rolling sample window: heights scale to the window's own range while colors map onto an absolute quality ramp, so a steady good ping stays green. Embed it in the new LatencyStatusWidget together with the textual ping readout and feed both through ConnectionController's forwarded signals; the whole area hides while disconnected or without samples. Took 9 minutes Took 14 seconds * [Client] Show latency details when clicking the ping display Clicking the status bar ping area opens a popup with a larger instance of the latency graph plus the numeric statistics, selectable and mirrored into the accessible name. Qt::Popup closes it on any outside click; contents refresh live while open. Took 33 seconds * Fixup from core commit Took 6 minutes Took 5 seconds Took 5 minutes * Lint. Took 12 minutes * Consolidate. Took 6 minutes --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
parent
fc0199d3db
commit
8a5723c0b5
9 changed files with 289 additions and 1 deletions
111
cockatrice/src/client/latency_status_widget.cpp
Normal file
111
cockatrice/src/client/latency_status_widget.cpp
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/**
|
||||
* @file latency_status_widget.cpp
|
||||
* @ingroup Client
|
||||
*/
|
||||
|
||||
#include "latency_status_widget.h"
|
||||
|
||||
#include "latency_graph_widget.h"
|
||||
|
||||
#include <QEvent>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
LatencyStatusWidget::LatencyStatusWidget(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
pingLabel = new QLabel(this);
|
||||
pingLabel->setAccessibleName(tr("Ping"));
|
||||
|
||||
latencyGraph = new LatencyGraphWidget(this);
|
||||
latencyGraph->setFixedSize(90, 14);
|
||||
|
||||
auto *layout = new QHBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setSpacing(4);
|
||||
layout->addWidget(latencyGraph);
|
||||
layout->addWidget(pingLabel);
|
||||
|
||||
// Clicking anywhere in the area opens the detail view.
|
||||
for (QObject *child : QList<QObject *>{pingLabel, latencyGraph}) {
|
||||
child->installEventFilter(this);
|
||||
}
|
||||
setCursor(Qt::PointingHandCursor);
|
||||
|
||||
hide();
|
||||
}
|
||||
|
||||
void LatencyStatusWidget::updateData(const LatencyTracker::Stats &stats, const QList<int> &samplesMs)
|
||||
{
|
||||
latestSamples = samplesMs;
|
||||
latencyGraph->setSamples(samplesMs);
|
||||
if (popup && popup->isVisible() && detailGraph) {
|
||||
detailGraph->setSamples(samplesMs);
|
||||
}
|
||||
|
||||
if (stats.sampleCount == 0) {
|
||||
hide();
|
||||
return;
|
||||
}
|
||||
|
||||
const QString statsStr = statsText(stats);
|
||||
|
||||
pingLabel->setText(tr("Ping: %1 ms").arg(stats.lastMs));
|
||||
pingLabel->setToolTip(statsStr);
|
||||
pingLabel->setAccessibleDescription(statsStr);
|
||||
if (popup && popup->isVisible() && detailLabel) {
|
||||
detailLabel->setText(statsStr);
|
||||
}
|
||||
show();
|
||||
}
|
||||
|
||||
bool LatencyStatusWidget::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
if ((watched == pingLabel || watched == latencyGraph) && event->type() == QEvent::MouseButtonPress) {
|
||||
togglePopup();
|
||||
return true;
|
||||
}
|
||||
return QWidget::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
void LatencyStatusWidget::togglePopup()
|
||||
{
|
||||
if (!popup) {
|
||||
popup = new QWidget(this, Qt::Popup | Qt::FramelessWindowHint);
|
||||
auto *layout = new QVBoxLayout(popup);
|
||||
layout->setContentsMargins(8, 8, 8, 8);
|
||||
|
||||
detailLabel = new QLabel(popup);
|
||||
detailLabel->setAccessibleName(tr("Connection latency details"));
|
||||
detailLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
|
||||
detailGraph = new LatencyGraphWidget(popup);
|
||||
detailGraph->setFixedSize(280, 80);
|
||||
|
||||
layout->addWidget(detailLabel, 0, Qt::AlignLeft);
|
||||
layout->addWidget(detailGraph, 0, Qt::AlignHCenter);
|
||||
}
|
||||
|
||||
if (popup->isVisible()) {
|
||||
popup->hide();
|
||||
return;
|
||||
}
|
||||
|
||||
// Qt::Popup closes itself on any outside click, so just position and show.
|
||||
if (latestSamples.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
detailGraph->setSamples(latestSamples);
|
||||
detailLabel->setText(pingLabel->toolTip());
|
||||
popup->adjustSize();
|
||||
const QPoint anchor = mapToGlobal(QPoint(width() / 2, 0));
|
||||
popup->move(anchor.x() - popup->width() / 2, anchor.y() - popup->height() - 6);
|
||||
popup->show();
|
||||
}
|
||||
|
||||
QString LatencyStatusWidget::statsText(const LatencyTracker::Stats &stats) const
|
||||
{
|
||||
return tr("Connection quality over the last %n sample(s):", "", stats.sampleCount) + "\n" +
|
||||
tr("Last: %1 ms").arg(stats.lastMs) + "\n" + tr("Median: %1 ms").arg(stats.medianMs) + "\n" +
|
||||
tr("95th percentile: %1 ms").arg(stats.p95Ms) + "\n" + tr("Maximum: %1 ms").arg(stats.maxMs);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue