X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=blobdiff_plain;f=pv%2Fwidgets%2Fsweeptimingwidget.cpp;h=b4943225dd8d44ddae54fad59b7231e70a8c6e3f;hp=d34d07e5f7c2a43cea1ed8b870253c358c2550ad;hb=dbed5609ae31cdfc3e9db10f3ab91b7607c08372;hpb=5cacd7d9fbc6ba6e9e67940d2497f04dd54e7f76 diff --git a/pv/widgets/sweeptimingwidget.cpp b/pv/widgets/sweeptimingwidget.cpp index d34d07e5..b4943225 100644 --- a/pv/widgets/sweeptimingwidget.cpp +++ b/pv/widgets/sweeptimingwidget.cpp @@ -14,13 +14,19 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * along with this program; if not, see . */ -#include "sweeptimingwidget.h" +#include "sweeptimingwidget.hpp" -#include +#include +#include +#include + +#include + +using std::abs; +using std::vector; namespace pv { namespace widgets { @@ -28,97 +34,145 @@ namespace widgets { SweepTimingWidget::SweepTimingWidget(const char *suffix, QWidget *parent) : QWidget(parent), - _layout(this), - _value(this), - _list(this), - _value_type(None) + suffix_(suffix), + layout_(this), + value_(this), + list_(this), + value_type_(None) { setContentsMargins(0, 0, 0, 0); - _value.setDecimals(0); - _value.setSuffix(QString::fromUtf8(suffix)); + value_.setDecimals(0); + value_.setSuffix(QString::fromUtf8(suffix)); - connect(&_list, SIGNAL(currentIndexChanged(int)), + connect(&list_, SIGNAL(currentIndexChanged(int)), this, SIGNAL(value_changed())); - connect(&_value, SIGNAL(editingFinished()), + connect(&value_, SIGNAL(editingFinished()), this, SIGNAL(value_changed())); - setLayout(&_layout); - _layout.setMargin(0); - _layout.addWidget(&_list); - _layout.addWidget(&_value); + setLayout(&layout_); + layout_.setMargin(0); + layout_.addWidget(&list_); + layout_.addWidget(&value_); show_none(); } void SweepTimingWidget::show_none() { - _value_type = None; - _value.hide(); - _list.hide(); + value_type_ = None; + value_.hide(); + list_.hide(); } void SweepTimingWidget::show_min_max_step(uint64_t min, uint64_t max, uint64_t step) { - _value_type = MinMaxStep; + assert(max > min); + assert(step > 0); + + value_type_ = MinMaxStep; - _value.setRange(min, max); - _value.setSingleStep(step); + value_.setRange(min, max); + value_.setSingleStep(step); - _value.show(); - _list.hide(); + value_.show(); + list_.hide(); } void SweepTimingWidget::show_list(const uint64_t *vals, size_t count) { - _value_type = List; + value_type_ = List; - _list.clear(); - for (size_t i = 0; i < count; i++) - { - char *const s = sr_samplerate_string(vals[i]); - _list.addItem(QString::fromUtf8(s), - qVariantFromValue(vals[i])); + list_.clear(); + for (size_t i = 0; i < count; i++) { + char *const s = sr_si_string_u64(vals[i], suffix_); + list_.addItem(QString::fromUtf8(s), qVariantFromValue(vals[i])); g_free(s); } - _value.hide(); - _list.show(); + value_.hide(); + list_.show(); +} + +void SweepTimingWidget::show_125_list(uint64_t min, uint64_t max) +{ + assert(max > min); + + // Create a 1-2-5-10 list of entries. + const unsigned int FineScales[] = {1, 2, 5}; + uint64_t value, decade; + unsigned int fine; + vector values; + + // Compute the starting decade + for (decade = 1; decade * 10 <= min; decade *= 10); + + // Compute the first entry + for (fine = 0; fine < countof(FineScales); fine++) + if (FineScales[fine] * decade >= min) + break; + + assert(fine < countof(FineScales)); + + // Add the minimum entry if it's not on the 1-2-5 progression + if (min != FineScales[fine] * decade) + values.push_back(min); + + while ((value = FineScales[fine] * decade) < max) { + values.push_back(value); + if (++fine >= countof(FineScales)) + fine = 0, decade *= 10; + } + + // Add the max value + values.push_back(max); + + // Make a C array, and give it to the sweep timing widget + uint64_t *const values_array = new uint64_t[values.size()]; + copy(values.begin(), values.end(), values_array); + show_list(values_array, values.size()); + delete[] values_array; } uint64_t SweepTimingWidget::value() const { - switch(_value_type) - { + switch (value_type_) { case None: return 0; - case MinMaxStep: - return (uint64_t)_value.value(); - + return (uint64_t)value_.value(); case List: { - const int index = _list.currentIndex(); - return (index >= 0) ? _list.itemData( + const int index = list_.currentIndex(); + return (index >= 0) ? list_.itemData( index).value() : 0; } - default: // Unexpected value type - assert(0); + assert(false); return 0; } } void SweepTimingWidget::set_value(uint64_t value) { - _value.setValue(value); + value_.setValue(value); + + int best_match = list_.count() - 1; + int64_t best_variance = INT64_MAX; + + for (int i = 0; i < list_.count(); i++) { + const int64_t this_variance = abs( + (int64_t)value - list_.itemData(i).value()); + if (this_variance < best_variance) { + best_variance = this_variance; + best_match = i; + } + } - for (int i = 0; i < _list.count(); i++) - if (value == _list.itemData(i).value()) - _list.setCurrentIndex(i); + list_.setCurrentIndex(best_match); } -} // widgets -} // pv +} // namespace widgets +} // namespace pv