201 const int W = width();
202 const int H = height();
203 const double spp =
static_cast<double>(m_spp);
205 if (W <= 0 || spp <= 0.0 || m_sfreq <= 0.0)
209 p.setRenderHint(QPainter::Antialiasing,
false);
210 p.setRenderHint(QPainter::TextAntialiasing,
true);
217 p.fillRect(QRect(0, 0, W,
kTimeZoneH), QColor(245, 245, 247));
223 p.setPen(QPen(QColor(190, 190, 205), 1));
227 p.setPen(QPen(QColor(185, 185, 195), 1));
228 p.drawLine(0, H - 1, W, H - 1);
231 if (!m_referenceMarkers.isEmpty()) {
232 QFont markerFont = p.font();
233 markerFont.setPixelSize(9);
234 markerFont.setBold(
true);
235 p.setFont(markerFont);
237 constexpr int kMarkerChipH = 12;
238 constexpr int kMarkerPadX = 5;
239 const int markerChipY = 2;
242 const float xF = (
static_cast<float>(marker.sample) - m_scrollSample) /
static_cast<float>(spp);
243 if (xF < -2.f || xF > W + 2.f) {
247 const int xi =
static_cast<int>(std::round(xF));
248 QColor markerColor = marker.color;
249 markerColor.setAlpha(210);
250 p.setPen(QPen(markerColor, 1));
251 p.drawLine(xi, 0, xi, H - 1);
253 const QString label = marker.label.isEmpty()
254 ? QString::number(marker.sample)
256 const int chipW = qMax(20, p.fontMetrics().horizontalAdvance(label) + 2 * kMarkerPadX);
257 QRect chipRect(xi - chipW / 2, markerChipY, chipW, kMarkerChipH);
258 chipRect.moveLeft(qBound(2, chipRect.left(), qMax(2, W - chipRect.width() - 2)));
260 QColor fillColor = marker.color;
261 fillColor.setAlpha(220);
262 p.fillRect(chipRect, fillColor);
264 p.drawText(chipRect, Qt::AlignCenter, label);
269 if (!m_events.isEmpty()) {
271 evFont.setPixelSize(9);
272 evFont.setBold(
true);
275 constexpr int kChipW = 26;
276 constexpr int kChipH = 11;
283 int lastChipRight = -kChipW;
286 float xF = (
static_cast<float>(ev.sample) - m_scrollSample) /
static_cast<float>(spp);
287 if (xF < -2.f || xF > W + 2.f)
289 int ix =
static_cast<int>(xF);
292 QColor col = ev.color;
294 p.setPen(QPen(col, 1));
300 int chipX = ix - kChipW / 2;
301 chipX = qMax(0, chipX);
302 if (chipX + kChipW > W)
304 if (chipX < lastChipRight + 2)
307 QRectF chip(chipX, kChipY, kChipW, kChipH);
308 QColor fill = ev.color;
310 p.fillRect(chip, fill);
312 QString lbl = ev.label.isEmpty() ? QStringLiteral(
"?") : ev.label;
313 p.drawText(chip, Qt::AlignCenter, lbl);
315 lastChipRight = chipX + kChipW;
320 const double pxPerSec = m_sfreq / spp;
321 double tickIntervalS = kNiceIntervals[0];
322 for (
double iv : kNiceIntervals) {
324 if (iv * pxPerSec >= kMinMajorPx)
328 const double tickSamples = tickIntervalS * m_sfreq;
329 const double minorSamples = tickSamples / 5.0;
330 const double origin =
static_cast<double>(m_firstFileSample);
333 QFont font = QFontDatabase::systemFont(QFontDatabase::FixedFont);
334 font.setPointSizeF(8.0);
336 const QFontMetrics fm(font);
340 double firstMinorS = std::ceil((m_scrollSample - origin - minorSamples) / minorSamples)
341 * minorSamples + origin;
342 p.setPen(QPen(QColor(165, 165, 175), 1));
343 for (
double s = firstMinorS; ; s += minorSamples) {
344 double xPx = (s - m_scrollSample) / spp;
345 if (xPx > W + 2)
break;
346 if (xPx < -2)
continue;
347 int xi =
static_cast<int>(std::round(xPx));
354 double firstMajorS = std::ceil((m_scrollSample - origin - tickSamples) / tickSamples)
355 * tickSamples + origin;
356 for (
double s = firstMajorS; ; s += tickSamples) {
357 double xPx = (s - m_scrollSample) / spp;
358 if (xPx > W + 2)
break;
359 if (xPx < -2)
continue;
361 int xi =
static_cast<int>(std::round(xPx));
363 p.setPen(QPen(QColor(100, 100, 115), 1));
366 double elapsedSec = (s - origin) / m_sfreq;
367 if (elapsedSec >= -tickIntervalS * 0.5) {
369 if (m_useClockTime && elapsedSec >= 0.0) {
370 int totalMs =
static_cast<int>(elapsedSec * 1000.0 + 0.5);
371 int m = totalMs / 60000;
372 int sec = (totalMs % 60000) / 1000;
373 int ms = totalMs % 1000;
374 label = QString(
"%1:%2.%3")
375 .arg(m, 2, 10, QChar(
'0'))
376 .arg(sec, 2, 10, QChar(
'0'))
377 .arg(ms, 3, 10, QChar(
'0'));
379 label = formatTime(elapsedSec);
381 const int lw = fm.horizontalAdvance(label);
383 int lx = xi - lw / 2;
384 lx = qBound(2, lx, W - lw - 2);
385 int ly =
kTimeZoneH - 1 - kMajorH - kLabelGap;
387 p.setPen(QColor(65, 65, 80));
388 p.drawText(lx, ly, label);
398 if (m_sfreq <= 0.0 || m_spp <= 0.0f) {
399 QWidget::contextMenuEvent(event);
403 const int sample = sampleAtX(event->pos().x());
404 const int nearbyMarkerIndex = nearestReferenceMarkerIndex(sample);
407 QAction *addMarkerAction = menu.addAction(tr(
"Add Marker Here"));
408 QAction *removeMarkerAction =
nullptr;
409 QAction *clearMarkersAction =
nullptr;
411 if (nearbyMarkerIndex >= 0) {
412 removeMarkerAction = menu.addAction(tr(
"Remove Nearest Marker"));
415 if (!m_referenceMarkers.isEmpty()) {
417 clearMarkersAction = menu.addAction(tr(
"Clear All Markers"));
420 QAction *selectedAction = menu.exec(event->globalPos());
421 if (!selectedAction) {
425 if (selectedAction == addMarkerAction) {
427 }
else if (selectedAction == removeMarkerAction) {
429 }
else if (selectedAction == clearMarkersAction) {