+void Viewport::paintEvent(QPaintEvent*)
+{
+ typedef void (ViewItem::*LayerPaintFunc)(
+ QPainter &p, ViewItemPaintParams &pp);
+ LayerPaintFunc layer_paint_funcs[] = {
+ &ViewItem::paint_back, &ViewItem::paint_mid,
+ &ViewItem::paint_fore, nullptr};
+
+ vector< shared_ptr<RowItem> > row_items(view_.list_by_type<RowItem>());
+ assert(none_of(row_items.begin(), row_items.end(),
+ [](const shared_ptr<RowItem> &r) { return !r; }));
+
+ stable_sort(row_items.begin(), row_items.end(),
+ [](const shared_ptr<RowItem> &a, const shared_ptr<RowItem> &b) {
+ return a->point(QRect()).y() < b->point(QRect()).y(); });
+
+ const vector< shared_ptr<TimeItem> > time_items(view_.time_items());
+ assert(none_of(time_items.begin(), time_items.end(),
+ [](const shared_ptr<TimeItem> &t) { return !t; }));
+
+ QPainter p(this);
+ p.setRenderHint(QPainter::Antialiasing);
+
+ for (LayerPaintFunc *paint_func = layer_paint_funcs;
+ *paint_func; paint_func++) {
+ ViewItemPaintParams time_pp(rect(), view_.scale(), view_.offset());
+ for (const shared_ptr<TimeItem> t : time_items)
+ (t.get()->*(*paint_func))(p, time_pp);
+
+ ViewItemPaintParams row_pp(rect(), view_.scale(), view_.offset());
+ for (const shared_ptr<RowItem> r : row_items)
+ (r.get()->*(*paint_func))(p, row_pp);
+ }
+
+ p.end();
+}
+
+void Viewport::mouseDoubleClickEvent(QMouseEvent *event)