#include #include #include #include #include #include #include "displaywidget.h" #include "helpers.h" static const double TimeBaseSteps [] = { 2.0e-6, 5.0e-6, 1.0e-5, 2.0e-5, 5.0e-5, 1.0e-4, 2.0e-4, 5.0e-4, 1.0e-3, 2.0e-3, 5.0e-3, 1.0e-2, 2.0e-2, 5.0e-2, 1.0e-1, 2.0e-1, 5.0e-1, 1.0, }; static const double ChannelsSteps [] = { 1.0, 2.0, 5.0, }; static constexpr double REF_Y = 3.3; // maximum napětí převodníku static constexpr double MAX_Y = double (1 << 12); // 12. bit rozlišení - 4096 steps static constexpr double STEP_Y = REF_Y / MAX_Y; // jeden krok ve Voltech static constexpr unsigned T_SIZE = 1u << 10; static constexpr unsigned T_MASK = T_SIZE - 1u; DisplayWidget::DisplayWidget(QWidget * p) : QWidget(p), ACopy(), BCopy(), m_forward(), m_inverse(), background(), m_ts(nullptr), ChA (T_SIZE), ChB(T_SIZE), m_items (MOVE_VALUE), m_timeBase(6), m_ChBase(0), m_timeCount(0u) { x_lenght = T_SIZE; m_time.a = 200.0; m_time.b = 300.0; m_volt.a = 1.0 / STEP_Y; m_volt.b = 2.0 / STEP_Y; marker_type = MARKER_TIME; int n = 0; for (QPointF & e : ChA) { const QPointF p (n++, 0); e = p; } n = 0; for (QPointF & e : ChB) { const QPointF p (n++, 0); e = p; } } DisplayWidget::~DisplayWidget() { } void DisplayWidget::MarkerChanged (bool b) { // qDebug ("Marker : %s", b ? "Time" : "Volt"); // OK if (b) marker_type = MARKER_TIME; else marker_type = MARKER_VOLT; drawBackground(); update(); } void DisplayWidget::TriggerValues(int n) { m_items = static_cast(n); } static constexpr double FMULT = 1.189207115002721; static constexpr double IMULT = 1.0 / FMULT; void DisplayWidget::wheelEvent(QWheelEvent * event) { if (m_ts == nullptr) return; const QPoint d = event->angleDelta(); const int increment = d.y() > 0 ? +1 : -1; switch (m_items) { case MOVE_VALUE: { m_ts->value += increment * 4; emit SettingsChanged (m_items); } break; case MOVE_OFSET: { m_ts->offset += increment; emit SettingsChanged (m_items); } break; case MOVE_MARKERA: { if (marker_type == MARKER_TIME) m_time.a += increment; else m_volt.a += increment; } break; case MOVE_MARKERB: { if (marker_type == MARKER_TIME) m_time.b += increment; else m_volt.b += increment; } break; case TIME_ZOOM: { const double mx = FMULT * double (size().width()) / x_lenght; if ((m_forward.m11() > mx) or (increment > 0)) { // limit to window const QMatrix m = increment > 0 ? QMatrix (FMULT,0,0,1,0,0) : QMatrix (IMULT,0,0,1,0,0); m_forward *= m; m_inverse = m_forward.inverted(); } } break; default : { qDebug ("wheelEvent : %d", int (m_items)); } break; } drawBackground(); update(); QWidget::wheelEvent(event); } void DisplayWidget::mousePressEvent(QMouseEvent * event) { if (m_ts == nullptr) return; const QPointF dp = m_inverse.map (event->pos ()); // qDebug ("dp:[%g, %g]", dp.x(), dp.y()); switch (m_items) { case MOVE_VALUE: { m_ts->value = dp.y(); emit SettingsChanged (m_items); } break; case MOVE_OFSET: { m_ts->offset = dp.x(); emit SettingsChanged (m_items); } break; case MOVE_MARKERA: { if (marker_type == MARKER_TIME) m_time.a = dp.x(); else m_volt.a = dp.y(); } break; case MOVE_MARKERB: { if (marker_type == MARKER_TIME) m_time.b = dp.x(); else m_volt.b = dp.y(); } break; case TIME_ZOOM: QWidget::mousePressEvent(event); return; default : { qDebug ("mousePressEvent : %d", int (m_items)); } break; } drawBackground(); update(); QWidget::mousePressEvent(event); } void DisplayWidget::resizeEvent(QResizeEvent * event) { const QSize sz = event->size(); reloadMatrix (sz); QImage tmpi (sz, QImage::Format_ARGB32); background = tmpi; drawBackground(); QWidget::resizeEvent(event); } void DisplayWidget::paintEvent(QPaintEvent * event) { QPainter p (this); p.drawImage(event->rect(), background); QPen pa (QColor(0,255, 0,255), 2); QPen pb (QColor(255,64,0,255), 2); p.setPen(pb); p.drawPolyline (m_forward.map(ChB)); p.setPen(pa); p.drawPolyline (m_forward.map(ChA)); } void DisplayWidget::setTrigger(TrigerSettings * ts) { m_ts = ts; } void DisplayWidget::DispChannels(QVector cha, QVector chb) { ACopy = cha; BCopy = chb; reloadData(); update(); } void DisplayWidget::reloadData () { const size_t Alen = ACopy.size(); const size_t Blen = BCopy.size(); const size_t Amin = Alen < T_SIZE ? Alen : T_SIZE; const size_t Bmin = Blen < T_SIZE ? Blen : T_SIZE; if ((Alen == 1u) and (Blen == 1u)) { // kontinuální mód const QPointF pta (m_timeCount, ACopy [0]), ptb (m_timeCount, BCopy [0]); ChA[m_timeCount] = pta; ChB[m_timeCount] = ptb; // printf("mode continuum\n"); m_timeCount += 1u; m_timeCount &= T_MASK; return; } for (unsigned n=0u; n Blen ? Alen : Blen; if (l != x_lenght) { x_lenght = l; reloadMatrix (size()); } } void DisplayWidget::reloadMatrix(const QSize & sz) { const double xm = sz.width(); const double ym = sz.height(); const double xz = xm / (x_lenght); // převod zpět ma pixely const double yz = ym / (MAX_Y); const QMatrix tm (xz,0,0,-yz, 0, ym); m_forward = tm; m_inverse = m_forward.inverted(); } /* void DisplayWidget::Refresh(int n) { m_timeBase = n; reloadMatrix (size()); drawBackground(); update(); } */ void DisplayWidget::TimeBaseRange(int n) { m_timeBase = n; reloadMatrix (size()); drawBackground(); update(); } void DisplayWidget::drawBackground() { QPainter p (&background); QRect r = background.rect(); p.fillRect (r, QBrush(Qt::black, Qt::SolidPattern)); if (!m_ts) return; const double yb = 0.0, ye = MAX_Y; const double xb = 0.0, xe = x_lenght; // rastr QPen pg (QColor(64,64,64), 1); p.setPen(pg); const double dx = 100.0; for (double x=xb; xoffset, m_ts->value); QPen pc (QColor(0,0,255), 1); p.setPen(pc); const QLineF hline (xb, trg.y(), xe, trg.y()); const QLineF vline (trg.x(), yb, trg.x(), ye); p.drawLine (m_forward.map(hline)); p.drawLine (m_forward.map(vline)); // markers QPen pm (QColor(255,255,0,196), 2); p.setPen(pm); if (marker_type == MARKER_TIME) { const QLineF ma (m_time.a, yb, m_time.a, ye); const QLineF mb (m_time.b, yb, m_time.b, ye); p.drawLine (m_forward.map(ma)); p.drawLine (m_forward.map(mb)); } else { const QLineF ma (xb, m_volt.a, xe, m_volt.a); const QLineF mb (xb, m_volt.b, xe, m_volt.b); p.drawLine (m_forward.map(ma)); p.drawLine (m_forward.map(mb)); } // text p.setPen (QPen (QColor(255,255,0))); QFont font = p.font(); font.setPixelSize(16); p.setFont (font); QString desc; const double xz = TimeBaseSteps [m_timeBase]; const double yz = STEP_Y; const int my = r.size().height() - 10; desc.sprintf("T=%ss/d; A,B=%gV/d", ing_fmt (xz * dx).c_str() , dv); p.drawText(10,20, desc); if (marker_type == MARKER_TIME) { const double delta = xz * (m_time.b - m_time.a); const double freq = delta == 0.0 ? 0.0 : 1.0 / delta; desc.sprintf("Marker A: %ss, Marker B: %ss, Δ=%ss, f=%sHz", ing_fmt(xz * m_time.a).c_str(), ing_fmt(xz * m_time.b).c_str(), ing_fmt(delta).c_str(), ing_fmt(freq).c_str()); } else { const double delta = yz * (m_volt.b - m_volt.a); desc.sprintf("Marker A: %sV, Marker B: %sV, Δ=%sV", ing_fmt(yz * m_volt.a).c_str(), ing_fmt(yz * m_volt.b).c_str(), ing_fmt(delta).c_str()); } p.drawText(10,my, desc); } void DisplayWidget::saveSettings(QSettings & setting) { setting.setValue("TimeBaseIndex", m_timeBase); setting.setValue("TimeA", m_time.a); setting.setValue("TimeB", m_time.b); setting.setValue("VoltA", m_volt.a); setting.setValue("VoltB", m_volt.b); } void DisplayWidget::restSettings(QSettings & setting) { m_time.a = setting.value("TimeA").toDouble(); m_time.b = setting.value("TimeB").toDouble(); m_volt.a = setting.value("VoltA").toDouble(); m_volt.b = setting.value("VoltB").toDouble(); }