Added pv::widgets::ColourButton
[pulseview.git] / pv / view / cursor.cpp
1 /*
2  * This file is part of the PulseView project.
3  *
4  * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
19  */
20
21 #include "cursor.h"
22
23 #include "ruler.h"
24 #include "view.h"
25
26 #include <QBrush>
27 #include <QPainter>
28 #include <QPointF>
29 #include <QRect>
30 #include <QRectF>
31
32 #include <stdio.h>
33
34 #include <extdef.h>
35
36 using namespace boost;
37
38 namespace pv {
39 namespace view {
40
41 const QColor Cursor::LineColour(32, 74, 135);
42 const QColor Cursor::FillColour(52, 101, 164);
43 const QColor Cursor::HighlightColour(83, 130, 186);
44 const QColor Cursor::TextColour(Qt::white);
45
46 const int Cursor::Offset = 1;
47
48 const int Cursor::ArrowSize = 4;
49
50 Cursor::Cursor(View &view, double time) :
51         TimeMarker(view, LineColour, time)
52 {
53 }
54
55 QRectF Cursor::get_label_rect(const QRect &rect) const
56 {
57         const shared_ptr<Cursor> other(get_other_cursor());
58         assert(other);
59
60         const float x = (_time - _view.offset()) / _view.scale();
61
62         const QSizeF label_size(
63                 _text_size.width() + View::LabelPadding.width() * 2,
64                 _text_size.height() + View::LabelPadding.height() * 2);
65         const float top = rect.height() - label_size.height() -
66                 Cursor::Offset - Cursor::ArrowSize - 0.5f;
67         const float height = label_size.height();
68
69         if (_time > other->time())
70                 return QRectF(x, top, label_size.width(), height);
71         else
72                 return QRectF(x - label_size.width(), top,
73                         label_size.width(), height);
74 }
75
76 void Cursor::paint_label(QPainter &p, const QRect &rect,
77         unsigned int prefix)
78 {
79         const shared_ptr<Cursor> other(get_other_cursor());
80         assert(other);
81
82         compute_text_size(p, prefix);
83         const QRectF r(get_label_rect(rect));
84
85         const QPointF left_points[] = {
86                 r.topLeft(),
87                 r.topRight(),
88                 r.bottomRight(),
89                 QPointF(r.left() + ArrowSize, r.bottom()),
90                 QPointF(r.left(), rect.bottom()),
91         };
92
93         const QPointF right_points[] = {
94                 r.topRight(),
95                 r.topLeft(),
96                 r.bottomLeft(),
97                 QPointF(r.right() - ArrowSize, r.bottom()),
98                 QPointF(r.right(), rect.bottom()),
99         };
100
101         const QPointF left_highlight_points[] = {
102                 QPointF(r.left() + 1, r.top() + 1),
103                 QPointF(r.right() - 1, r.top() + 1),
104                 QPointF(r.right() - 1, r.bottom() - 1),
105                 QPointF(r.left() + ArrowSize - 1, r.bottom() - 1),
106                 QPointF(r.left() + 1, rect.bottom() - 1),
107         };
108
109         const QPointF right_highlight_points[] = {
110                 QPointF(r.right() - 1, r.top() + 1),
111                 QPointF(r.left() + 1, r.top() + 1),
112                 QPointF(r.left() + 1, r.bottom() - 1),
113                 QPointF(r.right() - ArrowSize + 1, r.bottom() - 1),
114                 QPointF(r.right() - 1, rect.bottom() - 1),
115         };
116
117         const QPointF *const points = (_time > other->time()) ?
118                 left_points : right_points;
119         const QPointF *const highlight_points = (_time > other->time()) ?
120                 left_highlight_points : right_highlight_points;
121
122         if (selected()) {
123                 p.setPen(highlight_pen());
124                 p.setBrush(Qt::transparent);
125                 p.drawPolygon(points, countof(left_points));
126         }
127
128         p.setPen(Qt::transparent);
129         p.setBrush(FillColour);
130         p.drawPolygon(points, countof(left_points));
131
132         p.setPen(HighlightColour);
133         p.setBrush(Qt::transparent);
134         p.drawPolygon(highlight_points, countof(left_highlight_points));
135
136         p.setPen(LineColour);
137         p.setBrush(Qt::transparent);
138         p.drawPolygon(points, countof(left_points));
139
140         p.setPen(TextColour);
141         p.drawText(r, Qt::AlignCenter | Qt::AlignVCenter,
142                 Ruler::format_time(_time, prefix, 2));
143 }
144
145 void Cursor::compute_text_size(QPainter &p, unsigned int prefix)
146 {
147         _text_size = p.boundingRect(QRectF(), 0,
148                 Ruler::format_time(_time, prefix, 2)).size();
149 }
150
151 shared_ptr<Cursor> Cursor::get_other_cursor() const
152 {
153         const CursorPair &cursors = _view.cursors();
154         return (cursors.first().get() == this) ?
155                 cursors.second() : cursors.first();
156 }
157
158 } // namespace view
159 } // namespace pv