Freq field tweaks (#1306)

* UX improvements

* Prevent wrapping
This commit is contained in:
Kyle Reed 2023-07-25 06:06:13 -07:00 committed by GitHub
parent ea238f4988
commit 195a6224a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 65 additions and 15 deletions

View File

@ -43,7 +43,7 @@ FrequencyField::FrequencyField(
} }
FrequencyField::~FrequencyField() { FrequencyField::~FrequencyField() {
set_switches_long_press_config(initial_switch_config_); reset_switch_config();
} }
rf::Frequency FrequencyField::value() const { rf::Frequency FrequencyField::value() const {
@ -51,6 +51,12 @@ rf::Frequency FrequencyField::value() const {
} }
void FrequencyField::set_value(rf::Frequency new_value) { void FrequencyField::set_value(rf::Frequency new_value) {
// While in digit mode, don't update if the value is
// out of range. That way going out of range doesn't
// cause all the other digits to reset.
if (digit_mode_ && !range_.contains_inc(new_value))
return;
new_value = clamp_value(new_value); new_value = clamp_value(new_value);
if (new_value != value_) { if (new_value != value_) {
@ -67,6 +73,16 @@ void FrequencyField::set_step(rf::Frequency new_value) {
step_ = new_value; step_ = new_value;
} }
void FrequencyField::set_allow_digit_mode(bool allowed) {
allow_digit_mode_ = allowed;
if (!allowed && digit_mode_) {
digit_mode_ = false;
reset_switch_config();
set_dirty();
}
}
void FrequencyField::paint(Painter& painter) { void FrequencyField::paint(Painter& painter) {
const auto str_value = to_string_short_freq(value_); const auto str_value = to_string_short_freq(value_);
const auto paint_style = has_focus() ? style().invert() : style(); const auto paint_style = has_focus() ? style().invert() : style();
@ -100,6 +116,9 @@ bool FrequencyField::on_key(KeyEvent event) {
} }
if (digit_mode_) { if (digit_mode_) {
constexpr uint8_t decimal_pos = 4;
int8_t delta = 0;
switch (event) { switch (event) {
case KeyEvent::Up: case KeyEvent::Up:
set_value(value_ + digit_step()); set_value(value_ + digit_step());
@ -108,18 +127,28 @@ bool FrequencyField::on_key(KeyEvent event) {
set_value(value_ - digit_step()); set_value(value_ - digit_step());
break; break;
case KeyEvent::Left: case KeyEvent::Left:
digit_--; delta = -1;
break; break;
case KeyEvent::Right: case KeyEvent::Right:
digit_++; delta = 1;
break; break;
default: default:
return false; return false;
} }
// Clip value to the bounds of 'to_string_short_freq' result. if (delta != 0) {
digit_ = clip<uint8_t>(digit_, 0, 8); digit_ += delta;
set_dirty();
// If on decimal, skip it.
if (digit_ == decimal_pos)
digit_ += delta;
// Otherwise ensure in bounds.
else
digit_ = clip<int8_t>(digit_, 0, 8);
set_dirty();
}
return true; return true;
} }
@ -143,18 +172,14 @@ bool FrequencyField::on_touch(const TouchEvent event) {
} }
void FrequencyField::on_focus() { void FrequencyField::on_focus() {
if (on_show_options) { if (on_show_options)
on_show_options(); on_show_options();
}
// Enable long press on "Select". enable_switch_config();
SwitchesState config;
config[toUType(Switch::Sel)] = true;
set_switches_long_press_config(config);
} }
void FrequencyField::on_blur() { void FrequencyField::on_blur() {
set_switches_long_press_config(initial_switch_config_); reset_switch_config();
} }
rf::Frequency FrequencyField::digit_step() const { rf::Frequency FrequencyField::digit_step() const {
@ -177,6 +202,21 @@ rf::Frequency FrequencyField::clamp_value(rf::Frequency value) {
return range_.clip(value); return range_.clip(value);
} }
void FrequencyField::enable_switch_config() {
// Don't enable long press testing when not allowed.
if (!allow_digit_mode_)
return;
// Enable long press on "Select".
SwitchesState config;
config[toUType(Switch::Sel)] = true;
set_switches_long_press_config(config);
}
void FrequencyField::reset_switch_config() {
set_switches_long_press_config(initial_switch_config_);
}
/* FrequencyKeypadView ***************************************************/ /* FrequencyKeypadView ***************************************************/
bool FrequencyKeypadView::on_encoder(const EncoderEvent delta) { bool FrequencyKeypadView::on_encoder(const EncoderEvent delta) {

View File

@ -52,6 +52,7 @@ class FrequencyField : public Widget {
void set_value(rf::Frequency new_value); void set_value(rf::Frequency new_value);
void set_step(rf::Frequency new_value); void set_step(rf::Frequency new_value);
void set_allow_digit_mode(bool allowed);
void paint(Painter& painter) override; void paint(Painter& painter) override;
@ -71,11 +72,15 @@ class FrequencyField : public Widget {
uint8_t digit_{3}; uint8_t digit_{3};
bool digit_mode_{false}; bool digit_mode_{false};
bool allow_digit_mode_{true};
SwitchesState initial_switch_config_{}; SwitchesState initial_switch_config_{};
/* Gets the step value for the given digit when in digit_mode. */ /* Gets the step value for the given digit when in digit_mode. */
rf::Frequency digit_step() const; rf::Frequency digit_step() const;
rf::Frequency clamp_value(rf::Frequency value); rf::Frequency clamp_value(rf::Frequency value);
void enable_switch_config();
void reset_switch_config();
}; };
template <size_t N> template <size_t N>

View File

@ -186,13 +186,18 @@ struct range_t {
return value < minimum; return value < minimum;
} }
/* Exclusive of maximum. */
constexpr bool contains(const T& value) const { constexpr bool contains(const T& value) const {
// TODO: Subtle gotcha here! Range test doesn't include maximum!
return (value >= minimum) && (value < maximum); return (value >= minimum) && (value < maximum);
} }
/* Inclusive of maximum. */
constexpr bool contains_inc(const T& value) const {
return (value >= minimum) && (value <= maximum);
}
/* Exclusive of maximum. */
constexpr bool out_of_range(const T& value) const { constexpr bool out_of_range(const T& value) const {
// TODO: Subtle gotcha here! Range test in contains() doesn't include maximum!
return !contains(value); return !contains(value);
} }
}; };