#include "sweeptimingwidget.h"
+#include <cstdlib>
+
+#include <vector>
+
#include <assert.h>
+#include <extdef.h>
+
+using std::abs;
+using std::vector;
+
namespace pv {
namespace widgets {
SweepTimingWidget::SweepTimingWidget(const char *suffix,
QWidget *parent) :
QWidget(parent),
+ _suffix(suffix),
_layout(this),
- _read_only_value(this),
_value(this),
_list(this),
_value_type(None)
setLayout(&_layout);
_layout.setMargin(0);
- _layout.addWidget(&_read_only_value);
_layout.addWidget(&_list);
_layout.addWidget(&_value);
void SweepTimingWidget::show_none()
{
_value_type = None;
- _read_only_value.hide();
- _value.hide();
- _list.hide();
-}
-
-void SweepTimingWidget::show_read_only()
-{
- _value_type = ReadOnly;
- _read_only_value.show();
_value.hide();
_list.hide();
}
void SweepTimingWidget::show_min_max_step(uint64_t min, uint64_t max,
uint64_t step)
{
+ assert(max > min);
+ assert(step > 0);
+
_value_type = MinMaxStep;
_value.setRange(min, max);
_value.setSingleStep(step);
- _read_only_value.hide();
_value.show();
_list.hide();
}
_list.clear();
for (size_t i = 0; i < count; i++)
{
- char *const s = sr_samplerate_string(vals[i]);
+ char *const s = sr_si_string_u64(vals[i], _suffix);
_list.addItem(QString::fromUtf8(s),
qVariantFromValue(vals[i]));
g_free(s);
}
- _read_only_value.hide();
_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<uint64_t> 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)
{
case None:
- case ReadOnly:
return 0;
case MinMaxStep:
void SweepTimingWidget::set_value(uint64_t value)
{
- _read_only_value.setText(QString("%1").arg(value));
-
_value.setValue(value);
- for (int i = 0; i < _list.count(); i++)
- if (value == _list.itemData(i).value<uint64_t>())
- _list.setCurrentIndex(i);
+ 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<int64_t>());
+ if (this_variance < best_variance) {
+ best_variance = this_variance;
+ best_match = i;
+ }
+ }
+
+ _list.setCurrentIndex(best_match);
}
} // widgets