mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2025-08-15 05:57:40 +00:00
@@ -285,6 +285,9 @@ struct data_t {
|
||||
// Hardware
|
||||
uint32_t hardware_config;
|
||||
|
||||
// Recon App
|
||||
uint64_t recon_config;
|
||||
|
||||
constexpr data_t() :
|
||||
structure_version(data_structure_version_enum::VERSION_CURRENT),
|
||||
tuned_frequency(tuned_frequency_reset_value),
|
||||
@@ -311,7 +314,8 @@ struct data_t {
|
||||
|
||||
tone_mix(tone_mix_reset_value),
|
||||
|
||||
hardware_config(0)
|
||||
hardware_config(0),
|
||||
recon_config(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
@@ -663,6 +667,61 @@ void set_clkout_freq(uint32_t freq) {
|
||||
data->ui_config.set_clkout_freq(freq);
|
||||
}
|
||||
|
||||
bool recon_autosave_freqs() {
|
||||
return (data->recon_config & 0x80000000UL) ? true : false;
|
||||
}
|
||||
bool recon_autostart_recon() {
|
||||
return (data->recon_config & 0x40000000UL) ? true : false;
|
||||
}
|
||||
bool recon_continuous() {
|
||||
return (data->recon_config & 0x20000000UL) ? true : false;
|
||||
}
|
||||
bool recon_clear_output() {
|
||||
return (data->recon_config & 0x10000000UL) ? true : false;
|
||||
}
|
||||
bool recon_load_freqs() {
|
||||
return (data->recon_config & 0x08000000UL) ? true : false;
|
||||
}
|
||||
bool recon_load_ranges() {
|
||||
return (data->recon_config & 0x04000000UL) ? true : false;
|
||||
}
|
||||
bool recon_update_ranges_when_recon() {
|
||||
return (data->recon_config & 0x02000000UL) ? true : false;
|
||||
}
|
||||
bool recon_load_hamradios() {
|
||||
return (data->recon_config & 0x01000000UL) ? true : false;
|
||||
}
|
||||
bool recon_match_mode() {
|
||||
return (data->recon_config & 0x00800000UL) ? true : false;
|
||||
}
|
||||
|
||||
void set_recon_autosave_freqs(const bool v ){
|
||||
data->recon_config = (data->recon_config & ~0x80000000UL) | (v << 31);
|
||||
}
|
||||
void set_recon_autostart_recon(const bool v ){
|
||||
data->recon_config = (data->recon_config & ~0x40000000UL) | (v << 30);
|
||||
}
|
||||
void set_recon_continuous(const bool v ){
|
||||
data->recon_config = (data->recon_config & ~0x20000000UL) | (v << 29);
|
||||
}
|
||||
void set_recon_clear_output(const bool v ){
|
||||
data->recon_config = (data->recon_config & ~0x10000000UL) | (v << 28);
|
||||
}
|
||||
void set_recon_load_freqs(const bool v ){
|
||||
data->recon_config = (data->recon_config & ~0x08000000UL) | (v << 27);
|
||||
}
|
||||
void set_recon_load_ranges(const bool v ){
|
||||
data->recon_config = (data->recon_config & ~0x04000000UL) | (v << 26);
|
||||
}
|
||||
void set_recon_update_ranges_when_recon(const bool v ){
|
||||
data->recon_config = (data->recon_config & ~0x02000000UL) | (v << 25);
|
||||
}
|
||||
void set_recon_load_hamradios(const bool v ){
|
||||
data->recon_config = (data->recon_config & ~0x01000000UL) | (v << 24);
|
||||
}
|
||||
void set_recon_match_mode(const bool v ) {
|
||||
data->recon_config = (data->recon_config & ~0x00800000UL) | (v << 23);
|
||||
}
|
||||
|
||||
} /* namespace persistent_memory */
|
||||
} /* namespace portapack */
|
||||
|
@@ -188,6 +188,26 @@ void set_clkout_enabled(bool v);
|
||||
uint32_t clkout_freq();
|
||||
void set_clkout_freq(uint32_t freq);
|
||||
|
||||
/* Recon app */
|
||||
bool recon_autosave_freqs();
|
||||
bool recon_autostart_recon();
|
||||
bool recon_continuous();
|
||||
bool recon_clear_output();
|
||||
bool recon_load_freqs();
|
||||
bool recon_load_ranges();
|
||||
bool recon_update_ranges_when_recon();
|
||||
bool recon_load_hamradios();
|
||||
bool recon_match_mode();
|
||||
void set_recon_autosave_freqs(const bool v);
|
||||
void set_recon_autostart_recon(const bool v);
|
||||
void set_recon_continuous(const bool v);
|
||||
void set_recon_clear_output(const bool v);
|
||||
void set_recon_load_freqs(const bool v);
|
||||
void set_recon_load_ranges(const bool v);
|
||||
void set_recon_update_ranges_when_recon(const bool v);
|
||||
void set_recon_load_hamradios(const bool v );
|
||||
void set_recon_match_mode( const bool v );
|
||||
|
||||
} /* namespace persistent_memory */
|
||||
} /* namespace portapack */
|
||||
|
||||
|
@@ -984,6 +984,159 @@ bool Button::on_touch(const TouchEvent event) {
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* ButtonWithEncoder ****************************************************************/
|
||||
|
||||
ButtonWithEncoder::ButtonWithEncoder(
|
||||
Rect parent_rect,
|
||||
std::string text,
|
||||
bool instant_exec
|
||||
) : Widget { parent_rect },
|
||||
text_ { text },
|
||||
instant_exec_ { instant_exec }
|
||||
{
|
||||
set_focusable(true);
|
||||
}
|
||||
|
||||
void ButtonWithEncoder::set_text(const std::string value) {
|
||||
text_ = value;
|
||||
set_dirty();
|
||||
}
|
||||
int32_t ButtonWithEncoder::get_encoder_delta() {
|
||||
return encoder_delta ;
|
||||
}
|
||||
void ButtonWithEncoder::set_encoder_delta( const int32_t delta )
|
||||
{
|
||||
encoder_delta = delta ;
|
||||
}
|
||||
|
||||
std::string ButtonWithEncoder::text() const {
|
||||
return text_;
|
||||
}
|
||||
|
||||
void ButtonWithEncoder::paint(Painter& painter) {
|
||||
Color bg, fg;
|
||||
const auto r = screen_rect();
|
||||
|
||||
if (has_focus() || highlighted()) {
|
||||
bg = style().foreground;
|
||||
fg = Color::black();
|
||||
} else {
|
||||
bg = Color::grey();
|
||||
fg = style().foreground;
|
||||
}
|
||||
|
||||
const Style paint_style = { style().font, bg, fg };
|
||||
|
||||
painter.draw_rectangle({r.location(), {r.size().width(), 1}}, Color::light_grey());
|
||||
painter.draw_rectangle({r.location().x(), r.location().y() + r.size().height() - 1, r.size().width(), 1}, Color::dark_grey());
|
||||
painter.draw_rectangle({r.location().x() + r.size().width() - 1, r.location().y(), 1, r.size().height()}, Color::dark_grey());
|
||||
|
||||
painter.fill_rectangle(
|
||||
{ r.location().x(), r.location().y() + 1, r.size().width() - 1, r.size().height() - 2 },
|
||||
paint_style.background
|
||||
);
|
||||
|
||||
const auto label_r = paint_style.font.size_of(text_);
|
||||
painter.draw_string(
|
||||
{ r.location().x() + (r.size().width() - label_r.width()) / 2, r.location().y() + (r.size().height() - label_r.height()) / 2 },
|
||||
paint_style,
|
||||
text_
|
||||
);
|
||||
}
|
||||
|
||||
void ButtonWithEncoder::on_focus() {
|
||||
if( on_highlight )
|
||||
on_highlight(*this);
|
||||
}
|
||||
|
||||
bool ButtonWithEncoder::on_key(const KeyEvent key) {
|
||||
if( key == KeyEvent::Select ) {
|
||||
if( on_select ) {
|
||||
on_select(*this);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if( on_dir ) {
|
||||
return on_dir(*this, key);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ButtonWithEncoder::on_touch(const TouchEvent event) {
|
||||
switch(event.type) {
|
||||
case TouchEvent::Type::Start:
|
||||
set_highlighted(true);
|
||||
set_dirty();
|
||||
if( on_touch_press) {
|
||||
on_touch_press(*this);
|
||||
}
|
||||
if( on_select && instant_exec_ ) {
|
||||
on_select(*this);
|
||||
}
|
||||
return true;
|
||||
|
||||
|
||||
case TouchEvent::Type::End:
|
||||
set_highlighted(false);
|
||||
set_dirty();
|
||||
if( on_touch_release) {
|
||||
on_touch_release(*this);
|
||||
}
|
||||
if( on_select && !instant_exec_ ) {
|
||||
on_select(*this);
|
||||
}
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
#if 0
|
||||
switch(event.type) {
|
||||
case TouchEvent::Type::Start:
|
||||
flags.highlighted = true;
|
||||
set_dirty();
|
||||
return true;
|
||||
|
||||
case TouchEvent::Type::Move:
|
||||
{
|
||||
const bool new_highlighted = screen_rect().contains(event.point);
|
||||
if( flags.highlighted != new_highlighted ) {
|
||||
flags.highlighted = new_highlighted;
|
||||
set_dirty();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
case TouchEvent::Type::End:
|
||||
if( flags.highlighted ) {
|
||||
flags.highlighted = false;
|
||||
set_dirty();
|
||||
if( on_select ) {
|
||||
on_select(*this);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
bool ButtonWithEncoder::on_encoder(const EncoderEvent delta) {
|
||||
if( delta != 0 )
|
||||
{
|
||||
encoder_delta += delta ;
|
||||
delta_change = true ;
|
||||
on_change();
|
||||
}
|
||||
else
|
||||
delta_change = 0 ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
/* NewButton ****************************************************************/
|
||||
|
||||
NewButton::NewButton(
|
||||
|
@@ -414,6 +414,51 @@ private:
|
||||
bool instant_exec_ { false };
|
||||
};
|
||||
|
||||
|
||||
class ButtonWithEncoder : public Widget {
|
||||
public:
|
||||
std::function<void(ButtonWithEncoder&)> on_select { };
|
||||
std::function<void(ButtonWithEncoder&)> on_touch_release { }; // Executed when releasing touch, after on_select.
|
||||
std::function<void(ButtonWithEncoder&)> on_touch_press { }; // Executed when touching, before on_select.
|
||||
std::function<bool(ButtonWithEncoder&, KeyEvent)> on_dir { };
|
||||
std::function<void(ButtonWithEncoder&)> on_highlight { };
|
||||
|
||||
ButtonWithEncoder(Rect parent_rect, std::string text, bool instant_exec); // instant_exec: Execute on_select when you touching instead of releasing
|
||||
ButtonWithEncoder(
|
||||
Rect parent_rect,
|
||||
std::string text
|
||||
) : ButtonWithEncoder { parent_rect, text, false }
|
||||
{
|
||||
}
|
||||
|
||||
ButtonWithEncoder(
|
||||
) : ButtonWithEncoder { { }, { } }
|
||||
{
|
||||
}
|
||||
|
||||
std::function<void()> on_change { };
|
||||
|
||||
void set_text(const std::string value);
|
||||
int32_t get_encoder_delta();
|
||||
void set_encoder_delta( const int32_t delta );
|
||||
std::string text() const;
|
||||
|
||||
void paint(Painter& painter) override;
|
||||
|
||||
void on_focus() override;
|
||||
bool on_key(const KeyEvent key) override;
|
||||
bool on_touch(const TouchEvent event) override;
|
||||
bool on_encoder(const EncoderEvent delta) override;
|
||||
|
||||
private:
|
||||
std::string text_;
|
||||
int32_t encoder_delta = 0 ;
|
||||
bool delta_change = 0 ;
|
||||
bool instant_exec_ { false };
|
||||
};
|
||||
|
||||
|
||||
|
||||
class NewButton : public Widget {
|
||||
public:
|
||||
std::function<void(void)> on_select { };
|
||||
|
Reference in New Issue
Block a user