+void Ruler::mouseMoveEvent(QMouseEvent *e)
+{
+ mouse_point_ = e->pos();
+
+ if (!(e->buttons() & Qt::LeftButton))
+ return;
+
+ if ((e->pos() - mouse_down_point_).manhattanLength() <
+ QApplication::startDragDistance())
+ return;
+
+ // Do the drag
+ dragging_ = true;
+
+ const QPoint delta = e->pos() - mouse_down_point_;
+ const vector< shared_ptr<TimeItem> > items(view_.time_items());
+ for (auto &i : items)
+ if (i->dragging())
+ i->drag_by(delta);
+}
+
+void Ruler::mouseReleaseEvent(QMouseEvent *)
+{
+ using pv::widgets::Popup;
+
+ if (!dragging_ && mouse_down_item_)
+ show_popup(mouse_down_item_);
+
+ dragging_ = false;
+ mouse_down_item_.reset();
+
+ const vector< shared_ptr<TimeItem> > items(view_.time_items());
+ for (auto &i : items)
+ i->drag_release();
+}
+
+void Ruler::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ view_.add_flag(view_.offset() + ((double)e->x() + 0.5) * view_.scale());
+}
+
+void Ruler::draw_hover_mark(QPainter &p, int text_height)
+{
+ const int x = view_.hover_point().x();
+
+ if (x == -1)
+ return;
+
+ p.setPen(QPen(Qt::NoPen));
+ p.setBrush(QBrush(palette().color(foregroundRole())));
+
+ const int b = RulerHeight * text_height;
+ const float hover_arrow_size = HoverArrowSize * text_height;
+ const QPointF points[] = {
+ QPointF(x, b),
+ QPointF(x - hover_arrow_size, b - hover_arrow_size),
+ QPointF(x + hover_arrow_size, b - hover_arrow_size)
+ };
+ p.drawPolygon(points, countof(points));
+}
+
+int Ruler::calculate_text_height() const
+{
+ return QFontMetrics(font()).ascent();
+}
+
+void Ruler::hover_point_changed()
+{
+ update();