mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-12-24 06:49:24 -05:00
Freqman mem reduce (#1076)
-made frequency lists a widget to avoid a full frequency_list copy -reduced FREQMAN_MAX_PER_FILE to a working limit
This commit is contained in:
parent
00667cecf9
commit
89e24cb358
@ -218,6 +218,7 @@ set(CPPSRC
|
|||||||
ui/ui_btngrid.cpp
|
ui/ui_btngrid.cpp
|
||||||
ui/ui_receiver.cpp
|
ui/ui_receiver.cpp
|
||||||
ui/ui_rssi.cpp
|
ui/ui_rssi.cpp
|
||||||
|
ui/ui_freqlist.cpp
|
||||||
ui/ui_tv.cpp
|
ui/ui_tv.cpp
|
||||||
ui/ui_spectrum.cpp
|
ui/ui_spectrum.cpp
|
||||||
ui/ui_tabview.cpp
|
ui/ui_tabview.cpp
|
||||||
|
@ -97,8 +97,10 @@ void FreqManBaseView::change_category(int32_t category_id) {
|
|||||||
|
|
||||||
if (!load_freqman_file(file_list[categories[current_category_id].second], database))
|
if (!load_freqman_file(file_list[categories[current_category_id].second], database))
|
||||||
error_ = ERROR_ACCESS;
|
error_ = ERROR_ACCESS;
|
||||||
else
|
else {
|
||||||
|
menu_view.set_db(database);
|
||||||
refresh_list();
|
refresh_list();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreqManBaseView::refresh_list() {
|
void FreqManBaseView::refresh_list() {
|
||||||
@ -108,20 +110,6 @@ void FreqManBaseView::refresh_list() {
|
|||||||
} else {
|
} else {
|
||||||
if (on_refresh_widgets)
|
if (on_refresh_widgets)
|
||||||
on_refresh_widgets(false);
|
on_refresh_widgets(false);
|
||||||
|
|
||||||
menu_view.clear();
|
|
||||||
|
|
||||||
for (size_t n = 0; n < database.size(); n++) {
|
|
||||||
menu_view.add_item({freqman_item_string(database[n], 30),
|
|
||||||
ui::Color::white(),
|
|
||||||
nullptr,
|
|
||||||
[this](KeyEvent) {
|
|
||||||
if (on_select_frequency)
|
|
||||||
on_select_frequency();
|
|
||||||
}});
|
|
||||||
}
|
|
||||||
|
|
||||||
menu_view.set_highlighted(0); // Refresh
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,18 +194,13 @@ FrequencyLoadView::FrequencyLoadView(
|
|||||||
// Resize menu view to fill screen
|
// Resize menu view to fill screen
|
||||||
menu_view.set_parent_rect({0, 3 * 8, 240, 30 * 8});
|
menu_view.set_parent_rect({0, 3 * 8, 240, 30 * 8});
|
||||||
|
|
||||||
// Just to allow exit on left
|
|
||||||
menu_view.on_left = [&nav, this]() {
|
|
||||||
nav.pop();
|
|
||||||
};
|
|
||||||
|
|
||||||
change_category(last_category_id);
|
change_category(last_category_id);
|
||||||
refresh_list();
|
refresh_list();
|
||||||
|
|
||||||
on_select_frequency = [&nav, this]() {
|
menu_view.on_select = [&nav, this](FreqManUIList&) {
|
||||||
nav_.pop();
|
nav_.pop();
|
||||||
|
|
||||||
auto& entry = database[menu_view.highlighted_index()];
|
auto& entry = database[menu_view.get_index()];
|
||||||
|
|
||||||
if (entry.type == RANGE) {
|
if (entry.type == RANGE) {
|
||||||
// User chose a frequency range entry
|
// User chose a frequency range entry
|
||||||
@ -235,14 +218,14 @@ FrequencyLoadView::FrequencyLoadView(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FrequencyManagerView::on_edit_freq(rf::Frequency f) {
|
void FrequencyManagerView::on_edit_freq(rf::Frequency f) {
|
||||||
database[menu_view.highlighted_index()].frequency_a = f;
|
database[menu_view.get_index()].frequency_a = f;
|
||||||
save_freqman_file(file_list[categories[current_category_id].second], database);
|
save_freqman_file(file_list[categories[current_category_id].second], database);
|
||||||
refresh_list();
|
refresh_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrequencyManagerView::on_edit_desc(NavigationView& nav) {
|
void FrequencyManagerView::on_edit_desc(NavigationView& nav) {
|
||||||
text_prompt(nav, desc_buffer, 28, [this](std::string& buffer) {
|
text_prompt(nav, desc_buffer, 28, [this](std::string& buffer) {
|
||||||
database[menu_view.highlighted_index()].description = buffer;
|
database[menu_view.get_index()].description = buffer;
|
||||||
refresh_list();
|
refresh_list();
|
||||||
save_freqman_file(file_list[categories[current_category_id].second], database);
|
save_freqman_file(file_list[categories[current_category_id].second], database);
|
||||||
});
|
});
|
||||||
@ -258,7 +241,7 @@ void FrequencyManagerView::on_new_category(NavigationView& nav) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FrequencyManagerView::on_delete() {
|
void FrequencyManagerView::on_delete() {
|
||||||
database.erase(database.begin() + menu_view.highlighted_index());
|
database.erase(database.begin() + menu_view.get_index());
|
||||||
save_freqman_file(file_list[categories[current_category_id].second], database);
|
save_freqman_file(file_list[categories[current_category_id].second], database);
|
||||||
refresh_list();
|
refresh_list();
|
||||||
}
|
}
|
||||||
@ -292,15 +275,10 @@ FrequencyManagerView::FrequencyManagerView(
|
|||||||
&button_edit_desc,
|
&button_edit_desc,
|
||||||
&button_delete});
|
&button_delete});
|
||||||
|
|
||||||
// Just to allow exit on left
|
|
||||||
menu_view.on_left = [&nav, this]() {
|
|
||||||
nav.pop();
|
|
||||||
};
|
|
||||||
|
|
||||||
change_category(last_category_id);
|
change_category(last_category_id);
|
||||||
refresh_list();
|
refresh_list();
|
||||||
|
|
||||||
on_select_frequency = [this]() {
|
menu_view.on_select = [this](FreqManUIList&) {
|
||||||
button_edit_freq.focus();
|
button_edit_freq.focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -310,14 +288,14 @@ FrequencyManagerView::FrequencyManagerView(
|
|||||||
};
|
};
|
||||||
|
|
||||||
button_edit_freq.on_select = [this, &nav](Button&) {
|
button_edit_freq.on_select = [this, &nav](Button&) {
|
||||||
auto new_view = nav.push<FrequencyKeypadView>(database[menu_view.highlighted_index()].frequency_a);
|
auto new_view = nav.push<FrequencyKeypadView>(database[menu_view.get_index()].frequency_a);
|
||||||
new_view->on_changed = [this](rf::Frequency f) {
|
new_view->on_changed = [this](rf::Frequency f) {
|
||||||
on_edit_freq(f);
|
on_edit_freq(f);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
button_edit_desc.on_select = [this, &nav](Button&) {
|
button_edit_desc.on_select = [this, &nav](Button&) {
|
||||||
desc_buffer = database[menu_view.highlighted_index()].description;
|
desc_buffer = database[menu_view.get_index()].description;
|
||||||
on_edit_desc(nav);
|
on_edit_desc(nav);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "ui_receiver.hpp"
|
#include "ui_receiver.hpp"
|
||||||
#include "ui_textentry.hpp"
|
#include "ui_textentry.hpp"
|
||||||
#include "freqman.hpp"
|
#include "freqman.hpp"
|
||||||
|
#include "ui_freqlist.hpp"
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
@ -65,9 +66,9 @@ class FreqManBaseView : public View {
|
|||||||
14,
|
14,
|
||||||
{}};
|
{}};
|
||||||
|
|
||||||
MenuView menu_view{
|
FreqManUIList menu_view{
|
||||||
{0, 3 * 8, 240, 23 * 8},
|
{0, 3 * 8, 240, 23 * 8}};
|
||||||
true};
|
|
||||||
Text text_empty{
|
Text text_empty{
|
||||||
{7 * 8, 12 * 8, 16 * 8, 16},
|
{7 * 8, 12 * 8, 16 * 8, 16},
|
||||||
"Empty category !",
|
"Empty category !",
|
||||||
|
@ -36,7 +36,11 @@ void ReconView::clear_freqlist_for_ui_action() {
|
|||||||
freqlist_cleared_for_ui_action = true;
|
freqlist_cleared_for_ui_action = true;
|
||||||
// if in manual mode, there is enough memory to load freqman files, else we have to unload/reload
|
// if in manual mode, there is enough memory to load freqman files, else we have to unload/reload
|
||||||
if (!manual_mode) {
|
if (!manual_mode) {
|
||||||
frequency_list.clear();
|
// clear and shrink_to_fit are not enough to really start with a new, clean, empty vector
|
||||||
|
// swap is the only way to achieve a perfect memory liberation
|
||||||
|
std::vector<freqman_entry>().swap(frequency_list);
|
||||||
|
} else {
|
||||||
|
frequency_list.shrink_to_fit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -687,7 +691,10 @@ ReconView::ReconView(NavigationView& nav)
|
|||||||
} else {
|
} else {
|
||||||
audio::output::stop();
|
audio::output::stop();
|
||||||
|
|
||||||
frequency_list.clear();
|
// clear and shrink_to_fit are not enough to really start with a new, clean, empty vector
|
||||||
|
// swap is the only way to achieve a perfect memory liberation
|
||||||
|
std::vector<freqman_entry>().swap(frequency_list);
|
||||||
|
|
||||||
freqman_entry manual_freq_entry;
|
freqman_entry manual_freq_entry;
|
||||||
|
|
||||||
def_step = step_mode.selected_index(); // max range val
|
def_step = step_mode.selected_index(); // max range val
|
||||||
@ -895,8 +902,10 @@ void ReconView::frequency_file_load(bool stop_all_before) {
|
|||||||
audio::output::stop();
|
audio::output::stop();
|
||||||
|
|
||||||
def_step = step_mode.selected_index(); // use def_step from manual selector
|
def_step = step_mode.selected_index(); // use def_step from manual selector
|
||||||
frequency_list.clear(); // clear the existing frequency list (expected behavior)
|
// clear and shrink_to_fit are not enough to really start with a new, clean, empty vector
|
||||||
std::string file_input = input_file; // default recon mode
|
// swap is the only way to achieve a perfect memory liberation
|
||||||
|
std::vector<freqman_entry>().swap(frequency_list); // clear the existing frequency list (expected behavior)
|
||||||
|
std::string file_input = input_file; // default recon mode
|
||||||
if (scanner_mode) {
|
if (scanner_mode) {
|
||||||
file_input = output_file;
|
file_input = output_file;
|
||||||
file_name.set_style(&style_red);
|
file_name.set_style(&style_red);
|
||||||
|
@ -114,35 +114,40 @@ bool load_freqman_file_ex(std::string& file_stem, freqman_db& db, bool load_freq
|
|||||||
char* line_end;
|
char* line_end;
|
||||||
std::string description;
|
std::string description;
|
||||||
rf::Frequency frequency_a, frequency_b;
|
rf::Frequency frequency_a, frequency_b;
|
||||||
char file_data[257];
|
const int read_buf_size = 128;
|
||||||
|
char file_data[read_buf_size + 1];
|
||||||
freqman_entry_type type;
|
freqman_entry_type type;
|
||||||
freqman_index_t modulation = 0;
|
freqman_index_t modulation = 0;
|
||||||
freqman_index_t bandwidth = 0;
|
freqman_index_t bandwidth = 0;
|
||||||
freqman_index_t step = 0;
|
freqman_index_t step = 0;
|
||||||
freqman_index_t tone = 0;
|
freqman_index_t tone = 0;
|
||||||
|
|
||||||
db.clear();
|
// these are not enough to really start with a new, clean, empty vector
|
||||||
|
// swap is the only way to achieve a perfect memory liberation
|
||||||
|
// db.clear();
|
||||||
|
// db.shrink_to_fit():
|
||||||
|
std::vector<freqman_entry>().swap(db);
|
||||||
|
|
||||||
auto result = freqman_file.open("FREQMAN/" + file_stem + ".TXT");
|
auto result = freqman_file.open("FREQMAN/" + file_stem + ".TXT");
|
||||||
if (result.is_valid())
|
if (result.is_valid())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
// Read a 256 bytes block from file
|
// Read a read_buf_size bytes block from file
|
||||||
freqman_file.seek(file_position);
|
freqman_file.seek(file_position);
|
||||||
|
|
||||||
memset(file_data, 0, 257);
|
memset(file_data, 0, read_buf_size + 1);
|
||||||
auto read_size = freqman_file.read(file_data, 256);
|
auto read_size = freqman_file.read(file_data, read_buf_size);
|
||||||
if (read_size.is_error())
|
if (read_size.is_error())
|
||||||
return false; // Read error
|
return false; // Read error
|
||||||
|
|
||||||
file_position += 256;
|
file_position += read_buf_size;
|
||||||
|
|
||||||
// Reset line_start to beginning of buffer
|
// Reset line_start to beginning of buffer
|
||||||
line_start = file_data;
|
line_start = file_data;
|
||||||
|
|
||||||
// If EOF reached, insert 0x0A after, in case the last line doesn't have a C/R
|
// If EOF reached, insert 0x0A after, in case the last line doesn't have a C/R
|
||||||
if (read_size.value() < 256)
|
if (read_size.value() < read_buf_size)
|
||||||
*(line_start + read_size.value()) = 0x0A;
|
*(line_start + read_size.value()) = 0x0A;
|
||||||
|
|
||||||
// Look for complete lines in buffer
|
// Look for complete lines in buffer
|
||||||
@ -222,8 +227,7 @@ bool load_freqman_file_ex(std::string& file_stem, freqman_db& db, bool load_freq
|
|||||||
pos += 2;
|
pos += 2;
|
||||||
length = std::min(strcspn(pos, ",\x0A"), (size_t)FREQMAN_DESC_MAX_LEN);
|
length = std::min(strcspn(pos, ",\x0A"), (size_t)FREQMAN_DESC_MAX_LEN);
|
||||||
description = string(pos, length);
|
description = string(pos, length);
|
||||||
} else
|
}
|
||||||
description = "-";
|
|
||||||
if ((type == SINGLE && load_freqs) || (type == RANGE && load_ranges) || (type == HAMRADIO && load_hamradios)) {
|
if ((type == SINGLE && load_freqs) || (type == RANGE && load_ranges) || (type == HAMRADIO && load_hamradios)) {
|
||||||
db.push_back({frequency_a, frequency_b, description, type, modulation, bandwidth, step, tone});
|
db.push_back({frequency_a, frequency_b, description, type, modulation, bandwidth, step, tone});
|
||||||
n++;
|
n++;
|
||||||
@ -231,14 +235,14 @@ bool load_freqman_file_ex(std::string& file_stem, freqman_db& db, bool load_freq
|
|||||||
}
|
}
|
||||||
|
|
||||||
line_start = line_end + 1;
|
line_start = line_end + 1;
|
||||||
if (line_start - file_data >= 256) break;
|
if (line_start - file_data >= read_buf_size) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read_size.value() != 256)
|
if (read_size.value() != read_buf_size)
|
||||||
break; // End of file
|
break; // End of file
|
||||||
|
|
||||||
// Restart at beginning of last incomplete line
|
// Restart at beginning of last incomplete line
|
||||||
file_position -= (file_data + 256 - line_start);
|
file_position -= (file_data + read_buf_size - line_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* populate implicitly specified modulation / bandwidth */
|
/* populate implicitly specified modulation / bandwidth */
|
||||||
|
@ -32,10 +32,10 @@
|
|||||||
#include "string_format.hpp"
|
#include "string_format.hpp"
|
||||||
#include "ui_widget.hpp"
|
#include "ui_widget.hpp"
|
||||||
|
|
||||||
#define FREQMAN_DESC_MAX_LEN 24 // This is the number of characters that can be drawn in front of "R: TEXT..." before taking a full screen line
|
#define FREQMAN_DESC_MAX_LEN 24 // This is the number of characters that can be drawn in front of "R: TEXT..." before taking a full screen line
|
||||||
#define FREQMAN_MAX_PER_FILE 115 // Maximum of entries we can read. This is a hardware limit
|
#define FREQMAN_MAX_PER_FILE 60 // Maximum of entries we can read. This is a hardware limit
|
||||||
// It was tested and lowered to leave a bit of space to the caller
|
// It was tested and lowered to leave a bit of space to the caller
|
||||||
#define FREQMAN_MAX_PER_FILE_STR "115" // STRING OF FREQMAN_MAX_PER_FILE
|
#define FREQMAN_MAX_PER_FILE_STR "60" // STRING OF FREQMAN_MAX_PER_FILE
|
||||||
|
|
||||||
using namespace ui;
|
using namespace ui;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
157
firmware/application/ui/ui_freqlist.cpp
Normal file
157
firmware/application/ui/ui_freqlist.cpp
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of PortaPack.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ui_freqlist.hpp"
|
||||||
|
|
||||||
|
#include "baseband_api.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace ui {
|
||||||
|
FreqManUIList::FreqManUIList(
|
||||||
|
Rect parent_rect,
|
||||||
|
bool instant_exec)
|
||||||
|
: Widget{parent_rect},
|
||||||
|
instant_exec_{instant_exec} {
|
||||||
|
this->set_focusable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreqManUIList::set_highlighted_index(int index) {
|
||||||
|
if ((unsigned)(current_index + index) >= freqlist_db.size())
|
||||||
|
return;
|
||||||
|
if (index < 0) {
|
||||||
|
index = 0;
|
||||||
|
if (current_index > 0)
|
||||||
|
current_index--;
|
||||||
|
}
|
||||||
|
if (index >= freqlist_nb_lines) {
|
||||||
|
index = freqlist_nb_lines - 1;
|
||||||
|
if ((unsigned)(current_index + index) < freqlist_db.size())
|
||||||
|
current_index++;
|
||||||
|
else
|
||||||
|
current_index = freqlist_db.size() - freqlist_nb_lines - 1;
|
||||||
|
}
|
||||||
|
highlighted_index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t FreqManUIList::get_index() {
|
||||||
|
return current_index + highlighted_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreqManUIList::paint(Painter& painter) {
|
||||||
|
freqlist_nb_lines = 0;
|
||||||
|
const auto r = screen_rect();
|
||||||
|
uint8_t focused = has_focus();
|
||||||
|
const Rect r_widget_screen{r.left() + focused, r.top() + focused, r.width() - 2 * focused, r.height() - 2 * +focused};
|
||||||
|
painter.fill_rectangle(
|
||||||
|
r_widget_screen,
|
||||||
|
Color::black());
|
||||||
|
if (freqlist_db.size() == 0)
|
||||||
|
return;
|
||||||
|
uint8_t nb_lines = 0;
|
||||||
|
for (uint8_t it = current_index; it < freqlist_db.size(); it++) {
|
||||||
|
uint8_t line_height = (int)nb_lines * char_height;
|
||||||
|
if (line_height < (r.height() - char_height)) {
|
||||||
|
std::string description = freqman_item_string(freqlist_db[it], 30);
|
||||||
|
// line is within the widget
|
||||||
|
painter.draw_string(
|
||||||
|
{0, r.location().y() + (int)nb_lines * char_height},
|
||||||
|
style_default, description);
|
||||||
|
if (nb_lines == highlighted_index) {
|
||||||
|
const Rect r_highlighted_freq{0, r.location().y() + (int)nb_lines * char_height, 240, char_height};
|
||||||
|
painter.draw_rectangle(
|
||||||
|
r_highlighted_freq,
|
||||||
|
Color::white());
|
||||||
|
}
|
||||||
|
nb_lines++;
|
||||||
|
} else {
|
||||||
|
// rect is filled, we can break
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
freqlist_nb_lines = nb_lines;
|
||||||
|
if (has_focus() || highlighted()) {
|
||||||
|
const Rect r_focus{r.left(), r.top(), r.width(), r.height()};
|
||||||
|
painter.draw_rectangle(
|
||||||
|
r_focus,
|
||||||
|
Color::white());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreqManUIList::set_db(freqman_db& db) {
|
||||||
|
freqlist_db = db;
|
||||||
|
current_index = 0;
|
||||||
|
highlighted_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreqManUIList::on_focus() {
|
||||||
|
if (on_highlight)
|
||||||
|
on_highlight(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FreqManUIList::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 FreqManUIList::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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FreqManUIList::on_encoder(EncoderEvent delta) {
|
||||||
|
set_highlighted_index((int)highlighted_index + delta);
|
||||||
|
set_dirty();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} /* namespace ui */
|
80
firmware/application/ui/ui_freqlist.hpp
Normal file
80
firmware/application/ui/ui_freqlist.hpp
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of PortaPack.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __UI_FREQLIST_H__
|
||||||
|
#define __UI_FREQLIST_H__
|
||||||
|
|
||||||
|
#include "ui.hpp"
|
||||||
|
#include "ui_font_fixed_5x8.hpp"
|
||||||
|
#include "ui_widget.hpp"
|
||||||
|
#include "ui_painter.hpp"
|
||||||
|
#include "event_m0.hpp"
|
||||||
|
#include "message.hpp"
|
||||||
|
#include "freqman.hpp"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace ui {
|
||||||
|
|
||||||
|
class FreqManUIList : public Widget {
|
||||||
|
public:
|
||||||
|
std::function<void(FreqManUIList&)> on_select{};
|
||||||
|
std::function<void(FreqManUIList&)> on_touch_release{}; // Executed when releasing touch, after on_select.
|
||||||
|
std::function<void(FreqManUIList&)> on_touch_press{}; // Executed when touching, before on_select.
|
||||||
|
std::function<bool(FreqManUIList&, KeyEvent)> on_dir{};
|
||||||
|
std::function<void(FreqManUIList&)> on_highlight{};
|
||||||
|
|
||||||
|
FreqManUIList(Rect parent_rect, bool instant_exec); // instant_exec: Execute on_select when you touching instead of releasing
|
||||||
|
FreqManUIList(
|
||||||
|
Rect parent_rect)
|
||||||
|
: FreqManUIList{parent_rect, false} {
|
||||||
|
}
|
||||||
|
FreqManUIList()
|
||||||
|
: FreqManUIList{{}, {}} {
|
||||||
|
}
|
||||||
|
|
||||||
|
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(EncoderEvent delta) override;
|
||||||
|
|
||||||
|
bool set_highlighted_index(int index); // set highlighted_index and return capped highlighted_index value to set in caller
|
||||||
|
uint8_t get_index(); // return highlighed + index
|
||||||
|
void set_db(freqman_db& db);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static constexpr Style style_default{
|
||||||
|
.font = font::fixed_8x16,
|
||||||
|
.background = Color::black(),
|
||||||
|
.foreground = Color::white(),
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr int8_t char_height = 16;
|
||||||
|
bool instant_exec_{false};
|
||||||
|
freqman_db freqlist_db{};
|
||||||
|
int current_index{0};
|
||||||
|
int highlighted_index{0};
|
||||||
|
int freqlist_nb_lines{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ui
|
||||||
|
|
||||||
|
#endif /*__UI_FREQLIST_H__*/
|
Loading…
Reference in New Issue
Block a user