mirror of git://sigrok.org/pulseview
Implement segment display mode handling and update notifications
This commit is contained in:
parent
aa8da126bb
commit
7daebd054e
|
@ -268,19 +268,10 @@ void AnalogSignal::paint_mid(QPainter &p, ViewItemPaintParams &pp)
|
|||
if ((display_type_ == DisplayAnalog) || (display_type_ == DisplayBoth)) {
|
||||
paint_grid(p, y, pp.left(), pp.right());
|
||||
|
||||
const deque< shared_ptr<pv::data::AnalogSegment> > &segments =
|
||||
base_->analog_data()->analog_segments();
|
||||
if (segments.empty())
|
||||
shared_ptr<pv::data::AnalogSegment> segment = get_analog_segment_to_paint();
|
||||
if (!segment)
|
||||
return;
|
||||
|
||||
shared_ptr<pv::data::AnalogSegment> segment;
|
||||
try {
|
||||
segment = segments.at(current_segment_);
|
||||
} catch (out_of_range) {
|
||||
qDebug() << "Current analog segment out of range for signal" << base_->name();
|
||||
return;
|
||||
}
|
||||
|
||||
const double pixels_offset = pp.pixels_offset();
|
||||
const double samplerate = max(1.0, segment->samplerate());
|
||||
const pv::util::Timestamp& start_time = segment->start_time();
|
||||
|
@ -539,20 +530,10 @@ void AnalogSignal::paint_logic_mid(QPainter &p, ViewItemPaintParams &pp)
|
|||
const float high_offset = y - ph + signal_margin + 0.5f;
|
||||
const float low_offset = y + nh - signal_margin - 0.5f;
|
||||
|
||||
const deque< shared_ptr<pv::data::LogicSegment> > &segments =
|
||||
base_->logic_data()->logic_segments();
|
||||
|
||||
if (segments.empty())
|
||||
shared_ptr<pv::data::LogicSegment> segment = get_logic_segment_to_paint();
|
||||
if (!segment)
|
||||
return;
|
||||
|
||||
shared_ptr<pv::data::LogicSegment> segment;
|
||||
try {
|
||||
segment = segments.at(current_segment_);
|
||||
} catch (out_of_range) {
|
||||
qDebug() << "Current logic segment out of range for signal" << base_->name();
|
||||
return;
|
||||
}
|
||||
|
||||
double samplerate = segment->samplerate();
|
||||
|
||||
// Show sample rate as 1Hz when it is unknown
|
||||
|
@ -666,6 +647,52 @@ void AnalogSignal::paint_logic_caps(QPainter &p, QLineF *const lines,
|
|||
p.drawLines(lines, line - lines);
|
||||
}
|
||||
|
||||
shared_ptr<pv::data::AnalogSegment> AnalogSignal::get_analog_segment_to_paint() const
|
||||
{
|
||||
shared_ptr<pv::data::AnalogSegment> segment;
|
||||
|
||||
const deque< shared_ptr<pv::data::AnalogSegment> > &segments =
|
||||
base_->analog_data()->analog_segments();
|
||||
|
||||
if (!segments.empty()) {
|
||||
if (segment_display_mode_ == ShowLastSegmentOnly)
|
||||
segment = segments.back();
|
||||
|
||||
if (segment_display_mode_ == ShowSingleSegmentOnly) {
|
||||
try {
|
||||
segment = segments.at(current_segment_);
|
||||
} catch (out_of_range) {
|
||||
qDebug() << "Current analog segment out of range for signal" << base_->name();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return segment;
|
||||
}
|
||||
|
||||
shared_ptr<pv::data::LogicSegment> AnalogSignal::get_logic_segment_to_paint() const
|
||||
{
|
||||
shared_ptr<pv::data::LogicSegment> segment;
|
||||
|
||||
const deque< shared_ptr<pv::data::LogicSegment> > &segments =
|
||||
base_->logic_data()->logic_segments();
|
||||
|
||||
if (!segments.empty()) {
|
||||
if (segment_display_mode_ == ShowLastSegmentOnly)
|
||||
segment = segments.back();
|
||||
|
||||
if (segment_display_mode_ == ShowSingleSegmentOnly) {
|
||||
try {
|
||||
segment = segments.at(current_segment_);
|
||||
} catch (out_of_range) {
|
||||
qDebug() << "Current logic segment out of range for signal" << base_->name();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return segment;
|
||||
}
|
||||
|
||||
float AnalogSignal::get_resolution(int scale_index)
|
||||
{
|
||||
const float seq[] = {1.0f, 2.0f, 5.0f};
|
||||
|
|
|
@ -145,6 +145,9 @@ private:
|
|||
bool level, double samples_per_pixel, double pixels_offset,
|
||||
float x_offset, float y_offset);
|
||||
|
||||
shared_ptr<pv::data::AnalogSegment> get_analog_segment_to_paint() const;
|
||||
shared_ptr<pv::data::LogicSegment> get_logic_segment_to_paint() const;
|
||||
|
||||
/**
|
||||
* Computes the scale factor from the scale index and vdiv settings.
|
||||
*/
|
||||
|
|
|
@ -192,19 +192,10 @@ void LogicSignal::paint_mid(QPainter &p, ViewItemPaintParams &pp)
|
|||
const float high_offset = y - signal_height_ + 0.5f;
|
||||
const float low_offset = y + 0.5f;
|
||||
|
||||
const deque< shared_ptr<pv::data::LogicSegment> > &segments =
|
||||
base_->logic_data()->logic_segments();
|
||||
if (segments.empty())
|
||||
shared_ptr<pv::data::LogicSegment> segment = get_logic_segment_to_paint();
|
||||
if (!segment)
|
||||
return;
|
||||
|
||||
shared_ptr<pv::data::LogicSegment> segment;
|
||||
try {
|
||||
segment = segments.at(current_segment_);
|
||||
} catch (out_of_range) {
|
||||
qDebug() << "Current logic segment out of range for signal" << base_->name();
|
||||
return;
|
||||
}
|
||||
|
||||
double samplerate = segment->samplerate();
|
||||
|
||||
// Show sample rate as 1Hz when it is unknown
|
||||
|
@ -355,6 +346,30 @@ void LogicSignal::paint_caps(QPainter &p, QLineF *const lines,
|
|||
p.drawLines(lines, line - lines);
|
||||
}
|
||||
|
||||
shared_ptr<pv::data::LogicSegment> LogicSignal::get_logic_segment_to_paint() const
|
||||
{
|
||||
shared_ptr<pv::data::LogicSegment> segment;
|
||||
|
||||
const deque< shared_ptr<pv::data::LogicSegment> > &segments =
|
||||
base_->logic_data()->logic_segments();
|
||||
|
||||
if (!segments.empty()) {
|
||||
if (segment_display_mode_ == ShowLastSegmentOnly) {
|
||||
segment = segments.back();
|
||||
}
|
||||
|
||||
if (segment_display_mode_ == ShowSingleSegmentOnly) {
|
||||
try {
|
||||
segment = segments.at(current_segment_);
|
||||
} catch (out_of_range) {
|
||||
qDebug() << "Current logic segment out of range for signal" << base_->name();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return segment;
|
||||
}
|
||||
|
||||
void LogicSignal::init_trigger_actions(QWidget *parent)
|
||||
{
|
||||
trigger_none_ = new QAction(*get_icon(":/icons/trigger-none.svg"),
|
||||
|
|
|
@ -120,6 +120,8 @@ private:
|
|||
bool level, double samples_per_pixel, double pixels_offset,
|
||||
float x_offset, float y_offset);
|
||||
|
||||
shared_ptr<pv::data::LogicSegment> get_logic_segment_to_paint() const;
|
||||
|
||||
void init_trigger_actions(QWidget *parent);
|
||||
|
||||
const vector<int32_t> get_trigger_types() const;
|
||||
|
|
|
@ -91,6 +91,10 @@ StandardBar::StandardBar(Session &session, QWidget *parent,
|
|||
this, SLOT(on_new_segment(int)));
|
||||
connect(segment_selector_, SIGNAL(valueChanged(int)),
|
||||
view_, SLOT(on_segment_changed(int)));
|
||||
connect(view_, SIGNAL(segment_changed(int)),
|
||||
this, SLOT(on_segment_changed(int)));
|
||||
connect(view_, SIGNAL(segment_display_mode_changed(bool)),
|
||||
this, SLOT(on_segment_display_mode_changed(bool)));
|
||||
|
||||
connect(view_, SIGNAL(always_zoom_to_fit_changed(bool)),
|
||||
this, SLOT(on_always_zoom_to_fit_changed(bool)));
|
||||
|
@ -125,6 +129,8 @@ void StandardBar::show_multi_segment_ui(const bool state)
|
|||
{
|
||||
for (QAction* action : multi_segment_actions_)
|
||||
action->setVisible(state);
|
||||
|
||||
on_segment_display_mode_changed(view_->segment_is_selectable());
|
||||
}
|
||||
|
||||
QAction* StandardBar::action_view_zoom_in() const
|
||||
|
@ -195,6 +201,18 @@ void StandardBar::on_new_segment(int new_segment_id)
|
|||
show_multi_segment_ui(false);
|
||||
}
|
||||
|
||||
void StandardBar::on_segment_changed(int segment_id)
|
||||
{
|
||||
// This is called when the current segment was changed
|
||||
// by other parts of the UI, e.g. the view itself
|
||||
segment_selector_->setValue(segment_id);
|
||||
}
|
||||
|
||||
void StandardBar::on_segment_display_mode_changed(bool segment_selectable)
|
||||
{
|
||||
segment_selector_->setReadOnly(!segment_selectable);
|
||||
}
|
||||
|
||||
} // namespace trace
|
||||
} // namespace views
|
||||
} // namespace pv
|
||||
|
|
|
@ -89,6 +89,8 @@ protected Q_SLOTS:
|
|||
void on_always_zoom_to_fit_changed(bool state);
|
||||
|
||||
void on_new_segment(int new_segment_id);
|
||||
void on_segment_changed(int segment_id);
|
||||
void on_segment_display_mode_changed(bool segment_selectable);
|
||||
|
||||
private:
|
||||
vector<QAction*> multi_segment_actions_;
|
||||
|
|
|
@ -51,6 +51,7 @@ const QColor Trace::DarkGrayBGColour = QColor(0, 0, 0, 15 * 255 / 100);
|
|||
Trace::Trace(shared_ptr<data::SignalBase> channel) :
|
||||
base_(channel),
|
||||
axis_pen_(AxisPen),
|
||||
segment_display_mode_(ShowLastSegmentOnly), // Will be overwritten by View
|
||||
popup_(nullptr),
|
||||
popup_form_(nullptr)
|
||||
{
|
||||
|
@ -242,6 +243,14 @@ void Trace::set_colour(QColor colour)
|
|||
base_->set_colour(colour);
|
||||
}
|
||||
|
||||
void Trace::set_segment_display_mode(SegmentDisplayMode mode)
|
||||
{
|
||||
segment_display_mode_ = mode;
|
||||
|
||||
if (owner_)
|
||||
owner_->row_item_appearance_changed(true, true);
|
||||
}
|
||||
|
||||
void Trace::on_name_changed(const QString &text)
|
||||
{
|
||||
/* This event handler is called by SignalBase when the name was changed there */
|
||||
|
|
|
@ -63,6 +63,19 @@ class Trace : public TraceTreeItem
|
|||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
* Allowed values for the multi-segment display mode.
|
||||
*
|
||||
* Note: Consider @ref View::set_segment_display_mode when updating the list.
|
||||
*/
|
||||
enum SegmentDisplayMode {
|
||||
ShowLastSegmentOnly = 1,
|
||||
ShowSingleSegmentOnly,
|
||||
ShowAllSegments,
|
||||
ShowAccumulatedIntensity
|
||||
};
|
||||
|
||||
private:
|
||||
static const QPen AxisPen;
|
||||
static const int LabelHitPadding;
|
||||
|
@ -89,6 +102,11 @@ public:
|
|||
*/
|
||||
virtual void set_colour(QColor colour);
|
||||
|
||||
/**
|
||||
* Configures the segment display mode to use.
|
||||
*/
|
||||
virtual void set_segment_display_mode(SegmentDisplayMode mode);
|
||||
|
||||
/**
|
||||
* Paints the signal label.
|
||||
* @param p the QPainter to paint into.
|
||||
|
@ -146,6 +164,8 @@ protected:
|
|||
shared_ptr<data::SignalBase> base_;
|
||||
QPen axis_pen_;
|
||||
|
||||
SegmentDisplayMode segment_display_mode_;
|
||||
|
||||
private:
|
||||
pv::widgets::Popup *popup_;
|
||||
QFormLayout *popup_form_;
|
||||
|
|
|
@ -125,6 +125,8 @@ bool CustomScrollArea::viewportEvent(QEvent *event)
|
|||
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),
|
||||
|
@ -255,6 +257,8 @@ void View::add_signal(const shared_ptr<Signal> signal)
|
|||
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()));
|
||||
}
|
||||
|
@ -271,6 +275,8 @@ void View::add_decode_signal(shared_ptr<data::DecodeSignal> signal)
|
|||
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()));
|
||||
}
|
||||
|
@ -477,6 +483,26 @@ void View::set_time_unit(pv::util::TimeUnit time_unit)
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -1386,16 +1412,25 @@ void View::capture_state_updated(int state)
|
|||
void View::on_new_segment(int new_segment_id)
|
||||
{
|
||||
on_segment_changed(new_segment_id);
|
||||
segment_changed(new_segment_id);
|
||||
}
|
||||
|
||||
void View::on_segment_changed(int segment)
|
||||
{
|
||||
current_segment_ = segment - 1;
|
||||
switch (segment_display_mode_) {
|
||||
case Trace::ShowLastSegmentOnly:
|
||||
case Trace::ShowSingleSegmentOnly:
|
||||
current_segment_ = segment - 1;
|
||||
for (shared_ptr<Signal> signal : signals_)
|
||||
signal->set_current_segment(current_segment_);
|
||||
viewport_->update();
|
||||
break;
|
||||
|
||||
for (shared_ptr<Signal> signal : signals_)
|
||||
signal->set_current_segment(current_segment_);
|
||||
|
||||
viewport_->update();
|
||||
case Trace::ShowAllSegments:
|
||||
case Trace::ShowAccumulatedIntensity:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void View::perform_delayed_view_update()
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
#include "cursorpair.hpp"
|
||||
#include "flag.hpp"
|
||||
#include "trace.hpp"
|
||||
#include "tracetreeitemowner.hpp"
|
||||
|
||||
using std::list;
|
||||
|
@ -190,6 +191,14 @@ public:
|
|||
*/
|
||||
unsigned int depth() const;
|
||||
|
||||
/**
|
||||
* Returns whether the currently shown segment can be influenced
|
||||
* (selected) or not.
|
||||
*/
|
||||
bool segment_is_selectable() const;
|
||||
|
||||
void set_segment_display_mode(Trace::SegmentDisplayMode mode);
|
||||
|
||||
void zoom(double steps);
|
||||
void zoom(double steps, int offset);
|
||||
|
||||
|
@ -295,6 +304,12 @@ Q_SIGNALS:
|
|||
/// Emitted when the time_unit changed.
|
||||
void time_unit_changed();
|
||||
|
||||
/// Emitted when the currently selected segment changed
|
||||
void segment_changed(int segment_id);
|
||||
|
||||
/// Emitted when the multi-segment display mode changed
|
||||
void segment_display_mode_changed(bool segment_selectable);
|
||||
|
||||
public Q_SLOTS:
|
||||
void trigger_event(util::Timestamp location);
|
||||
|
||||
|
@ -424,6 +439,10 @@ private:
|
|||
|
||||
/// The ID of the currently displayed segment
|
||||
int current_segment_;
|
||||
Trace::SegmentDisplayMode segment_display_mode_;
|
||||
|
||||
/// Signals whether the user can change the currently shown segment.
|
||||
bool segment_selectable_;
|
||||
|
||||
/// The view time scale in seconds per pixel.
|
||||
double scale_;
|
||||
|
|
Loading…
Reference in New Issue