mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2025-04-22 18:01:29 +00:00
Support showing invalid entries in Freqman and allow minor edits (#1269)
* Support showing invalid entries in Freqman and allow minor edits * Use light_grey instead of grey * Fix comment * Fix null in description bug * Fix spacing in delete entry dialog * trim in delete modal
This commit is contained in:
parent
4ed06b9eff
commit
d72d935607
@ -140,7 +140,7 @@ FrequencySaveView::FrequencySaveView(
|
|||||||
|
|
||||||
button_edit.on_select = [this, &nav](Button&) {
|
button_edit.on_select = [this, &nav](Button&) {
|
||||||
temp_buffer_ = entry_.description;
|
temp_buffer_ = entry_.description;
|
||||||
text_prompt(nav_, temp_buffer_, 30, [this](std::string& new_desc) {
|
text_prompt(nav_, temp_buffer_, desc_edit_max, [this](std::string& new_desc) {
|
||||||
entry_.description = new_desc;
|
entry_.description = new_desc;
|
||||||
refresh_ui();
|
refresh_ui();
|
||||||
});
|
});
|
||||||
@ -189,7 +189,7 @@ FrequencyLoadView::FrequencyLoadView(
|
|||||||
/* FrequencyManagerView **********************************/
|
/* FrequencyManagerView **********************************/
|
||||||
|
|
||||||
void FrequencyManagerView::on_edit_freq() {
|
void FrequencyManagerView::on_edit_freq() {
|
||||||
// TODO: range edit support?
|
// TODO: range edit support.
|
||||||
auto freq_edit_view = nav_.push<FrequencyKeypadView>(current_entry().frequency_a);
|
auto freq_edit_view = nav_.push<FrequencyKeypadView>(current_entry().frequency_a);
|
||||||
freq_edit_view->on_changed = [this](rf::Frequency f) {
|
freq_edit_view->on_changed = [this](rf::Frequency f) {
|
||||||
auto entry = current_entry();
|
auto entry = current_entry();
|
||||||
@ -201,7 +201,7 @@ void FrequencyManagerView::on_edit_freq() {
|
|||||||
|
|
||||||
void FrequencyManagerView::on_edit_desc() {
|
void FrequencyManagerView::on_edit_desc() {
|
||||||
temp_buffer_ = current_entry().description;
|
temp_buffer_ = current_entry().description;
|
||||||
text_prompt(nav_, temp_buffer_, 28, [this](std::string& new_desc) {
|
text_prompt(nav_, temp_buffer_, desc_edit_max, [this](std::string& new_desc) {
|
||||||
auto entry = current_entry();
|
auto entry = current_entry();
|
||||||
entry.description = std::move(new_desc);
|
entry.description = std::move(new_desc);
|
||||||
db_.replace_entry(current_index(), entry);
|
db_.replace_entry(current_index(), entry);
|
||||||
@ -211,7 +211,7 @@ void FrequencyManagerView::on_edit_desc() {
|
|||||||
|
|
||||||
void FrequencyManagerView::on_add_category() {
|
void FrequencyManagerView::on_add_category() {
|
||||||
temp_buffer_.clear();
|
temp_buffer_.clear();
|
||||||
text_prompt(nav_, temp_buffer_, 12, [this](std::string& new_name) {
|
text_prompt(nav_, temp_buffer_, 20, [this](std::string& new_name) {
|
||||||
if (!new_name.empty()) {
|
if (!new_name.empty()) {
|
||||||
create_freqman_file(new_name);
|
create_freqman_file(new_name);
|
||||||
refresh_categories();
|
refresh_categories();
|
||||||
@ -249,7 +249,7 @@ void FrequencyManagerView::on_del_entry() {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
nav_.push<ModalMessageView>(
|
nav_.push<ModalMessageView>(
|
||||||
"Delete", "Delete" + pretty_string(current_entry(), 23) + "\nAre you sure?", YESNO,
|
"Delete", "Delete " + trim(pretty_string(current_entry(), 23)) + "\nAre you sure?", YESNO,
|
||||||
[this](bool choice) {
|
[this](bool choice) {
|
||||||
if (choice) {
|
if (choice) {
|
||||||
db_.delete_entry(current_index());
|
db_.delete_entry(current_index());
|
||||||
|
@ -79,6 +79,7 @@ class FreqManBaseView : public View {
|
|||||||
protected:
|
protected:
|
||||||
/* Static so selected category is persisted across UI instances. */
|
/* Static so selected category is persisted across UI instances. */
|
||||||
static size_t current_category_index;
|
static size_t current_category_index;
|
||||||
|
static constexpr size_t desc_edit_max = 0x80;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: support for new category.
|
// TODO: support for new category.
|
||||||
|
@ -200,9 +200,12 @@ std::string pretty_string(const freqman_entry& entry, size_t max_length) {
|
|||||||
to_string_dec_uint(entry.frequency_b / 1'000'000) + "M: " + entry.description;
|
to_string_dec_uint(entry.frequency_b / 1'000'000) + "M: " + entry.description;
|
||||||
break;
|
break;
|
||||||
case freqman_type::HamRadio:
|
case freqman_type::HamRadio:
|
||||||
str = "" + to_string_dec_uint(entry.frequency_a / 1'000'000) + "M," +
|
str = "R:" + to_string_dec_uint(entry.frequency_a / 1'000'000) + "M,T:" +
|
||||||
to_string_dec_uint(entry.frequency_b / 1'000'000) + "M: " + entry.description;
|
to_string_dec_uint(entry.frequency_b / 1'000'000) + "M: " + entry.description;
|
||||||
break;
|
break;
|
||||||
|
case freqman_type::Raw:
|
||||||
|
str = entry.description;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
str = "UNK:" + entry.description;
|
str = "UNK:" + entry.description;
|
||||||
break;
|
break;
|
||||||
@ -244,8 +247,10 @@ std::string to_freqman_string(const freqman_entry& entry) {
|
|||||||
if (is_valid(entry.tone))
|
if (is_valid(entry.tone))
|
||||||
append_field("c", tonekey::tone_key_value_string(entry.tone));
|
append_field("c", tonekey::tone_key_value_string(entry.tone));
|
||||||
break;
|
break;
|
||||||
|
case freqman_type::Raw:
|
||||||
|
return entry.description;
|
||||||
default:
|
default:
|
||||||
return {}; // TODO: Comment type with description?
|
return {};
|
||||||
};
|
};
|
||||||
|
|
||||||
if (is_valid(entry.modulation) && entry.modulation < freqman_modulations.size()) {
|
if (is_valid(entry.modulation) && entry.modulation < freqman_modulations.size()) {
|
||||||
@ -429,6 +434,11 @@ freqman_entry FreqmanDB::operator[](FileWrapper::Line line) const {
|
|||||||
freqman_entry entry;
|
freqman_entry entry;
|
||||||
if (parse_freqman_entry(*line_text, entry))
|
if (parse_freqman_entry(*line_text, entry))
|
||||||
return entry;
|
return entry;
|
||||||
|
else {
|
||||||
|
entry.type = freqman_type::Raw;
|
||||||
|
entry.description = trim(*line_text);
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
@ -444,7 +454,7 @@ void FreqmanDB::insert_entry(const freqman_entry& entry, FileWrapper::Line line)
|
|||||||
void FreqmanDB::replace_entry(FileWrapper::Line line, const freqman_entry& entry) {
|
void FreqmanDB::replace_entry(FileWrapper::Line line, const freqman_entry& entry) {
|
||||||
auto range = wrapper_->line_range(line);
|
auto range = wrapper_->line_range(line);
|
||||||
if (!range)
|
if (!range)
|
||||||
return; // TODO: Message?
|
return;
|
||||||
|
|
||||||
// Don't overwrite the '\n'.
|
// Don't overwrite the '\n'.
|
||||||
range->end--;
|
range->end--;
|
||||||
|
@ -59,6 +59,7 @@ enum class freqman_type : uint8_t {
|
|||||||
Single, // f=
|
Single, // f=
|
||||||
Range, // a=,b=
|
Range, // a=,b=
|
||||||
HamRadio, // r=,t=
|
HamRadio, // r=,t=
|
||||||
|
Raw, // line content in description
|
||||||
Unknown,
|
Unknown,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -142,7 +143,7 @@ enum class freqman_type : uint8_t {
|
|||||||
struct freqman_entry {
|
struct freqman_entry {
|
||||||
int64_t frequency_a{0}; // 'f=freq' or 'a=freq_start' or 'r=recv_freq'
|
int64_t frequency_a{0}; // 'f=freq' or 'a=freq_start' or 'r=recv_freq'
|
||||||
int64_t frequency_b{0}; // 'b=freq_end' or 't=tx_freq'
|
int64_t frequency_b{0}; // 'b=freq_end' or 't=tx_freq'
|
||||||
std::string description{0}; // 'd=desc'
|
std::string description{}; // 'd=desc'
|
||||||
freqman_type type{freqman_type::Unknown};
|
freqman_type type{freqman_type::Unknown};
|
||||||
freqman_index_t modulation{freqman_invalid_index};
|
freqman_index_t modulation{freqman_invalid_index};
|
||||||
freqman_index_t bandwidth{freqman_invalid_index};
|
freqman_index_t bandwidth{freqman_invalid_index};
|
||||||
|
@ -56,16 +56,19 @@ void FreqManUIList::paint(Painter& painter) {
|
|||||||
auto text = std::string{};
|
auto text = std::string{};
|
||||||
auto index = start_index_ + offset;
|
auto index = start_index_ + offset;
|
||||||
auto line_position = rect.location() + Point{4, 1 + (int)offset * char_height};
|
auto line_position = rect.location() + Point{4, 1 + (int)offset * char_height};
|
||||||
|
auto is_selected = offset == selected_index_;
|
||||||
// Highlight the selected item.
|
auto style = base_style;
|
||||||
auto style = (offset == selected_index_) ? &Styles::bg_white : base_style;
|
|
||||||
|
|
||||||
if (index < db_->entry_count()) {
|
if (index < db_->entry_count()) {
|
||||||
auto entry = (*db_)[index];
|
auto entry = (*db_)[index];
|
||||||
// db_ is directly backed by a file, so invalid lines cannot be
|
// db_ is directly backed by a file, so invalid lines cannot be
|
||||||
// pre-filtered. Just show an empty 'slot' in this case.
|
// pre-filtered. Show an empty entry if 'Unknown'.
|
||||||
if (entry.type != freqman_type::Unknown)
|
if (entry.type != freqman_type::Unknown)
|
||||||
text = pretty_string(entry, line_max_length);
|
text = pretty_string(entry, line_max_length);
|
||||||
|
|
||||||
|
// Otherwise, if 'Raw' indicate an invalid entry by color.
|
||||||
|
if (entry.type == freqman_type::Raw)
|
||||||
|
style = &Styles::light_grey;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pad right with ' ' so trailing chars are cleaned up.
|
// Pad right with ' ' so trailing chars are cleaned up.
|
||||||
@ -73,7 +76,8 @@ void FreqManUIList::paint(Painter& painter) {
|
|||||||
if (text.length() < line_max_length)
|
if (text.length() < line_max_length)
|
||||||
text.resize(line_max_length, ' ');
|
text.resize(line_max_length, ' ');
|
||||||
|
|
||||||
painter.draw_string(line_position, *style, text);
|
painter.draw_string(
|
||||||
|
line_position, (is_selected ? style->invert() : *style), text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a bounding rectangle when focused.
|
// Draw a bounding rectangle when focused.
|
||||||
|
@ -47,3 +47,7 @@ TEST_CASE("trim removes whitespace.") {
|
|||||||
TEST_CASE("trim returns empty for only whitespace.") {
|
TEST_CASE("trim returns empty for only whitespace.") {
|
||||||
CHECK(trim(" \n").empty());
|
CHECK(trim(" \n").empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("trim empty returns empty.") {
|
||||||
|
CHECK(trim("").empty());
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user