From: Joel Holdsworth Date: Sat, 30 Aug 2014 08:48:06 +0000 (+0100) Subject: Replace View ownership of traces with RowItemOwner X-Git-Url: http://git.code-monkey.de/?p=pulseview.git;a=commitdiff_plain;h=eae6e30af53f6b3e42dc5be212c82870078276b0 Replace View ownership of traces with RowItemOwner --- diff --git a/pv/view/analogsignal.cpp b/pv/view/analogsignal.cpp index bba84ca..eaa25bc 100644 --- a/pv/view/analogsignal.cpp +++ b/pv/view/analogsignal.cpp @@ -89,13 +89,17 @@ void AnalogSignal::paint_mid(QPainter &p, int left, int right) { assert(_data); assert(right >= left); + assert(_owner); const int y = get_y(); - const double scale = _view->scale(); + const View *const view = _owner->view(); + assert(view); + + const double scale = view->scale(); assert(scale > 0); - const double offset = _view->offset(); + const double offset = view->offset(); if (!_channel->enabled()) return; diff --git a/pv/view/decodetrace.cpp b/pv/view/decodetrace.cpp index ae2ec16..899de3b 100644 --- a/pv/view/decodetrace.cpp +++ b/pv/view/decodetrace.cpp @@ -505,14 +505,17 @@ void DecodeTrace::draw_unresolved_period(QPainter &p, int h, int left, pair DecodeTrace::get_pixels_offset_samples_per_pixel() const { - assert(_view); + assert(_owner); assert(_decoder_stack); - const double scale = _view->scale(); + const View *view = _owner->view(); + assert(view); + + const double scale = view->scale(); assert(scale > 0); const double pixels_offset = - (_view->offset() - _decoder_stack->get_start_time()) / scale; + (view->offset() - _decoder_stack->get_start_time()) / scale; double samplerate = _decoder_stack->samplerate(); @@ -580,10 +583,15 @@ void DecodeTrace::hide_hover_annotation() void DecodeTrace::hover_point_changed() { - QPoint hp = _view->hover_point(); + assert(_owner); + + const View *const view = _owner->view(); + assert(view); + + QPoint hp = view->hover_point(); QString ann = get_annotation_at_point(hp); - assert(_view); + assert(view); assert(_row_height); if (ann.isEmpty()) { @@ -609,7 +617,7 @@ void DecodeTrace::hover_point_changed() hp.setY(get_y() - (_row_height / 2) + (hover_row * _row_height) - _row_height - text_size.height()); - QToolTip::showText(_view->viewport()->mapToGlobal(hp), ann); + QToolTip::showText(view->viewport()->mapToGlobal(hp), ann); } void DecodeTrace::create_decoder_form(int index, @@ -750,8 +758,8 @@ void DecodeTrace::commit_channels() void DecodeTrace::on_new_decode_data() { - if (_view) - _view->update_viewport(); + if (_owner) + _owner->update_viewport(); } void DecodeTrace::delete_pressed() @@ -810,7 +818,7 @@ void DecodeTrace::on_show_hide_decoder(int index) assert(index < (int)_decoder_forms.size()); _decoder_forms[index]->set_decoder_visible(show); - _view->update_viewport(); + _owner->update_viewport(); } } // namespace view diff --git a/pv/view/header.cpp b/pv/view/header.cpp index 653cac4..361a60c 100644 --- a/pv/view/header.cpp +++ b/pv/view/header.cpp @@ -68,39 +68,39 @@ QSize Header::sizeHint() const { int max_width = 0; - const vector< shared_ptr > traces(_view.get_traces()); - for (shared_ptr t : traces) { - assert(t); + const vector< shared_ptr > row_items(_view.child_items()); + for (shared_ptr r : row_items) { + assert(r); - if (t->enabled()) { - max_width = max(max_width, (int)t->label_rect(0).width()); + if (r->enabled()) { + max_width = max(max_width, (int)r->label_rect(0).width()); } } return QSize(max_width + Padding + BaselineOffset, 0); } -shared_ptr Header::get_mouse_over_trace(const QPoint &pt) +shared_ptr Header::get_mouse_over_row_item(const QPoint &pt) { const int w = width() - BaselineOffset; - const vector< shared_ptr > traces(_view.get_traces()); + const vector< shared_ptr > row_items(_view.child_items()); - for (const shared_ptr t : traces) + for (const shared_ptr r : row_items) { - assert(t); - if (t->enabled() && t->label_rect(w).contains(pt)) - return t; + assert(r); + if (r->enabled() && r->label_rect(w).contains(pt)) + return r; } - return shared_ptr(); + return shared_ptr(); } void Header::clear_selection() { - const vector< shared_ptr > traces(_view.get_traces()); - for (const shared_ptr t : traces) { - assert(t); - t->select(false); + const vector< shared_ptr > row_items(_view.child_items()); + for (const shared_ptr r : row_items) { + assert(r); + r->select(false); } update(); @@ -112,19 +112,19 @@ void Header::paintEvent(QPaintEvent*) // left edge of the widget, because then the selection shadow // would be clipped away. const int w = width() - BaselineOffset; - const vector< shared_ptr > traces(_view.get_traces()); + const vector< shared_ptr > row_items(_view.child_items()); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); - const bool dragging = !_drag_traces.empty(); - for (const shared_ptr t : traces) + const bool dragging = !_drag_row_items.empty(); + for (const shared_ptr r : row_items) { - assert(t); + assert(r); const bool highlight = !dragging && - t->label_rect(w).contains(_mouse_point); - t->paint_label(painter, w, highlight); + r->label_rect(w).contains(_mouse_point); + r->paint_label(painter, w, highlight); } painter.end(); @@ -134,45 +134,45 @@ void Header::mousePressEvent(QMouseEvent *event) { assert(event); - const vector< shared_ptr > traces(_view.get_traces()); + const vector< shared_ptr > row_items(_view.child_items()); if (event->button() & Qt::LeftButton) { _mouse_down_point = event->pos(); // Save the offsets of any signals which will be dragged - for (const shared_ptr t : traces) - if (t->selected()) - _drag_traces.push_back( - make_pair(t, t->v_offset())); + for (const shared_ptr r : row_items) + if (r->selected()) + _drag_row_items.push_back( + make_pair(r, r->v_offset())); } // Select the signal if it has been clicked - const shared_ptr mouse_over_trace = - get_mouse_over_trace(event->pos()); - if (mouse_over_trace) { - if (mouse_over_trace->selected()) - mouse_over_trace->select(false); + const shared_ptr mouse_over_row_item = + get_mouse_over_row_item(event->pos()); + if (mouse_over_row_item) { + if (mouse_over_row_item->selected()) + mouse_over_row_item->select(false); else { - mouse_over_trace->select(true); + mouse_over_row_item->select(true); if (~QApplication::keyboardModifiers() & Qt::ControlModifier) - _drag_traces.clear(); + _drag_row_items.clear(); // Add the signal to the drag list if (event->button() & Qt::LeftButton) - _drag_traces.push_back( - make_pair(mouse_over_trace, - mouse_over_trace->v_offset())); + _drag_row_items.push_back( + make_pair(mouse_over_row_item, + mouse_over_row_item->v_offset())); } } if (~QApplication::keyboardModifiers() & Qt::ControlModifier) { // Unselect all other signals because the Ctrl is not // pressed - for (const shared_ptr t : traces) - if (t != mouse_over_trace) - t->select(false); + for (const shared_ptr r : row_items) + if (r != mouse_over_row_item) + r->select(false); } selection_changed(); @@ -189,21 +189,21 @@ void Header::mouseReleaseEvent(QMouseEvent *event) _view.normalize_layout(); else { - const shared_ptr mouse_over_trace = - get_mouse_over_trace(event->pos()); - if (mouse_over_trace) { + const shared_ptr mouse_over_row_item = + get_mouse_over_row_item(event->pos()); + if (mouse_over_row_item) { const int w = width() - BaselineOffset; Popup *const p = - mouse_over_trace->create_popup(&_view); + mouse_over_row_item->create_popup(&_view); p->set_position(mapToGlobal(QPoint(w, - mouse_over_trace->get_y())), + mouse_over_row_item->get_y())), Popup::Right); p->show(); } } _dragging = false; - _drag_traces.clear(); + _drag_row_items.clear(); } } @@ -220,24 +220,25 @@ void Header::mouseMoveEvent(QMouseEvent *event) return; // Move the signals if we are dragging - if (!_drag_traces.empty()) + if (!_drag_row_items.empty()) { _dragging = true; const int delta = event->pos().y() - _mouse_down_point.y(); - for (auto i = _drag_traces.begin(); i != _drag_traces.end(); i++) { - const std::shared_ptr trace((*i).first); - if (trace) { + for (auto i = _drag_row_items.begin(); + i != _drag_row_items.end(); i++) { + const std::shared_ptr row_item((*i).first); + if (row_item) { const int y = (*i).second + delta; const int y_snap = ((y + View::SignalSnapGridSize / 2) / View::SignalSnapGridSize) * View::SignalSnapGridSize; - trace->set_v_offset(y_snap); + row_item->set_v_offset(y_snap); // Ensure the trace is selected - trace->select(); + row_item->select(); } } @@ -256,10 +257,10 @@ void Header::leaveEvent(QEvent*) void Header::contextMenuEvent(QContextMenuEvent *event) { - const shared_ptr t = get_mouse_over_trace(_mouse_point); + const shared_ptr r = get_mouse_over_row_item(_mouse_point); - if (t) - t->create_context_menu(this)->exec(event->globalPos()); + if (r) + r->create_context_menu(this)->exec(event->globalPos()); } void Header::keyPressEvent(QKeyEvent *e) @@ -270,10 +271,10 @@ void Header::keyPressEvent(QKeyEvent *e) { case Qt::Key_Delete: { - const vector< shared_ptr > traces(_view.get_traces()); - for (const shared_ptr t : traces) - if (t->selected()) - t->delete_pressed(); + const vector< shared_ptr > row_items(_view.child_items()); + for (const shared_ptr r : row_items) + if (r->selected()) + r->delete_pressed(); break; } } @@ -281,14 +282,14 @@ void Header::keyPressEvent(QKeyEvent *e) void Header::on_signals_changed() { - const vector< shared_ptr > traces(_view.get_traces()); - for (shared_ptr t : traces) { - assert(t); - connect(t.get(), SIGNAL(visibility_changed()), + const vector< shared_ptr > row_items(_view.child_items()); + for (shared_ptr r : row_items) { + assert(r); + connect(r.get(), SIGNAL(visibility_changed()), this, SLOT(on_trace_changed())); - connect(t.get(), SIGNAL(text_changed()), + connect(r.get(), SIGNAL(text_changed()), this, SLOT(on_trace_changed())); - connect(t.get(), SIGNAL(colour_changed()), + connect(r.get(), SIGNAL(colour_changed()), this, SLOT(update())); } } diff --git a/pv/view/header.h b/pv/view/header.h index 7759652..f4e7ef4 100644 --- a/pv/view/header.h +++ b/pv/view/header.h @@ -30,7 +30,7 @@ namespace pv { namespace view { -class Trace; +class RowItem; class View; class Header : public MarginWidget @@ -52,7 +52,7 @@ public: static const int BaselineOffset; private: - std::shared_ptr get_mouse_over_trace( + std::shared_ptr get_mouse_over_row_item( const QPoint &pt); void clear_selection(); @@ -88,8 +88,8 @@ private: QPoint _mouse_down_point; bool _dragging; - std::list, int> > - _drag_traces; + std::list, int> > + _drag_row_items; }; } // namespace view diff --git a/pv/view/logicsignal.cpp b/pv/view/logicsignal.cpp index d998717..69c495e 100644 --- a/pv/view/logicsignal.cpp +++ b/pv/view/logicsignal.cpp @@ -137,13 +137,17 @@ void LogicSignal::paint_mid(QPainter &p, int left, int right) assert(_channel); assert(_data); assert(right >= left); + assert(_owner); const int y = get_y(); + + const View *const view = _owner->view(); + assert(view); - const double scale = _view->scale(); + const double scale = view->scale(); assert(scale > 0); - const double offset = _view->offset(); + const double offset = view->offset(); if (!_channel->enabled()) return; diff --git a/pv/view/rowitem.cpp b/pv/view/rowitem.cpp index 81c1ab2..38a6d43 100644 --- a/pv/view/rowitem.cpp +++ b/pv/view/rowitem.cpp @@ -28,7 +28,7 @@ namespace pv { namespace view { RowItem::RowItem() : - _view(NULL), + _owner(NULL), _v_offset(0) { } @@ -43,24 +43,16 @@ void RowItem::set_v_offset(int v_offset) _v_offset = v_offset; } -void RowItem::set_view(View *view) +void RowItem::set_owner(RowItemOwner *owner) { - assert(view); - - if (_view) - disconnect(_view, SIGNAL(hover_point_changed()), - this, SLOT(on_hover_point_changed())); - - _view = view; - - connect(view, SIGNAL(hover_point_changed()), - this, SLOT(on_hover_point_changed())); + assert((_owner && !owner) || (!_owner && owner)); + _owner = owner; } int RowItem::get_y() const { - assert(_view); - return _v_offset + _view->v_offset(); + assert(_owner); + return _v_offset + _owner->owner_v_offset(); } void RowItem::paint_back(QPainter &p, int left, int right) diff --git a/pv/view/rowitem.h b/pv/view/rowitem.h index edf4573..130904a 100644 --- a/pv/view/rowitem.h +++ b/pv/view/rowitem.h @@ -26,7 +26,7 @@ namespace pv { namespace view { -class View; +class RowItemOwner; class RowItem : public SelectableItem { @@ -52,10 +52,10 @@ public: void set_v_offset(int v_offset); /** - * Sets the view that owns this trace in the view trace hierachy. + * Sets the owner this trace in the view trace hierachy. * @param The new owner of the trace. */ - void set_view(pv::view::View *view); + void set_owner(pv::view::RowItemOwner *owner); /** * Gets the y-offset of the axis. @@ -107,7 +107,7 @@ public: virtual void hover_point_changed(); protected: - pv::view::View *_view; + pv::view::RowItemOwner *_owner; int _v_offset; }; diff --git a/pv/view/rowitemowner.h b/pv/view/rowitemowner.h index d961d6b..53e2e14 100644 --- a/pv/view/rowitemowner.h +++ b/pv/view/rowitemowner.h @@ -63,7 +63,6 @@ public: */ virtual std::vector< std::shared_ptr > child_items() const = 0; -protected: virtual void update_viewport() = 0; }; diff --git a/pv/view/view.cpp b/pv/view/view.cpp index 2cb3f3e..7a55bbb 100644 --- a/pv/view/view.cpp +++ b/pv/view/view.cpp @@ -149,6 +149,16 @@ const SigSession& View::session() const return _session; } +View* View::view() +{ + return this; +} + +const View* View::view() const +{ + return this; +} + Viewport* View::viewport() { return _viewport; @@ -169,7 +179,7 @@ double View::offset() const return _offset; } -int View::v_offset() const +int View::owner_v_offset() const { return -_v_offset; } @@ -241,25 +251,25 @@ void View::set_scale_offset(double scale, double offset) scale_offset_changed(); } -vector< shared_ptr > View::get_traces() const +vector< shared_ptr > View::child_items() const { - vector< shared_ptr > traces; + vector< shared_ptr > row_items; const vector< shared_ptr > sigs( session().get_signals()); - copy(sigs.begin(), sigs.end(), back_inserter(traces)); + copy(sigs.begin(), sigs.end(), back_inserter(row_items)); #ifdef ENABLE_DECODE const vector< shared_ptr > decode_sigs( session().get_decode_signals()); - copy(decode_sigs.begin(), decode_sigs.end(), back_inserter(traces)); + copy(decode_sigs.begin(), decode_sigs.end(), back_inserter(row_items)); #endif - stable_sort(traces.begin(), traces.end(), - [](const shared_ptr &a, const shared_ptr &b) { + stable_sort(row_items.begin(), row_items.end(), + [](const shared_ptr &a, const shared_ptr &b) { return a->v_offset() < b->v_offset(); }); - return traces; + return row_items; } list > View::selected_items() const @@ -267,11 +277,11 @@ list > View::selected_items() const list > items; // List the selected signals - const vector< shared_ptr > traces(get_traces()); - for (shared_ptr t : traces) { - assert(t); - if (t->selected()) - items.push_back(t); + const vector< shared_ptr > row_items(child_items()); + for (shared_ptr r : row_items) { + assert(r); + if (r->selected()) + items.push_back(r); } // List the selected cursors @@ -357,15 +367,15 @@ const QPoint& View::hover_point() const void View::normalize_layout() { - const vector< shared_ptr > traces(get_traces()); + const vector< shared_ptr > row_items(child_items()); int v_min = INT_MAX; - for (const shared_ptr t : traces) - v_min = min(t->v_offset(), v_min); + for (const shared_ptr r : row_items) + v_min = min(r->v_offset(), v_min); const int delta = -min(v_min, 0); - for (shared_ptr t : traces) - t->set_v_offset(t->v_offset() + delta); + for (shared_ptr r : row_items) + r->set_v_offset(r->v_offset() + delta); verticalScrollBar()->setSliderPosition(_v_offset + delta); v_scroll_value_changed(verticalScrollBar()->sliderPosition()); @@ -441,6 +451,19 @@ void View::update_layout() update_scroll(); } +void View::paint_label(QPainter &p, int right, bool hover) +{ + (void)p; + (void)right; + (void)hover; +} + +QRectF View::label_rect(int right) +{ + (void)right; + return QRectF(); +} + bool View::eventFilter(QObject *object, QEvent *event) { const QEvent::Type type = event->type(); @@ -519,10 +542,10 @@ void View::v_scroll_value_changed(int value) void View::signals_changed() { int offset = SignalMargin + SignalHeight; - const vector< shared_ptr > traces(get_traces()); - for (shared_ptr t : traces) { - t->set_view(this); - t->set_v_offset(offset); + const vector< shared_ptr > row_items(child_items()); + for (shared_ptr r : row_items) { + r->set_owner(this); + r->set_v_offset(offset); offset += SignalHeight + 2 * SignalMargin; } @@ -558,9 +581,9 @@ void View::on_geometry_updated() void View::on_hover_point_changed() { - const vector< shared_ptr > traces(get_traces()); - for (shared_ptr t : traces) - t->hover_point_changed(); + const vector< shared_ptr > row_items(child_items()); + for (shared_ptr r : row_items) + r->hover_point_changed(); } } // namespace view diff --git a/pv/view/view.h b/pv/view/view.h index 6e097a4..5fbc0ad 100644 --- a/pv/view/view.h +++ b/pv/view/view.h @@ -33,6 +33,7 @@ #include #include "cursorpair.h" +#include "rowitemowner.h" namespace pv { @@ -43,10 +44,9 @@ namespace view { class CursorHeader; class Header; class Ruler; -class Trace; class Viewport; -class View : public QAbstractScrollArea { +class View : public QAbstractScrollArea, public RowItemOwner { Q_OBJECT private: @@ -70,6 +70,16 @@ public: SigSession& session(); const SigSession& session() const; + /** + * Returns the view of the owner. + */ + virtual pv::view::View* view(); + + /** + * Returns the view of the owner. + */ + virtual const pv::view::View* view() const; + Viewport* viewport(); const Viewport* viewport() const; @@ -84,7 +94,7 @@ public: * seconds. */ double offset() const; - int v_offset() const; + int owner_v_offset() const; void zoom(double steps); void zoom(double steps, int offset); @@ -100,7 +110,10 @@ public: */ void set_scale_offset(double scale, double offset); - std::vector< std::shared_ptr > get_traces() const; + /** + * Returns a list of traces owned by this object. + */ + std::vector< std::shared_ptr > child_items() const; std::list > selected_items() const; @@ -164,6 +177,23 @@ private: void update_layout(); + /** + * Satisifies RowItem functionality. + * @param p the QPainter to paint into. + * @param right the x-coordinate of the right edge of the header + * area. + * @param hover true if the label is being hovered over by the mouse. + */ + void paint_label(QPainter &p, int right, bool hover); + + /** + * Computes the outline rectangle of a label. + * @param right the x-coordinate of the right edge of the header + * area. + * @return Returns the rectangle of the signal label. + */ + QRectF label_rect(int right); + private: bool eventFilter(QObject *object, QEvent *event); diff --git a/pv/view/viewport.cpp b/pv/view/viewport.cpp index 7108638..c987c36 100644 --- a/pv/view/viewport.cpp +++ b/pv/view/viewport.cpp @@ -64,10 +64,10 @@ Viewport::Viewport(View &parent) : int Viewport::get_total_height() const { int h = 0; - const vector< shared_ptr > traces(_view.get_traces()); - for (const shared_ptr t : traces) { - assert(t); - h = max(t->v_offset() + View::SignalHeight, h); + const vector< shared_ptr > row_items(_view.child_items()); + for (const shared_ptr r : row_items) { + assert(r); + h = max(r->v_offset() + View::SignalHeight, h); } return h; @@ -75,7 +75,7 @@ int Viewport::get_total_height() const void Viewport::paintEvent(QPaintEvent*) { - const vector< shared_ptr > traces(_view.get_traces()); + const vector< shared_ptr > row_items(_view.child_items()); QPainter p(this); p.setRenderHint(QPainter::Antialiasing); @@ -84,17 +84,17 @@ void Viewport::paintEvent(QPaintEvent*) _view.cursors().draw_viewport_background(p, rect()); // Plot the signal - for (const shared_ptr t : traces) + for (const shared_ptr r : row_items) { - assert(t); - t->paint_back(p, 0, width()); + assert(r); + r->paint_back(p, 0, width()); } - for (const shared_ptr t : traces) - t->paint_mid(p, 0, width()); + for (const shared_ptr r : row_items) + r->paint_mid(p, 0, width()); - for (const shared_ptr t : traces) - t->paint_fore(p, 0, width()); + for (const shared_ptr r : row_items) + r->paint_fore(p, 0, width()); if (_view.cursors_shown()) _view.cursors().draw_viewport_foreground(p, rect()); @@ -230,10 +230,10 @@ bool Viewport::touchEvent(QTouchEvent *event) void Viewport::on_signals_changed() { - const vector< shared_ptr > traces(_view.get_traces()); - for (shared_ptr t : traces) { - assert(t); - connect(t.get(), SIGNAL(visibility_changed()), + const vector< shared_ptr > row_items(_view.child_items()); + for (shared_ptr r : row_items) { + assert(r); + connect(r.get(), SIGNAL(visibility_changed()), this, SLOT(update())); } }