#include "pv/devicemanager.hpp"
#include "pv/globalsettings.hpp"
#include "pv/logging.hpp"
+#include "pv/widgets/colorbutton.hpp"
#include <libsigrokcxx/libsigrokcxx.hpp>
#endif
using std::shared_ptr;
+using pv::widgets::ColorButton;
namespace pv {
namespace dialogs {
SLOT(on_view_showSamplingPoints_changed(int)));
trace_view_layout->addRow(tr("Show data &sampling points"), cb);
+ cb = create_checkbox(GlobalSettings::Key_View_FillSignalHighAreas,
+ SLOT(on_view_fillSignalHighAreas_changed(int)));
+ trace_view_layout->addRow(tr("Fill high areas of logic signals"), cb);
+
+ ColorButton* high_fill_cb = new ColorButton(parent);
+ high_fill_cb->set_color(QColor::fromRgba(
+ settings.value(GlobalSettings::Key_View_FillSignalHighAreaColor).value<uint32_t>()));
+ connect(high_fill_cb, SIGNAL(selected(QColor)),
+ this, SLOT(on_view_fillSignalHighAreaColor_changed(QColor)));
+ trace_view_layout->addRow(tr("Fill high areas of logic signals"), high_fill_cb);
+
cb = create_checkbox(GlobalSettings::Key_View_ShowAnalogMinorGrid,
SLOT(on_view_showAnalogMinorGrid_changed(int)));
trace_view_layout->addRow(tr("Show analog minor grid in addition to div grid"), cb);
settings.setValue(GlobalSettings::Key_View_ShowSamplingPoints, state ? true : false);
}
+void Settings::on_view_fillSignalHighAreas_changed(int state)
+{
+ GlobalSettings settings;
+ settings.setValue(GlobalSettings::Key_View_FillSignalHighAreas, state ? true : false);
+}
+
+void Settings::on_view_fillSignalHighAreaColor_changed(QColor color)
+{
+ GlobalSettings settings;
+ settings.setValue(GlobalSettings::Key_View_FillSignalHighAreaColor, color.rgba());
+}
+
void Settings::on_view_showAnalogMinorGrid_changed(int state)
{
GlobalSettings settings;
#define PULSEVIEW_PV_SETTINGS_HPP
#include <QCheckBox>
+#include <QColor>
#include <QDialog>
#include <QListWidget>
#include <QPlainTextEdit>
void on_view_coloredBG_changed(int state);
void on_view_stickyScrolling_changed(int state);
void on_view_showSamplingPoints_changed(int state);
+ void on_view_fillSignalHighAreas_changed(int state);
+ void on_view_fillSignalHighAreaColor_changed(QColor color);
void on_view_showAnalogMinorGrid_changed(int state);
void on_view_showHoverMarker_changed(int state);
void on_view_snapDistance_changed(int value);
#include "globalsettings.hpp"
#include <QApplication>
+#include <QColor>
#include <QDebug>
#include <QFontMetrics>
#include <QString>
const QString GlobalSettings::Key_View_ColoredBG = "View_ColoredBG";
const QString GlobalSettings::Key_View_StickyScrolling = "View_StickyScrolling";
const QString GlobalSettings::Key_View_ShowSamplingPoints = "View_ShowSamplingPoints";
+const QString GlobalSettings::Key_View_FillSignalHighAreas = "View_FillSignalHighAreas";
+const QString GlobalSettings::Key_View_FillSignalHighAreaColor = "View_FillSignalHighAreaColor";
const QString GlobalSettings::Key_View_ShowAnalogMinorGrid = "View_ShowAnalogMinorGrid";
const QString GlobalSettings::Key_View_ConversionThresholdDispMode = "View_ConversionThresholdDispMode";
const QString GlobalSettings::Key_View_DefaultDivHeight = "View_DefaultDivHeight";
if (!contains(Key_View_ShowSamplingPoints))
setValue(Key_View_ShowSamplingPoints, true);
+ // Enable filling logic signal high areas by default
+ if (!contains(Key_View_FillSignalHighAreas))
+ setValue(Key_View_FillSignalHighAreas, true);
+ if (!contains(Key_View_FillSignalHighAreaColor))
+ setValue(Key_View_FillSignalHighAreaColor,
+ QColor(0, 0, 0, 5 * 256 / 100).rgba());
+
if (!contains(Key_View_DefaultDivHeight))
setValue(Key_View_DefaultDivHeight,
3 * QFontMetrics(QApplication::font()).height());
static const QString Key_View_ColoredBG;
static const QString Key_View_StickyScrolling;
static const QString Key_View_ShowSamplingPoints;
+ static const QString Key_View_FillSignalHighAreas;
+ static const QString Key_View_FillSignalHighAreaColor;
static const QString Key_View_ShowAnalogMinorGrid;
static const QString Key_View_ConversionThresholdDispMode;
static const QString Key_View_DefaultDivHeight;
const int nh = min(neg_vdivs_, 1) * div_height_;
const float high_offset = y - ph + signal_margin + 0.5f;
const float low_offset = y + nh - signal_margin - 0.5f;
+ const float signal_height = low_offset - high_offset;
shared_ptr<pv::data::LogicSegment> segment = get_logic_segment_to_paint();
if (!segment || (segment->get_sample_count() == 0))
samples_per_pixel / LogicSignal::Oversampling, 0);
assert(edges.size() >= 2);
+ const float first_sample_x =
+ pp.left() + (edges.front().first / samples_per_pixel - pixels_offset);
+ const float last_sample_x =
+ pp.left() + (edges.back().first / samples_per_pixel - pixels_offset);
+
// Check whether we need to paint the sampling points
GlobalSettings settings;
const bool show_sampling_points =
(samples_per_pixel < 0.25);
vector<QRectF> sampling_points;
- float sampling_point_x = 0.0f;
+ float sampling_point_x = first_sample_x;
int64_t sampling_point_sample = start_sample;
const int w = 2;
- if (show_sampling_points) {
+ if (show_sampling_points)
sampling_points.reserve(end_sample - start_sample + 1);
- sampling_point_x = (edges.cbegin()->first / samples_per_pixel - pixels_offset) + pp.left();
- }
+
+ // Check whether we need to fill the high areas
+ const bool fill_high_areas =
+ settings.value(GlobalSettings::Key_View_FillSignalHighAreas).toBool();
+ float high_start_x;
+ vector<QRectF> high_rects;
// Paint the edges
const unsigned int edge_count = edges.size() - 2;
pixels_offset) + pp.left();
*line++ = QLineF(x, high_offset, x, low_offset);
+ if (fill_high_areas) {
+ if ((*i).second)
+ high_start_x = x;
+ else
+ high_rects.emplace_back(high_start_x, high_offset,
+ x - high_start_x, signal_height);
+ }
+
if (show_sampling_points)
while (sampling_point_sample < (*i).first) {
const float y = (*i).second ? low_offset : high_offset;
sampling_point_x += pixels_per_sample;
};
+ if (fill_high_areas) {
+ // Add last high rectangle if the signal is still high at the end of the view
+ if ((edges.cend() - 1)->second)
+ high_rects.emplace_back(high_start_x, high_offset,
+ last_sample_x - high_start_x, signal_height);
+
+ const QColor fill_color = QColor::fromRgba(settings.value(
+ GlobalSettings::Key_View_FillSignalHighAreaColor).value<uint32_t>());
+ p.setPen(fill_color);
+ p.setBrush(fill_color);
+ p.drawRects((const QRectF*)(high_rects.data()), high_rects.size());
+ }
+
p.setPen(LogicSignal::EdgeColor);
p.drawLines(edge_lines, edge_count);
delete[] edge_lines;
if (!base_->enabled())
return;
- const float high_offset = y - signal_height_ + 0.5f;
const float low_offset = y + 0.5f;
+ const float high_offset = low_offset - signal_height_;
shared_ptr<LogicSegment> segment = get_logic_segment_to_paint();
if (!segment || (segment->get_sample_count() == 0))
samples_per_pixel / Oversampling, base_->index());
assert(edges.size() >= 2);
+ const float first_sample_x =
+ pp.left() + (edges.front().first / samples_per_pixel - pixels_offset);
+ const float last_sample_x =
+ pp.left() + (edges.back().first / samples_per_pixel - pixels_offset);
+
// Check whether we need to paint the sampling points
GlobalSettings settings;
const bool show_sampling_points =
(samples_per_pixel < 0.25);
vector<QRectF> sampling_points;
- float sampling_point_x = 0.0f;
+ float sampling_point_x = first_sample_x;
int64_t sampling_point_sample = start_sample;
const int w = 2;
- if (show_sampling_points) {
+ if (show_sampling_points)
sampling_points.reserve(end_sample - start_sample + 1);
- sampling_point_x = (edges.cbegin()->first / samples_per_pixel - pixels_offset) + pp.left();
- }
+
+ // Check whether we need to fill the high areas
+ const bool fill_high_areas =
+ settings.value(GlobalSettings::Key_View_FillSignalHighAreas).toBool();
+ float high_start_x;
+ vector<QRectF> high_rects;
// Paint the edges
const unsigned int edge_count = edges.size() - 2;
QLineF *const edge_lines = new QLineF[edge_count];
line = edge_lines;
+ if (edges.front().second)
+ high_start_x = first_sample_x; // Beginning of signal is high
+
for (auto i = edges.cbegin() + 1; i != edges.cend() - 1; i++) {
const float x = ((*i).first / samples_per_pixel -
pixels_offset) + pp.left();
*line++ = QLineF(x, high_offset, x, low_offset);
+ if (fill_high_areas) {
+ if ((*i).second)
+ high_start_x = x;
+ else
+ high_rects.emplace_back(high_start_x, high_offset,
+ x - high_start_x, signal_height_);
+ }
+
if (show_sampling_points)
while (sampling_point_sample < (*i).first) {
const float y = (*i).second ? low_offset : high_offset;
sampling_point_x += pixels_per_sample;
};
+ if (fill_high_areas) {
+ // Add last high rectangle if the signal is still high at the end of the view
+ if ((edges.cend() - 1)->second)
+ high_rects.emplace_back(high_start_x, high_offset,
+ last_sample_x - high_start_x, signal_height_);
+
+ const QColor fill_color = QColor::fromRgba(settings.value(
+ GlobalSettings::Key_View_FillSignalHighAreaColor).value<uint32_t>());
+ p.setPen(fill_color);
+ p.setBrush(fill_color);
+ p.drawRects((const QRectF*)(high_rects.data()), high_rects.size());
+ }
+
p.setPen(EdgeColor);
p.drawLines(edge_lines, edge_count);
delete[] edge_lines;
#include <cassert>
#include <QApplication>
+#include <QColorDialog>
#include <QPainter>
namespace pv {
const int ColorButton::SwatchMargin = 7;
+ColorButton::ColorButton(QWidget *parent) :
+ QPushButton("", parent),
+ popup_(nullptr)
+{
+ connect(this, SIGNAL(clicked(bool)), this, SLOT(on_clicked(bool)));
+}
+
ColorButton::ColorButton(int rows, int cols, QWidget *parent) :
QPushButton("", parent),
- popup_(rows, cols, this)
+ popup_(new ColorPopup(rows, cols, this))
{
connect(this, SIGNAL(clicked(bool)), this, SLOT(on_clicked(bool)));
- connect(&popup_, SIGNAL(selected(int, int)),
+ connect(popup_, SIGNAL(selected(int, int)),
this, SLOT(on_selected(int, int)));
}
-ColorPopup& ColorButton::popup()
+ColorPopup* ColorButton::popup()
{
return popup_;
}
{
cur_color_ = color;
- const unsigned int rows = popup_.well_array().numRows();
- const unsigned int cols = popup_.well_array().numCols();
-
- for (unsigned int r = 0; r < rows; r++)
- for (unsigned int c = 0; c < cols; c++)
- if (popup_.well_array().cellBrush(r, c).color() == color) {
- popup_.well_array().setSelected(r, c);
- popup_.well_array().setCurrent(r, c);
- return;
- }
+ if (popup_) {
+ const unsigned int rows = popup_->well_array().numRows();
+ const unsigned int cols = popup_->well_array().numCols();
+
+ for (unsigned int r = 0; r < rows; r++)
+ for (unsigned int c = 0; c < cols; c++)
+ if (popup_->well_array().cellBrush(r, c).color() == color) {
+ popup_->well_array().setSelected(r, c);
+ popup_->well_array().setCurrent(r, c);
+ return;
+ }
+ }
}
void ColorButton::set_palette(const QColor *const palette)
{
assert(palette);
+ assert(popup_);
- const unsigned int rows = popup_.well_array().numRows();
- const unsigned int cols = popup_.well_array().numCols();
+ const unsigned int rows = popup_->well_array().numRows();
+ const unsigned int cols = popup_->well_array().numCols();
for (unsigned int r = 0; r < rows; r++)
for (unsigned int c = 0; c < cols; c++)
- popup_.well_array().setCellBrush(r, c,
- QBrush(palette[r * cols + c]));
+ popup_->well_array().setCellBrush(r, c, QBrush(palette[r * cols + c]));
}
void ColorButton::on_clicked(bool)
{
- popup_.set_position(mapToGlobal(rect().center()), Popup::Bottom);
- popup_.show();
+ if (popup_) {
+ popup_->set_position(mapToGlobal(rect().center()), Popup::Bottom);
+ popup_->show();
+ } else {
+ QColorDialog dlg(this);
+ dlg.setOption(QColorDialog::ShowAlphaChannel);
+ dlg.setOption(QColorDialog::DontUseNativeDialog);
+ connect(&dlg, SIGNAL(colorSelected(const QColor)),
+ this, SLOT(on_color_selected(const QColor)));
+ dlg.setCurrentColor(cur_color_);
+ dlg.exec();
+ }
}
void ColorButton::on_selected(int row, int col)
{
- cur_color_ = popup_.well_array().cellBrush(row, col).color();
+ assert(popup_);
+
+ cur_color_ = popup_->well_array().cellBrush(row, col).color();
+ selected(cur_color_);
+}
+
+void ColorButton::on_color_selected(const QColor& color)
+{
+ cur_color_ = color;
selected(cur_color_);
}
static const int SwatchMargin;
public:
+ /**
+ * Construct a ColorButton instance that uses a QColorDialog
+ */
+ ColorButton(QWidget *parent);
+
+ /**
+ * Construct a ColorButton instance that uses a ColorPopup
+ */
ColorButton(int rows, int cols, QWidget *parent);
- ColorPopup& popup();
+ ColorPopup* popup();
const QColor& color() const;
private Q_SLOTS:
void on_clicked(bool);
-
void on_selected(int row, int col);
+ void on_color_selected(const QColor& color);
Q_SIGNALS:
void selected(const QColor &color);
private:
- ColorPopup popup_;
+ ColorPopup* popup_;
QColor cur_color_;
};