const int View::MaxScrollValue = INT_MAX / 2;
-const int View::ScaleUnits[3] = {1, 2, 5};
+/* Area at the top and bottom of the view that can't be scrolled out of sight */
+const int View::ViewScrollMargin = 50;
+const int View::ScaleUnits[3] = {1, 2, 5};
CustomScrollArea::CustomScrollArea(QWidget *parent) :
QAbstractScrollArea(parent)
connect(&lazy_event_handler_, SIGNAL(timeout()),
this, SLOT(process_sticky_events()));
lazy_event_handler_.setSingleShot(true);
+ lazy_event_handler_.setInterval(1000 / ViewBase::MaxViewAutoUpdateRate);
// Set up local keyboard shortcuts
zoom_in_shortcut_ = new QShortcut(QKeySequence(Qt::Key_Plus), this,
return session_;
}
-unordered_set< shared_ptr<Signal> > View::signals() const
+vector< shared_ptr<Signal> > View::signals() const
{
return signals_;
}
void View::add_signal(const shared_ptr<Signal> signal)
{
ViewBase::add_signalbase(signal->base());
- signals_.insert(signal);
+ signals_.push_back(signal);
signal->set_segment_display_mode(segment_display_mode_);
signal->set_current_segment(current_segment_);
set_scale_offset(scale.convert_to<double>(), extents.first);
}
+void View::focus_on_range(uint64_t start_sample, uint64_t end_sample)
+{
+ assert(viewport_);
+ const int w = viewport_->width();
+ if (w <= 0)
+ return;
+
+ const double samplerate = session_.get_samplerate();
+
+ const uint64_t sample_delta = (end_sample - start_sample);
+
+ // Note: We add 20% margin on the left and 5% on the right
+ const Timestamp delta = (sample_delta * 1.25) / samplerate;
+
+ const Timestamp scale = max(min(delta / w, MaxScale), MinScale);
+ const Timestamp offset = (start_sample - sample_delta * 0.20) / samplerate;
+
+ set_scale_offset(scale.convert_to<double>(), offset);
+}
+
void View::set_scale_offset(double scale, const Timestamp& offset)
{
// Disable sticky scrolling / always zoom to fit when acquisition runs
viewport_->update();
}
-set< shared_ptr<SignalData> > View::get_visible_data() const
+vector< shared_ptr<SignalData> > View::get_visible_data() const
{
// Make a set of all the visible data objects
- set< shared_ptr<SignalData> > visible_data;
+ vector< shared_ptr<SignalData> > visible_data;
for (const shared_ptr<Signal>& sig : signals_)
if (sig->enabled())
- visible_data.insert(sig->data());
+ visible_data.push_back(sig->data());
return visible_data;
}
pair<Timestamp, Timestamp> View::get_time_extents() const
{
boost::optional<Timestamp> left_time, right_time;
- const set< shared_ptr<SignalData> > visible_data = get_visible_data();
- for (const shared_ptr<SignalData>& d : visible_data) {
+
+ vector< shared_ptr<SignalData> > data;
+ if (signals_.size() == 0)
+ return make_pair(0, 0);
+
+ data.push_back(signals_.front()->data());
+
+ for (const shared_ptr<SignalData>& d : data) {
const vector< shared_ptr<Segment> > segments = d->segments();
for (const shared_ptr<Segment>& s : segments) {
double samplerate = s->samplerate();
const pair<int, int> extents = v_extents();
// Don't change the scrollbar range if there are no traces
- if (extents.first != extents.second)
- vscrollbar->setRange(extents.first - areaSize.height(),
- extents.second);
+ if (extents.first != extents.second) {
+ int top_margin = ViewScrollMargin;
+ int btm_margin = ViewScrollMargin;
+
+ vscrollbar->setRange(extents.first - areaSize.height() + top_margin,
+ extents.second - btm_margin);
+ }
if (scroll_needs_defaults_) {
set_scroll_default();
(horz ? TraceTreeItemHExtentsChanged : 0) |
(vert ? TraceTreeItemVExtentsChanged : 0);
- lazy_event_handler_.stop();
- lazy_event_handler_.start();
+ if (!lazy_event_handler_.isActive())
+ lazy_event_handler_.start();
}
void View::on_signal_name_changed()
void View::on_settingViewTriggerIsZeroTime_changed(const QVariant new_value)
{
+ (void)new_value;
+
if (!custom_zero_offset_set_)
reset_zero_position();
}