View::View(Session &session, bool is_main_view, QWidget *parent) :
ViewBase(session, is_main_view, parent),
splitter_(new QSplitter()),
+ segment_display_mode_(Trace::ShowLastSegmentOnly),
+ segment_selectable_(false),
scale_(1e-3),
offset_(0),
updating_scroll_(false),
settings_restored_(false),
+ header_was_shrunk_(false),
sticky_scrolling_(false), // Default setting is set in MainWindow::setup_ui()
always_zoom_to_fit_(false),
tick_period_(0),
ViewBase::add_signalbase(signal->base());
signals_.insert(signal);
+ signal->set_segment_display_mode(segment_display_mode_);
+
connect(signal->base().get(), SIGNAL(name_changed(const QString&)),
this, SLOT(on_signal_name_changed()));
}
new DecodeTrace(session_, signal, decode_traces_.size()));
decode_traces_.push_back(d);
+ d->set_segment_display_mode(segment_display_mode_);
+
connect(signal.get(), SIGNAL(name_changed(const QString&)),
this, SLOT(on_signal_name_changed()));
}
}
}
+bool View::segment_is_selectable() const
+{
+ return segment_selectable_;
+}
+
+void View::set_segment_display_mode(Trace::SegmentDisplayMode mode)
+{
+ for (shared_ptr<Signal> signal : signals_)
+ signal->set_segment_display_mode(mode);
+
+ viewport_->update();
+
+ segment_selectable_ = true;
+
+ if (mode == Trace::ShowSingleSegmentOnly)
+ segment_selectable_ = false;
+
+ segment_display_mode_changed(segment_selectable_);
+}
+
void View::zoom(double steps)
{
zoom(steps, viewport_->width() / 2);
set_v_offset(extents.first);
}
-bool View::header_was_shrunk() const
+void View::determine_if_header_was_shrunk()
{
const int header_pane_width = splitter_->sizes().front();
const int header_width = header_->extended_size_hint().width();
// Allow for a slight margin of error so that we also accept
// slight differences when e.g. a label name change increased
// the overall width
- return (header_pane_width < (header_width - 10));
+ header_was_shrunk_ = (header_pane_width < (header_width - 10));
}
-void View::expand_header_to_fit()
+void View::resize_header_to_fit()
{
+ // Setting the maximum width of the header widget doesn't work as
+ // expected because the splitter would allow the user to make the
+ // pane wider than that, creating empty space as a result.
+ // To make this work, we stricly enforce the maximum width by
+ // expanding the header unless the user shrunk it on purpose.
+ // As we're then setting the width of the header pane, we set the
+ // splitter to the maximum allowed position.
+
int splitter_area_width = 0;
for (int w : splitter_->sizes())
splitter_area_width += w;
// resized to their final sizes.
update_layout();
- if (!settings_restored_)
- expand_header_to_fit();
+ if (settings_restored_)
+ determine_if_header_was_shrunk();
+ else
+ resize_header_to_fit();
if (scroll_needs_defaults_) {
set_scroll_default();
void View::on_signal_name_changed()
{
- if (!header_was_shrunk())
- expand_header_to_fit();
+ if (!header_was_shrunk_)
+ resize_header_to_fit();
}
void View::on_splitter_moved()
{
- // Setting the maximum width of the header widget doesn't work as
- // expected because the splitter would allow the user to make the
- // pane wider than that, creating empty space as a result.
- // To make this work, we stricly enforce the maximum width by
- // expanding the header unless the user shrunk it on purpose.
- // As we're then setting the width of the header pane, we set the
- // splitter to the maximum allowed position.
- if (!header_was_shrunk())
- expand_header_to_fit();
+ // The header can only shrink when the splitter is moved manually
+ determine_if_header_was_shrunk();
+
+ if (!header_was_shrunk_)
+ resize_header_to_fit();
}
void View::h_scroll_value_changed(int value)
vector< shared_ptr<Channel> > channels;
shared_ptr<sigrok::Device> sr_dev;
+ bool signals_added_or_removed = false;
// Do we need to set the vertical scrollbar to its default position later?
// We do if there are no traces, i.e. the scroll bar has no range set
TraceTreeItemOwner *const owner = trace->owner();
assert(owner);
owner->remove_child_item(trace);
+ signals_added_or_removed = true;
}
// Remove any empty trace groups
if (item->enabled())
offset += extents.second;
+ signals_added_or_removed = true;
}
- if (!new_top_level_items.empty())
- // Expand the header pane because the header should become fully
- // visible when new signals are added
- expand_header_to_fit();
+ if (signals_added_or_removed && !header_was_shrunk_)
+ resize_header_to_fit();
update_layout();
}
}
-void View::on_segment_changed(int segment)
+void View::on_new_segment(int new_segment_id)
{
- current_segment_ = segment - 1;
+ on_segment_changed(new_segment_id);
+ segment_changed(new_segment_id);
+}
- for (shared_ptr<Signal> signal : signals_)
- signal->set_current_segment(current_segment_);
+void View::on_segment_changed(int segment)
+{
+ switch (segment_display_mode_) {
+ case Trace::ShowLastSegmentOnly:
+ case Trace::ShowSingleSegmentOnly:
+ current_segment_ = segment;
+ for (shared_ptr<Signal> signal : signals_)
+ signal->set_current_segment(current_segment_);
+ viewport_->update();
+ break;
- viewport_->update();
+ case Trace::ShowAllSegments:
+ case Trace::ShowAccumulatedIntensity:
+ default:
+ break;
+ }
}
void View::perform_delayed_view_update()