PulseView  0.3.0
A Qt-based sigrok GUI
cursorpair.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the PulseView project.
3  *
4  * Copyright (C) 2013 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 "cursorpair.hpp"
22 
23 #include "ruler.hpp"
24 #include "view.hpp"
25 #include "pv/util.hpp"
26 
27 #include <cassert>
28 #include <algorithm>
29 
30 using std::max;
31 using std::make_pair;
32 using std::min;
33 using std::shared_ptr;
34 using std::pair;
35 
36 namespace pv {
37 namespace view {
38 
39 const int CursorPair::DeltaPadding = 8;
40 const QColor CursorPair::ViewportFillColour(220, 231, 243);
41 
43  TimeItem(view),
44  first_(new Cursor(view, 0.0)),
45  second_(new Cursor(view, 1.0))
46 {
47 }
48 
49 bool CursorPair::enabled() const
50 {
51  return view_.cursors_shown();
52 }
53 
54 shared_ptr<Cursor> CursorPair::first() const
55 {
56  return first_;
57 }
58 
59 shared_ptr<Cursor> CursorPair::second() const
60 {
61  return second_;
62 }
63 
65 {
66  const pv::util::Timestamp delta = second_->time() - first_->time();
67  first_->set_time(time);
68  second_->set_time(time + delta);
69 }
70 
71 float CursorPair::get_x() const
72 {
73  return (first_->get_x() + second_->get_x()) / 2.0f;
74 }
75 
76 QPoint CursorPair::point(const QRect &rect) const
77 {
78  return first_->point(rect);
79 }
80 
82 {
83  (void)parent;
84  return nullptr;
85 }
86 
87 QRectF CursorPair::label_rect(const QRectF &rect) const
88 {
89  const QSizeF label_size(text_size_ + LabelPadding * 2);
90  const pair<float, float> offsets(get_cursor_offsets());
91  const pair<float, float> normal_offsets(
92  (offsets.first < offsets.second) ? offsets :
93  make_pair(offsets.second, offsets.first));
94 
95  const float height = label_size.height();
96  const float left = max(normal_offsets.first + DeltaPadding, -height);
97  const float right = min(normal_offsets.second - DeltaPadding,
98  (float)rect.width() + height);
99 
100  return QRectF(left, rect.height() - label_size.height() -
101  TimeMarker::ArrowSize - 0.5f,
102  right - left, height);
103 }
104 
105 void CursorPair::paint_label(QPainter &p, const QRect &rect, bool hover)
106 {
107  assert(first_);
108  assert(second_);
109 
110  if (!enabled())
111  return;
112 
113  const QColor text_colour =
115 
116  p.setPen(text_colour);
118  QRectF delta_rect(label_rect(rect));
119 
120  const int radius = delta_rect.height() / 2;
121  const QRectF text_rect(delta_rect.intersected(
122  rect).adjusted(radius, 0, -radius, 0));
123  if (text_rect.width() >= text_size_.width()) {
124  const int highlight_radius = delta_rect.height() / 2 - 2;
125 
126  if (selected()) {
127  p.setBrush(Qt::transparent);
128  p.setPen(highlight_pen());
129  p.drawRoundedRect(delta_rect, radius, radius);
130  }
131 
132  p.setBrush(hover ? Cursor::FillColour.lighter() :
134  p.setPen(Cursor::FillColour.darker());
135  p.drawRoundedRect(delta_rect, radius, radius);
136 
137  delta_rect.adjust(1, 1, -1, -1);
138  p.setPen(Cursor::FillColour.lighter());
139  p.drawRoundedRect(delta_rect, highlight_radius, highlight_radius);
140 
141  p.setPen(text_colour);
142  p.drawText(text_rect, Qt::AlignCenter | Qt::AlignVCenter,
143  format_string());
144  }
145 }
146 
147 void CursorPair::paint_back(QPainter &p, const ViewItemPaintParams &pp)
148 {
149  if (!enabled())
150  return;
151 
152  p.setPen(Qt::NoPen);
153  p.setBrush(QBrush(ViewportFillColour));
154 
155  const pair<float, float> offsets(get_cursor_offsets());
156  const int l = (int)max(min(
157  offsets.first, offsets.second), 0.0f);
158  const int r = (int)min(max(
159  offsets.first, offsets.second), (float)pp.width());
160 
161  p.drawRect(l, pp.top(), r - l, pp.height());
162 }
163 
165 {
166  const pv::util::SIPrefix prefix = view_.tick_prefix();
167  const pv::util::Timestamp diff = abs(second_->time() - first_->time());
168 
169  const QString s1 = Ruler::format_time_with_distance(
170  diff, diff, prefix, view_.time_unit(), view_.tick_precision(), false);
171  const QString s2 = util::format_time_si(
172  1 / diff, pv::util::SIPrefix::unspecified, 4, "Hz", false);
173 
174  return QString("%1 / %2").arg(s1).arg(s2);
175 }
176 
178 {
179  assert(first_);
180  assert(second_);
181 
182  text_size_ = p.boundingRect(QRectF(), 0, format_string()).size();
183 }
184 
185 pair<float, float> CursorPair::get_cursor_offsets() const
186 {
187  assert(first_);
188  assert(second_);
189 
190  return pair<float, float>(
191  ((first_->time() - view_.offset()) / view_.scale()).convert_to<float>(),
192  ((second_->time() - view_.offset()) / view_.scale()).convert_to<float>());
193 }
194 
195 } // namespace view
196 } // namespace pv
static const QSizeF LabelPadding
Definition: viewitem.hpp:49
void paint_back(QPainter &p, const ViewItemPaintParams &pp)
Definition: cursorpair.cpp:147
std::pair< float, float > get_cursor_offsets() const
Definition: cursorpair.cpp:185
CursorPair(View &view)
Definition: cursorpair.cpp:42
pv::util::SIPrefix tick_prefix() const
Definition: view.cpp:263
std::shared_ptr< Cursor > first() const
Definition: cursorpair.cpp:54
SIPrefix
Definition: util.hpp:41
static const QColor ViewportFillColour
Definition: cursorpair.hpp:39
QString format_time_si(const Timestamp &v, SIPrefix prefix, unsigned int precision, QString unit, bool sign)
Definition: util.cpp:107
void paint_label(QPainter &p, const QRect &rect, bool hover)
Definition: cursorpair.cpp:105
std::shared_ptr< Cursor > second() const
Definition: cursorpair.cpp:59
static const int ArrowSize
Definition: timemarker.hpp:49
static const QColor FillColour
Definition: cursor.hpp:40
unsigned int tick_precision() const
Definition: view.cpp:276
float get_x() const
Definition: cursorpair.cpp:71
bool enabled() const
Definition: cursorpair.cpp:49
static QColor select_text_colour(QColor background)
Definition: viewitem.cpp:133
static QString format_time_with_distance(const pv::util::Timestamp &distance, const pv::util::Timestamp &t, pv::util::SIPrefix prefix=pv::util::SIPrefix::unspecified, pv::util::TimeUnit unit=pv::util::TimeUnit::Time, unsigned precision=0, bool sign=true)
Definition: ruler.cpp:80
static const int DeltaPadding
Definition: cursorpair.hpp:38
void compute_text_size(QPainter &p)
Definition: cursorpair.cpp:177
util::TimeUnit time_unit() const
Definition: view.cpp:302
double scale() const
Definition: view.cpp:220
bool cursors_shown() const
Definition: view.cpp:466
bool selected() const
Definition: viewitem.cpp:42
pv::widgets::Popup * create_popup(QWidget *parent)
Definition: cursorpair.cpp:81
void set_time(const pv::util::Timestamp &time) override
Definition: cursorpair.cpp:64
QPoint point(const QRect &rect) const
Definition: cursorpair.cpp:76
const pv::util::Timestamp & offset() const
Definition: view.cpp:233
boost::multiprecision::number< boost::multiprecision::cpp_dec_float< 24 >, boost::multiprecision::et_off > Timestamp
Timestamp type providing yoctosecond resolution.
Definition: util.hpp:58
std::shared_ptr< Cursor > first_
Definition: cursorpair.hpp:103
static QPen highlight_pen()
Definition: viewitem.cpp:101
std::shared_ptr< Cursor > second_
Definition: cursorpair.hpp:103
QRectF label_rect(const QRectF &rect) const
Definition: cursorpair.cpp:87