{
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;
pair<double, double> 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();
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()) {
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,
void DecodeTrace::on_new_decode_data()
{
- if (_view)
- _view->update_viewport();
+ if (_owner)
+ _owner->update_viewport();
}
void DecodeTrace::delete_pressed()
assert(index < (int)_decoder_forms.size());
_decoder_forms[index]->set_decoder_visible(show);
- _view->update_viewport();
+ _owner->update_viewport();
}
} // namespace view
{
int max_width = 0;
- const vector< shared_ptr<Trace> > traces(_view.get_traces());
- for (shared_ptr<Trace> t : traces) {
- assert(t);
+ const vector< shared_ptr<RowItem> > row_items(_view.child_items());
+ for (shared_ptr<RowItem> 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<Trace> Header::get_mouse_over_trace(const QPoint &pt)
+shared_ptr<RowItem> Header::get_mouse_over_row_item(const QPoint &pt)
{
const int w = width() - BaselineOffset;
- const vector< shared_ptr<Trace> > traces(_view.get_traces());
+ const vector< shared_ptr<RowItem> > row_items(_view.child_items());
- for (const shared_ptr<Trace> t : traces)
+ for (const shared_ptr<RowItem> 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<Trace>();
+ return shared_ptr<RowItem>();
}
void Header::clear_selection()
{
- const vector< shared_ptr<Trace> > traces(_view.get_traces());
- for (const shared_ptr<Trace> t : traces) {
- assert(t);
- t->select(false);
+ const vector< shared_ptr<RowItem> > row_items(_view.child_items());
+ for (const shared_ptr<RowItem> r : row_items) {
+ assert(r);
+ r->select(false);
}
update();
// left edge of the widget, because then the selection shadow
// would be clipped away.
const int w = width() - BaselineOffset;
- const vector< shared_ptr<Trace> > traces(_view.get_traces());
+ const vector< shared_ptr<RowItem> > row_items(_view.child_items());
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
- const bool dragging = !_drag_traces.empty();
- for (const shared_ptr<Trace> t : traces)
+ const bool dragging = !_drag_row_items.empty();
+ for (const shared_ptr<RowItem> 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();
{
assert(event);
- const vector< shared_ptr<Trace> > traces(_view.get_traces());
+ const vector< shared_ptr<RowItem> > 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<Trace> t : traces)
- if (t->selected())
- _drag_traces.push_back(
- make_pair(t, t->v_offset()));
+ for (const shared_ptr<RowItem> 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<Trace> 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<RowItem> 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<Trace> t : traces)
- if (t != mouse_over_trace)
- t->select(false);
+ for (const shared_ptr<RowItem> r : row_items)
+ if (r != mouse_over_row_item)
+ r->select(false);
}
selection_changed();
_view.normalize_layout();
else
{
- const shared_ptr<Trace> mouse_over_trace =
- get_mouse_over_trace(event->pos());
- if (mouse_over_trace) {
+ const shared_ptr<RowItem> 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();
}
}
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> trace((*i).first);
- if (trace) {
+ for (auto i = _drag_row_items.begin();
+ i != _drag_row_items.end(); i++) {
+ const std::shared_ptr<RowItem> 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();
}
}
void Header::contextMenuEvent(QContextMenuEvent *event)
{
- const shared_ptr<Trace> t = get_mouse_over_trace(_mouse_point);
+ const shared_ptr<RowItem> 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)
{
case Qt::Key_Delete:
{
- const vector< shared_ptr<Trace> > traces(_view.get_traces());
- for (const shared_ptr<Trace> t : traces)
- if (t->selected())
- t->delete_pressed();
+ const vector< shared_ptr<RowItem> > row_items(_view.child_items());
+ for (const shared_ptr<RowItem> r : row_items)
+ if (r->selected())
+ r->delete_pressed();
break;
}
}
void Header::on_signals_changed()
{
- const vector< shared_ptr<Trace> > traces(_view.get_traces());
- for (shared_ptr<Trace> t : traces) {
- assert(t);
- connect(t.get(), SIGNAL(visibility_changed()),
+ const vector< shared_ptr<RowItem> > row_items(_view.child_items());
+ for (shared_ptr<RowItem> 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()));
}
}
namespace pv {
namespace view {
-class Trace;
+class RowItem;
class View;
class Header : public MarginWidget
static const int BaselineOffset;
private:
- std::shared_ptr<pv::view::Trace> get_mouse_over_trace(
+ std::shared_ptr<pv::view::RowItem> get_mouse_over_row_item(
const QPoint &pt);
void clear_selection();
QPoint _mouse_down_point;
bool _dragging;
- std::list<std::pair<std::weak_ptr<Trace>, int> >
- _drag_traces;
+ std::list<std::pair<std::weak_ptr<RowItem>, int> >
+ _drag_row_items;
};
} // namespace view
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;
namespace view {
RowItem::RowItem() :
- _view(NULL),
+ _owner(NULL),
_v_offset(0)
{
}
_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)
namespace pv {
namespace view {
-class View;
+class RowItemOwner;
class RowItem : public SelectableItem
{
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.
virtual void hover_point_changed();
protected:
- pv::view::View *_view;
+ pv::view::RowItemOwner *_owner;
int _v_offset;
};
*/
virtual std::vector< std::shared_ptr<RowItem> > child_items() const = 0;
-protected:
virtual void update_viewport() = 0;
};
return _session;
}
+View* View::view()
+{
+ return this;
+}
+
+const View* View::view() const
+{
+ return this;
+}
+
Viewport* View::viewport()
{
return _viewport;
return _offset;
}
-int View::v_offset() const
+int View::owner_v_offset() const
{
return -_v_offset;
}
scale_offset_changed();
}
-vector< shared_ptr<Trace> > View::get_traces() const
+vector< shared_ptr<RowItem> > View::child_items() const
{
- vector< shared_ptr<Trace> > traces;
+ vector< shared_ptr<RowItem> > row_items;
const vector< shared_ptr<Signal> > 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<DecodeTrace> > 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<Trace> &a, const shared_ptr<Trace> &b) {
+ stable_sort(row_items.begin(), row_items.end(),
+ [](const shared_ptr<RowItem> &a, const shared_ptr<RowItem> &b) {
return a->v_offset() < b->v_offset(); });
- return traces;
+ return row_items;
}
list<weak_ptr<SelectableItem> > View::selected_items() const
list<weak_ptr<SelectableItem> > items;
// List the selected signals
- const vector< shared_ptr<Trace> > traces(get_traces());
- for (shared_ptr<Trace> t : traces) {
- assert(t);
- if (t->selected())
- items.push_back(t);
+ const vector< shared_ptr<RowItem> > row_items(child_items());
+ for (shared_ptr<RowItem> r : row_items) {
+ assert(r);
+ if (r->selected())
+ items.push_back(r);
}
// List the selected cursors
void View::normalize_layout()
{
- const vector< shared_ptr<Trace> > traces(get_traces());
+ const vector< shared_ptr<RowItem> > row_items(child_items());
int v_min = INT_MAX;
- for (const shared_ptr<Trace> t : traces)
- v_min = min(t->v_offset(), v_min);
+ for (const shared_ptr<RowItem> r : row_items)
+ v_min = min(r->v_offset(), v_min);
const int delta = -min(v_min, 0);
- for (shared_ptr<Trace> t : traces)
- t->set_v_offset(t->v_offset() + delta);
+ for (shared_ptr<RowItem> r : row_items)
+ r->set_v_offset(r->v_offset() + delta);
verticalScrollBar()->setSliderPosition(_v_offset + delta);
v_scroll_value_changed(verticalScrollBar()->sliderPosition());
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();
void View::signals_changed()
{
int offset = SignalMargin + SignalHeight;
- const vector< shared_ptr<Trace> > traces(get_traces());
- for (shared_ptr<Trace> t : traces) {
- t->set_view(this);
- t->set_v_offset(offset);
+ const vector< shared_ptr<RowItem> > row_items(child_items());
+ for (shared_ptr<RowItem> r : row_items) {
+ r->set_owner(this);
+ r->set_v_offset(offset);
offset += SignalHeight + 2 * SignalMargin;
}
void View::on_hover_point_changed()
{
- const vector< shared_ptr<Trace> > traces(get_traces());
- for (shared_ptr<Trace> t : traces)
- t->hover_point_changed();
+ const vector< shared_ptr<RowItem> > row_items(child_items());
+ for (shared_ptr<RowItem> r : row_items)
+ r->hover_point_changed();
}
} // namespace view
#include <pv/data/signaldata.h>
#include "cursorpair.h"
+#include "rowitemowner.h"
namespace pv {
class CursorHeader;
class Header;
class Ruler;
-class Trace;
class Viewport;
-class View : public QAbstractScrollArea {
+class View : public QAbstractScrollArea, public RowItemOwner {
Q_OBJECT
private:
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;
* seconds.
*/
double offset() const;
- int v_offset() const;
+ int owner_v_offset() const;
void zoom(double steps);
void zoom(double steps, int offset);
*/
void set_scale_offset(double scale, double offset);
- std::vector< std::shared_ptr<Trace> > get_traces() const;
+ /**
+ * Returns a list of traces owned by this object.
+ */
+ std::vector< std::shared_ptr<RowItem> > child_items() const;
std::list<std::weak_ptr<SelectableItem> > selected_items() const;
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);
int Viewport::get_total_height() const
{
int h = 0;
- const vector< shared_ptr<Trace> > traces(_view.get_traces());
- for (const shared_ptr<Trace> t : traces) {
- assert(t);
- h = max(t->v_offset() + View::SignalHeight, h);
+ const vector< shared_ptr<RowItem> > row_items(_view.child_items());
+ for (const shared_ptr<RowItem> r : row_items) {
+ assert(r);
+ h = max(r->v_offset() + View::SignalHeight, h);
}
return h;
void Viewport::paintEvent(QPaintEvent*)
{
- const vector< shared_ptr<Trace> > traces(_view.get_traces());
+ const vector< shared_ptr<RowItem> > row_items(_view.child_items());
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
_view.cursors().draw_viewport_background(p, rect());
// Plot the signal
- for (const shared_ptr<Trace> t : traces)
+ for (const shared_ptr<RowItem> r : row_items)
{
- assert(t);
- t->paint_back(p, 0, width());
+ assert(r);
+ r->paint_back(p, 0, width());
}
- for (const shared_ptr<Trace> t : traces)
- t->paint_mid(p, 0, width());
+ for (const shared_ptr<RowItem> r : row_items)
+ r->paint_mid(p, 0, width());
- for (const shared_ptr<Trace> t : traces)
- t->paint_fore(p, 0, width());
+ for (const shared_ptr<RowItem> r : row_items)
+ r->paint_fore(p, 0, width());
if (_view.cursors_shown())
_view.cursors().draw_viewport_foreground(p, rect());
void Viewport::on_signals_changed()
{
- const vector< shared_ptr<Trace> > traces(_view.get_traces());
- for (shared_ptr<Trace> t : traces) {
- assert(t);
- connect(t.get(), SIGNAL(visibility_changed()),
+ const vector< shared_ptr<RowItem> > row_items(_view.child_items());
+ for (shared_ptr<RowItem> r : row_items) {
+ assert(r);
+ connect(r.get(), SIGNAL(visibility_changed()),
this, SLOT(update()));
}
}