From 63b68e2dfb5c987f474e5a58f7ff3e299ec7cf01 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Tue, 4 Mar 2014 21:45:57 -0600 Subject: Add ability to set digital trace viewer cursors with the mouse Fix oversized cursor control buttons --- clients/tde/src/part/logicanalyzer/part.cpp | 12 +- clients/tde/src/widgets/tracewidget.cpp | 214 +++++++++++++++++++++++----- clients/tde/src/widgets/tracewidget.h | 29 +++- 3 files changed, 211 insertions(+), 44 deletions(-) (limited to 'clients/tde/src') diff --git a/clients/tde/src/part/logicanalyzer/part.cpp b/clients/tde/src/part/logicanalyzer/part.cpp index fbece40..e3a9675 100644 --- a/clients/tde/src/part/logicanalyzer/part.cpp +++ b/clients/tde/src/part/logicanalyzer/part.cpp @@ -130,18 +130,24 @@ LogicAnalyzerPart::LogicAnalyzerPart( TQWidget *parentWidget, const char *widget m_traceWidget->setLeftTraceInfoAreaFitSpacing(10); m_traceWidget->showLeftCursorTraceInfoArea(true); m_traceWidget->setMinimumPixelsPerHorizDiv(30); - m_traceWidget->setNumberOfCursors(2); - m_traceWidget->setTraceInfoCursor(1); + m_traceWidget->setNumberOfCursors(3); + m_traceWidget->setTraceInfoCursor(2); + m_traceWidget->setHoverCursor(2); m_traceWidget->setCursorColor(0, TQColor(0, 255, 0)); m_traceWidget->setCursorColor(1, TQColor(0, 255, 0)); + m_traceWidget->setCursorColor(2, TQColor(255, 255, 0)); m_traceWidget->setCursorHighlightColor(0, TQColor(192, 255, 192)); m_traceWidget->setCursorHighlightColor(1, TQColor(192, 255, 192)); + m_traceWidget->setCursorHighlightColor(2, TQColor(255, 255, 192)); m_traceWidget->setCursorOrientation(0, TQt::Vertical); m_traceWidget->setCursorOrientation(1, TQt::Vertical); + m_traceWidget->setCursorOrientation(2, TQt::Vertical); m_traceWidget->setCursorEnabled(0, true); m_traceWidget->setCursorEnabled(1, true); + m_traceWidget->setCursorEnabled(2, true); m_traceWidget->setCursorName(0, "Cursor V1"); m_traceWidget->setCursorName(1, "Cursor V2"); + m_traceWidget->setCursorName(2, "Cursor VH"); m_traceWidget->setCursorPosition(0, 25); m_traceWidget->setCursorPosition(1, 75); TraceNumberList activeTraces; @@ -150,7 +156,9 @@ LogicAnalyzerPart::LogicAnalyzerPart( TQWidget *parentWidget, const char *widget } m_traceWidget->setCursorActiveTraceList(0, activeTraces); m_traceWidget->setCursorActiveTraceList(1, activeTraces); + m_traceWidget->setCursorActiveTraceList(2, activeTraces); m_traceWidget->setZoomBoxEnabled(false); + m_traceWidget->setHorizCursorDirectClickEnabled(true); connect(m_base->acqStart, SIGNAL(clicked()), this, SLOT(startDAQ())); connect(m_base->acqStop, SIGNAL(clicked()), this, SLOT(stopDAQ())); diff --git a/clients/tde/src/widgets/tracewidget.cpp b/clients/tde/src/widgets/tracewidget.cpp index 60bc7ce..c0527c4 100644 --- a/clients/tde/src/widgets/tracewidget.cpp +++ b/clients/tde/src/widgets/tracewidget.cpp @@ -7,10 +7,12 @@ #include #include +#include #include #include #include #include +#include #include #include @@ -96,6 +98,64 @@ bool TQRectF::operator!=(const TQRectF &r1) { return !operator==(r1); } +TraceWidgetPushButton::TraceWidgetPushButton(TQWidget *parent, const char* name) : TQPushButton(parent, name) { + // +} + +TraceWidgetPushButton::TraceWidgetPushButton(const TQString &text, TQWidget *parent, const char* name) : TQPushButton(text, parent, name) { + // +} + +TraceWidgetPushButton::TraceWidgetPushButton(const TQIconSet& icon, const TQString &text, TQWidget *parent, const char* name) : TQPushButton(icon, text, parent, name) { + // +} + +TraceWidgetPushButton::~TraceWidgetPushButton() { + // +} + +// Largely taken from TQPushButton::sizeHint() +TQSize TraceWidgetPushButton::sizeHint() const { + constPolish(); + + int w = 0, h = 0; + + // calculate contents size... + if (iconSet() && !iconSet()->isNull()) { + int iw = iconSet()->pixmap( TQIconSet::Small, TQIconSet::Normal ).width() + 4; + int ih = iconSet()->pixmap( TQIconSet::Small, TQIconSet::Normal ).height(); + w += iw; + h = TQMAX(h, ih); + } + + if (isMenuButton()) { + w += style().pixelMetric(TQStyle::PM_MenuButtonIndicator, this); + } + + if (pixmap()) { + TQPixmap *pm = (TQPixmap *)pixmap(); + w += pm->width(); + h += pm->height(); + } + else { + TQString s(text()); + bool empty = s.isEmpty(); + if (empty) { + s = TQString::fromLatin1("XXXX"); + } + TQFontMetrics fm = fontMetrics(); + TQSize sz = fm.size(ShowPrefix, s); + if (!empty || !w) { + w += sz.width(); + } + if (!empty || !h) { + h = TQMAX(h, sz.height()); + } + } + + return (TQSize(w, h).expandedTo(TQApplication::globalStrut()).expandedTo(TQSize(20, 20))); +} + class TraceLabelLayout : public TQLayout { public: @@ -639,7 +699,7 @@ void TraceData::drawTrace(TQPainter* p, int graticule_width, int graticule_heigh // Draw fill areas if ((sampleArray[n] != 0) && (sampleArray[n+1] != 0)) { p->save(); - p->fillRect(x+1, y+1, x2-x, baseline-y-1, TQBrush(color.dark(400))); + p->fillRect(x+1, y+1, x2-x, baseline-y, TQBrush(color.dark(400))); p->restore(); } else if ((sampleArray[n] != 0) && (sampleArray[n+1] == 0)) { @@ -649,7 +709,7 @@ void TraceData::drawTrace(TQPainter* p, int graticule_width, int graticule_heigh p->drawLine(x2-3, y+1, x2-1, y2-1); p->drawLine(x2-2, y+1, x2, y2-1); // Fill rectangle under trace - p->fillRect(x+2, y+1, (x2-1)-(x+1)-1, baseline-y-1, TQBrush(color.dark(400))); + p->fillRect(x+2, y+1, (x2-1)-(x+1)-1, baseline-y, TQBrush(color.dark(400))); p->restore(); } else if ((sampleArray[n] == 0) && (sampleArray[n+1] != 0)) { @@ -761,10 +821,10 @@ CursorData::CursorData(TraceWidget* parent, TQWidget* labelParent) : TQObject(), font.setPointSize(font.pointSize()-1); paramLabel->setFont(font); paramLabel->hide(); - singleIncrBtn = new TQPushButton(labelParent); - singleDecrBtn = new TQPushButton(labelParent); - multiIncrBtn = new TQPushButton(labelParent); - multiDecrBtn = new TQPushButton(labelParent); + singleIncrBtn = new TraceWidgetPushButton(labelParent); + singleDecrBtn = new TraceWidgetPushButton(labelParent); + multiIncrBtn = new TraceWidgetPushButton(labelParent); + multiDecrBtn = new TraceWidgetPushButton(labelParent); font = singleIncrBtn->font(); font.setPointSize(font.pointSize()-1); singleIncrBtn->setFont(font); @@ -1100,7 +1160,7 @@ void GraticuleWidget::mousePressEvent(TQMouseEvent *e) { } else { m_prevCursorRect = m_base->zoomCursorBox(); - if (m_base->m_zoomBoxEnabled) { + if (m_base->m_zoomBoxEnabled || m_base->m_horizCursorDirectClickEnabled) { m_leftMouseDown = true; m_prevDownPos = e->pos(); } @@ -1149,16 +1209,25 @@ void GraticuleWidget::mouseReleaseEvent(TQMouseEvent *e) { double y2 = e->y(); double pixelDiffX = fabs(x1-x2); double pixelDiffY = fabs(y1-y2); - if ((x1 < virtualWidth()) && (y1 < height()) && (x2 < virtualWidth()) && (y2 < height()) && (x1 > 0) && (y1 > 0) && (x2 > 0) && (y2 > 0) && (pixelDiffX>0) && (pixelDiffY>0)) { + if (m_base->m_zoomBoxEnabled) { + if ((x1 < virtualWidth()) && (y1 < height()) && (x2 < virtualWidth()) && (y2 < height()) && (x1 > 0) && (y1 > 0) && (x2 > 0) && (y2 > 0) && (pixelDiffX>0) && (pixelDiffY>0)) { + x1 = ((x1/virtualWidth())*100.0); + y1 = ((y1/height())*100.0); + x2 = ((x2/virtualWidth())*100.0); + y2 = ((y2/height())*100.0); + m_base->setZoomCursorBox(TQRectF(x1, y1, x2, y2)); + } + else { + // Reset original zoom box + m_base->setZoomCursorBox(m_prevCursorRect); + } + } + else if (m_base->m_horizCursorDirectClickEnabled) { + // Allow the first two cursors to be set via click+drag x1 = ((x1/virtualWidth())*100.0); - y1 = ((y1/height())*100.0); x2 = ((x2/virtualWidth())*100.0); - y2 = ((y2/height())*100.0); - m_base->setZoomCursorBox(TQRectF(x1, y1, x2, y2)); - } - else { - // Reset original zoom box - m_base->setZoomCursorBox(m_prevCursorRect); + m_base->setCursorPosition(0, x1); + m_base->setCursorPosition(1, x2); } } } @@ -1201,6 +1270,10 @@ void GraticuleWidget::mouseMoveEvent(TQMouseEvent *e) { m_closestCursorDistance = -1; if ((!m_leftMouseDown) && (!m_middleMouseDown) && (m_movingCursor < 0)) { for (uint cursor=0;cursorm_cursorArray.count();cursor++) { + if ((int)cursor == m_base->m_hoverCursor) { + continue; + } + double scaledYPos = (e->y()*100.0)/height(); double scaledXPos = ((e->x()+m_base->horizScrollOffset())*100.0)/virtualWidth(); unsigned int pixelDistance; @@ -1282,11 +1355,20 @@ void GraticuleWidget::mouseMoveEvent(TQMouseEvent *e) { double x2 = e->x(); double y2 = e->y(); if ((x1 < virtualWidth()) && (y1 < height()) && (x2 < virtualWidth()) && (y2 < height()) && (x1 > 0) && (y1 > 0) && (x2 > 0) && (y2 > 0)) { - x1 = ((x1/virtualWidth())*100.0); - y1 = ((y1/height())*100.0); - x2 = ((x2/virtualWidth())*100.0); - y2 = ((y2/height())*100.0); - m_base->setZoomCursorBox(TQRectF(x1, y1, x2, y2)); + if (m_base->m_zoomBoxEnabled) { + x1 = ((x1/virtualWidth())*100.0); + y1 = ((y1/height())*100.0); + x2 = ((x2/virtualWidth())*100.0); + y2 = ((y2/height())*100.0); + m_base->setZoomCursorBox(TQRectF(x1, y1, x2, y2)); + } + else if (m_base->m_horizCursorDirectClickEnabled) { + // Allow the first two cursors to be set via click+drag + x1 = ((x1/virtualWidth())*100.0); + x2 = ((x2/virtualWidth())*100.0); + m_base->setCursorPosition(0, x1); + m_base->setCursorPosition(1, x2); + } } } else if ((m_leftMouseDown) && (m_movingCursor >= 0)) { @@ -1317,6 +1399,22 @@ void GraticuleWidget::mouseMoveEvent(TQMouseEvent *e) { m_base->setZoomCursorBox(TQRectF(m_prevCursorRect.x()+dx, m_prevCursorRect.y()+dy, m_prevCursorRect.width()+dx, m_prevCursorRect.height()+dy)); } + if (m_base->m_hoverCursor >= 0) { + if (m_base->m_cursorArray[m_base->m_hoverCursor]->enabled) { + double scaledXPos = ((e->x()+m_base->horizScrollOffset())*100.0)/virtualWidth(); + if (scaledXPos < 0.0) { + scaledXPos = 0.0; + } + if (scaledXPos > 100.0) { + scaledXPos = 100.0; + } + m_base->m_cursorArray[m_base->m_hoverCursor]->position = scaledXPos; + emit(cursorPositionChanged(m_base->m_hoverCursor, m_base->m_cursorArray[m_base->m_hoverCursor]->position)); + updateGraticule(); + repaint(false); + } + } + m_base->updateCursorText(); if (cursorHighlightChanged) { updateGraticule(); @@ -1342,11 +1440,13 @@ TraceWidget::TraceWidget(TQWidget* parent, const char* name) : TQWidget(parent, m_zoomBoxDarkness(ZOOM_SHADING_DARKNESS_FACTOR), m_zoomCursorStartIndex(0), m_zoomBoxEnabled(false), + m_horizCursorDirectClickEnabled(false), m_horizScrollBar(0), m_useAbsoluteHorizontalRange(true), m_showLeftTraceInfoArea(false), m_showLeftCursorInfoArea(false), m_traceInfoCursor(0), + m_hoverCursor(-1), m_leftTraceInfoLabelsFit(false), m_leftTraceInfoAreaFitSpacing(0), m_minimumPixelsPerHorizDiv(0) { @@ -1589,7 +1689,7 @@ void TraceWidget::updateCursorText() { else { double realCursorPosition = (m_traceArray[trace]->leftEdge+((m_cursorArray[cursor]->position/100.0)*horizontal_range)); TQString deltaText; - if (cursor >= m_zoomCursorStartIndex) { + if ((cursor >= m_zoomCursorStartIndex) && ((int)cursor != m_hoverCursor)) { for (uint cursor2=m_zoomCursorStartIndex;cursor2orientation == m_cursorArray[cursor]->orientation) { @@ -1613,22 +1713,32 @@ void TraceWidget::updateCursorText() { double horizontal_range = (m_traceArray[trace]->rightEdge-m_traceArray[trace]->leftEdge); double realCursorPosition = (m_traceArray[trace]->leftEdge+((m_cursorArray[cursor]->position/100.0)*horizontal_range)); - // Find closest data point - unsigned int n; - unsigned int closest = 0; - double diff; - double distance = DBL_MAX; - for (n=0; nnumberOfSamples; n++) { - diff = fabs(m_traceArray[trace]->positionArray[n] - realCursorPosition); - if (diff < distance) { - distance = diff; - closest = n; - } - } if (m_traceArray[trace]->m_digitalTraceDrawing) { + // Find closest data point + unsigned int n; + unsigned int closest = 0; + for (n=0; nnumberOfSamples-1; n++) { + if ((realCursorPosition >= m_traceArray[trace]->positionArray[n]) && (realCursorPosition < m_traceArray[trace]->positionArray[n+1])) { + closest = n; + break; + } + } + m_traceArray[trace]->leftCursorLabel->setText(TQString("%2").arg((m_traceArray[trace]->sampleArray[closest]==0)?"0":"1")); } else { + // Find closest data point + unsigned int n; + unsigned int closest = 0; + double diff; + double distance = DBL_MAX; + for (n=0; nnumberOfSamples; n++) { + diff = fabs(m_traceArray[trace]->positionArray[n] - realCursorPosition); + if (diff < distance) { + distance = diff; + closest = n; + } + } m_traceArray[trace]->leftCursorLabel->setText(TQString("%2").arg(TraceWidget::prettyFormat(m_traceArray[trace]->sampleArray[closest], m_traceArray[trace]->sampleArray[closest], m_traceArray[trace]->verticalUnits))); } } @@ -1865,10 +1975,18 @@ void TraceWidget::setCursorEnabled(uint cursorNumber, bool enabled) { m_cursorArray[cursorNumber]->enabled = enabled; if (enabled) { m_cursorArray[cursorNumber]->paramLabel->show(); - m_cursorArray[cursorNumber]->singleIncrBtn->show(); - m_cursorArray[cursorNumber]->singleDecrBtn->show(); - m_cursorArray[cursorNumber]->multiIncrBtn->show(); - m_cursorArray[cursorNumber]->multiDecrBtn->show(); + if ((int)cursorNumber != m_hoverCursor) { + m_cursorArray[cursorNumber]->singleIncrBtn->show(); + m_cursorArray[cursorNumber]->singleDecrBtn->show(); + m_cursorArray[cursorNumber]->multiIncrBtn->show(); + m_cursorArray[cursorNumber]->multiDecrBtn->show(); + } + else { + m_cursorArray[cursorNumber]->singleIncrBtn->hide(); + m_cursorArray[cursorNumber]->singleDecrBtn->hide(); + m_cursorArray[cursorNumber]->multiIncrBtn->hide(); + m_cursorArray[cursorNumber]->multiDecrBtn->hide(); + } } else { m_cursorArray[cursorNumber]->paramLabel->hide(); @@ -1915,6 +2033,13 @@ void TraceWidget::setTraceInfoCursor(uint cursorNumber) { updateCursorText(); } +void TraceWidget::setHoverCursor(uint cursorNumber) { + VERIFY_CURSOR_ARRAY_SIZE + + m_hoverCursor = cursorNumber; + updateCursorText(); +} + void TraceWidget::setNumberOfTraces(uint traceNumber) { resizeTraceArray(traceNumber); } @@ -1931,6 +2056,16 @@ TQRectF TraceWidget::zoomBox() { m_zoomBoxPrev = TQRectF(); emit(zoomBoxChanged(m_zoomBoxPrev)); } + if ((!m_zoomBoxEnabled) && (m_horizCursorDirectClickEnabled) && (m_cursorArray.count() > 1)) { + double x; + if (m_cursorArray[0]->position > m_cursorArray[1]->position) { + x = m_cursorArray[1]->position; + } + else { + x = m_cursorArray[0]->position; + } + return TQRectF(x, 0, fabs(m_cursorArray[0]->position - m_cursorArray[1]->position), 100); + } return m_zoomBoxPrev; } else { @@ -2111,6 +2246,11 @@ void TraceWidget::setZoomBoxEnabled(bool enabled) { m_graticuleWidget->updateGraticule(); } +void TraceWidget::setHorizCursorDirectClickEnabled(bool enabled) { + m_horizCursorDirectClickEnabled = enabled; + m_graticuleWidget->updateGraticule(); +} + void TraceWidget::showLeftTraceInfoArea(bool show) { m_showLeftTraceInfoArea = show; for (uint i=0;i #include +#include #include #include @@ -11,7 +12,7 @@ class TQPixmap; class TQLabel; class TQVBoxLayout; class TQGridLayout; -class TQPushButton; +class TraceWidgetPushButton; class TQToolButton; class TraceWidget; class TraceLabelLayout; @@ -46,6 +47,20 @@ class TQRectF double m_h; }; +class TraceWidgetPushButton : public TQPushButton +{ + Q_OBJECT + + public: + TraceWidgetPushButton(TQWidget *parent, const char* name=0); + TraceWidgetPushButton(const TQString &text, TQWidget *parent, const char* name=0); + TraceWidgetPushButton(const TQIconSet& icon, const TQString &text, TQWidget *parent, const char* name=0); + ~TraceWidgetPushButton(); + + public: + TQSize sizeHint() const; +}; + typedef TQValueList TraceNumberList; class TraceData : public TQObject @@ -135,10 +150,10 @@ class CursorData : public TQObject TraceNumberList activeTraceLabelList; TQString cursorName; TQLabel* paramLabel; - TQPushButton* singleIncrBtn; - TQPushButton* singleDecrBtn; - TQPushButton* multiIncrBtn; - TQPushButton* multiDecrBtn; + TraceWidgetPushButton* singleIncrBtn; + TraceWidgetPushButton* singleDecrBtn; + TraceWidgetPushButton* multiIncrBtn; + TraceWidgetPushButton* multiDecrBtn; TraceWidget* parentWidget; friend class TraceWidget; @@ -249,6 +264,7 @@ class TraceWidget : public TQWidget TQt::Orientation cursorOrientation(uint cursorNumber); void setCursorOrientation(uint cursorNumber, TQt::Orientation orient); void setTraceInfoCursor(uint cursorNumber); + void setHoverCursor(uint cursorNumber); void setForegroundColor(const TQColor color); void setBackgroundColor(const TQColor color); @@ -268,6 +284,7 @@ class TraceWidget : public TQWidget void showLeftCursorInfoArea(bool show); void setMinimumPixelsPerHorizDiv(unsigned int pixels); + void setHorizCursorDirectClickEnabled(bool enabled); double traceOffset(uint traceNumber); void setTraceOffset(uint traceNumber, double offset, bool deferUpdate); @@ -308,6 +325,7 @@ class TraceWidget : public TQWidget unsigned int m_zoomBoxDarkness; unsigned int m_zoomCursorStartIndex; bool m_zoomBoxEnabled; + bool m_horizCursorDirectClickEnabled; TQRectF m_zoomBoxPrev; TraceList m_traceArray; CursorList m_cursorArray; @@ -327,6 +345,7 @@ class TraceWidget : public TQWidget bool m_showLeftTraceInfoArea; bool m_showLeftCursorInfoArea; unsigned int m_traceInfoCursor; + int m_hoverCursor; bool m_leftTraceInfoLabelsFit; int m_leftTraceInfoAreaFitSpacing; unsigned int m_minimumPixelsPerHorizDiv; -- cgit v1.2.1