#include <libsigrokcxx/libsigrokcxx.hpp>
-#include "decodetrace.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/data/logicsegment.hpp"
#include "pv/util.hpp"
+#ifdef ENABLE_DECODE
+#include "decodetrace.hpp"
+#endif
+
using boost::shared_lock;
using boost::shared_mutex;
using pv::util::TimeUnit;
using pv::util::Timestamp;
+using std::back_inserter;
+using std::copy_if;
using std::deque;
using std::dynamic_pointer_cast;
using std::inserter;
using std::lock_guard;
using std::max;
using std::make_pair;
+using std::make_shared;
using std::min;
using std::pair;
using std::set;
show_cursors_(false),
cursors_(new CursorPair(*this)),
next_flag_text_('A'),
+ trigger_markers_(),
hover_point_(-1, -1)
{
connect(horizontalScrollBar(), SIGNAL(valueChanged(int)),
items.push_back(cursors_);
items.push_back(cursors_->first());
items.push_back(cursors_->second());
+
+ for (auto trigger_marker : trigger_markers_)
+ items.push_back(trigger_marker);
+
return items;
}
if (visible_data.empty())
return;
- double samplerate = 0.0;
- for (const shared_ptr<SignalData> d : visible_data) {
- assert(d);
- const vector< shared_ptr<Segment> > segments =
- d->segments();
- for (const shared_ptr<Segment> &s : segments)
- samplerate = max(samplerate, s->samplerate());
- }
-
- if (samplerate == 0.0)
- return;
-
assert(viewport_);
const int w = viewport_->width();
if (w <= 0)
return;
- set_zoom(1.0 / samplerate, w / 2);
+ set_zoom(1.0 / session_.get_samplerate(), w / 2);
}
void View::set_scale_offset(double scale, const Timestamp& offset)
{
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)
- {
+ for (const shared_ptr<SignalData> d : visible_data) {
const vector< shared_ptr<Segment> > segments =
d->segments();
for (const shared_ptr<Segment> &s : segments) {
sticky_scrolling_ = state;
}
+void View::enable_coloured_bg(bool state)
+{
+ const vector<shared_ptr<TraceTreeItem>> items(
+ list_by_type<TraceTreeItem>());
+
+ for (shared_ptr<TraceTreeItem> i : items) {
+ // Can't cast to Trace because it's abstract, so we need to
+ // check for any derived classes individually
+
+ shared_ptr<AnalogSignal> a = dynamic_pointer_cast<AnalogSignal>(i);
+ if (a)
+ a->set_coloured_bg(state);
+
+ shared_ptr<LogicSignal> l = dynamic_pointer_cast<LogicSignal>(i);
+ if (l)
+ l->set_coloured_bg(state);
+
+#ifdef ENABLE_DECODE
+ shared_ptr<DecodeTrace> d = dynamic_pointer_cast<DecodeTrace>(i);
+ if (d)
+ d->set_coloured_bg(state);
+#endif
+ }
+
+ viewport_->update();
+}
+
bool View::cursors_shown() const
{
return show_cursors_;
{
flags_.push_back(shared_ptr<Flag>(new Flag(*this, time,
QString("%1").arg(next_flag_text_))));
+
next_flag_text_ = (next_flag_text_ >= 'Z') ? 'A' :
(next_flag_text_ + 1);
+
time_item_appearance_changed(true, true);
}
for (auto &o : sorted_owners)
o->restack_items();
+ // Re-assign background colors
+ bool next_bgcolour_state = 0;
+
+ for (auto &o : sorted_owners)
+ next_bgcolour_state = o->reassign_bgcolour_states(next_bgcolour_state);
+
// Animate the items to their destination
for (const auto &i : items)
i->animate_to_layout_v_offset();
}
+void View::trigger_event(util::Timestamp location)
+{
+ trigger_markers_.push_back(shared_ptr<TriggerMarker>(
+ new TriggerMarker(*this, location)));
+}
+
void View::get_scroll_layout(double &length, Timestamp &offset) const
{
const pair<Timestamp, Timestamp> extents = get_time_extents();
{
vector< shared_ptr<Trace> > filtered_traces;
- for (const auto &channel : channels)
- {
+ for (const auto &channel : channels) {
const auto map_iter = signal_map.find(channel);
if (map_iter == signal_map.end())
continue;
bool View::viewportEvent(QEvent *e)
{
- switch(e->type()) {
+ switch (e->type()) {
case QEvent::Paint:
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
return false;
-
default:
return QAbstractScrollArea::viewportEvent(e);
}
void View::signals_changed()
{
+ using sigrok::Channel;
+
vector< shared_ptr<TraceTreeItem> > new_top_level_items;
const auto device = session_.device();
shared_ptr<sigrok::Device> sr_dev = device->device();
assert(sr_dev);
+ const vector< shared_ptr<Channel> > channels(
+ sr_dev->channels());
+
// Make a list of traces that are being added, and a list of traces
// that are being removed
const vector<shared_ptr<Trace>> prev_trace_list = list_by_type<Trace>();
signal_map[sig->channel()] = sig;
// Populate channel groups
- for (auto entry : sr_dev->channel_groups())
- {
+ for (auto entry : sr_dev->channel_groups()) {
const shared_ptr<sigrok::ChannelGroup> &group = entry.second;
if (group->channels().size() <= 1)
new_top_level_items.push_back(new_trace_group);
}
+ // Enqueue the remaining logic channels in a group
+ vector< shared_ptr<Channel> > logic_channels;
+ copy_if(channels.begin(), channels.end(), back_inserter(logic_channels),
+ [](const shared_ptr<Channel>& c) {
+ return c->type() == sigrok::ChannelType::LOGIC; });
+ const vector< shared_ptr<Trace> > non_grouped_logic_signals =
+ extract_new_traces_for_channels(logic_channels,
+ signal_map, add_traces);
+ const shared_ptr<TraceGroup> non_grouped_trace_group(
+ make_shared<TraceGroup>());
+ for (shared_ptr<Trace> trace : non_grouped_logic_signals)
+ non_grouped_trace_group->add_child_item(trace);
+ new_top_level_items.push_back(non_grouped_trace_group);
+
// Enqueue the remaining channels as free ungrouped traces
const vector< shared_ptr<Trace> > new_top_level_signals =
- extract_new_traces_for_channels(sr_dev->channels(),
+ extract_new_traces_for_channels(channels,
signal_map, add_traces);
new_top_level_items.insert(new_top_level_items.end(),
new_top_level_signals.begin(), new_top_level_signals.end());
void View::capture_state_updated(int state)
{
- if (state == Session::Running)
+ if (state == Session::Running) {
set_time_unit(util::TimeUnit::Samples);
+ trigger_markers_.clear();
+ }
+
if (state == Session::Stopped) {
// After acquisition has stopped we need to re-calculate the ticks once
// as it's otherwise done when the user pans or zooms, which is too late