/* * Analog and Digital Trace Viewing Widget * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (c) 2012-2019 Timothy Pearson * Raptor Engineering * http://www.raptorengineeringinc.com */ #include "tracewidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #define VERIFY_TRACE_ARRAY_SIZE if (traceNumber >= m_traceArray.count()) resizeTraceArray(traceNumber+1); #define VERIFY_CURSOR_ARRAY_SIZE if (cursorNumber >= m_cursorArray.count()) resizeCursorArray(cursorNumber+1); #define CURSOR_DARKNESS_FACTOR 200 #define ZOOM_SHADING_DARKNESS_FACTOR 200 #define DIGITAL_SHADING_DARKNESS_FACTOR 400 #define CURSOR_MOVE_CAPTURE_DISTANCE 0 TQRectF::TQRectF() { m_x = 0; m_y = 0; m_w = 0; m_h = 0; m_valid = false; } TQRectF::TQRectF(double x, double y, double w, double h) { m_x = x; m_y = y; m_w = w; m_h = h; m_valid = true; } double TQRectF::x() const { return m_x; } double TQRectF::y() const { return m_y; } double TQRectF::width() const { return m_w; } double TQRectF::height() const { return m_h; } void TQRectF::setX(double val) { m_x = val; m_valid = true; } void TQRectF::setY(double val) { m_y = val; m_valid = true; } void TQRectF::setWidth(double val) { m_w = val; m_valid = true; } void TQRectF::setHeight(double val) { m_h = val; m_valid = true; } bool TQRectF::isNull() const { return !m_valid; } bool TQRectF::operator!() const { return isNull(); } bool TQRectF::operator==(const TQRectF &r1) { bool match = true; if (r1.m_valid != m_valid) match = false; if (r1.m_x != m_x) match = false; if (r1.m_y != m_y) match = false; if (r1.m_w != m_w) match = false; if (r1.m_h != m_h) match = false; return match; } 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: TraceLabelLayout(TraceWidget *traceWidget, TQWidget *parent, int spacing=-1) : TQLayout(parent, 0, spacing), m_traceWidget(traceWidget) { // } TraceLabelLayout(TraceWidget *traceWidget, TQLayout* parent, int spacing=-1) : TQLayout(parent, spacing), m_traceWidget(traceWidget) { // } TraceLabelLayout(TraceWidget *traceWidget, int spacing=-1) : TQLayout(spacing), m_traceWidget(traceWidget) { // } ~TraceLabelLayout(); void addItem(TQLayoutItem *item); void addWidget(TQWidget *w, int alignment); TQSize sizeHint() const; TQSize minimumSize() const; TQLayoutIterator iterator(); void setGeometry(const TQRect &rect); virtual void invalidate(); private: TQPtrList list; TraceWidget* m_traceWidget; }; class TraceLabelLayoutIterator : public TQGLayoutIterator { public: TraceLabelLayoutIterator( TQPtrList *l ) : idx(0), list(l) { // } TQLayoutItem *current() { return idx < int(list->count()) ? list->at(idx) : 0; } TQLayoutItem *next() { idx++; return current(); } TQLayoutItem *takeCurrent() { return list->take(idx); } private: int idx; TQPtrList *list; }; TQLayoutIterator TraceLabelLayout::iterator() { return TQLayoutIterator(new TraceLabelLayoutIterator(&list)); } void TraceLabelLayout::addItem(TQLayoutItem *item) { list.append( item ); } void TraceLabelLayout::addWidget(TQWidget *w, int alignment) { if (!w) { return; } TQWidgetItem *b = new TQWidgetItem(w); b->setAlignment(alignment); addItem( b ); } TraceLabelLayout::~TraceLabelLayout() { deleteAllItems(); } void TraceLabelLayout::setGeometry(const TQRect &rect) { TQLayout::setGeometry(rect); TQPtrListIterator it(list); if (it.count() == 0) { return; } TQLayoutItem *item; while ((item = it.current()) != 0) { ++it; TQWidgetItem *widgetItem = dynamic_cast(item); if (!widgetItem) { continue; } TQWidget* widget = widgetItem->widget(); if (!widget) { continue; } // Find the trace number const TraceData* currentTrace = NULL; for (uint trace=0;tracem_traceArray.count();trace++) { if (m_traceWidget->m_traceArray[trace]->leftLabel == widget) { currentTrace = m_traceWidget->m_traceArray[trace]; break; } } TQFontMetrics fm(currentTrace->leftLabel->font()); int font_height = fm.boundingRect(currentTrace->leftLabel->text()).height(); int font_vertical_offset = font_height/2; int graticule_height = m_traceWidget->m_graticuleWidget->height(); int y = ((((currentTrace->offset+currentTrace->textOffset)-currentTrace->topEdge)/(currentTrace->bottomEdge-currentTrace->topEdge))*(graticule_height))-font_vertical_offset; if (m_traceWidget->m_showLeftTraceInfoArea) { if ((y < 0) || ((y+font_height) > graticule_height)) { currentTrace->leftLabel->hide(); item->setGeometry(TQRect(0, 0, rect.width(), currentTrace->leftLabel->sizeHint().height())); } else { item->setGeometry(TQRect(0, y, rect.width(), currentTrace->leftLabel->sizeHint().height())); currentTrace->leftLabel->show(); } } else { currentTrace->leftLabel->hide(); } } } void TraceLabelLayout::invalidate() { setGeometry(geometry()); } TQSize TraceLabelLayout::sizeHint() const { TQSize size; if (!m_traceWidget->m_showLeftTraceInfoArea) { return TQSize(0, 0); } TQSize s(0, 0); TQPtrListIterator it( list ); TQLayoutItem *item; while ((item = it.current()) != 0) { ++it; s = s.expandedTo(item->sizeHint()); } size = s + TQSize(spacing(), spacing()); if (m_traceWidget->m_leftTraceInfoLabelsFit && list.getFirst()) { return TQSize(size.width(), ((list.getFirst()->sizeHint().height() + m_traceWidget->m_leftTraceInfoAreaFitSpacing) * list.count())); } else { return size; } } TQSize TraceLabelLayout::minimumSize() const { TQSize minSize; if (!m_traceWidget->m_showLeftTraceInfoArea) { return TQSize(0, 0); } TQSize s(0, 0); TQPtrListIterator it(list); TQLayoutItem *item; while ((item = it.current()) != 0) { ++it; s = s.expandedTo(item->minimumSize()); } minSize = s + TQSize(spacing(), spacing()); if (m_traceWidget->m_leftTraceInfoLabelsFit && list.getFirst()) { return TQSize(minSize.width(), ((list.getFirst()->minimumSize().height()+ m_traceWidget->m_leftTraceInfoAreaFitSpacing) * list.count())); } else { return minSize; } } class TraceCursorLabelLayout : public TQLayout { public: TraceCursorLabelLayout(TraceWidget *traceWidget, TQWidget *parent, int spacing=-1) : TQLayout(parent, 0, spacing), m_traceWidget(traceWidget) { // } TraceCursorLabelLayout(TraceWidget *traceWidget, TQLayout* parent, int spacing=-1) : TQLayout(parent, spacing), m_traceWidget(traceWidget) { // } TraceCursorLabelLayout(TraceWidget *traceWidget, int spacing=-1) : TQLayout(spacing), m_traceWidget(traceWidget) { // } ~TraceCursorLabelLayout(); void addItem(TQLayoutItem *item); void addWidget(TQWidget *w, int alignment); TQSize sizeHint() const; TQSize minimumSize() const; TQLayoutIterator iterator(); void setGeometry(const TQRect &rect); virtual void invalidate(); private: TQPtrList list; TraceWidget* m_traceWidget; }; class TraceCursorLabelLayoutIterator : public TQGLayoutIterator { public: TraceCursorLabelLayoutIterator( TQPtrList *l ) : idx(0), list(l) { // } TQLayoutItem *current() { return idx < int(list->count()) ? list->at(idx) : 0; } TQLayoutItem *next() { idx++; return current(); } TQLayoutItem *takeCurrent() { return list->take(idx); } private: int idx; TQPtrList *list; }; TQLayoutIterator TraceCursorLabelLayout::iterator() { return TQLayoutIterator(new TraceCursorLabelLayoutIterator(&list)); } void TraceCursorLabelLayout::addItem(TQLayoutItem *item) { list.append( item ); } void TraceCursorLabelLayout::addWidget(TQWidget *w, int alignment) { if (!w) { return; } TQWidgetItem *b = new TQWidgetItem(w); b->setAlignment(alignment); addItem( b ); } TraceCursorLabelLayout::~TraceCursorLabelLayout() { deleteAllItems(); } void TraceCursorLabelLayout::setGeometry(const TQRect &rect) { TQLayout::setGeometry(rect); TQPtrListIterator it(list); if (it.count() == 0) { return; } TQLayoutItem *item; while ((item = it.current()) != 0) { ++it; TQWidgetItem *widgetItem = dynamic_cast(item); if (!widgetItem) { continue; } TQWidget* widget = widgetItem->widget(); if (!widget) { continue; } // Find the trace number const TraceData* currentTrace = NULL; for (uint trace=0;tracem_traceArray.count();trace++) { if (m_traceWidget->m_traceArray[trace]->leftCursorLabel == widget) { currentTrace = m_traceWidget->m_traceArray[trace]; break; } } TQFontMetrics fm(currentTrace->leftCursorLabel->font()); int font_height = fm.boundingRect(currentTrace->leftCursorLabel->text()).height(); int font_vertical_offset = font_height/2; int graticule_height = m_traceWidget->m_graticuleWidget->height(); int y = ((((currentTrace->offset+currentTrace->textOffset)-currentTrace->topEdge)/(currentTrace->bottomEdge-currentTrace->topEdge))*(graticule_height))-font_vertical_offset; if (m_traceWidget->m_showLeftTraceInfoArea) { if ((y < 0) || ((y+font_height) > graticule_height)) { currentTrace->leftCursorLabel->hide(); item->setGeometry(TQRect(rect.x(), 0, rect.width(), currentTrace->leftCursorLabel->sizeHint().height())); } else { item->setGeometry(TQRect(rect.x(), y, rect.width(), currentTrace->leftCursorLabel->sizeHint().height())); currentTrace->leftCursorLabel->show(); } } else { currentTrace->leftCursorLabel->hide(); } } } void TraceCursorLabelLayout::invalidate() { setGeometry(geometry()); } TQSize TraceCursorLabelLayout::sizeHint() const { TQSize size; if (!m_traceWidget->m_showLeftTraceInfoArea) { return TQSize(0, 0); } TQSize s(0, 0); TQPtrListIterator it( list ); TQLayoutItem *item; while ((item = it.current()) != 0) { ++it; s = s.expandedTo(item->sizeHint()); } size = s + TQSize(spacing(), spacing()); if (m_traceWidget->m_leftTraceInfoLabelsFit && list.getFirst()) { return TQSize(size.width(), ((list.getFirst()->sizeHint().height() + m_traceWidget->m_leftTraceInfoAreaFitSpacing) * list.count())); } else { return size; } } TQSize TraceCursorLabelLayout::minimumSize() const { TQSize minSize; if (!m_traceWidget->m_showLeftTraceInfoArea) { return TQSize(0, 0); } TQSize s(0, 0); TQPtrListIterator it(list); TQLayoutItem *item; while ((item = it.current()) != 0) { ++it; s = s.expandedTo(item->minimumSize()); } minSize = s + TQSize(spacing(), spacing()); if (m_traceWidget->m_leftTraceInfoLabelsFit && list.getFirst()) { return TQSize(minSize.width(), ((list.getFirst()->minimumSize().height()+ m_traceWidget->m_leftTraceInfoAreaFitSpacing) * list.count())); } else { return minSize; } } TraceData::TraceData(TraceWidget* parent, TQWidget* labelParent) : TQObject(), parentWidget(parent) { color = TQColor(0, 255, 0); numberOfSamples = 0; sampleMax = 0; sampleMin = 0; sampleAverage = 0; leftEdgeIndex = -1; rightEdgeIndex = -1; offset = 0.0; textOffset = 0.0; leftEdge = 0; rightEdge = 0; topEdge = 0; bottomEdge = 0; traceName = i18n("Unknown"); horizontalUnits = i18n("Units"); verticalUnits = i18n("Units"); m_digitalTraceDrawing = false; m_digitalShaderDarkness = DIGITAL_SHADING_DARKNESS_FACTOR; m_suppressNameInCursorText = false; enabled = false; if (labelParent) { paramLabel = new TQLabel(labelParent); paramLabel->setPaletteBackgroundColor(labelParent->paletteBackgroundColor()); paramLabel->setPaletteForegroundColor(color); paramLabel->setAlignment(TQt::AlignHCenter|TQt::AlignVCenter|TQt::SingleLine); TQFont font; font = paramLabel->font(); font.setPointSize(font.pointSize()-1); paramLabel->setFont(font); paramLabel->hide(); leftLabel = new TQLabel(labelParent); leftLabel->setPaletteBackgroundColor(labelParent->paletteBackgroundColor()); leftLabel->setPaletteForegroundColor(color); leftLabel->setAlignment(TQt::AlignLeft|TQt::AlignVCenter|TQt::SingleLine); font = leftLabel->font(); font.setPointSize(font.pointSize()-1); leftLabel->setFont(font); leftLabel->setText(""); leftLabel->hide(); leftCursorLabel = new TQLabel(labelParent); leftCursorLabel->setPaletteBackgroundColor(labelParent->paletteBackgroundColor()); leftCursorLabel->setPaletteForegroundColor(color); leftCursorLabel->setAlignment(TQt::AlignLeft|TQt::AlignVCenter|TQt::SingleLine); font = leftCursorLabel->font(); font.setPointSize(font.pointSize()-1); leftCursorLabel->setFont(font); leftCursorLabel->setText(""); leftCursorLabel->hide(); graphStatusLabel = new TQLabel(labelParent); graphStatusLabel->setPaletteBackgroundColor(labelParent->paletteBackgroundColor()); graphStatusLabel->setPaletteForegroundColor(color); graphStatusLabel->setAlignment(TQt::AlignHCenter|TQt::AlignVCenter|TQt::SingleLine); font = graphStatusLabel->font(); font.setPointSize(font.pointSize()-1); graphStatusLabel->setFont(font); graphStatusLabel->setText(""); graphStatusLabel->hide(); graphStatusLabelInner = new TQLabel(labelParent); graphStatusLabelInner->setPaletteBackgroundColor(labelParent->paletteBackgroundColor()); graphStatusLabelInner->setPaletteForegroundColor(color); graphStatusLabelInner->setAlignment(TQt::AlignHCenter|TQt::AlignVCenter|TQt::SingleLine); font = graphStatusLabelInner->font(); font.setPointSize(font.pointSize()-1); graphStatusLabelInner->setFont(font); graphStatusLabelInner->setText(""); graphStatusLabelInner->hide(); singleIncrBtn = new TQToolButton(TQt::UpArrow, labelParent); singleDecrBtn = new TQToolButton(TQt::DownArrow, labelParent); posResetBtn = new TQToolButton(labelParent); posResetBtn->setText("0"); posSetBtn = new TQToolButton(labelParent); posSetBtn->setText("M"); singleIncrBtn->setFixedSize(16,16); singleDecrBtn->setFixedSize(16,16); posResetBtn->setFixedSize(16,16); posSetBtn->setFixedSize(16,16); singleIncrBtn->setAutoRepeat(true); singleDecrBtn->setAutoRepeat(true); posResetBtn->setAutoRepeat(false); posSetBtn->setAutoRepeat(false); singleIncrBtn->setSizePolicy(TQSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed)); singleDecrBtn->setSizePolicy(TQSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed)); posResetBtn->setSizePolicy(TQSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed)); posSetBtn->setSizePolicy(TQSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed)); singleIncrBtn->setPaletteBackgroundColor(labelParent->paletteBackgroundColor()); singleIncrBtn->setPaletteForegroundColor(color); singleDecrBtn->setPaletteBackgroundColor(labelParent->paletteBackgroundColor()); singleDecrBtn->setPaletteForegroundColor(color); posResetBtn->setPaletteBackgroundColor(labelParent->paletteBackgroundColor()); posResetBtn->setPaletteForegroundColor(color); posSetBtn->setPaletteBackgroundColor(labelParent->paletteBackgroundColor()); posSetBtn->setPaletteForegroundColor(color); singleIncrBtn->hide(); singleDecrBtn->hide(); posResetBtn->hide(); posSetBtn->hide(); connect(singleIncrBtn, SIGNAL(clicked()), this, SLOT(movePosOneTick())); connect(singleDecrBtn, SIGNAL(clicked()), this, SLOT(moveNegOneTick())); connect(posResetBtn, SIGNAL(clicked()), this, SLOT(resetVPosition())); connect(posSetBtn, SIGNAL(clicked()), this, SLOT(setVPosition())); } else { paramLabel = NULL; leftLabel = NULL; leftCursorLabel = NULL; graphStatusLabel = NULL; graphStatusLabelInner = NULL; singleIncrBtn = NULL; singleDecrBtn = NULL; posResetBtn = NULL; posSetBtn = NULL; } } TraceData::~TraceData() { // } void TraceData::drawTrace(TQPainter* p, int graticule_width, int graticule_height, int virtual_width, int virtual_height) { p->save(); p->setPen(color); if ((bottomEdge != topEdge) && (enabled) && (positionArray.count() >= numberOfSamples) && (sampleArray.count() >= numberOfSamples) && (numberOfSamples > 0)) { // Draw the points unsigned int n; unsigned int incr; unsigned int activeSamples; int x,y,x2,y2,baseline,horizoffset; // Obtain horizontal scrolling offset horizoffset = parentWidget->horizScrollOffset(); // Determine how many samples are actually being displayed if ((leftEdgeIndex < 0) || (rightEdgeIndex < 0)) { for (n=0; n= 0) { leftEdgeIndex = n; } } else { if (x >= virtual_width) { rightEdgeIndex = n; break; } } } if (rightEdgeIndex < 0) { rightEdgeIndex = numberOfSamples-1; } } activeSamples = abs(rightEdgeIndex-leftEdgeIndex); incr = (activeSamples/virtual_width)+1; for (n=leftEdgeIndex; n graticule_width) && (x2 > graticule_width)) continue; if ((y > graticule_height) && (y2 > graticule_height)) continue; // Clip lines to screen borders if (x < (0-horizoffset)) x = (0-horizoffset); if (x > (virtual_width-horizoffset)) x = (virtual_width-horizoffset); if (y < 0) y = 0; if (y > virtual_height) y = virtual_height; if (x2 < (0-horizoffset)) x2 = (0-horizoffset); if (x2 > (virtual_width-horizoffset)) x2 = (virtual_width-horizoffset); if (y2 < 0) y2 = 0; if (y2 > virtual_height) y2 = virtual_height; if (baseline < 0) baseline = 0; if (baseline > virtual_height) baseline = virtual_height; // Draw line(s)! if (m_digitalTraceDrawing) { p->drawLine(x+1, y, x2-1, y); p->drawLine(x2-1, y, x2+1, y2); // Draw fill areas if ((sampleArray[n] != 0) && (sampleArray[n+1] != 0)) { p->save(); p->fillRect(x+1, y+1, x2-x, baseline-y, TQBrush(color.dark(m_digitalShaderDarkness))); p->restore(); } else if ((sampleArray[n] != 0) && (sampleArray[n+1] == 0)) { p->save(); // Fill sloping edges p->setPen(color.dark(m_digitalShaderDarkness)); 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, TQBrush(color.dark(m_digitalShaderDarkness))); p->restore(); } else if ((sampleArray[n] == 0) && (sampleArray[n+1] != 0)) { p->save(); // Fill sloping edges p->setPen(color.dark(m_digitalShaderDarkness)); p->drawLine(x2+1, y+1, x2+3, y2-1); p->drawLine(x2, y+1, x2+2, y2-1); p->restore(); } } else { p->drawLine(x, y, x2, y2); } } // Draw the zero level indicator int pixel_size = 20; TQFont painterFont = p->font(); painterFont.setFamily("Monospace"); painterFont.setPixelSize(pixel_size); p->setFont(painterFont); int font_vertical_offset = pixel_size/5; int font_height = p->fontMetrics().boundingRect("→").height(); x = 0; y = ((((offset+textOffset)-topEdge)/(bottomEdge-topEdge))*(graticule_height))+(font_height/2)-(font_vertical_offset/2); if (y > graticule_height) { font_height = p->fontMetrics().boundingRect("↓").height(); y = graticule_height-font_vertical_offset; p->drawText(x, y, trUtf8("↓")); } else if (y < 0) { font_height = p->fontMetrics().boundingRect("↑").height(); y = font_height-font_vertical_offset; p->drawText(x, y, trUtf8("↑")); } else { p->drawText(x, y, trUtf8("→")); } } p->restore(); } void TraceData::movePosOneTick() { double increment; increment = (bottomEdge-topEdge)/parentWidget->m_graticuleWidget->height(); offset -= increment; emit(offsetChanged(offset)); parentWidget->updateTraceText(); parentWidget->updateCursorText(); parentWidget->m_graticuleWidget->repaint(false); } void TraceData::moveNegOneTick() { double increment; increment = (bottomEdge-topEdge)/parentWidget->m_graticuleWidget->height(); offset += increment; emit(offsetChanged(offset)); parentWidget->updateTraceText(); parentWidget->updateCursorText(); parentWidget->m_graticuleWidget->repaint(false); } void TraceData::resetVPosition() { offset = 0.0; emit(offsetChanged(offset)); parentWidget->updateTraceText(); parentWidget->updateCursorText(); parentWidget->m_graticuleWidget->repaint(false); } void TraceData::setVPosition() { bool ok; double newoffset; ok = false; newoffset = KInputDialog::getDouble(i18n("Set Trace Offset"), i18n("New offset for %1 (%2):").arg(traceName).arg(verticalUnits), offset, double(INT_MIN), double(INT_MAX), 0.1, 1, &ok, parentWidget); if (ok) { offset = newoffset; emit(offsetChanged(offset)); parentWidget->updateTraceText(); parentWidget->updateCursorText(); parentWidget->m_graticuleWidget->repaint(false); } } CursorData::CursorData(TraceWidget* parent, TQWidget* labelParent) : TQObject(), parentWidget(parent) { color = TQColor(0, 255, 0); highlightColor = TQColor(192, 255, 192); highlighted = false; enabled = false; orientation = TQt::Vertical; position = 50; cursorName = i18n("Cursor "); if (labelParent) { paramLabel = new TQLabel(labelParent); paramLabel->setPaletteBackgroundColor(labelParent->paletteBackgroundColor()); paramLabel->setPaletteForegroundColor(color); paramLabel->setAlignment(TQt::AlignHCenter|TQt::AlignVCenter|TQt::SingleLine); TQFont font; font = paramLabel->font(); font.setPointSize(font.pointSize()-1); paramLabel->setFont(font); paramLabel->hide(); 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); singleDecrBtn->setFont(font); multiIncrBtn->setFont(font); multiDecrBtn->setFont(font); singleIncrBtn->setText("+"); singleDecrBtn->setText("-"); multiIncrBtn->setText("++"); multiDecrBtn->setText("--"); singleIncrBtn->setAutoRepeat(true); singleDecrBtn->setAutoRepeat(true); multiIncrBtn->setAutoRepeat(true); multiDecrBtn->setAutoRepeat(true); singleIncrBtn->setSizePolicy(TQSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed)); singleDecrBtn->setSizePolicy(TQSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed)); multiIncrBtn->setSizePolicy(TQSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed)); multiDecrBtn->setSizePolicy(TQSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Fixed)); singleIncrBtn->setPaletteBackgroundColor(labelParent->paletteBackgroundColor()); singleIncrBtn->setPaletteForegroundColor(color); singleDecrBtn->setPaletteBackgroundColor(labelParent->paletteBackgroundColor()); singleDecrBtn->setPaletteForegroundColor(color); multiIncrBtn->setPaletteBackgroundColor(labelParent->paletteBackgroundColor()); multiIncrBtn->setPaletteForegroundColor(color); multiDecrBtn->setPaletteBackgroundColor(labelParent->paletteBackgroundColor()); multiDecrBtn->setPaletteForegroundColor(color); singleIncrBtn->hide(); singleDecrBtn->hide(); multiIncrBtn->hide(); multiDecrBtn->hide(); paramLabel->installEventFilter(this); singleIncrBtn->installEventFilter(this); singleDecrBtn->installEventFilter(this); multiIncrBtn->installEventFilter(this); multiDecrBtn->installEventFilter(this); connect(singleIncrBtn, SIGNAL(clicked()), this, SLOT(movePosOneTick())); connect(singleDecrBtn, SIGNAL(clicked()), this, SLOT(moveNegOneTick())); connect(multiIncrBtn, SIGNAL(clicked()), this, SLOT(movePosMultiTicks())); connect(multiDecrBtn, SIGNAL(clicked()), this, SLOT(moveNegMultiTicks())); } else { paramLabel = NULL; singleIncrBtn = NULL; singleDecrBtn = NULL; multiIncrBtn = NULL; multiDecrBtn = NULL; } } CursorData::~CursorData() { // } void CursorData::drawCursor(TQPainter* p, int graticule_width, int graticule_height, int virtual_width, int virtual_height, int offset) { if (enabled) { if (highlighted) { p->setPen(highlightColor.dark(parentWidget->m_cursorDarkness)); } else { p->setPen(color.dark(parentWidget->m_cursorDarkness)); } if (orientation == TQt::Vertical) { int x = (abs(((position)/(100.0))*(virtual_width))-offset); if ((x >= 0) && (x < graticule_width)) { p->drawLine(x, 0, x, graticule_height); } } else { int y = abs(((position)/(100.0))*(virtual_height)); p->drawLine(0, y, graticule_width, y); } } } void CursorData::movePosOneTick() { double increment; if (orientation == TQt::Horizontal) { increment = 100.0/parentWidget->m_graticuleWidget->height(); } else { increment = 100.0/parentWidget->m_graticuleWidget->virtualWidth(); } if (orientation == TQt::Horizontal) { position -= increment; } else { position += increment; } if (position < 0.0) position = 0.0; if (position > 100.0) position = 100.0; emit(positionChanged(position)); parentWidget->updateCursorText(); parentWidget->m_graticuleWidget->updateGraticule(); parentWidget->m_graticuleWidget->repaint(false); } void CursorData::moveNegOneTick() { double increment; if (orientation == TQt::Horizontal) { increment = 100.0/parentWidget->m_graticuleWidget->height(); } else { increment = 100.0/parentWidget->m_graticuleWidget->virtualWidth(); } if (orientation == TQt::Horizontal) { position += increment; } else { position -= increment; } if (position < 0.0) position = 0.0; if (position > 100.0) position = 100.0; emit(positionChanged(position)); parentWidget->updateCursorText(); parentWidget->m_graticuleWidget->updateGraticule(); parentWidget->m_graticuleWidget->repaint(false); } void CursorData::movePosMultiTicks() { double increment; if (orientation == TQt::Horizontal) { increment = 100.0/parentWidget->m_graticuleWidget->height(); } else { increment = 100.0/parentWidget->m_graticuleWidget->virtualWidth(); } if (orientation == TQt::Horizontal) { position -= (increment*10.0); } else { position += (increment*10.0); } if (position < 0.0) position = 0.0; if (position > 100.0) position = 100.0; emit(positionChanged(position)); parentWidget->updateCursorText(); parentWidget->m_graticuleWidget->updateGraticule(); parentWidget->m_graticuleWidget->repaint(false); } void CursorData::moveNegMultiTicks() { double increment; if (orientation == TQt::Horizontal) { increment = 100.0/parentWidget->m_graticuleWidget->height(); } else { increment = 100.0/parentWidget->m_graticuleWidget->virtualWidth(); } if (orientation == TQt::Horizontal) { position += (increment*10.0); } else { position -= (increment*10.0); } if (position < 0.0) position = 0.0; if (position > 100.0) position = 100.0; emit(positionChanged(position)); parentWidget->updateCursorText(); parentWidget->m_graticuleWidget->updateGraticule(); parentWidget->m_graticuleWidget->repaint(false); } bool CursorData::eventFilter(TQObject *o, TQEvent *e) { // Intercept mouse entry/leave events for cursor labels and movement buttons if ((o == paramLabel) || (o == singleIncrBtn) || (o == singleDecrBtn) || (o == multiIncrBtn) || (o == multiDecrBtn)) { if (e->type() == TQEvent::Enter) { highlighted = true; parentWidget->updateCursorText(); parentWidget->m_graticuleWidget->updateGraticule(); parentWidget->m_graticuleWidget->repaint(false); } if (e->type() == TQEvent::Leave) { highlighted = false; parentWidget->updateCursorText(); parentWidget->m_graticuleWidget->updateGraticule(); parentWidget->m_graticuleWidget->repaint(false); } } // Allow event processing by other routines return FALSE; } GraticuleWidget::GraticuleWidget(TraceWidget* parent, const char* name) : TQWidget(parent, name), m_base(parent), m_graticulePixmap(0), m_prevWidgetWidth(-1), m_virtualWidth(0), m_leftMouseDown(false), m_middleMouseDown(false), m_closestCursor(-1), m_closestCursorDistance(-1), m_movingCursor(-1) { setBackgroundMode(NoBackground); setSizePolicy(TQSizePolicy(TQSizePolicy::MinimumExpanding, TQSizePolicy::MinimumExpanding)); setPaletteBackgroundColor(TQt::black); setPaletteForegroundColor(TQColor(0,128,0)); setMouseTracking(true); setCursor(tqcrossCursor); } GraticuleWidget::~GraticuleWidget() { // } TQSizePolicy GraticuleWidget::sizePolicy() const { return TQSizePolicy(TQSizePolicy::MinimumExpanding, TQSizePolicy::MinimumExpanding, true, true); } int GraticuleWidget::virtualWidth() { int widgetWidth = width(); if (widgetWidth != m_prevWidgetWidth) { m_virtualWidth = widgetWidth; int minimumHorizWidth = m_base->m_horizDivs * m_base->m_minimumPixelsPerHorizDiv; if (m_virtualWidth < minimumHorizWidth) { m_virtualWidth = minimumHorizWidth; } if (m_base->m_horizScrollBar) { int offScreenPixels = m_virtualWidth - widgetWidth; if (offScreenPixels > 0) { m_base->m_horizScrollBar->setMinValue(0); m_base->m_horizScrollBar->setMaxValue(offScreenPixels); m_base->m_horizScrollBar->show(); } else { m_base->m_horizScrollBar->hide(); m_base->m_horizScrollBar->setMinValue(0); m_base->m_horizScrollBar->setMaxValue(0); } } } return m_virtualWidth; } void GraticuleWidget::horizScrollValueChanged(int) { updateGraticule(); repaint(false); } void GraticuleWidget::updateGraticule() { unsigned int d,s,x,y; int rx; if (m_graticulePixmap) { delete m_graticulePixmap; } m_graticulePixmap = new TQPixmap(width(), height()); // Draw the graticule into the pixmap TQPainter p(m_graticulePixmap); p.setPen(TQPen(foregroundColor(), 1, TQt::SolidLine)); p.fillRect(0, 0, m_graticulePixmap->width(), m_graticulePixmap->height(), backgroundColor()); p.setPen(TQPen(foregroundColor(), 1, TQt::DotLine)); if (m_base->m_horizDivs > 0) { s = virtualWidth() / m_base->m_horizDivs; x = 0; for (d=0; dm_horizDivs; d++) { rx = x - m_base->horizScrollOffset(); if ((rx >= 0) && (rx < m_graticulePixmap->width())) { p.drawLine(rx, 0, rx, m_graticulePixmap->height()); } x += s; } } if (m_base->m_vertDivs > 0) { s = m_graticulePixmap->height() / m_base->m_vertDivs; y = 0; for (d=0; dm_vertDivs; d++) { p.drawLine(0, y, m_graticulePixmap->width(), y); y += s; } } p.setPen(TQPen(foregroundColor(), 1, TQt::SolidLine)); p.drawRect(0, 0, m_graticulePixmap->width(), m_graticulePixmap->height()); // If there are 4 or more cursors, lightly shade the area returned by ZoomBox TQRectF zoomBox = m_base->zoomBox(); if (!zoomBox.isNull()) { // Translate zoombox coordinates to local drawing coordinates TQRect drawingRect(abs(((zoomBox.x())/(100.0))*(virtualWidth()))-m_base->horizScrollOffset(), abs(((zoomBox.y())/(100.0))*(height())), abs(((zoomBox.width())/(100.0))*(virtualWidth())), abs(((zoomBox.height())/(100.0))*(height()))); p.fillRect(drawingRect, TQBrush(foregroundColor().dark(m_base->m_zoomBoxDarkness), TQt::BDiagPattern)); } // Repaint the widget repaint(false); } void GraticuleWidget::paintEvent(TQPaintEvent*) { // Paint onto background pixmap before painting to window to reduce flickering TQPixmap updatePixmap(width(), height()); TQPainter p(&updatePixmap); if (m_graticulePixmap) { // Draw the graticule pixmap to erase the widget p.drawPixmap(0, 0, *m_graticulePixmap); // Draw the traces for (uint trace=0;tracem_traceArray.count();trace++) { m_base->m_traceArray[trace]->drawTrace(&p, m_graticulePixmap->width(), m_graticulePixmap->height(), virtualWidth(), m_graticulePixmap->height()); } // Draw the cursors for (uint cursor=0;cursorm_cursorArray.count();cursor++) { m_base->m_cursorArray[cursor]->drawCursor(&p, m_graticulePixmap->width(), m_graticulePixmap->height(), virtualWidth(), m_graticulePixmap->height(), ((m_base->m_cursorArray[cursor]->orientation == TQt::Vertical)?m_base->horizScrollOffset():0)); } } else { p.fillRect(x(), y(), virtualWidth(), height(), backgroundColor()); } p.end(); // Paint to window bitBlt(this, 0, 0, &updatePixmap, 0, 0, updatePixmap.width(), updatePixmap.height(), TQt::CopyROP); } void GraticuleWidget::resizeEvent(TQResizeEvent *) { updateGraticule(); } void GraticuleWidget::mousePressEvent(TQMouseEvent *e) { if ((e->button() == TQt::LeftButton) && (!m_leftMouseDown) && (!m_middleMouseDown)) { if (m_closestCursorDistance <= CURSOR_MOVE_CAPTURE_DISTANCE) { m_prevDownPos = e->pos(); m_movingCursor = m_closestCursor; m_prevCursorPos = m_base->m_cursorArray[m_movingCursor]->position; m_leftMouseDown = true; } else { m_prevCursorRect = m_base->zoomCursorBox(); if (m_base->m_zoomBoxEnabled || m_base->m_horizCursorDirectClickEnabled) { m_leftMouseDown = true; m_prevDownPos = e->pos(); } } } else if ((e->button() == TQt::MidButton) && (!m_leftMouseDown) && (!m_middleMouseDown)) { m_prevCursorRect = m_base->zoomCursorBox(); if (m_base->m_zoomBoxEnabled) { m_middleMouseDown = true; m_prevDownPos = e->pos(); setCursor(tqsizeAllCursor); } } } void GraticuleWidget::mouseReleaseEvent(TQMouseEvent *e) { if (m_leftMouseDown) { if (e->button() == TQt::LeftButton) { m_leftMouseDown = false; if (m_movingCursor >= 0) { TQPoint diff = e->pos() - m_prevDownPos; double dx = diff.x()*(100.0/virtualWidth()); double dy = diff.y()*(100.0/height()); if (m_base->m_cursorArray[m_movingCursor]->orientation == TQt::Horizontal) { m_base->m_cursorArray[m_movingCursor]->position = m_prevCursorPos+dy; } else { m_base->m_cursorArray[m_movingCursor]->position = m_prevCursorPos+dx; } if (m_base->m_cursorArray[m_movingCursor]->position < 0.0) { m_base->m_cursorArray[m_movingCursor]->position = 0.0; } if (m_base->m_cursorArray[m_movingCursor]->position > 100.0) { m_base->m_cursorArray[m_movingCursor]->position = 100.0; } emit(cursorPositionChanged(m_movingCursor, m_base->m_cursorArray[m_movingCursor]->position)); m_movingCursor = -1; updateGraticule(); repaint(false); } else { double x1 = m_prevDownPos.x(); double y1 = m_prevDownPos.y(); double x2 = e->x(); double y2 = e->y(); double pixelDiffX = fabs(x1-x2); double pixelDiffY = fabs(y1-y2); 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); x2 = ((x2/virtualWidth())*100.0); m_base->setCursorPosition(0, x1); m_base->setCursorPosition(1, x2); } } } } else if (m_middleMouseDown) { if (e->button() == TQt::MidButton) { m_middleMouseDown = false; double x1 = m_prevDownPos.x()+m_base->horizScrollOffset(); double y1 = m_prevDownPos.y(); double x2 = e->x()+m_base->horizScrollOffset(); double y2 = e->y(); if ((x1 < virtualWidth()) && (y1 < height()) && (x2 < virtualWidth()) && (y2 < height()) && (x1 > 0) && (y1 > 0) && (x2 > 0) && (y2 > 0)) { TQPoint diff = e->pos() - m_prevDownPos; double dx = diff.x()*(100.0/virtualWidth()); double dy = diff.y()*(100.0/height()); m_base->setZoomCursorBox(TQRectF(m_prevCursorRect.x()+dx, m_prevCursorRect.y()+dy, m_prevCursorRect.width()+dx, m_prevCursorRect.height()+dy)); } else { // Reset original zoom box m_base->setZoomCursorBox(m_prevCursorRect); } setCursor(tqcrossCursor); } } updateGraticule(); repaint(false); } void GraticuleWidget::mouseDoubleClickEvent(TQMouseEvent *) { // } void GraticuleWidget::mouseMoveEvent(TQMouseEvent *e) { // If we are within X pixels of a cursor, change icon to appopriate drag arrows and set up to drag the cursor instead of replacing the zoom box // Replacing the zoom box might need to be assigned to the right mouse button... bool cursorHighlightChanged = false; m_closestCursor = -1; 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; if (m_base->m_cursorArray[cursor]->orientation == TQt::Horizontal) { pixelDistance = (fabs(m_base->m_cursorArray[cursor]->position - scaledYPos)*height())/100.0; if (pixelDistance < m_closestCursorDistance) { m_closestCursorDistance = pixelDistance; m_closestCursor = cursor; } } else { pixelDistance = (fabs(m_base->m_cursorArray[cursor]->position - scaledXPos)*virtualWidth())/100.0; if (pixelDistance < m_closestCursorDistance) { m_closestCursorDistance = pixelDistance; m_closestCursor = cursor; } } // Ensure previous highlighting is cleared // This is needed when two cursors are placed right next to one another if (m_base->m_cursorArray[m_closestCursor]->highlighted) { cursorHighlightChanged = true; } m_base->m_cursorArray[cursor]->highlighted = false; } if (m_closestCursor >= 0) { if (m_closestCursorDistance <= CURSOR_MOVE_CAPTURE_DISTANCE) { if (m_base->m_cursorArray[m_closestCursor]->orientation == TQt::Horizontal) { setCursor(tqsizeVerCursor); } else { setCursor(tqsizeHorCursor); } if (!m_base->m_cursorArray[m_closestCursor]->highlighted) { cursorHighlightChanged = true; } m_base->m_cursorArray[m_closestCursor]->highlighted = true; } else { setCursor(tqcrossCursor); if (m_base->m_cursorArray[m_closestCursor]->highlighted) { cursorHighlightChanged = true; } m_base->m_cursorArray[m_closestCursor]->highlighted = false; } } else { setCursor(tqcrossCursor); } } // Print current cursor location for all traces if ((e->x() < virtualWidth()) && (e->y() < height())) { for (uint trace=0;tracem_traceArray.count();trace++) { // Calculate location double scaledYPos = (e->y()*100.0)/height(); double scaledXPos = (e->x()*100.0)/virtualWidth(); double horizontal_range = (m_base->m_traceArray[trace]->rightEdge-m_base->m_traceArray[trace]->leftEdge); double vertical_range = (m_base->m_traceArray[trace]->bottomEdge-m_base->m_traceArray[trace]->topEdge); double realCursorYPosition = (m_base->m_traceArray[trace]->topEdge+((scaledYPos/100.0)*vertical_range)-m_base->m_traceArray[trace]->offset); double realCursorXPosition = (m_base->m_traceArray[trace]->leftEdge+((scaledXPos/100.0)*horizontal_range)); #if 0 m_base->m_traceArray[trace]->graphStatusLabel->setText(TQString("%1
@%2,%3
").arg(m_base->m_traceArray[trace]->traceName).arg(TraceWidget::prettyFormat(realCursorXPosition, horizontal_range, m_base->m_traceArray[trace]->horizontalUnits)).arg(TraceWidget::prettyFormat(realCursorYPosition, vertical_range, m_base->m_traceArray[trace]->verticalUnits))); #else m_base->m_traceArray[trace]->graphStatusLabel->setText(TQString("@%2,%3").arg(TraceWidget::prettyFormat(realCursorXPosition, (m_base->m_useAbsoluteHorizontalRange)?m_base->m_traceArray[trace]->rightEdge:horizontal_range, m_base->m_traceArray[trace]->horizontalUnits)).arg(TraceWidget::prettyFormat(realCursorYPosition, vertical_range, m_base->m_traceArray[trace]->verticalUnits))); #endif m_base->m_traceArray[trace]->graphStatusLabelInner->setText(m_base->m_traceArray[trace]->graphStatusLabel->text()); } } else { for (uint trace=0;tracem_traceArray.count();trace++) { m_base->m_traceArray[trace]->graphStatusLabel->setText(""); m_base->m_traceArray[trace]->graphStatusLabelInner->setText(m_base->m_traceArray[trace]->graphStatusLabel->text()); } } if ((m_leftMouseDown) && (m_movingCursor < 0)) { double x1 = m_prevDownPos.x(); double y1 = m_prevDownPos.y(); 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)) { 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)) { TQPoint diff = e->pos() - m_prevDownPos; double dx = diff.x()*(100.0/virtualWidth()); double dy = diff.y()*(100.0/height()); if (m_base->m_cursorArray[m_movingCursor]->orientation == TQt::Horizontal) { m_base->m_cursorArray[m_movingCursor]->position = m_prevCursorPos+dy; } else { m_base->m_cursorArray[m_movingCursor]->position = m_prevCursorPos+dx; } if (m_base->m_cursorArray[m_movingCursor]->position < 0.0) { m_base->m_cursorArray[m_movingCursor]->position = 0.0; } if (m_base->m_cursorArray[m_movingCursor]->position > 100.0) { m_base->m_cursorArray[m_movingCursor]->position = 100.0; } emit(cursorPositionChanged(m_movingCursor, m_base->m_cursorArray[m_movingCursor]->position)); updateGraticule(); repaint(false); cursorHighlightChanged = false; } else if (m_middleMouseDown) { TQPoint diff = e->pos() - m_prevDownPos; double dx = diff.x()*(100.0/virtualWidth()); double dy = diff.y()*(100.0/height()); 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(); repaint(false); } } bool GraticuleWidget::userIsInteractingWithCursor() { return (m_movingCursor >= 0); } void GraticuleWidget::enterEvent(TQEvent *) { // } void GraticuleWidget::leaveEvent(TQEvent *) { for (uint trace=0;tracem_traceArray.count();trace++) { m_base->m_traceArray[trace]->graphStatusLabel->setText(""); m_base->m_traceArray[trace]->graphStatusLabelInner->setText(m_base->m_traceArray[trace]->graphStatusLabel->text()); } } TraceWidget::TraceWidget(TQWidget* parent, const char* name) : TQWidget(parent, name), m_horizDivs(0), m_vertDivs(0), m_cursorDarkness(CURSOR_DARKNESS_FACTOR), 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) { setBackgroundMode(NoBackground); setSizePolicy(TQSizePolicy(TQSizePolicy::MinimumExpanding, TQSizePolicy::MinimumExpanding)); m_primaryLayout = new TQGridLayout(this); m_graticuleWidget = new GraticuleWidget(this); connect(m_graticuleWidget, SIGNAL(cursorPositionChanged(uint, double)), this, SLOT(processChangedCursor(uint, double))); m_primaryLayout->addMultiCellWidget(m_graticuleWidget, 0, 253, 1, 254); m_primaryLayout->setAlignment(TQt::AlignTop); m_rightPaneLayout = new TQGridLayout; m_leftPaneLayout = new TQGridLayout; m_traceLabelLayout = new TQGridLayout; m_infoLabelLayout = new TQGridLayout; m_cursorLabelLayout = new TQGridLayout; m_traceLeftLabelLayout = new TraceLabelLayout(this); m_traceLeftCursorLabelLayout = new TraceCursorLabelLayout(this); m_statusLabelLayout = new TQVBoxLayout; m_statusLabelLayoutInner = new TQVBoxLayout; m_primaryLayout->addLayout(m_traceLabelLayout, 255, 1); m_primaryLayout->addLayout(m_rightPaneLayout, 0, 255); m_primaryLayout->addLayout(m_leftPaneLayout, 0, 0); m_primaryLayout->addLayout(m_statusLabelLayout, 255, 255); m_primaryLayout->addLayout(m_statusLabelLayoutInner, 1, 253); m_rightPaneLayout->addLayout(m_cursorLabelLayout, 0, 1); m_rightPaneLayout->addLayout(m_infoLabelLayout, 1, 1); m_leftPaneLayout->addLayout(m_traceLeftLabelLayout, 0, 1); m_leftPaneLayout->addLayout(m_traceLeftCursorLabelLayout, 0, 2); m_traceLabelLayout->addItem(new TQSpacerItem(0, 0, TQSizePolicy::Expanding, TQSizePolicy::Minimum), 0, 255); m_rightPaneLayout->addItem(new TQSpacerItem(0, 0, TQSizePolicy::Minimum, TQSizePolicy::Expanding), 255, 0); m_leftPaneLayout->addItem(new TQSpacerItem(0, 0, TQSizePolicy::Minimum, TQSizePolicy::Expanding), 255, 0); m_primaryLayout->addItem(new TQSpacerItem(0, 0, TQSizePolicy::Expanding, TQSizePolicy::Minimum), 1, 128); m_statusLabelLayout->setSpacing(0); m_leftPaneLayout->setSpacing(0); setPaletteBackgroundColor(TQt::black); setPaletteForegroundColor(TQColor(0,128,0)); } TraceWidget::~TraceWidget() { for (uint i=0;ivalue(); } else { return 0; } } void TraceWidget::setForegroundColor(const TQColor color) { setPaletteForegroundColor(color); m_graticuleWidget->setPaletteForegroundColor(color); } void TraceWidget::setBackgroundColor(const TQColor color) { setPaletteBackgroundColor(color); m_graticuleWidget->setPaletteBackgroundColor(color); for (uint trace=0;traceparamLabel->setPaletteBackgroundColor(color); m_traceArray[trace]->graphStatusLabel->setPaletteBackgroundColor(color); m_traceArray[trace]->graphStatusLabelInner->setPaletteBackgroundColor(color); m_traceArray[trace]->singleIncrBtn->setPaletteBackgroundColor(color); m_traceArray[trace]->singleDecrBtn->setPaletteBackgroundColor(color); m_traceArray[trace]->posResetBtn->setPaletteBackgroundColor(color); m_traceArray[trace]->posSetBtn->setPaletteBackgroundColor(color); } for (uint cursor=0;cursorparamLabel->setPaletteBackgroundColor(color); m_cursorArray[cursor]->singleIncrBtn->setPaletteBackgroundColor(color); m_cursorArray[cursor]->singleDecrBtn->setPaletteBackgroundColor(color); m_cursorArray[cursor]->multiIncrBtn->setPaletteBackgroundColor(color); m_cursorArray[cursor]->multiDecrBtn->setPaletteBackgroundColor(color); } } void TraceWidget::setNumberOfSamples(uint traceNumber, unsigned int samples, bool deferUpdate) { VERIFY_TRACE_ARRAY_SIZE unsigned int i; int prev_samples = m_traceArray[traceNumber]->sampleArray.count(); m_traceArray[traceNumber]->numberOfSamples = samples; m_traceArray[traceNumber]->sampleArray.resize(samples); m_traceArray[traceNumber]->positionArray.resize(samples); m_traceArray[traceNumber]->leftEdgeIndex = -1; m_traceArray[traceNumber]->rightEdgeIndex = -1; // Zero the uninitialized portion of the data arrays to avoid ugly drawing artifacts on resize for (i=prev_samples; isampleArray[i] = 0; m_traceArray[traceNumber]->positionArray[i] = 0; } if (!deferUpdate) { m_graticuleWidget->updateGraticule(); updateTraceText(); } } void TraceWidget::setDigitalTraceMode(uint traceNumber, bool enabled, bool deferUpdate) { VERIFY_TRACE_ARRAY_SIZE m_traceArray[traceNumber]->m_digitalTraceDrawing = enabled; if (!deferUpdate) { m_graticuleWidget->updateGraticule(); updateTraceText(); } } void TraceWidget::suppressNameInCursorText(uint traceNumber, bool suppress, bool deferUpdate) { VERIFY_TRACE_ARRAY_SIZE m_traceArray[traceNumber]->m_suppressNameInCursorText = suppress; if (!deferUpdate) { m_graticuleWidget->updateGraticule(); updateTraceText(); } } void TraceWidget::setNumberOfHorizontalDivisions(unsigned int divisions) { m_horizDivs = divisions; m_graticuleWidget->updateGraticule(); updateTraceText(); updateCursorText(); } void TraceWidget::setNumberOfVerticalDivisions(unsigned int divisions) { m_vertDivs = divisions; m_graticuleWidget->updateGraticule(); updateTraceText(); updateCursorText(); } void TraceWidget::setDisplayLimits(uint traceNumber, TQRectF limits, bool deferUpdate) { VERIFY_TRACE_ARRAY_SIZE m_traceArray[traceNumber]->leftEdge = limits.x(); m_traceArray[traceNumber]->rightEdge = limits.width(); m_traceArray[traceNumber]->topEdge = limits.y(); m_traceArray[traceNumber]->bottomEdge = limits.height(); m_traceArray[traceNumber]->leftEdgeIndex = -1; m_traceArray[traceNumber]->rightEdgeIndex = -1; if (!deferUpdate) { m_graticuleWidget->updateGraticule(); m_graticuleWidget->repaint(false); updateTraceText(); updateCursorText(); } } TQRectF TraceWidget::displayLimits(uint traceNumber) { VERIFY_TRACE_ARRAY_SIZE return TQRectF(m_traceArray[traceNumber]->leftEdge, m_traceArray[traceNumber]->topEdge, m_traceArray[traceNumber]->rightEdge, m_traceArray[traceNumber]->bottomEdge); } void TraceWidget::updateTraceText() { for (uint trace=0;tracerightEdge-m_traceArray[trace]->leftEdge)/m_horizDivs; double vertical_units_per_division = fabs(m_traceArray[trace]->bottomEdge-m_traceArray[trace]->topEdge)/m_vertDivs; double horizontal_range = (m_traceArray[trace]->rightEdge-m_traceArray[trace]->leftEdge); double vertical_range = (m_traceArray[trace]->bottomEdge-m_traceArray[trace]->topEdge); m_traceArray[trace]->paramLabel->setPaletteBackgroundColor(paletteBackgroundColor()); m_traceArray[trace]->paramLabel->setPaletteForegroundColor(m_traceArray[trace]->color); m_traceArray[trace]->leftLabel->setPaletteBackgroundColor(paletteBackgroundColor()); m_traceArray[trace]->leftLabel->setPaletteForegroundColor(m_traceArray[trace]->color); m_traceArray[trace]->leftCursorLabel->setPaletteBackgroundColor(paletteBackgroundColor()); m_traceArray[trace]->leftCursorLabel->setPaletteForegroundColor(m_traceArray[trace]->color); m_traceArray[trace]->graphStatusLabel->setPaletteBackgroundColor(paletteBackgroundColor()); m_traceArray[trace]->graphStatusLabel->setPaletteForegroundColor(m_traceArray[trace]->color); m_traceArray[trace]->graphStatusLabelInner->setPaletteBackgroundColor(paletteBackgroundColor()); m_traceArray[trace]->graphStatusLabelInner->setPaletteForegroundColor(m_traceArray[trace]->color); TQString offsetText; double offset = m_traceArray[trace]->offset; if (offset != 0) { if (offset < 0) { offsetText = TQString(" -%1").arg(prettyFormat(fabs(offset), vertical_range, m_traceArray[trace]->verticalUnits)); } else { offsetText = TQString(" +%1").arg(prettyFormat(fabs(offset), vertical_range, m_traceArray[trace]->verticalUnits)); } } TQString traceDataString = TQString("
%1,%2,%3").arg(prettyFormat(m_traceArray[trace]->sampleMin, vertical_range, m_traceArray[trace]->verticalUnits)).arg(prettyFormat(m_traceArray[trace]->sampleMax, vertical_range, m_traceArray[trace]->verticalUnits)).arg(prettyFormat(m_traceArray[trace]->sampleAverage, vertical_range, m_traceArray[trace]->verticalUnits)); m_traceArray[trace]->paramLabel->setText(TQString("
%1%2
%3/div,%4/div
%5,%6
%7,%8%9").arg(m_traceArray[trace]->traceName).arg(offsetText).arg(prettyFormat(horizontal_units_per_division, horizontal_range, m_traceArray[trace]->horizontalUnits)).arg(prettyFormat(vertical_units_per_division, vertical_range, m_traceArray[trace]->verticalUnits)).arg(prettyFormat(m_traceArray[trace]->leftEdge, (m_useAbsoluteHorizontalRange)?m_traceArray[trace]->rightEdge:horizontal_range, m_traceArray[trace]->horizontalUnits)).arg(prettyFormat(m_traceArray[trace]->topEdge, vertical_range, m_traceArray[trace]->verticalUnits)).arg(prettyFormat(m_traceArray[trace]->rightEdge, (m_useAbsoluteHorizontalRange)?m_traceArray[trace]->rightEdge:horizontal_range, m_traceArray[trace]->horizontalUnits)).arg(prettyFormat(m_traceArray[trace]->bottomEdge, vertical_range, m_traceArray[trace]->verticalUnits)).arg(traceDataString)); m_traceArray[trace]->leftLabel->setText(TQString("
%1").arg(m_traceArray[trace]->traceName)); } } void TraceWidget::updateCursorText() { for (uint cursor=0;cursorparamLabel->setPaletteBackgroundColor(paletteBackgroundColor()); if (m_cursorArray[cursor]->highlighted) { m_cursorArray[cursor]->paramLabel->setPaletteForegroundColor(m_cursorArray[cursor]->highlightColor); m_cursorArray[cursor]->singleIncrBtn->setPaletteForegroundColor(m_cursorArray[cursor]->highlightColor); m_cursorArray[cursor]->singleDecrBtn->setPaletteForegroundColor(m_cursorArray[cursor]->highlightColor); m_cursorArray[cursor]->multiIncrBtn->setPaletteForegroundColor(m_cursorArray[cursor]->highlightColor); m_cursorArray[cursor]->multiDecrBtn->setPaletteForegroundColor(m_cursorArray[cursor]->highlightColor); } else { m_cursorArray[cursor]->paramLabel->setPaletteForegroundColor(m_cursorArray[cursor]->color); m_cursorArray[cursor]->singleIncrBtn->setPaletteForegroundColor(m_cursorArray[cursor]->color); m_cursorArray[cursor]->singleDecrBtn->setPaletteForegroundColor(m_cursorArray[cursor]->color); m_cursorArray[cursor]->multiIncrBtn->setPaletteForegroundColor(m_cursorArray[cursor]->color); m_cursorArray[cursor]->multiDecrBtn->setPaletteForegroundColor(m_cursorArray[cursor]->color); } TQString cursorText; cursorText = TQString("%1").arg(m_cursorArray[cursor]->cursorName); // If this is a horizontal cursor, list all vertical positions for all channels // If this is a vertical cursor, list the horizontal positions for all channels for (uint trace=0;traceenabled) { if (m_cursorArray[cursor]->activeTraceLabelList.contains(trace) > 0) { double horizontal_range = (m_traceArray[trace]->rightEdge-m_traceArray[trace]->leftEdge); double vertical_range = (m_traceArray[trace]->bottomEdge-m_traceArray[trace]->topEdge); if (m_cursorArray[cursor]->orientation == TQt::Horizontal) { double realCursorPosition = (m_traceArray[trace]->topEdge+((m_cursorArray[cursor]->position/100.0)*vertical_range)-m_traceArray[trace]->offset); TQString deltaText; if (cursor >= m_zoomCursorStartIndex) { for (uint cursor2=m_zoomCursorStartIndex;cursor2orientation == m_cursorArray[cursor]->orientation) { double realSecondaryCursorPosition = (m_traceArray[trace]->topEdge+((m_cursorArray[cursor2]->position/100.0)*vertical_range)-m_traceArray[trace]->offset); deltaText = trUtf8("Δ") + prettyFormat(fabs(realCursorPosition-realSecondaryCursorPosition), vertical_range, m_traceArray[trace]->verticalUnits); break; } } } } cursorText.append(TQString("
%1: %2%3").arg(m_traceArray[trace]->traceName).arg(prettyFormat(realCursorPosition, vertical_range, m_traceArray[trace]->verticalUnits)).arg(deltaText)); } else { double realCursorPosition = (m_traceArray[trace]->leftEdge+((m_cursorArray[cursor]->position/100.0)*horizontal_range)); TQString deltaText; if ((cursor >= m_zoomCursorStartIndex) && ((int)cursor != m_hoverCursor)) { for (uint cursor2=m_zoomCursorStartIndex;cursor2orientation == m_cursorArray[cursor]->orientation) { double realSecondaryCursorPosition = (m_traceArray[trace]->leftEdge+((m_cursorArray[cursor2]->position/100.0)*horizontal_range)); deltaText = trUtf8("Δ") + prettyFormat(fabs(realCursorPosition-realSecondaryCursorPosition), horizontal_range, m_traceArray[trace]->horizontalUnits); break; } } } } if (m_traceArray[trace]->m_suppressNameInCursorText) { cursorText.append(TQString("
%2%3").arg(prettyFormat(realCursorPosition, (m_useAbsoluteHorizontalRange)?m_traceArray[trace]->rightEdge:horizontal_range, m_traceArray[trace]->horizontalUnits)).arg(deltaText)); } else { cursorText.append(TQString("
%1: %2%3").arg(m_traceArray[trace]->traceName).arg(prettyFormat(realCursorPosition, (m_useAbsoluteHorizontalRange)?m_traceArray[trace]->rightEdge:horizontal_range, m_traceArray[trace]->horizontalUnits)).arg(deltaText)); } } } if (cursor == m_traceInfoCursor) { 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)); 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; } } if (m_traceArray[trace]->sampleArray.count() > 0) { m_traceArray[trace]->leftCursorLabel->setText(TQString("
%2").arg((m_traceArray[trace]->sampleArray[closest]==0)?"0":"1")); } else { m_traceArray[trace]->leftCursorLabel->setText(TQString("")); } } else { // Find closest data point unsigned int n; unsigned int closest = 0; double diff; double distance = DBL_MAX; if (m_traceArray[trace]->positionArray.count() >= m_traceArray[trace]->numberOfSamples) { for (n=0; nnumberOfSamples; n++) { diff = fabs(m_traceArray[trace]->positionArray[n] - realCursorPosition); if (diff < distance) { distance = diff; closest = n; } } } if (m_traceArray[trace]->sampleArray.count() > 0) { m_traceArray[trace]->leftCursorLabel->setText(TQString("%2").arg(TraceWidget::prettyFormat(m_traceArray[trace]->sampleArray[closest], m_traceArray[trace]->sampleArray[closest], m_traceArray[trace]->verticalUnits))); } else { m_traceArray[trace]->leftCursorLabel->setText(TQString("")); } } } } } cursorText.append(""); m_cursorArray[cursor]->paramLabel->setText(cursorText); } } TQDoubleArray& TraceWidget::samples(uint traceNumber) { VERIFY_TRACE_ARRAY_SIZE return m_traceArray[traceNumber]->sampleArray; } void TraceWidget::setSamples(uint traceNumber, TQDoubleArray& tqda, bool deferUpdate) { VERIFY_TRACE_ARRAY_SIZE unsigned int i; double curValue; m_traceArray[traceNumber]->sampleArray = tqda; m_traceArray[traceNumber]->numberOfSamples = tqda.size(); // Calculate trace minimum, maximum, and average m_traceArray[traceNumber]->sampleMin = DBL_MAX; m_traceArray[traceNumber]->sampleMax = DBL_MIN; m_traceArray[traceNumber]->sampleAverage = 0; m_traceArray[traceNumber]->minIndex = 0; m_traceArray[traceNumber]->maxIndex = 0; for (i=0; isampleArray.size(); i++) { curValue = m_traceArray[traceNumber]->sampleArray[i]; if (curValue < m_traceArray[traceNumber]->sampleMin) { m_traceArray[traceNumber]->sampleMin = curValue; m_traceArray[traceNumber]->minIndex = i; } if (curValue > m_traceArray[traceNumber]->sampleMax) { m_traceArray[traceNumber]->sampleMax = curValue; m_traceArray[traceNumber]->maxIndex = i; } m_traceArray[traceNumber]->sampleAverage = m_traceArray[traceNumber]->sampleAverage + curValue; } m_traceArray[traceNumber]->sampleAverage = m_traceArray[traceNumber]->sampleAverage / m_traceArray[traceNumber]->numberOfSamples; if (!deferUpdate) { updateTraceText(); updateCursorText(); m_graticuleWidget->repaint(false); } } TQDoubleArray& TraceWidget::positions(uint traceNumber) { VERIFY_TRACE_ARRAY_SIZE return m_traceArray[traceNumber]->positionArray; } void TraceWidget::setPositions(uint traceNumber, TQDoubleArray& tqda, bool deferUpdate) { VERIFY_TRACE_ARRAY_SIZE m_traceArray[traceNumber]->positionArray = tqda; m_traceArray[traceNumber]->numberOfSamples = tqda.size(); m_traceArray[traceNumber]->leftEdgeIndex = -1; m_traceArray[traceNumber]->rightEdgeIndex = -1; if (!deferUpdate) { updateCursorText(); m_graticuleWidget->repaint(false); } } TQColor TraceWidget::traceColor(uint traceNumber) { VERIFY_TRACE_ARRAY_SIZE return m_traceArray[traceNumber]->color; } void TraceWidget::setTraceColor(uint traceNumber, TQColor color) { VERIFY_TRACE_ARRAY_SIZE m_traceArray[traceNumber]->color = color; m_graticuleWidget->updateGraticule(); m_graticuleWidget->repaint(false); updateTraceText(); } bool TraceWidget::traceEnabled(uint traceNumber) { VERIFY_TRACE_ARRAY_SIZE return m_traceArray[traceNumber]->enabled; } void TraceWidget::setTraceEnabled(uint traceNumber, bool enabled, TextDisplayType showText, bool deferUpdate) { VERIFY_TRACE_ARRAY_SIZE m_traceArray[traceNumber]->enabled = enabled; if (enabled) { if (showText == FullText) { m_traceArray[traceNumber]->paramLabel->show(); m_traceArray[traceNumber]->leftLabel->show(); m_traceArray[traceNumber]->leftCursorLabel->show(); m_traceArray[traceNumber]->graphStatusLabel->show(); m_traceArray[traceNumber]->graphStatusLabelInner->hide(); m_traceArray[traceNumber]->singleIncrBtn->show(); m_traceArray[traceNumber]->singleDecrBtn->show(); m_traceArray[traceNumber]->posResetBtn->show(); m_traceArray[traceNumber]->posSetBtn->show(); } else { m_traceArray[traceNumber]->paramLabel->hide(); m_traceArray[traceNumber]->leftLabel->hide(); m_traceArray[traceNumber]->leftCursorLabel->hide(); m_traceArray[traceNumber]->graphStatusLabel->hide(); if (showText == SummaryText) { m_traceArray[traceNumber]->graphStatusLabelInner->show(); } else { m_traceArray[traceNumber]->graphStatusLabelInner->hide(); } m_traceArray[traceNumber]->singleIncrBtn->hide(); m_traceArray[traceNumber]->singleDecrBtn->hide(); m_traceArray[traceNumber]->posResetBtn->hide(); m_traceArray[traceNumber]->posSetBtn->hide(); } } else { m_traceArray[traceNumber]->paramLabel->hide(); m_traceArray[traceNumber]->leftLabel->hide(); m_traceArray[traceNumber]->leftCursorLabel->hide(); m_traceArray[traceNumber]->graphStatusLabel->hide(); m_traceArray[traceNumber]->graphStatusLabelInner->hide(); m_traceArray[traceNumber]->singleIncrBtn->hide(); m_traceArray[traceNumber]->singleDecrBtn->hide(); m_traceArray[traceNumber]->posResetBtn->hide(); m_traceArray[traceNumber]->posSetBtn->hide(); } if (!deferUpdate) { m_graticuleWidget->updateGraticule(); m_graticuleWidget->repaint(false); updateTraceText(); } } TQString TraceWidget::traceName(uint traceNumber) { VERIFY_TRACE_ARRAY_SIZE return m_traceArray[traceNumber]->traceName; } void TraceWidget::setTraceName(uint traceNumber, TQString name, bool deferUpdate) { VERIFY_TRACE_ARRAY_SIZE m_traceArray[traceNumber]->traceName = name; if (!deferUpdate) { updateTraceText(); } } TQString TraceWidget::traceHorizontalUnits(uint traceNumber) { VERIFY_TRACE_ARRAY_SIZE return m_traceArray[traceNumber]->horizontalUnits; } void TraceWidget::setTraceHorizontalUnits(uint traceNumber, TQString units, bool deferUpdate) { VERIFY_TRACE_ARRAY_SIZE m_traceArray[traceNumber]->horizontalUnits = units; if (!deferUpdate) { updateTraceText(); } } TQString TraceWidget::traceVerticalUnits(uint traceNumber) { VERIFY_TRACE_ARRAY_SIZE return m_traceArray[traceNumber]->verticalUnits; } void TraceWidget::setTraceVerticalUnits(uint traceNumber, TQString units, bool deferUpdate) { VERIFY_TRACE_ARRAY_SIZE m_traceArray[traceNumber]->verticalUnits = units; if (!deferUpdate) { updateTraceText(); } } double TraceWidget::cursorPosition(uint cursorNumber) { VERIFY_CURSOR_ARRAY_SIZE return m_cursorArray[cursorNumber]->position; } void TraceWidget::setCursorPosition(uint cursorNumber, double position) { VERIFY_CURSOR_ARRAY_SIZE if (position < 0.0) position = 0.0; if (position > 100.0) position = 100.0; m_cursorArray[cursorNumber]->position = position; emit(cursorPositionChanged(cursorNumber, m_cursorArray[cursorNumber]->position)); updateCursorText(); m_graticuleWidget->updateGraticule(); m_graticuleWidget->repaint(false); } TQColor TraceWidget::cursorColor(uint cursorNumber) { VERIFY_CURSOR_ARRAY_SIZE return m_cursorArray[cursorNumber]->color; } void TraceWidget::setCursorColor(uint cursorNumber, TQColor color) { VERIFY_CURSOR_ARRAY_SIZE m_cursorArray[cursorNumber]->color = color; updateCursorText(); m_graticuleWidget->updateGraticule(); m_graticuleWidget->repaint(false); } TQColor TraceWidget::cursorHighlightColor(uint cursorNumber) { VERIFY_CURSOR_ARRAY_SIZE return m_cursorArray[cursorNumber]->highlightColor; } void TraceWidget::setCursorHighlightColor(uint cursorNumber, TQColor color) { VERIFY_CURSOR_ARRAY_SIZE m_cursorArray[cursorNumber]->highlightColor = color; updateCursorText(); m_graticuleWidget->updateGraticule(); m_graticuleWidget->repaint(false); } void TraceWidget::setCursorActiveTraceList(uint cursorNumber, TraceNumberList list) { VERIFY_CURSOR_ARRAY_SIZE m_cursorArray[cursorNumber]->activeTraceLabelList = list; updateCursorText(); } bool TraceWidget::cursorEnabled(uint cursorNumber) { VERIFY_CURSOR_ARRAY_SIZE return m_cursorArray[cursorNumber]->enabled; } void TraceWidget::setCursorEnabled(uint cursorNumber, bool enabled) { VERIFY_CURSOR_ARRAY_SIZE m_cursorArray[cursorNumber]->enabled = enabled; if (enabled) { m_cursorArray[cursorNumber]->paramLabel->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(); m_cursorArray[cursorNumber]->singleIncrBtn->hide(); m_cursorArray[cursorNumber]->singleDecrBtn->hide(); m_cursorArray[cursorNumber]->multiIncrBtn->hide(); m_cursorArray[cursorNumber]->multiDecrBtn->hide(); } m_graticuleWidget->updateGraticule(); updateCursorText(); } TQString TraceWidget::cursorName(uint cursorNumber) { VERIFY_CURSOR_ARRAY_SIZE return m_cursorArray[cursorNumber]->cursorName; } void TraceWidget::setCursorName(uint cursorNumber, TQString name) { VERIFY_CURSOR_ARRAY_SIZE m_cursorArray[cursorNumber]->cursorName = name; updateCursorText(); } TQt::Orientation TraceWidget::cursorOrientation(uint cursorNumber) { VERIFY_CURSOR_ARRAY_SIZE return m_cursorArray[cursorNumber]->orientation; } void TraceWidget::setCursorOrientation(uint cursorNumber, TQt::Orientation orient) { VERIFY_CURSOR_ARRAY_SIZE m_cursorArray[cursorNumber]->orientation = orient; updateCursorText(); } void TraceWidget::setTraceInfoCursor(uint cursorNumber) { VERIFY_CURSOR_ARRAY_SIZE m_traceInfoCursor = cursorNumber; updateCursorText(); } void TraceWidget::setHoverCursor(uint cursorNumber) { VERIFY_CURSOR_ARRAY_SIZE m_hoverCursor = cursorNumber; updateCursorText(); } void TraceWidget::setNumberOfTraces(uint traceNumber) { resizeTraceArray(traceNumber); } void TraceWidget::setNumberOfCursors(uint cursorNumber) { resizeCursorArray(cursorNumber); } TQRectF TraceWidget::zoomBox() { uint i; if ((m_cursorArray.count() < (4+m_zoomCursorStartIndex)) || (!m_zoomBoxEnabled)) { if (!m_zoomBoxPrev.isNull()) { 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 { // Find the first two horizontal and first two vertical cursors // If two of each cannot be found, return TQRectF() double horiz[2]; double vert[2]; int j = 0; int k = 0; for (i=m_zoomCursorStartIndex;iorientation == TQt::Horizontal) { if (j<2) { vert[j] = m_cursorArray[i]->position; j++; } } else { if (k<2) { horiz[k] = m_cursorArray[i]->position; k++; } } if ((j>1) && (k>1)) { break; } } if ((j>1) && (k>1)) { // Calculate zoom box double leftBound = (horiz[0] < horiz[1])?horiz[0]:horiz[1]; double topBound = (vert[0] < vert[1])?vert[0]:vert[1]; TQRectF newRect(leftBound, topBound, fabs(horiz[0]-horiz[1]), fabs(vert[0]-vert[1])); if (m_zoomBoxPrev != newRect) { m_zoomBoxPrev = newRect; emit(zoomBoxChanged(m_zoomBoxPrev)); } return m_zoomBoxPrev; } else { if (!m_zoomBoxPrev.isNull()) { m_zoomBoxPrev = TQRectF(); emit(zoomBoxChanged(m_zoomBoxPrev)); } return m_zoomBoxPrev; } } } TQRectF TraceWidget::zoomCursorBox() { uint i; if ((m_cursorArray.count() < (4+m_zoomCursorStartIndex)) || (!m_zoomBoxEnabled)) { return TQRectF(); } else { // Find the first two horizontal and first two vertical cursors // If two of each cannot be found, return TQRectF() double horiz[2]; double vert[2]; int j = 0; int k = 0; for (i=m_zoomCursorStartIndex;iorientation == TQt::Horizontal) { if (j<2) { vert[j] = m_cursorArray[i]->position; j++; } } else { if (k<2) { horiz[k] = m_cursorArray[i]->position; k++; } } if ((j>1) && (k>1)) { break; } } if ((j>1) && (k>1)) { return TQRectF(horiz[0], vert[0], horiz[1], vert[1]); } else { return TQRectF(); } } } void TraceWidget::setZoomCursorBox(const TQRectF rect) { uint i; TQRectF boundedRect = rect; if (boundedRect.x() < 0.0) { boundedRect.setX(0.0); } if (boundedRect.x() > 100.0) { boundedRect.setX(100.0); } if (boundedRect.y() < 0.0) { boundedRect.setY(0.0); } if (boundedRect.y() > 100.0) { boundedRect.setY(100.0); } if (boundedRect.width() < 0.0) { boundedRect.setWidth(0.0); } if (boundedRect.width() > 100.0) { boundedRect.setWidth(100.0); } if (boundedRect.height() < 0.0) { boundedRect.setHeight(0.0); } if (boundedRect.height() > 100.0) { boundedRect.setHeight(100.0); } if ((m_cursorArray.count() < (4+m_zoomCursorStartIndex)) || (!m_zoomBoxEnabled)) { return; } else { // Find the first two horizontal and first two vertical cursors // If two of each cannot be found, return TQRectF() CursorData* horiz[2]; CursorData* vert[2]; uint horizIndex[2]; uint vertIndex[2]; int j = 0; int k = 0; for (i=m_zoomCursorStartIndex;iorientation == TQt::Horizontal) { if (j<2) { vert[j] = m_cursorArray[i]; vertIndex[j] = i; j++; } } else { if (k<2) { horiz[k] = m_cursorArray[i]; horizIndex[k] = i; k++; } } if ((j>1) && (k>1)) { break; } } if ((j>1) && (k>1)) { // Set cursors... vert[0]->position = boundedRect.y(); emit(cursorPositionChanged(vertIndex[0], m_cursorArray[vertIndex[0]]->position)); vert[1]->position = boundedRect.height(); emit(cursorPositionChanged(vertIndex[1], m_cursorArray[vertIndex[1]]->position)); horiz[0]->position = boundedRect.x(); emit(cursorPositionChanged(horizIndex[0], m_cursorArray[horizIndex[0]]->position)); horiz[1]->position = boundedRect.width(); emit(cursorPositionChanged(horizIndex[1], m_cursorArray[horizIndex[1]]->position)); updateCursorText(); m_graticuleWidget->updateGraticule(); m_graticuleWidget->repaint(false); return; } } } unsigned int TraceWidget::zoomCursorStartIndex() { return m_zoomCursorStartIndex; } void TraceWidget::setZoomCursorStartIndex(unsigned int index) { m_zoomCursorStartIndex = index; } void TraceWidget::setZoomBoxEnabled(bool enabled) { m_zoomBoxEnabled = 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;ileftLabel->show(); } else { m_traceArray[i]->leftLabel->hide(); } } } void TraceWidget::showLeftCursorTraceInfoArea(bool show) { m_showLeftCursorInfoArea = show; for (uint i=0;ileftCursorLabel->show(); } else { m_traceArray[i]->leftCursorLabel->hide(); } } } void TraceWidget::fitLeftTraceInfoArea(bool fit) { m_leftTraceInfoLabelsFit = fit; m_traceLeftLabelLayout->invalidate(); m_traceLeftCursorLabelLayout->invalidate(); } void TraceWidget::setLeftTraceInfoAreaFitSpacing(int spacing) { m_leftTraceInfoAreaFitSpacing = spacing; m_traceLeftLabelLayout->invalidate(); m_traceLeftCursorLabelLayout->invalidate(); } void TraceWidget::setMinimumPixelsPerHorizDiv(unsigned int pixels) { m_minimumPixelsPerHorizDiv = pixels; } TQString TraceWidget::prettyFormat(double value, double rangeDetectValue, TQString baseUnits, unsigned int precision) { TQString result; TQString unitMultiplier; double valueMultiplier; if (fabs(rangeDetectValue) < 1e-9) { unitMultiplier = "p"; valueMultiplier = 1e+12; } else if (fabs(rangeDetectValue) < 1e-6) { unitMultiplier = "n"; valueMultiplier = 1e+9; } else if (fabs(rangeDetectValue) < 1e-3) { unitMultiplier = "u"; valueMultiplier = 1e+6; } else if (fabs(rangeDetectValue) < 1e-0) { unitMultiplier = "m"; valueMultiplier = 1e+3; } else if (fabs(rangeDetectValue) < 1e+3) { unitMultiplier = ""; valueMultiplier = 1e+0; } else if (fabs(rangeDetectValue) < 1e+6) { unitMultiplier = "k"; valueMultiplier = 1e-3; } else if (fabs(rangeDetectValue) < 1e+9) { unitMultiplier = "M"; valueMultiplier = 1e-6; } else if (fabs(rangeDetectValue) < 1e+12) { unitMultiplier = "G"; valueMultiplier = 1e-9; } else if (fabs(rangeDetectValue) < 1e+15) { unitMultiplier = "T"; valueMultiplier = 1e-12; } else { unitMultiplier = ""; valueMultiplier = 1.0; } double scaledValue = value * valueMultiplier; TQString valueString = TQString("%1").arg(scaledValue, 0, 'f', precision); if (valueString.contains("-") && valueString.contains(".")) { valueString.truncate(precision+2); } else if (valueString.contains("-")) { valueString.truncate(precision+1); } else if (valueString.contains(".")) { valueString.truncate(precision+1); } else { valueString.truncate(precision); } if (valueString.endsWith(".")) { valueString.truncate(valueString.length()-1); } result = TQString("%1%2%3").arg(valueString).arg(unitMultiplier).arg(baseUnits); return result; } double TraceWidget::traceOffset(uint traceNumber) { VERIFY_TRACE_ARRAY_SIZE return m_traceArray[traceNumber]->offset; } void TraceWidget::setTraceOffset(uint traceNumber, double offset) { setTraceOffset(traceNumber, offset, false); } void TraceWidget::setTraceOffset(uint traceNumber, double offset, bool deferUpdate) { VERIFY_TRACE_ARRAY_SIZE m_traceArray[traceNumber]->offset = offset; if (!deferUpdate) { m_graticuleWidget->repaint(false); updateTraceText(); } } double TraceWidget::traceTextOffset(uint traceNumber) { VERIFY_TRACE_ARRAY_SIZE return m_traceArray[traceNumber]->textOffset; } void TraceWidget::setTraceTextOffset(uint traceNumber, double offset) { setTraceOffset(traceNumber, offset, false); } void TraceWidget::setTraceTextOffset(uint traceNumber, double offset, bool deferUpdate) { VERIFY_TRACE_ARRAY_SIZE m_traceArray[traceNumber]->textOffset = offset; if (!deferUpdate) { m_graticuleWidget->repaint(false); updateTraceText(); } } void TraceWidget::processChangedOffset(double offset) { // Find the sending trace number const TraceData* sendingTrace = dynamic_cast(sender()); if (sendingTrace) { int tracenumber = -1; for (uint trace=0;trace= 0) { m_traceLeftLabelLayout->invalidate(); m_traceLeftCursorLabelLayout->invalidate(); emit(offsetChanged(tracenumber, offset)); } } } void TraceWidget::processChangedCusorPosition(double position) { // Find the sending cursor number const CursorData* sendingCursor = dynamic_cast(sender()); if (sendingCursor) { int cursornumber = -1; for (uint cursor=0;cursor= 0) { emit(cursorDragged(cursornumber, position)); } } } void TraceWidget::processChangedCursor(uint cursorNumber, double newPosition) { emit(cursorDragged(cursorNumber, newPosition)); } void TraceWidget::resizeTraceArray(uint newsize) { uint oldcount = m_traceArray.count(); if (newsize > oldcount) { m_traceArray.resize(newsize); for (uint i=oldcount;iparamLabel) { m_traceLabelLayout->addMultiCellWidget(m_traceArray[i]->paramLabel, 0, 2, i*2, i*2); m_traceLabelLayout->addWidget(m_traceArray[i]->singleIncrBtn, 0, (i*2)+1); m_traceLabelLayout->addWidget(m_traceArray[i]->posResetBtn, 1, (i*2)+1); m_traceLabelLayout->addWidget(m_traceArray[i]->posSetBtn, 2, (i*2)+1); m_traceLabelLayout->addWidget(m_traceArray[i]->singleDecrBtn, 3, (i*2)+1); m_traceLeftLabelLayout->addWidget(m_traceArray[i]->leftLabel, TQt::AlignTop); m_traceLeftCursorLabelLayout->addWidget(m_traceArray[i]->leftCursorLabel, TQt::AlignTop); m_statusLabelLayout->insertWidget(i, m_traceArray[i]->graphStatusLabel, TQt::AlignTop); m_statusLabelLayoutInner->insertWidget(i, m_traceArray[i]->graphStatusLabelInner); } } } else if (newsize < oldcount) { for (uint i=newsize;iparamLabel) { m_traceLabelLayout->remove(m_traceArray[i]->paramLabel); m_traceLabelLayout->remove(m_traceArray[i]->singleIncrBtn); m_traceLabelLayout->remove(m_traceArray[i]->posResetBtn); m_traceLabelLayout->remove(m_traceArray[i]->posSetBtn); m_traceLabelLayout->remove(m_traceArray[i]->singleDecrBtn); m_traceLeftLabelLayout->remove(m_traceArray[i]->leftLabel); m_traceLeftCursorLabelLayout->remove(m_traceArray[i]->leftCursorLabel); m_statusLabelLayout->remove(m_traceArray[i]->graphStatusLabel); m_statusLabelLayoutInner->remove(m_traceArray[i]->graphStatusLabelInner); } delete m_traceArray[i]; m_traceArray[i] = NULL; } m_traceArray.resize(newsize); } } void TraceWidget::resizeCursorArray(uint newsize) { uint oldcount = m_cursorArray.count(); if (newsize > oldcount) { m_cursorArray.resize(newsize); for (uint i=oldcount;iparamLabel) { m_cursorLabelLayout->addMultiCellWidget(m_cursorArray[i]->paramLabel, i*2, i*2, 0, 3); m_cursorLabelLayout->addMultiCellWidget(m_cursorArray[i]->multiIncrBtn, (i*2)+1, (i*2)+1, 0, 0, TQt::AlignHCenter); m_cursorLabelLayout->addMultiCellWidget(m_cursorArray[i]->singleIncrBtn, (i*2)+1, (i*2)+1, 1, 1, TQt::AlignHCenter); m_cursorLabelLayout->addMultiCellWidget(m_cursorArray[i]->singleDecrBtn, (i*2)+1, (i*2)+1, 2, 2, TQt::AlignHCenter); m_cursorLabelLayout->addMultiCellWidget(m_cursorArray[i]->multiDecrBtn, (i*2)+1, (i*2)+1, 3, 3, TQt::AlignHCenter); } } } else { m_cursorArray.resize(newsize); for (uint i=newsize;iparamLabel) { m_cursorLabelLayout->remove(m_cursorArray[i]->paramLabel); m_cursorLabelLayout->remove(m_cursorArray[i]->multiIncrBtn); m_cursorLabelLayout->remove(m_cursorArray[i]->singleIncrBtn); m_cursorLabelLayout->remove(m_cursorArray[i]->singleDecrBtn); m_cursorLabelLayout->remove(m_cursorArray[i]->multiDecrBtn); } delete m_cursorArray[i]; } } } bool TraceWidget::userIsInteractingWithCursor() { return m_graticuleWidget->userIsInteractingWithCursor(); } TQSize TraceWidget::sizeHint() const { return TQWidget::sizeHint(); } TQSize TraceWidget::minimumSizeHint() const { return TQWidget::minimumSizeHint(); } TraceScrollView::TraceScrollView(TQWidget* parent, const char* name) : TQScrollView(parent, name) { m_traceWidget = new TraceWidget(viewport()); addChild(m_traceWidget); } TraceScrollView::~TraceScrollView() { delete m_traceWidget; m_traceWidget = NULL; } TQSize TraceScrollView::sizeHint() const { return TQScrollView::sizeHint(); } TQSize TraceScrollView::minimumSizeHint() const { return m_traceWidget->minimumSizeHint(); } TraceWidget* TraceScrollView::traceWidget() { return m_traceWidget; } TraceScrollWidget::TraceScrollWidget(TQWidget* parent, const char* name) : TQVBox(parent, name) { m_traceScrollView = new TraceScrollView(this); m_horizScrollBar = new TQScrollBar(this); m_traceScrollView->m_traceWidget->m_horizScrollBar = m_horizScrollBar; connect(m_horizScrollBar, TQT_SIGNAL(valueChanged(int)), m_traceScrollView->m_traceWidget->m_graticuleWidget, TQT_SLOT(horizScrollValueChanged(int))); m_traceScrollView->setHScrollBarMode(TQScrollView::AlwaysOff); m_horizScrollBar->setOrientation(TQt::Horizontal); m_horizScrollBarMode = TQScrollView::AlwaysOff; } TraceScrollWidget::~TraceScrollWidget() { delete m_traceScrollView; m_traceScrollView = NULL; delete m_horizScrollBar; m_horizScrollBar = NULL; } void TraceScrollWidget::setResizePolicy(TQScrollView::ResizePolicy rp) { m_traceScrollView->setResizePolicy(rp); } TQScrollView::ResizePolicy TraceScrollWidget::resizePolicy() const { return m_traceScrollView->resizePolicy(); } void TraceScrollWidget::setHScrollBarMode(TQScrollView::ScrollBarMode sm) { m_horizScrollBarMode = sm; } void TraceScrollWidget::setVScrollBarMode(TQScrollView::ScrollBarMode sm) { m_traceScrollView->setVScrollBarMode(sm); } TraceWidget* TraceScrollWidget::traceWidget() { return m_traceScrollView->m_traceWidget; } #include "tracewidget.moc"