#include <libsigrokcxx/libsigrokcxx.hpp>
-#include "analogsignal.hpp"
-#include "header.hpp"
-#include "logicsignal.hpp"
-#include "ruler.hpp"
-#include "signal.hpp"
-#include "tracegroup.hpp"
-#include "triggermarker.hpp"
#include "view.hpp"
-#include "viewport.hpp"
+#include "pv/globalsettings.hpp"
#include "pv/metadata_obj.hpp"
+#include "pv/session.hpp"
+#include "pv/util.hpp"
#include "pv/data/logic.hpp"
#include "pv/data/logicsegment.hpp"
#include "pv/data/signalbase.hpp"
#include "pv/devices/device.hpp"
-#include "pv/globalsettings.hpp"
-#include "pv/session.hpp"
-#include "pv/util.hpp"
+#include "pv/views/trace/mathsignal.hpp"
+#include "pv/views/trace/analogsignal.hpp"
+#include "pv/views/trace/header.hpp"
+#include "pv/views/trace/logicsignal.hpp"
+#include "pv/views/trace/ruler.hpp"
+#include "pv/views/trace/signal.hpp"
+#include "pv/views/trace/tracegroup.hpp"
+#include "pv/views/trace/triggermarker.hpp"
+#include "pv/views/trace/viewport.hpp"
#ifdef ENABLE_DECODE
-#include "decodetrace.hpp"
+#include "pv/views/trace/decodetrace.hpp"
#endif
using pv::data::SignalBase;
signal = shared_ptr<Signal>(new AnalogSignal(session_, signalbase));
break;
+ case SignalBase::MathChannel:
+ signal = shared_ptr<Signal>(new MathSignal(session_, signalbase));
+ break;
+
default:
qDebug() << "Unknown signalbase type:" << signalbase->type();
assert(false);
{
if (scale_ != scale) {
scale_ = scale;
+
+ update_view_range_metaobject();
+
scale_changed();
}
}
offset_ = offset;
ruler_offset_ = offset_ + zero_offset_;
- const int w = viewport_->width();
- if (w > 0) {
- const double samplerate = session_.get_samplerate();
- // Note: sample_num = time * samplerate
- // Note: samples_per_pixel = samplerate * scale
- int64_t start_sample = (offset_ * samplerate).convert_to<int64_t>();
- int64_t end_sample = (offset_ * samplerate).convert_to<int64_t>() +
- (w * session_.get_samplerate() * scale_);
-
- MetadataObject* md_obj =
- session_.metadata_obj_manager()->find_object_by_type(MetadataObjMainViewRange);
- md_obj->set_value(MetadataValueStartSample, QVariant((qlonglong)start_sample));
- md_obj->set_value(MetadataValueEndSample, QVariant((qlonglong)end_sample));
- }
+ update_view_range_metaobject();
offset_changed();
}
for (const shared_ptr<Signal>& signal : signals_)
signal->set_segment_display_mode(mode);
- uint32_t last_segment = session_.get_segment_count() - 1;
+ uint32_t last_segment = session_.get_highest_segment_id();
switch (mode) {
case Trace::ShowLastSegmentOnly:
void View::focus_on_range(uint64_t start_sample, uint64_t end_sample)
{
assert(viewport_);
- const int w = viewport_->width();
+ const uint64_t w = viewport_->width();
if (w <= 0)
return;
const double samplerate = session_.get_samplerate();
+ const double samples_per_pixel = samplerate * scale_;
+ const uint64_t viewport_samples = w * samples_per_pixel;
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);
+ const uint64_t ext_sample_delta = sample_delta * 1.25;
+
+ // Check if we can keep the zoom level and just center the supplied range
+ if (viewport_samples >= ext_sample_delta) {
+ // Note: offset is the left edge of the view so to center, we subtract half the view width
+ const int64_t sample_offset = (start_sample + (sample_delta / 2) - (viewport_samples / 2));
+ const Timestamp offset = sample_offset / samplerate;
+ set_scale_offset(scale_, offset);
+ } else {
+ const Timestamp offset = (start_sample - sample_delta * 0.20) / samplerate;
+ const Timestamp delta = ext_sample_delta / samplerate;
+ const Timestamp scale = max(min(delta / w, MaxScale), MinScale);
+ set_scale_offset(scale.convert_to<double>(), offset);
+ }
}
void View::set_scale_offset(double scale, const Timestamp& offset)
if (signals_.size() == 0)
return make_pair(0, 0);
- data.push_back(signals_.front()->data());
+ for (shared_ptr<Signal> s : signals_)
+ if (s->data() && (s->data()->segments().size() > 0))
+ data.push_back(s->data());
for (const shared_ptr<SignalData>& d : data) {
const vector< shared_ptr<Segment> > segments = d->segments();
void View::update_layout()
{
update_scroll();
+
+ update_view_range_metaobject();
}
TraceTreeItemOwner* View::find_prevalent_trace_group(
update_layout();
}
+void View::update_view_range_metaobject() const
+{
+ const int w = viewport_->width();
+ if (w > 0) {
+ const double samplerate = session_.get_samplerate();
+ // Note: sample_num = time * samplerate
+ // Note: samples_per_pixel = samplerate * scale
+ const int64_t start_sample = (offset_ * samplerate).convert_to<int64_t>();
+ const int64_t end_sample = (offset_ * samplerate).convert_to<int64_t>() +
+ (w * session_.get_samplerate() * scale_);
+
+ MetadataObject* md_obj =
+ session_.metadata_obj_manager()->find_object_by_type(MetadataObjMainViewRange);
+
+ const int64_t old_start_sample = md_obj->value(MetadataValueStartSample).toLongLong();
+ const int64_t old_end_sample = md_obj->value(MetadataValueEndSample).toLongLong();
+
+ if (start_sample != old_start_sample)
+ md_obj->set_value(MetadataValueStartSample, QVariant((qlonglong)start_sample));
+
+ if (end_sample != old_end_sample)
+ md_obj->set_value(MetadataValueEndSample, QVariant((qlonglong)end_sample));
+ }
+}
+
void View::update_hover_point()
{
// Determine signal that the mouse cursor is hovering over