mirror of
https://github.com/eried/portapack-mayhem.git
synced 2025-01-11 07:19:34 -05:00
Added utilities > Frequency manager + load/save
This commit is contained in:
parent
ad2a4b6743
commit
7df5987b3b
@ -140,13 +140,13 @@ set(CPPSRC
|
||||
afsk.cpp
|
||||
rds.cpp
|
||||
ctcss.cpp
|
||||
freqman.cpp
|
||||
${COMMON}/lcd_ili9341.cpp
|
||||
${COMMON}/ui.cpp
|
||||
${COMMON}/ui_text.cpp
|
||||
${COMMON}/ui_widget.cpp
|
||||
${COMMON}/ui_painter.cpp
|
||||
${COMMON}/ui_focus.cpp
|
||||
${COMMON}/msgpack.cpp
|
||||
ui_about.cpp
|
||||
ui_adsbtx.cpp
|
||||
ui_afsksetup.cpp
|
||||
|
@ -2408,33 +2408,6 @@ __/common/message_queue.cpp.s:
|
||||
cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/__/common/message_queue.cpp.s
|
||||
.PHONY : __/common/message_queue.cpp.s
|
||||
|
||||
__/common/msgpack.obj: __/common/msgpack.cpp.obj
|
||||
|
||||
.PHONY : __/common/msgpack.obj
|
||||
|
||||
# target to build an object file
|
||||
__/common/msgpack.cpp.obj:
|
||||
cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/__/common/msgpack.cpp.obj
|
||||
.PHONY : __/common/msgpack.cpp.obj
|
||||
|
||||
__/common/msgpack.i: __/common/msgpack.cpp.i
|
||||
|
||||
.PHONY : __/common/msgpack.i
|
||||
|
||||
# target to preprocess a source file
|
||||
__/common/msgpack.cpp.i:
|
||||
cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/__/common/msgpack.cpp.i
|
||||
.PHONY : __/common/msgpack.cpp.i
|
||||
|
||||
__/common/msgpack.s: __/common/msgpack.cpp.s
|
||||
|
||||
.PHONY : __/common/msgpack.s
|
||||
|
||||
# target to generate assembly for a file
|
||||
__/common/msgpack.cpp.s:
|
||||
cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/__/common/msgpack.cpp.s
|
||||
.PHONY : __/common/msgpack.cpp.s
|
||||
|
||||
__/common/png_writer.obj: __/common/png_writer.cpp.obj
|
||||
|
||||
.PHONY : __/common/png_writer.obj
|
||||
@ -3299,6 +3272,33 @@ filewriter.cpp.s:
|
||||
cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/filewriter.cpp.s
|
||||
.PHONY : filewriter.cpp.s
|
||||
|
||||
freqman.obj: freqman.cpp.obj
|
||||
|
||||
.PHONY : freqman.obj
|
||||
|
||||
# target to build an object file
|
||||
freqman.cpp.obj:
|
||||
cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/freqman.cpp.obj
|
||||
.PHONY : freqman.cpp.obj
|
||||
|
||||
freqman.i: freqman.cpp.i
|
||||
|
||||
.PHONY : freqman.i
|
||||
|
||||
# target to preprocess a source file
|
||||
freqman.cpp.i:
|
||||
cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/freqman.cpp.i
|
||||
.PHONY : freqman.cpp.i
|
||||
|
||||
freqman.s: freqman.cpp.s
|
||||
|
||||
.PHONY : freqman.s
|
||||
|
||||
# target to generate assembly for a file
|
||||
freqman.cpp.s:
|
||||
cd /home/furrtek/portapack-hackrf && $(MAKE) -f firmware/application/CMakeFiles/application.elf.dir/build.make firmware/application/CMakeFiles/application.elf.dir/freqman.cpp.s
|
||||
.PHONY : freqman.cpp.s
|
||||
|
||||
hackrf_cpld_data.obj: hackrf_cpld_data.cpp.obj
|
||||
|
||||
.PHONY : hackrf_cpld_data.obj
|
||||
@ -5316,9 +5316,6 @@ help:
|
||||
@echo "... __/common/message_queue.obj"
|
||||
@echo "... __/common/message_queue.i"
|
||||
@echo "... __/common/message_queue.s"
|
||||
@echo "... __/common/msgpack.obj"
|
||||
@echo "... __/common/msgpack.i"
|
||||
@echo "... __/common/msgpack.s"
|
||||
@echo "... __/common/png_writer.obj"
|
||||
@echo "... __/common/png_writer.i"
|
||||
@echo "... __/common/png_writer.s"
|
||||
@ -5415,6 +5412,9 @@ help:
|
||||
@echo "... filewriter.obj"
|
||||
@echo "... filewriter.i"
|
||||
@echo "... filewriter.s"
|
||||
@echo "... freqman.obj"
|
||||
@echo "... freqman.i"
|
||||
@echo "... freqman.s"
|
||||
@echo "... hackrf_cpld_data.obj"
|
||||
@echo "... hackrf_cpld_data.i"
|
||||
@echo "... hackrf_cpld_data.s"
|
||||
|
@ -76,26 +76,18 @@ static constexpr Bitmap bitmap_speaker {
|
||||
};
|
||||
|
||||
static constexpr uint8_t bitmap_more_data[] = {
|
||||
0x00, 0x00,
|
||||
0xC0, 0x03,
|
||||
0xC0, 0x03,
|
||||
0xC0, 0x03,
|
||||
0xC0, 0x03,
|
||||
0xC0, 0x03,
|
||||
0xC0, 0x03,
|
||||
0xC0, 0x03,
|
||||
0xC6, 0x63,
|
||||
0xCF, 0xF3,
|
||||
0xDE, 0x7B,
|
||||
0xFC, 0x3F,
|
||||
0xF8, 0x1F,
|
||||
0xF0, 0x0F,
|
||||
0xE0, 0x07,
|
||||
0xC0, 0x03
|
||||
0x18,
|
||||
0x18,
|
||||
0x18,
|
||||
0x18,
|
||||
0xFF,
|
||||
0x7E,
|
||||
0x3C,
|
||||
0x18,
|
||||
};
|
||||
|
||||
static constexpr Bitmap bitmap_more {
|
||||
{ 16, 16 }, bitmap_more_data
|
||||
{ 8, 8 }, bitmap_more_data
|
||||
};
|
||||
|
||||
static constexpr uint8_t bitmap_rssipwm_data[] = {
|
||||
|
110
firmware/application/freqman.cpp
Normal file
110
firmware/application/freqman.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
|
||||
* Copyright (C) 2016 Furrtek
|
||||
*
|
||||
* 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 "freqman.hpp"
|
||||
|
||||
bool load_freqman_file(std::vector<freqman_entry> &frequencies) {
|
||||
File freqs_file;
|
||||
size_t end, n = 0;
|
||||
char * file_buffer;
|
||||
char * desc_pos;
|
||||
char desc_buffer[32] = { 0 };
|
||||
std::string description;
|
||||
rf::Frequency value;
|
||||
|
||||
file_buffer = (char *)chHeapAlloc(0, 2048);
|
||||
|
||||
while (freqs_file.open("freqman.txt").is_valid()) {
|
||||
auto result = freqs_file.create("freqman.txt");
|
||||
if (result.is_valid()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
freqs_file.read(file_buffer, 2048);
|
||||
|
||||
char * pos = file_buffer;
|
||||
while ((pos = strstr(pos, "f=")) && n < 32) {
|
||||
pos += 2;
|
||||
|
||||
value = strtol(pos, nullptr, 10);
|
||||
|
||||
desc_pos = strstr(pos, "d=");
|
||||
if (desc_pos) {
|
||||
desc_pos += 2;
|
||||
end = strcspn(desc_pos, ",\x0D\x0A"); // CR LF
|
||||
if (end > 31) end = 31;
|
||||
memcpy(desc_buffer, desc_pos, end);
|
||||
desc_buffer[end] = (char)0;
|
||||
description = desc_buffer;
|
||||
pos = desc_pos;
|
||||
} else {
|
||||
description = "-";
|
||||
}
|
||||
|
||||
frequencies.push_back({ value, "", description });
|
||||
}
|
||||
|
||||
chHeapFree(file_buffer);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool save_freqman_file(std::vector<freqman_entry> &frequencies) {
|
||||
File freqs_file;
|
||||
size_t n;
|
||||
std::string item_string;
|
||||
|
||||
auto result = freqs_file.create("freqman.txt");
|
||||
if (result.is_valid()) return false;
|
||||
|
||||
for (n = 0; n < frequencies.size(); n++) {
|
||||
item_string = "f=" + to_string_dec_uint(frequencies[n].value);
|
||||
|
||||
if (frequencies[n].description.size())
|
||||
item_string += ",d=" + frequencies[n].description;
|
||||
|
||||
freqs_file.write_line(item_string);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string freqman_item_string(freqman_entry &entry) {
|
||||
std::string item_string, frequency_str, description;
|
||||
char temp_buffer[32];
|
||||
rf::Frequency value;
|
||||
|
||||
value = entry.value;
|
||||
entry.frequency_str = to_string_dec_int(value / 1000000, 4) + "." +
|
||||
to_string_dec_int((value / 100) % 10000, 4, '0');
|
||||
|
||||
if (entry.description.size() <= 19) {
|
||||
item_string = entry.frequency_str + ":" + entry.description;
|
||||
} else {
|
||||
memcpy(temp_buffer, entry.description.c_str(), 16);
|
||||
temp_buffer[16] = (char)0;
|
||||
item_string = entry.frequency_str + ":" + temp_buffer + "...";
|
||||
}
|
||||
|
||||
return item_string;
|
||||
}
|
44
firmware/application/freqman.hpp
Normal file
44
firmware/application/freqman.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
|
||||
* Copyright (C) 2016 Furrtek
|
||||
*
|
||||
* 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 <cstring>
|
||||
#include <string>
|
||||
#include "file.hpp"
|
||||
#include "ui_receiver.hpp"
|
||||
#include "string_format.hpp"
|
||||
|
||||
#ifndef __FREQMAN_H__
|
||||
#define __FREQMAN_H__
|
||||
|
||||
using namespace ui;
|
||||
|
||||
struct freqman_entry {
|
||||
rf::Frequency value;
|
||||
std::string frequency_str;
|
||||
std::string description;
|
||||
};
|
||||
|
||||
bool load_freqman_file(std::vector<freqman_entry> &frequencies);
|
||||
bool save_freqman_file(std::vector<freqman_entry> &frequencies);
|
||||
std::string freqman_item_string(freqman_entry &frequencies);
|
||||
|
||||
#endif/*__FREQMAN_H__*/
|
@ -23,30 +23,29 @@
|
||||
// Color bitmaps generated with:
|
||||
// Gimp image > indexed colors (16), then "xxd -i *.bmp"
|
||||
|
||||
//BUG: Xylos doesn't play last tone ?
|
||||
//BUG (fixed ?): Unistroke text entry screen doesn't care about string max length parameter
|
||||
//TEST: Imperial in whipcalc
|
||||
//TEST: Numbers
|
||||
//TEST: Jammer
|
||||
//TEST: Frequency manager + save/load
|
||||
|
||||
//BUG: Xylos doesn't play last tone ?
|
||||
//BUG (fixed ?): Soundboard crashes on exit if no wav files on sd card
|
||||
//BUG (fixed ?): Unistroke text entry screen doesn't care about string max length parameter
|
||||
//BUG: POCSAG RX sometimes misses the first codeword after SYNC
|
||||
//BUG: Check AFSK transmit end, skips last bits ?
|
||||
//BUG: RDS doesn't stop baseband when stopping tx ?
|
||||
|
||||
//TODO: File browser ?
|
||||
//TODO: Mousejack ?
|
||||
//TODO: Waveform widget ?
|
||||
//TODO: Frequency manager save/load (ui_freqman)
|
||||
//TODO: Wav visualizer
|
||||
//TODO: Move frequencykeypad from ui_receiver to ui_widget (used everywhere)
|
||||
//TODO: ADS-B draw trajectory + GPS coordinates + scale, and playback
|
||||
//TODO: Finish EPAR tx
|
||||
//TODO: Wav visualizer
|
||||
//TODO: Analog TV tx with camcorder font character generator
|
||||
//TODO: Test dual tone in proc_tones and remove proc_dtmf_tx
|
||||
//TODO: Morse coder for foxhunts
|
||||
//TODO: Make Morse coder and Whistle use proc_tones
|
||||
//TODO: RDS multiple groups (sequence)
|
||||
//TODO: Frequency manager
|
||||
//TODO: IQ replay
|
||||
//TODO: Use ModalMessageView confirmation for TX ?
|
||||
//TODO: Show address/data bit fields in OOK TX
|
||||
|
@ -62,7 +62,7 @@ private:
|
||||
void update_text();
|
||||
|
||||
Text text_input {
|
||||
{ 8, 0, 224, 16 }
|
||||
{ 8, 0, 232, 16 }
|
||||
};
|
||||
|
||||
std::array<Button, 40> buttons;
|
||||
|
@ -24,7 +24,6 @@
|
||||
|
||||
#include "portapack.hpp"
|
||||
#include "event_m0.hpp"
|
||||
#include "portapack_shared_memory.hpp"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
@ -32,73 +31,197 @@ using namespace portapack;
|
||||
|
||||
namespace ui {
|
||||
|
||||
void FrequencySaveView::on_save_name(NavigationView& nav) {
|
||||
textentry(nav, desc_buffer, 28);
|
||||
frequencies.push_back({ value_, "", desc_buffer });
|
||||
nav.pop();
|
||||
}
|
||||
void FrequencySaveView::on_save_timestamp(NavigationView& nav) {
|
||||
frequencies.push_back({ value_, "", text_timestamp.text() });
|
||||
nav.pop();
|
||||
}
|
||||
|
||||
void FrequencySaveView::focus() {
|
||||
button_save_timestamp.focus();
|
||||
|
||||
if (error)
|
||||
nav_.display_modal("Error", "File acces error !", ABORT, nullptr);
|
||||
}
|
||||
|
||||
void FrequencySaveView::on_tick_second() {
|
||||
rtcGetTime(&RTCD1, &datetime);
|
||||
text_timestamp.set(to_string_dec_uint(datetime.month(), 2, '0') + "/" + to_string_dec_uint(datetime.day(), 2, '0') + " " +
|
||||
to_string_dec_uint(datetime.hour(), 2, '0') + ":" + to_string_dec_uint(datetime.minute(), 2, '0'));
|
||||
}
|
||||
|
||||
FrequencySaveView::~FrequencySaveView() {
|
||||
time::signal_tick_second -= signal_token_tick_second;
|
||||
save_freqman_file(frequencies);
|
||||
}
|
||||
|
||||
FrequencySaveView::FrequencySaveView(
|
||||
NavigationView& nav,
|
||||
const rf::Frequency value
|
||||
) {
|
||||
) : nav_ (nav),
|
||||
value_ (value)
|
||||
{
|
||||
error = !load_freqman_file(frequencies);
|
||||
|
||||
signal_token_tick_second = time::signal_tick_second += [this]() {
|
||||
this->on_tick_second();
|
||||
};
|
||||
|
||||
add_children({ {
|
||||
&big_display,
|
||||
&text_save,
|
||||
&button_save_name,
|
||||
&button_save_timestamp,
|
||||
&text_timestamp,
|
||||
&button_cancel
|
||||
} });
|
||||
|
||||
on_tick_second();
|
||||
|
||||
big_display.set(value);
|
||||
|
||||
button_save_name.on_select = [this, &nav](Button&) {
|
||||
on_save_name(nav);
|
||||
};
|
||||
button_save_timestamp.on_select = [this, &nav](Button&) {
|
||||
on_save_timestamp(nav);
|
||||
};
|
||||
button_cancel.on_select = [this, &nav](Button&) {
|
||||
nav.pop();
|
||||
};
|
||||
}
|
||||
|
||||
void FrequencyLoadView::setup_list() {
|
||||
size_t n;
|
||||
|
||||
menu_view.clear();
|
||||
|
||||
for (n = 0; n < frequencies.size(); n++) {
|
||||
menu_view.add_item({ freqman_item_string(frequencies[n]), ui::Color::white(), [this](){ on_frequency_select(); } });
|
||||
}
|
||||
|
||||
menu_view.set_parent_rect({ 0, 0, 240, 216 });
|
||||
menu_view.set_highlighted(menu_view.highlighted()); // Refresh
|
||||
}
|
||||
|
||||
void FrequencyLoadView::on_frequency_select() {
|
||||
nav_.pop();
|
||||
if (on_changed) on_changed(frequencies[menu_view.highlighted()].value);
|
||||
}
|
||||
|
||||
void FrequencyLoadView::focus() {
|
||||
menu_view.focus();
|
||||
|
||||
if (error)
|
||||
nav_.display_modal("Error", "File acces error !", ABORT, nullptr);
|
||||
}
|
||||
|
||||
FrequencyLoadView::FrequencyLoadView(
|
||||
NavigationView& nav
|
||||
) : nav_ (nav)
|
||||
{
|
||||
error = !load_freqman_file(frequencies);
|
||||
|
||||
add_children({ {
|
||||
&menu_view,
|
||||
&button_cancel
|
||||
} });
|
||||
|
||||
setup_list();
|
||||
|
||||
button_cancel.on_select = [this, &nav](Button&) {
|
||||
nav.pop();
|
||||
};
|
||||
}
|
||||
|
||||
void FrequencyLoadView::focus() {
|
||||
button_exit.focus();
|
||||
void FreqManView::on_frequency_select() {
|
||||
button_edit_freq.focus();
|
||||
}
|
||||
|
||||
FrequencyLoadView::FrequencyLoadView(
|
||||
NavigationView& nav,
|
||||
const rf::Frequency value
|
||||
) {
|
||||
void FreqManView::on_edit_freq(rf::Frequency f) {
|
||||
frequencies[menu_view.highlighted()].value = f;
|
||||
setup_list();
|
||||
}
|
||||
|
||||
add_children({ {
|
||||
&button_exit
|
||||
} });
|
||||
void FreqManView::on_edit_desc(NavigationView& nav) {
|
||||
char desc_buffer[32] = { 0 };
|
||||
|
||||
button_exit.on_select = [this, &nav](Button&) {
|
||||
nav.pop();
|
||||
};
|
||||
strcpy(desc_buffer, frequencies[menu_view.highlighted()].description.c_str());
|
||||
textentry(nav, desc_buffer, 28, [this, &desc_buffer](char * buffer) {
|
||||
frequencies[menu_view.highlighted()].description = buffer;
|
||||
setup_list();
|
||||
});
|
||||
}
|
||||
|
||||
void FreqManView::on_delete() {
|
||||
frequencies.erase(frequencies.begin() + menu_view.highlighted());
|
||||
setup_list();
|
||||
}
|
||||
|
||||
void FreqManView::setup_list() {
|
||||
size_t n;
|
||||
|
||||
menu_view.clear();
|
||||
|
||||
for (n = 0; n < frequencies.size(); n++) {
|
||||
menu_view.add_item({ freqman_item_string(frequencies[n]), ui::Color::white(), [this](){ on_frequency_select(); } });
|
||||
}
|
||||
|
||||
menu_view.set_parent_rect({ 0, 0, 240, 168 });
|
||||
menu_view.set_highlighted(menu_view.highlighted()); // Refresh
|
||||
}
|
||||
|
||||
void FreqManView::focus() {
|
||||
button_exit.focus();
|
||||
menu_view.focus();
|
||||
|
||||
if (error)
|
||||
nav_.display_modal("Error", "File acces error !", ABORT, nullptr);
|
||||
}
|
||||
|
||||
FreqManView::~FreqManView() {
|
||||
save_freqman_file(frequencies);
|
||||
}
|
||||
|
||||
FreqManView::FreqManView(
|
||||
NavigationView& nav
|
||||
) {
|
||||
|
||||
) : nav_ (nav)
|
||||
{
|
||||
error = !load_freqman_file(frequencies);
|
||||
|
||||
add_children({ {
|
||||
&menu_view,
|
||||
&button_edit_freq,
|
||||
&button_edit_desc,
|
||||
&button_del,
|
||||
&button_exit
|
||||
} });
|
||||
|
||||
size_t n = 0;
|
||||
for(auto& text : text_list) {
|
||||
add_child(&text);
|
||||
text.set_parent_rect({
|
||||
static_cast<Coord>(0),
|
||||
static_cast<Coord>(16 + (n * 16)),
|
||||
240, 16
|
||||
});
|
||||
const std::string label {
|
||||
(char)(n + 0x30)
|
||||
|
||||
setup_list();
|
||||
|
||||
button_edit_freq.on_select = [this, &nav](Button&) {
|
||||
auto new_view = nav.push<FrequencyKeypadView>(frequencies[menu_view.highlighted()].value);
|
||||
new_view->on_changed = [this](rf::Frequency f) {
|
||||
on_edit_freq(f);
|
||||
};
|
||||
text.set(label);
|
||||
n++;
|
||||
}
|
||||
};
|
||||
|
||||
button_edit_desc.on_select = [this, &nav](Button&) {
|
||||
on_edit_desc(nav);
|
||||
};
|
||||
|
||||
button_del.on_select = [this, &nav](Button&) {
|
||||
nav.push<ModalMessageView>("Confirm", "Are you sure ?", YESNO,
|
||||
[this](bool choice) {
|
||||
if (choice) {
|
||||
on_delete();
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
button_exit.on_select = [this, &nav](Button&) {
|
||||
nav.pop();
|
||||
|
@ -25,35 +25,57 @@
|
||||
#include "ui_painter.hpp"
|
||||
#include "ui_menu.hpp"
|
||||
#include "ui_navigation.hpp"
|
||||
#include "ui_receiver.hpp"
|
||||
#include "ui_textentry.hpp"
|
||||
#include "freqman.hpp"
|
||||
#include "time.hpp"
|
||||
|
||||
namespace ui {
|
||||
|
||||
class FrequencySaveView : public View {
|
||||
public:
|
||||
FrequencySaveView(NavigationView& nav, const rf::Frequency value);
|
||||
//~FrequencySaveView();
|
||||
~FrequencySaveView();
|
||||
|
||||
void focus() override;
|
||||
|
||||
std::string title() const override { return "Save frequency"; };
|
||||
|
||||
private:
|
||||
NavigationView& nav_;
|
||||
bool error = false;
|
||||
char desc_buffer[32] = { 0 };
|
||||
rtc::RTC datetime;
|
||||
rf::Frequency value_;
|
||||
|
||||
void on_save_name(NavigationView& nav);
|
||||
void on_save_timestamp(NavigationView& nav);
|
||||
void on_tick_second();
|
||||
|
||||
std::vector<freqman_entry> frequencies;
|
||||
|
||||
SignalToken signal_token_tick_second;
|
||||
|
||||
BigFrequency big_display {
|
||||
{ 4, 2 * 16, 28 * 8, 32 },
|
||||
0
|
||||
};
|
||||
|
||||
Text text_save {
|
||||
{ 72, 124, 10 * 8, 16 },
|
||||
"Save with:",
|
||||
{ 88, 120, 8 * 8, 16 },
|
||||
"Save as:",
|
||||
};
|
||||
Button button_save_name {
|
||||
{ 72, 144, 96, 32 },
|
||||
"Name"
|
||||
"Name (set)"
|
||||
};
|
||||
Button button_save_timestamp {
|
||||
{ 72, 184, 96, 32 },
|
||||
"Timestamp"
|
||||
"Timestamp:"
|
||||
};
|
||||
Text text_timestamp {
|
||||
{ 76, 220, 11 * 8, 16 },
|
||||
"MM/DD HH:MM",
|
||||
};
|
||||
|
||||
Button button_cancel {
|
||||
@ -64,34 +86,69 @@ private:
|
||||
|
||||
class FrequencyLoadView : public View {
|
||||
public:
|
||||
FrequencyLoadView(NavigationView& nav, const rf::Frequency value);
|
||||
//~FrequencySaveView();
|
||||
std::function<void(rf::Frequency)> on_changed;
|
||||
|
||||
FrequencyLoadView(NavigationView& nav);
|
||||
|
||||
void focus() override;
|
||||
|
||||
std::string title() const override { return "Load frequency"; };
|
||||
|
||||
private:
|
||||
Button button_exit {
|
||||
NavigationView& nav_;
|
||||
bool error = false;
|
||||
|
||||
void on_frequency_select();
|
||||
void setup_list();
|
||||
|
||||
std::vector<freqman_entry> frequencies;
|
||||
|
||||
MenuView menu_view;
|
||||
|
||||
Button button_cancel {
|
||||
{ 72, 264, 96, 32 },
|
||||
"Exit"
|
||||
"Cancel"
|
||||
};
|
||||
};
|
||||
|
||||
class FreqManView : public View {
|
||||
public:
|
||||
FreqManView(NavigationView& nav);
|
||||
//~FreqManView();
|
||||
~FreqManView();
|
||||
|
||||
void focus() override;
|
||||
|
||||
std::string title() const override { return "Freq. manager"; };
|
||||
|
||||
private:
|
||||
std::array<Text, 10> text_list;
|
||||
NavigationView& nav_;
|
||||
bool error = false;
|
||||
|
||||
void on_frequency_select();
|
||||
void on_edit_freq(rf::Frequency f);
|
||||
void on_edit_desc(NavigationView& nav);
|
||||
void on_delete();
|
||||
void setup_list();
|
||||
|
||||
std::vector<freqman_entry> frequencies;
|
||||
|
||||
MenuView menu_view { true };
|
||||
|
||||
Button button_edit_freq {
|
||||
{ 52, 194, 106, 30 },
|
||||
"Edit freq."
|
||||
};
|
||||
Button button_edit_desc {
|
||||
{ 52, 192 + 32, 106, 30 },
|
||||
"Edit desc."
|
||||
};
|
||||
Button button_del {
|
||||
{ 168, 192, 64, 64 },
|
||||
"Del"
|
||||
};
|
||||
|
||||
Button button_exit {
|
||||
{ 72, 264, 96, 32 },
|
||||
{ 168, 264, 64, 32 },
|
||||
"Exit"
|
||||
};
|
||||
};
|
||||
|
@ -142,7 +142,7 @@ void HandWriteView::clear_zone(const Color color, const bool flash) {
|
||||
color
|
||||
);
|
||||
if (flash) {
|
||||
flash_timer = 4;
|
||||
flash_timer = 8;
|
||||
} else {
|
||||
// Draw grid
|
||||
_painter->draw_rectangle(
|
||||
@ -239,7 +239,7 @@ void HandWriteView::guess_letter() {
|
||||
}
|
||||
} else {
|
||||
// Short tap is space
|
||||
txtinput[txtidx++] = ' ';
|
||||
char_add(' ');
|
||||
clear_zone(Color::green(), true); // Green flash
|
||||
}
|
||||
update_text();
|
||||
|
@ -71,7 +71,7 @@ private:
|
||||
void update_text();
|
||||
|
||||
Text text_input {
|
||||
{ 8, 0, 224, 16 }
|
||||
{ 8, 0, 232, 16 }
|
||||
};
|
||||
|
||||
std::array<Button, 10> num_buttons;
|
||||
|
@ -46,7 +46,7 @@ void MenuItemView::unhighlight() {
|
||||
void MenuItemView::paint(Painter& painter) {
|
||||
const auto r = screen_rect();
|
||||
|
||||
const auto paint_style = (highlighted() && parent()->has_focus()) ? style().invert() : style();
|
||||
const auto paint_style = (highlighted() && (parent()->has_focus() || keep_highlight_)) ? style().invert() : style();
|
||||
|
||||
const auto font_height = paint_style.font.line_height();
|
||||
|
||||
@ -75,15 +75,18 @@ void MenuItemView::paint(Painter& painter) {
|
||||
|
||||
/* MenuView **************************************************************/
|
||||
|
||||
MenuView::MenuView() {
|
||||
MenuView::MenuView(
|
||||
bool keep_highlight
|
||||
) : keep_highlight_ { keep_highlight }
|
||||
{
|
||||
set_focusable(true);
|
||||
|
||||
add_child(&arrow_more);
|
||||
signal_token_tick_second = time::signal_tick_second += [this]() {
|
||||
this->on_tick_second();
|
||||
};
|
||||
|
||||
arrow_more.set_parent_rect( { 216, 320 - 16 - 24, 16, 16 } );
|
||||
add_child(&arrow_more);
|
||||
arrow_more.id = 1; // Special flag
|
||||
arrow_more.set_focusable(false);
|
||||
arrow_more.set_foreground(Color::black());
|
||||
}
|
||||
@ -97,39 +100,47 @@ void MenuView::on_tick_second() {
|
||||
arrow_more.set_foreground(Color::white());
|
||||
else
|
||||
arrow_more.set_foreground(Color::black());
|
||||
|
||||
|
||||
blink_ = !blink_;
|
||||
|
||||
arrow_more.set_dirty();
|
||||
}
|
||||
|
||||
void MenuView::clear() {
|
||||
children_.erase(children_.begin() + 1, children_.end());
|
||||
}
|
||||
|
||||
void MenuView::add_item(const MenuItem item) {
|
||||
add_child(new MenuItemView { item });
|
||||
add_child(new MenuItemView { item, keep_highlight_ });
|
||||
}
|
||||
|
||||
void MenuView::set_parent_rect(const Rect new_parent_rect) {
|
||||
View::set_parent_rect(new_parent_rect);
|
||||
|
||||
displayed_max_ = new_parent_rect.size.h / 24;
|
||||
arrow_more.set_parent_rect( { 228, (Coord)(displayed_max_ * item_height), 8, 8 } );
|
||||
|
||||
update_items();
|
||||
}
|
||||
|
||||
void MenuView::update_items() {
|
||||
constexpr size_t item_height = 24;
|
||||
size_t i = 0;
|
||||
Coord y_pos;
|
||||
int32_t y_pos;
|
||||
|
||||
if ((children_.size() - 1) > MENU_MAX + offset_)
|
||||
if ((children_.size() - 1) > displayed_max_ + offset_) {
|
||||
more_ = true;
|
||||
else
|
||||
blink_ = true;
|
||||
} else
|
||||
more_ = false;
|
||||
|
||||
for (auto child : children_) {
|
||||
if (i) { // Skip arrow widget
|
||||
y_pos = (i - 1 - offset_) * item_height;
|
||||
if (!child->id) {
|
||||
y_pos = (i - offset_ - 1) * item_height;
|
||||
child->set_parent_rect({
|
||||
{ 0, y_pos },
|
||||
{ size().w, item_height }
|
||||
{ size().w, (Coord)item_height }
|
||||
});
|
||||
if ((y_pos < 0) || (y_pos >= (320 - 16 - 24 - 16)))
|
||||
if ((y_pos < 0) || (y_pos > (Coord)(screen_rect().size.h - item_height)))
|
||||
child->hidden(true);
|
||||
else
|
||||
child->hidden(false);
|
||||
@ -142,20 +153,24 @@ MenuItemView* MenuView::item_view(size_t index) const {
|
||||
/* TODO: Terrible cast! Take it as a sign I must be doing something
|
||||
* shamefully wrong here, right?
|
||||
*/
|
||||
return static_cast<MenuItemView*>(children_[index + 1]); // Skip arrow widget
|
||||
return static_cast<MenuItemView*>(children_[index + 1]);
|
||||
}
|
||||
|
||||
size_t MenuView::highlighted() const {
|
||||
return highlighted_;
|
||||
}
|
||||
|
||||
bool MenuView::set_highlighted(const size_t new_value) {
|
||||
if( new_value >= (children_.size() - 1) ) // Skip arrow widget
|
||||
bool MenuView::set_highlighted(int32_t new_value) {
|
||||
int32_t item_count = (int32_t)children_.size() - 1;
|
||||
if (new_value < 0)
|
||||
return false;
|
||||
|
||||
if ((new_value > offset_) && ((new_value - offset_ + 1) >= MENU_MAX)) {
|
||||
if (new_value >= item_count)
|
||||
new_value = item_count - 1;
|
||||
|
||||
if ((new_value > offset_) && ((new_value - offset_ + 1) >= displayed_max_)) {
|
||||
// Shift MenuView up
|
||||
offset_ = new_value - MENU_MAX + 1;
|
||||
offset_ = new_value - displayed_max_ + 1;
|
||||
update_items();
|
||||
} else if (new_value < offset_) {
|
||||
// Shift MenuView down
|
||||
@ -175,7 +190,7 @@ void MenuView::on_focus() {
|
||||
}
|
||||
|
||||
void MenuView::on_blur() {
|
||||
item_view(highlighted())->unhighlight();
|
||||
if (!keep_highlight_) item_view(highlighted())->unhighlight();
|
||||
}
|
||||
|
||||
bool MenuView::on_key(const KeyEvent key) {
|
||||
|
@ -33,8 +33,6 @@
|
||||
#include <string>
|
||||
#include <functional>
|
||||
|
||||
#define MENU_MAX 11
|
||||
|
||||
namespace ui {
|
||||
|
||||
struct MenuItem {
|
||||
@ -50,8 +48,10 @@ struct MenuItem {
|
||||
class MenuItemView : public Widget {
|
||||
public:
|
||||
MenuItemView(
|
||||
MenuItem item
|
||||
) : item(item)
|
||||
MenuItem item,
|
||||
bool keep_highlight
|
||||
) : item(item),
|
||||
keep_highlight_ { keep_highlight }
|
||||
{
|
||||
}
|
||||
|
||||
@ -63,16 +63,19 @@ public:
|
||||
|
||||
private:
|
||||
const MenuItem item;
|
||||
bool keep_highlight_ = false;
|
||||
};
|
||||
|
||||
class MenuView : public View {
|
||||
public:
|
||||
std::function<void(void)> on_left;
|
||||
|
||||
MenuView();
|
||||
MenuView(bool keep_highlight = false);
|
||||
|
||||
~MenuView();
|
||||
|
||||
void add_item(const MenuItem item);
|
||||
void clear();
|
||||
|
||||
template<size_t N>
|
||||
void add_items(const std::array<MenuItem, N>& items) {
|
||||
@ -86,7 +89,7 @@ public:
|
||||
MenuItemView* item_view(size_t index) const;
|
||||
|
||||
size_t highlighted() const;
|
||||
bool set_highlighted(const size_t new_value);
|
||||
bool set_highlighted(int32_t new_value);
|
||||
|
||||
void on_focus() override;
|
||||
void on_blur() override;
|
||||
@ -98,17 +101,21 @@ private:
|
||||
void update_items();
|
||||
void on_tick_second();
|
||||
|
||||
bool keep_highlight_ = false;
|
||||
|
||||
SignalToken signal_token_tick_second;
|
||||
|
||||
Image arrow_more {
|
||||
{ 216, 320 - 16 - 24, 16, 16 },
|
||||
{ 228, 320 - 8, 8, 8 },
|
||||
&bitmap_more,
|
||||
Color::white(),
|
||||
Color::black()
|
||||
};
|
||||
|
||||
const size_t item_height = 24;
|
||||
bool blink_ = false;
|
||||
bool more_ = false;
|
||||
size_t displayed_max_;
|
||||
size_t highlighted_ { 0 };
|
||||
size_t offset_ { 0 };
|
||||
};
|
||||
|
@ -76,7 +76,7 @@ SystemStatusView::SystemStatusView() {
|
||||
&sd_card_status_view,
|
||||
} });
|
||||
|
||||
if (portapack::persistent_memory::ui_config_textentry())
|
||||
if (!portapack::persistent_memory::ui_config_textentry())
|
||||
button_textentry.set_bitmap(&bitmap_keyboard);
|
||||
else
|
||||
button_textentry.set_bitmap(&bitmap_unistroke);
|
||||
@ -326,6 +326,16 @@ UtilitiesView::UtilitiesView(NavigationView& nav) {
|
||||
}
|
||||
/* SystemMenuView ********************************************************/
|
||||
|
||||
void SystemMenuView::hackrf_mode(NavigationView& nav) {
|
||||
nav.push<ModalMessageView>("Confirm", "Switch to HackRF mode ?", YESNO,
|
||||
[this](bool choice) {
|
||||
if (choice) {
|
||||
EventDispatcher::request_stop();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
SystemMenuView::SystemMenuView(NavigationView& nav) {
|
||||
add_items<11>({ {
|
||||
{ "Play dead", ui::Color::red(), [&nav](){ nav.push<PlayDeadView>(); } },
|
||||
@ -339,7 +349,7 @@ SystemMenuView::SystemMenuView(NavigationView& nav) {
|
||||
//{ "Analyze", ui::Color::white(), [&nav](){ nav.push<NotImplementedView>(); } },
|
||||
{ "Setup", ui::Color::white(), [&nav](){ nav.push<SetupMenuView>(); } },
|
||||
//{ "Debug", ui::Color::white(), [&nav](){ nav.push<DebugMenuView>(); } },
|
||||
{ "HackRF mode", ui::Color::white(), [&nav](){ nav.push<HackRFFirmwareView>(); } },
|
||||
{ "HackRF mode", ui::Color::white(), [this, &nav](){ hackrf_mode(nav); } },
|
||||
{ "About", ui::Color::white(), [&nav](){ nav.push<AboutView>(); } }
|
||||
} });
|
||||
|
||||
@ -399,28 +409,6 @@ Context& SystemView::context() const {
|
||||
return context_;
|
||||
}
|
||||
|
||||
/* HackRFFirmwareView ****************************************************/
|
||||
|
||||
HackRFFirmwareView::HackRFFirmwareView(NavigationView& nav) {
|
||||
button_yes.on_select = [](Button&){
|
||||
EventDispatcher::request_stop();
|
||||
};
|
||||
|
||||
button_no.on_select = [&nav](Button&){
|
||||
nav.pop();
|
||||
};
|
||||
|
||||
add_children({ {
|
||||
&text_title,
|
||||
&text_description_1,
|
||||
&text_description_2,
|
||||
&text_description_3,
|
||||
&text_description_4,
|
||||
&button_yes,
|
||||
&button_no,
|
||||
} });
|
||||
}
|
||||
|
||||
/* ***********************************************************************/
|
||||
|
||||
void BMPView::focus() {
|
||||
@ -490,10 +478,6 @@ PlayDeadView::PlayDeadView(NavigationView& nav) {
|
||||
};
|
||||
}
|
||||
|
||||
void HackRFFirmwareView::focus() {
|
||||
button_no.focus();
|
||||
}
|
||||
|
||||
/* NotImplementedView ****************************************************/
|
||||
|
||||
NotImplementedView::NotImplementedView(NavigationView& nav) {
|
||||
@ -563,7 +547,7 @@ ModalMessageView::ModalMessageView(
|
||||
}
|
||||
|
||||
void ModalMessageView::paint(Painter&) {
|
||||
portapack::display.drawBMP({96, 64}, modal_warning_bmp, false);
|
||||
portapack::display.drawBMP({ 100, 64 }, modal_warning_bmp, false);
|
||||
}
|
||||
|
||||
void ModalMessageView::focus() {
|
||||
|
@ -223,6 +223,8 @@ public:
|
||||
class SystemMenuView : public MenuView {
|
||||
public:
|
||||
SystemMenuView(NavigationView& nav);
|
||||
private:
|
||||
void hackrf_mode(NavigationView& nav);
|
||||
};
|
||||
|
||||
class SystemView : public View {
|
||||
@ -240,49 +242,6 @@ private:
|
||||
Context& context_;
|
||||
};
|
||||
|
||||
class HackRFFirmwareView : public View {
|
||||
public:
|
||||
HackRFFirmwareView(NavigationView& nav);
|
||||
|
||||
void focus() override;
|
||||
|
||||
private:
|
||||
Text text_title {
|
||||
{ 76, 4 * 16, 19 * 8, 16 },
|
||||
"HackRF Mode"
|
||||
};
|
||||
|
||||
Text text_description_1 {
|
||||
{ 4, 7 * 16, 19 * 8, 16 },
|
||||
"Run stock HackRF firmware and"
|
||||
};
|
||||
|
||||
Text text_description_2 {
|
||||
{ 12, 8 * 16, 19 * 8, 16 },
|
||||
"disable PortaPack until the"
|
||||
};
|
||||
|
||||
Text text_description_3 {
|
||||
{ 4, 9 * 16, 19 * 8, 16 },
|
||||
"unit is reset or disconnected"
|
||||
};
|
||||
|
||||
Text text_description_4 {
|
||||
{ 76, 10 * 16, 19 * 8, 16 },
|
||||
"from power?"
|
||||
};
|
||||
|
||||
Button button_yes {
|
||||
{ 4 * 8, 13 * 16, 8 * 8, 24 },
|
||||
"Yes",
|
||||
};
|
||||
|
||||
Button button_no {
|
||||
{ 18 * 8, 13 * 16, 8 * 8, 24 },
|
||||
"No",
|
||||
};
|
||||
};
|
||||
|
||||
class NotImplementedView : public View {
|
||||
public:
|
||||
NotImplementedView(NavigationView& nav);
|
||||
@ -329,11 +288,12 @@ private:
|
||||
};
|
||||
|
||||
Button button_yes {
|
||||
{ 40, 13 * 16, 64, 24 },
|
||||
{ 5 * 8, 13 * 16, 8 * 8, 48 },
|
||||
"YES",
|
||||
};
|
||||
|
||||
Button button_no {
|
||||
{ 152, 13 * 16, 64, 24 },
|
||||
{ 17 * 8, 13 * 16, 8 * 8, 48 },
|
||||
"NO",
|
||||
};
|
||||
};
|
||||
|
@ -158,7 +158,10 @@ FrequencyKeypadView::FrequencyKeypadView(
|
||||
nav.push<FrequencySaveView>(this->value());
|
||||
};
|
||||
button_load.on_select = [this, &nav](Button&) {
|
||||
nav.push<FrequencyLoadView>(this->value());
|
||||
auto load_view = nav.push<FrequencyLoadView>();
|
||||
load_view->on_changed = [this](rf::Frequency value) {
|
||||
set_value(value);
|
||||
};
|
||||
};
|
||||
|
||||
button_close.on_select = [this, &nav](Button&) {
|
||||
|
@ -24,16 +24,19 @@
|
||||
|
||||
namespace ui {
|
||||
|
||||
bool textentry(NavigationView& nav, char * str, size_t max_length) {
|
||||
bool textentry(NavigationView& nav, char * str, const size_t max_length, const std::function<void(char *)> on_done) {
|
||||
|
||||
if (portapack::persistent_memory::ui_config_textentry() == 0) {
|
||||
auto an_view = nav.push<AlphanumView>(str, max_length);
|
||||
an_view->on_changed = [str, max_length](char * value) {
|
||||
memcpy(str, value, max_length + 1);
|
||||
auto te_view = nav.push<AlphanumView>(str, max_length);
|
||||
te_view->on_changed = [str, max_length, on_done](char * value) {
|
||||
//memcpy(str, value, max_length + 1);
|
||||
if (on_done) on_done(value);
|
||||
};
|
||||
} else {
|
||||
auto an_view = nav.push<HandWriteView>(str, max_length);
|
||||
an_view->on_changed = [str, max_length](char * value) {
|
||||
memcpy(str, value, max_length + 1);
|
||||
auto te_view = nav.push<HandWriteView>(str, max_length);
|
||||
te_view->on_changed = [str, max_length, on_done](char * value) {
|
||||
//memcpy(str, value, max_length + 1);
|
||||
if (on_done) on_done(value);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -20,14 +20,21 @@
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __UI_TEXTENTRY_H__
|
||||
#define __UI_TEXTENTRY_H__
|
||||
|
||||
#include "ui.hpp"
|
||||
#include "ui_navigation.hpp"
|
||||
#include "ui_handwrite.hpp"
|
||||
#include "ui_alphanum.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
|
||||
// TODO: Make class
|
||||
|
||||
namespace ui {
|
||||
|
||||
bool textentry(NavigationView& nav, char * str, size_t max_length);
|
||||
bool textentry(NavigationView& nav, char * str, size_t max_length, const std::function<void(char *)> on_done = nullptr);
|
||||
|
||||
} /* namespace ui */
|
||||
|
||||
#endif/*__UI_TEXTENTRY_H__*/
|
||||
|
@ -316,7 +316,7 @@ Text::Text(
|
||||
Rect parent_rect,
|
||||
std::string text
|
||||
) : Widget { parent_rect },
|
||||
text { text }
|
||||
text_ { text }
|
||||
{
|
||||
}
|
||||
|
||||
@ -327,10 +327,14 @@ Text::Text(
|
||||
}
|
||||
|
||||
void Text::set(const std::string value) {
|
||||
text = value;
|
||||
text_ = value;
|
||||
set_dirty();
|
||||
}
|
||||
|
||||
std::string Text::text() const {
|
||||
return text_;
|
||||
}
|
||||
|
||||
void Text::paint(Painter& painter) {
|
||||
const auto rect = screen_rect();
|
||||
const auto s = style();
|
||||
@ -340,7 +344,7 @@ void Text::paint(Painter& painter) {
|
||||
painter.draw_string(
|
||||
rect.pos,
|
||||
s,
|
||||
text
|
||||
text_
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -104,6 +104,7 @@ public:
|
||||
void set_style(const Style* new_style);
|
||||
|
||||
const Style& style() const;
|
||||
uint16_t id = 0;
|
||||
|
||||
// State management methods.
|
||||
void set_dirty();
|
||||
@ -115,8 +116,6 @@ public:
|
||||
|
||||
bool highlighted() const;
|
||||
void set_highlighted(const bool value);
|
||||
|
||||
uint16_t id = 0;
|
||||
|
||||
protected:
|
||||
void dirty_overlapping_children_in_rect(const Rect& child_rect);
|
||||
@ -192,18 +191,19 @@ private:
|
||||
class Text : public Widget {
|
||||
public:
|
||||
Text(
|
||||
) : text { "" } {
|
||||
) : text_ { "" } {
|
||||
}
|
||||
|
||||
Text(Rect parent_rect, std::string text);
|
||||
Text(Rect parent_rect);
|
||||
|
||||
void set(const std::string value);
|
||||
std::string text() const;
|
||||
|
||||
void paint(Painter& painter) override;
|
||||
|
||||
private:
|
||||
std::string text;
|
||||
std::string text_;
|
||||
};
|
||||
|
||||
class BigFrequency : public Widget {
|
||||
@ -265,7 +265,6 @@ public:
|
||||
}
|
||||
|
||||
void set_text(const std::string value);
|
||||
// std::string text() const;
|
||||
bool set_value(const bool value);
|
||||
bool value() const;
|
||||
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user