mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2026-09-10 08:39:29 +00:00
Multi screen support, with dyn alignment (#2801)
This commit is contained in:
@@ -37,7 +37,9 @@ BtnGridView::BtnGridView(
|
||||
: keep_highlight{keep_highlight} {
|
||||
set_parent_rect(new_parent_rect);
|
||||
set_focusable(true);
|
||||
|
||||
if (screen_height == 480) {
|
||||
button_h = 64;
|
||||
}
|
||||
button_pgup.set_focusable(false);
|
||||
button_pgup.on_select = [this](Button&) {
|
||||
if (arrow_up_enabled) {
|
||||
@@ -76,30 +78,11 @@ int BtnGridView::rows() {
|
||||
void BtnGridView::set_parent_rect(const Rect new_parent_rect) {
|
||||
View::set_parent_rect(new_parent_rect);
|
||||
|
||||
button_h = 48; // btn_h_min;
|
||||
/*
|
||||
// DISABLED FOR NOW. TODO fix next, prev button pos
|
||||
int min_remainder = parent_rect().size().height();
|
||||
uint8_t max_button_count = 0;
|
||||
|
||||
for (int h = btn_h_min; h <= btn_h_max; ++h) {
|
||||
int count = parent_rect().size().height() / h;
|
||||
int remainder = parent_rect().size().height() % h;
|
||||
|
||||
// Prefer smaller remainder, then more buttons, then larger height
|
||||
if (remainder < min_remainder ||
|
||||
(remainder == min_remainder && count > max_button_count) ||
|
||||
(remainder == min_remainder && count == max_button_count && h > button_h)) {
|
||||
button_h = h;
|
||||
min_remainder = remainder;
|
||||
max_button_count = count;
|
||||
}
|
||||
}
|
||||
*/
|
||||
int space_available = parent_rect().size().height() - 16; // leave space for arrows
|
||||
displayed_max = (parent_rect().size().height() / button_h);
|
||||
|
||||
button_pgup.set_parent_rect({0, (Coord)(displayed_max * button_h), screen_width / 2, 16});
|
||||
button_pgdown.set_parent_rect({screen_width / 2, (Coord)(displayed_max * button_h), screen_width / 2, 16});
|
||||
button_pgup.set_parent_rect({0, (Coord)(space_available), screen_width / 2, 16});
|
||||
button_pgdown.set_parent_rect({screen_width / 2, (Coord)(space_available), screen_width / 2, 16});
|
||||
|
||||
displayed_max *= rows_;
|
||||
|
||||
@@ -115,10 +98,10 @@ void BtnGridView::set_parent_rect(const Rect new_parent_rect) {
|
||||
for (size_t c = 0; c < displayed_max; c++) {
|
||||
auto item = std::make_unique<NewButton>();
|
||||
add_child(item.get());
|
||||
item->set_vertical_center(true);
|
||||
item->set_parent_rect({(int)(c % rows_) * button_w,
|
||||
(int)(c / rows_) * button_h,
|
||||
button_w, button_h});
|
||||
|
||||
menu_item_views.push_back(std::move(item));
|
||||
}
|
||||
update_items();
|
||||
|
||||
@@ -89,9 +89,8 @@ class BtnGridView : public View {
|
||||
bool blacklisted_app(GridItem new_item);
|
||||
|
||||
void update_items();
|
||||
void set_btn_min_max_height(uint8_t min, uint8_t max) {
|
||||
btn_h_min = min;
|
||||
btn_h_max = max;
|
||||
void set_btn_height_fixed(uint8_t h) {
|
||||
button_h = h;
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -99,8 +98,6 @@ class BtnGridView : public View {
|
||||
|
||||
private:
|
||||
int rows_{3};
|
||||
uint8_t btn_h_min{40};
|
||||
uint8_t btn_h_max{60};
|
||||
bool keep_highlight{false};
|
||||
|
||||
std::vector<GridItem> menu_items{};
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace ui {
|
||||
FreqManUIList::FreqManUIList(Rect parent_rect)
|
||||
: Widget{parent_rect},
|
||||
visible_lines_{(unsigned)parent_rect.height() / char_height} {
|
||||
line_max_length = (parent_rect.width() - 8) / char_width;
|
||||
this->set_focusable(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ class FreqManUIList : public Widget {
|
||||
|
||||
static constexpr int8_t char_height = 16;
|
||||
static constexpr int8_t char_width = 8;
|
||||
static constexpr int8_t line_max_length = 29;
|
||||
uint8_t line_max_length = 29;
|
||||
size_t visible_lines_{0};
|
||||
|
||||
FreqmanDB* db_{nullptr};
|
||||
|
||||
@@ -38,7 +38,7 @@ GeoPos::GeoPos(
|
||||
const alt_unit altitude_unit,
|
||||
const spd_unit speed_unit)
|
||||
: altitude_unit_(altitude_unit), speed_unit_(speed_unit) {
|
||||
set_parent_rect({pos, {screen_width, 3 * 16}});
|
||||
set_parent_rect({pos, {screen_width, UI_POS_HEIGHT(3)}});
|
||||
|
||||
add_children({&labels_position,
|
||||
&label_spd_position,
|
||||
@@ -231,6 +231,8 @@ bool GeoMap::on_encoder(const EncoderEvent delta) {
|
||||
}
|
||||
|
||||
void GeoMap::map_read_line_bin(ui::Color* buffer, uint16_t pixels) {
|
||||
const auto r = screen_rect();
|
||||
ui::Dim width = r.width();
|
||||
if (map_zoom == 1) {
|
||||
map_file.read(buffer, pixels << 1);
|
||||
} else if (map_zoom > 1) {
|
||||
@@ -242,7 +244,7 @@ void GeoMap::map_read_line_bin(ui::Color* buffer, uint16_t pixels) {
|
||||
// For 240 width, than means no check is needed for map_zoom values up to 6.
|
||||
// (Rectangle height must also divide evenly into map_zoom or we get black lines at end of screen)
|
||||
// Note that zooming in results in a map offset of (1/map_zoom) pixels to the right & downward directions (see zoom_pixel_offset).
|
||||
for (int i = (geomap_rect_width / map_zoom) - 1; i >= 0; i--) {
|
||||
for (int i = (width / map_zoom) - 1; i >= 0; i--) {
|
||||
for (int j = 0; j < map_zoom; j++) {
|
||||
buffer[(i * map_zoom) + j] = buffer[i];
|
||||
}
|
||||
@@ -253,7 +255,7 @@ void GeoMap::map_read_line_bin(ui::Color* buffer, uint16_t pixels) {
|
||||
|
||||
// Zoom out: Collapse each group of "-map_zoom" pixels into one pixel.
|
||||
// Future TODO: Average each group of pixels (in both X & Y directions if possible).
|
||||
for (int i = 0; i < geomap_rect_width; i++) {
|
||||
for (int i = 0; i < width; i++) {
|
||||
buffer[i] = zoom_out_buffer[i * (-map_zoom)];
|
||||
}
|
||||
delete[] zoom_out_buffer;
|
||||
@@ -466,7 +468,8 @@ bool GeoMap::draw_osm_file(int zoom, int tile_x, int tile_y, int relative_x, int
|
||||
|
||||
void GeoMap::paint(Painter& painter) {
|
||||
const auto r = screen_rect();
|
||||
std::array<ui::Color, geomap_rect_width> map_line_buffer;
|
||||
std::vector<ui::Color> map_line_buffer;
|
||||
map_line_buffer.resize(r.width());
|
||||
int16_t zoom_seek_x, zoom_seek_y;
|
||||
|
||||
if (!use_osm) {
|
||||
|
||||
@@ -42,8 +42,6 @@ namespace ui {
|
||||
#define INVALID_ANGLE 400
|
||||
|
||||
#define GEOMAP_BANNER_HEIGHT (3 * 16)
|
||||
#define GEOMAP_RECT_WIDTH 240
|
||||
#define GEOMAP_RECT_HEIGHT (320 - 16 - GEOMAP_BANNER_HEIGHT)
|
||||
|
||||
#define TILE_SIZE 256
|
||||
|
||||
@@ -115,31 +113,31 @@ class GeoPos : public View {
|
||||
spd_unit speed_unit_{};
|
||||
|
||||
Labels labels_position{
|
||||
{{1 * 8, 0 * 16}, "Alt:", Theme::getInstance()->fg_light->foreground},
|
||||
{{1 * 8, UI_POS_Y(0)}, "Alt:", Theme::getInstance()->fg_light->foreground},
|
||||
{{1 * 8, 1 * 16}, "Lat: \xB0 ' \"", Theme::getInstance()->fg_light->foreground}, // 0xB0 is degree ° symbol in our 8x16 font
|
||||
{{1 * 8, 2 * 16}, "Lon: \xB0 ' \"", Theme::getInstance()->fg_light->foreground},
|
||||
};
|
||||
Labels label_spd_position{
|
||||
{{15 * 8, 0 * 16}, "Spd:", Theme::getInstance()->fg_light->foreground},
|
||||
{{15 * 8, UI_POS_Y(0)}, "Spd:", Theme::getInstance()->fg_light->foreground},
|
||||
};
|
||||
NumberField field_altitude{
|
||||
{6 * 8, 0 * 16},
|
||||
{6 * 8, UI_POS_Y(0)},
|
||||
5,
|
||||
{-1000, 50000},
|
||||
250,
|
||||
' '};
|
||||
|
||||
NumberField field_speed{
|
||||
{19 * 8, 0 * 16},
|
||||
{19 * 8, UI_POS_Y(0)},
|
||||
4,
|
||||
{0, 5000},
|
||||
1,
|
||||
' '};
|
||||
Text text_alt_unit{
|
||||
{12 * 8, 0 * 16, 2 * 8, 16},
|
||||
{12 * 8, UI_POS_Y(0), 2 * 8, 16},
|
||||
""};
|
||||
Text text_speed_unit{
|
||||
{25 * 8, 0 * 16, 5 * 8, 16},
|
||||
{25 * 8, UI_POS_Y(0), 5 * 8, 16},
|
||||
""};
|
||||
|
||||
NumberField field_lat_degrees{
|
||||
@@ -243,10 +241,6 @@ class GeoMap : public Widget {
|
||||
void clear_markers();
|
||||
MapMarkerStored store_marker(GeoMarker& marker);
|
||||
|
||||
static const Dim banner_height = GEOMAP_BANNER_HEIGHT;
|
||||
static const Dim geomap_rect_width = GEOMAP_RECT_WIDTH;
|
||||
static const Dim geomap_rect_height = GEOMAP_RECT_HEIGHT;
|
||||
|
||||
private:
|
||||
void draw_scale(Painter& painter);
|
||||
ui::Point item_rect_pixel(GeoMarker& item);
|
||||
@@ -370,7 +364,7 @@ class GeoMapView : public View {
|
||||
speed_unit_};
|
||||
|
||||
GeoMap geomap{
|
||||
{0, GeoMap::banner_height, GeoMap::geomap_rect_width, GeoMap::geomap_rect_height}};
|
||||
{0, GEOMAP_BANNER_HEIGHT, screen_width, screen_height - 16 - GEOMAP_BANNER_HEIGHT}};
|
||||
|
||||
Button button_ok{
|
||||
{screen_width - 15 * 8, 0, 15 * 8, 1 * 16},
|
||||
|
||||
@@ -55,7 +55,7 @@ QRCodeImage& QRCodeImage::operator=(const QRCodeImage& Image) {
|
||||
|
||||
void QRCodeImage::paint(Painter& painter) {
|
||||
(void)painter;
|
||||
|
||||
auto r = screen_rect();
|
||||
// The structure to manage the QR code
|
||||
QRCode qrcode;
|
||||
|
||||
@@ -66,12 +66,12 @@ void QRCodeImage::paint(Painter& painter) {
|
||||
|
||||
qrcode_initText(&qrcode, qrcodeBytes, qr_version, ECC_HIGH, qr_text_);
|
||||
|
||||
display.fill_rectangle(Rect(57, 65, 126, 127), Color::white());
|
||||
display.fill_rectangle(Rect(r.left(), r.top(), 126, 127), Color::white()); // 57,63
|
||||
|
||||
for (uint8_t y = 0; y < qrcode.size; y++) {
|
||||
for (uint8_t x = 0; x < qrcode.size; x++) {
|
||||
if (qrcode_getModule(&qrcode, x, y)) {
|
||||
display.fill_rectangle(Rect(63 + (x * 2), 71 + (y * 2), 2, 2), Color::black());
|
||||
display.fill_rectangle(Rect((r.left() + 6) + (x * 2), (r.top() + 8) + (y * 2), 2, 2), Color::black());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ class QRCodeView : public View {
|
||||
std::function<void(void)> on_close_{nullptr};
|
||||
|
||||
QRCodeImage qr_code{
|
||||
{50, 100, 100, 100}};
|
||||
{UI_POS_X_CENTER(16), 63, 100, 100}};
|
||||
|
||||
// Text text_qr {
|
||||
// { 0 * 8, 10 * 16, 32 * 8, 1 * 8 },
|
||||
@@ -77,7 +77,7 @@ class QRCodeView : public View {
|
||||
// };
|
||||
|
||||
Button button_close{
|
||||
{9 * 8, 31 * 8, 12 * 8, 3 * 16},
|
||||
{UI_POS_X_CENTER(12), 31 * 8, 12 * 8, 3 * 16},
|
||||
"Back"};
|
||||
};
|
||||
|
||||
|
||||
@@ -256,6 +256,7 @@ bool FrequencyKeypadView::on_encoder(const EncoderEvent delta) {
|
||||
FrequencyKeypadView::FrequencyKeypadView(
|
||||
NavigationView& nav,
|
||||
const rf::Frequency value) {
|
||||
button_w = screen_width / 3;
|
||||
add_child(&text_value);
|
||||
|
||||
const auto button_fn = [this](Button& button) {
|
||||
|
||||
@@ -222,7 +222,7 @@ class FrequencyKeypadView : public View {
|
||||
|
||||
private:
|
||||
int16_t focused_button = 0;
|
||||
static constexpr int button_w = 240 / 3;
|
||||
int button_w = 240 / 3;
|
||||
static constexpr int button_h = 48;
|
||||
|
||||
static constexpr int mhz_digits = 4;
|
||||
@@ -232,33 +232,33 @@ class FrequencyKeypadView : public View {
|
||||
static constexpr int text_digits = mhz_digits + 1 + submhz_digits;
|
||||
|
||||
Text text_value{
|
||||
{0, 4, screen_width, 16}};
|
||||
{UI_POS_X(0), 4, screen_width, 16}};
|
||||
|
||||
std::array<Button, 12> buttons{};
|
||||
|
||||
Button button_save_ghz{
|
||||
{0, 14 * 16, 80 / 2 - 1, 2 * 16},
|
||||
{UI_POS_X(0), 14 * 16, UI_POS_WIDTH_PERCENT(16) + 1, UI_POS_HEIGHT(2)},
|
||||
"GHz"};
|
||||
Button button_save_khz{
|
||||
{0 + 40 - 1, 14 * 16, 80 / 2, 2 * 16},
|
||||
{UI_POS_X(0) + UI_POS_WIDTH_PERCENT(16) + 1, 14 * 16, UI_POS_WIDTH_PERCENT(16) + 2, UI_POS_HEIGHT(2)},
|
||||
"kHz"};
|
||||
Button button_save_mhz{
|
||||
{0, 16 * 16, 80 - 1, 3 * 16},
|
||||
{UI_POS_X(0), 16 * 16, UI_POS_WIDTH_PERCENT(33), UI_POS_HEIGHT(3)},
|
||||
"Save MHz"};
|
||||
Button button_load{
|
||||
{80 + 1, 14 * 16, 80 - 2, 40},
|
||||
{UI_POS_WIDTH_PERCENT(33) + 1, 14 * 16, UI_POS_WIDTH_PERCENT(33), 40},
|
||||
"Load"};
|
||||
Button button_clear{
|
||||
{80 + 1, 264, 80 - 2, 40},
|
||||
{UI_POS_WIDTH_PERCENT(33) + 1, 264, UI_POS_WIDTH_PERCENT(33), 40},
|
||||
"Clear"};
|
||||
Button button_done_ghz{
|
||||
{160 + 1, 14 * 16, 80 / 2 - 1, 2 * 16},
|
||||
{UI_POS_WIDTH_PERCENT(66) + 1, 14 * 16, UI_POS_WIDTH_PERCENT(16) + 1, UI_POS_HEIGHT(2)},
|
||||
"GHz"};
|
||||
Button button_done_khz{
|
||||
{160 + 40, 14 * 16, 80 / 2 - 1, 2 * 16},
|
||||
{UI_POS_WIDTH_PERCENT(82) + 2, 14 * 16, UI_POS_WIDTH_PERCENT(16) + 2, UI_POS_HEIGHT(2)},
|
||||
"kHz"};
|
||||
Button button_done_mhz{
|
||||
{160 + 1, 16 * 16, 80 - 2, 3 * 16},
|
||||
{UI_POS_WIDTH_PERCENT(66) + 1, 16 * 16, UI_POS_WIDTH_PERCENT(33), UI_POS_HEIGHT(3)},
|
||||
"Done MHz"};
|
||||
|
||||
/* TODO: Template arg required in enum?! */
|
||||
@@ -312,29 +312,29 @@ class FrequencyOptionsView : public View {
|
||||
|
||||
private:
|
||||
Text text_step{
|
||||
{0 * 8, 0 * 16, 4 * 8, 1 * 16},
|
||||
{UI_POS_X(0), UI_POS_Y(0), 4 * 8, 1 * 16},
|
||||
"Step"};
|
||||
|
||||
FrequencyStepView field_step{
|
||||
{5 * 8, 0 * 16},
|
||||
{5 * 8, UI_POS_Y(0)},
|
||||
};
|
||||
|
||||
void on_step_changed(rf::Frequency v);
|
||||
void on_reference_ppm_correction_changed(int32_t v);
|
||||
|
||||
NumberField field_ppm{
|
||||
{23 * 8, 0 * 16},
|
||||
{23 * 8, UI_POS_Y(0)},
|
||||
3,
|
||||
{-99, 99},
|
||||
1,
|
||||
'0',
|
||||
};
|
||||
Text text_ext{
|
||||
{23 * 8, 0 * 16, 3 * 8, 1 * 16},
|
||||
{23 * 8, UI_POS_Y(0), 3 * 8, 1 * 16},
|
||||
"EXT",
|
||||
};
|
||||
Text text_ppm{
|
||||
{27 * 8, 0 * 16, 3 * 8, 16},
|
||||
{27 * 8, UI_POS_Y(0), 3 * 8, 16},
|
||||
"PPM",
|
||||
};
|
||||
};
|
||||
@@ -350,11 +350,11 @@ class RadioGainOptionsView : public View {
|
||||
|
||||
private:
|
||||
Text label_rf_amp{
|
||||
{0 * 8, 0 * 16, 3 * 8, 1 * 16},
|
||||
{UI_POS_X(0), UI_POS_Y(0), 3 * 8, 1 * 16},
|
||||
"Amp"};
|
||||
|
||||
RFAmpField field_rf_amp{
|
||||
{4 * 8, 0 * 16},
|
||||
{4 * 8, UI_POS_Y(0)},
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ void AudioSpectrumView::paint(Painter& painter) {
|
||||
|
||||
// Cursor
|
||||
const Rect r_cursor{
|
||||
field_frequency.value() / (48000 / 240), r.bottom() - 32 - cursor_band_height,
|
||||
field_frequency.value() / (48000 / screen_width), r.bottom() - 32 - cursor_band_height,
|
||||
1, cursor_band_height};
|
||||
painter.fill_rectangle(
|
||||
r_cursor,
|
||||
@@ -104,8 +104,8 @@ void FrequencyScale::set_channel_filter(
|
||||
void FrequencyScale::set_cursor_position(const int32_t position) {
|
||||
cursor_position = position;
|
||||
|
||||
cursor_position = std::min<int32_t>(cursor_position, 119);
|
||||
cursor_position = std::max<int32_t>(cursor_position, -120);
|
||||
cursor_position = std::min<int32_t>(cursor_position, screen_width / 2 - 1);
|
||||
cursor_position = std::max<int32_t>(cursor_position, -1 * screen_width / 2);
|
||||
|
||||
set_dirty();
|
||||
}
|
||||
@@ -124,7 +124,7 @@ void FrequencyScale::paint(Painter& painter) {
|
||||
draw_frequency_ticks(painter, r);
|
||||
|
||||
const Rect r_cursor{
|
||||
118 + cursor_position, r.bottom() - filter_band_height,
|
||||
(screen_width / 2 - 2) + cursor_position, r.bottom() - filter_band_height,
|
||||
5, filter_band_height};
|
||||
painter.fill_rectangle(
|
||||
r_cursor,
|
||||
@@ -222,8 +222,8 @@ void FrequencyScale::on_blur() {
|
||||
bool FrequencyScale::on_encoder(const EncoderEvent delta) {
|
||||
cursor_position += delta;
|
||||
|
||||
cursor_position = std::min<int32_t>(cursor_position, 119);
|
||||
cursor_position = std::max<int32_t>(cursor_position, -120);
|
||||
cursor_position = std::min<int32_t>(cursor_position, screen_width / 2 - 1);
|
||||
cursor_position = std::max<int32_t>(cursor_position, -1 * screen_width / 2);
|
||||
|
||||
set_dirty();
|
||||
|
||||
@@ -233,7 +233,7 @@ bool FrequencyScale::on_encoder(const EncoderEvent delta) {
|
||||
bool FrequencyScale::on_key(const KeyEvent key) {
|
||||
if (key == KeyEvent::Select) {
|
||||
if (on_select) {
|
||||
on_select((cursor_position * spectrum_sampling_rate) / 240);
|
||||
on_select((cursor_position * spectrum_sampling_rate) / screen_width);
|
||||
cursor_position = 0;
|
||||
set_dirty();
|
||||
return true;
|
||||
@@ -246,7 +246,7 @@ bool FrequencyScale::on_key(const KeyEvent key) {
|
||||
bool FrequencyScale::on_touch(const TouchEvent touch) {
|
||||
if (touch.type == TouchEvent::Type::Start) {
|
||||
if (on_select) {
|
||||
on_select((touch.point.x() * spectrum_sampling_rate) / 240);
|
||||
on_select((touch.point.x() * spectrum_sampling_rate) / screen_width);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -261,6 +261,8 @@ void WaterfallWidget::on_show() {
|
||||
|
||||
const auto screen_r = screen_rect();
|
||||
display.scroll_set_area(screen_r.top(), screen_r.bottom());
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
void WaterfallWidget::on_hide() {
|
||||
@@ -268,27 +270,25 @@ void WaterfallWidget::on_hide() {
|
||||
* position?
|
||||
*/
|
||||
display.scroll_disable();
|
||||
clear();
|
||||
}
|
||||
|
||||
void WaterfallWidget::on_channel_spectrum(
|
||||
const ChannelSpectrum& spectrum) {
|
||||
/* TODO: static_assert that message.spectrum.db.size() >= pixel_row.size() */
|
||||
|
||||
std::array<Color, 240> pixel_row;
|
||||
for (size_t i = 0; i < 120; i++) {
|
||||
const auto pixel_color = gradient.lut[spectrum.db[256 - 120 + i]];
|
||||
std::vector<Color> pixel_row(screen_width);
|
||||
for (size_t i = 0; i < screen_width / 2; i++) {
|
||||
const auto pixel_color = gradient.lut[spectrum.db[256 - screen_width / 2 + i]];
|
||||
pixel_row[i] = pixel_color;
|
||||
}
|
||||
|
||||
for (size_t i = 120; i < 240; i++) {
|
||||
const auto pixel_color = gradient.lut[spectrum.db[i - 120]];
|
||||
for (size_t i = screen_width / 2; i < screen_width; i++) {
|
||||
const auto pixel_color = gradient.lut[spectrum.db[i - screen_width / 2]];
|
||||
pixel_row[i] = pixel_color;
|
||||
}
|
||||
|
||||
const auto draw_y = display.scroll(1);
|
||||
|
||||
display.draw_pixels(
|
||||
{{0, draw_y}, {pixel_row.size(), 1}},
|
||||
{{0, draw_y}, {(int)pixel_row.size(), 1}},
|
||||
pixel_row);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,10 +51,10 @@ class AudioSpectrumView : public View {
|
||||
int16_t audio_spectrum[128]{0};
|
||||
|
||||
Labels labels{
|
||||
{{6 * 8, 0 * 16}, "Hz", Theme::getInstance()->fg_light->foreground}};
|
||||
{{6 * 8, UI_POS_Y(0)}, "Hz", Theme::getInstance()->fg_light->foreground}};
|
||||
|
||||
NumberField field_frequency{
|
||||
{0 * 8, 0 * 16},
|
||||
{UI_POS_X(0), UI_POS_Y(0)},
|
||||
5,
|
||||
{0, 48000},
|
||||
48000 / 240,
|
||||
@@ -150,7 +150,7 @@ class WaterfallView : public View {
|
||||
private:
|
||||
void update_widgets_rect();
|
||||
|
||||
const Rect audio_spectrum_view_rect{0 * 8, 0 * 16, screen_width, 2 * 16 + 20};
|
||||
const Rect audio_spectrum_view_rect{UI_POS_X(0), UI_POS_Y(0), UI_POS_MAXWIDTH, 2 * 16 + 20};
|
||||
static constexpr Dim audio_spectrum_height = 16 * 2 + 20;
|
||||
static constexpr Dim scale_height = 20;
|
||||
|
||||
|
||||
@@ -56,17 +56,21 @@ static const Style* get_style_for_gain(uint8_t tot_gain) {
|
||||
void TransmitterView::paint(Painter& painter) {
|
||||
size_t c;
|
||||
Point pos = {0, screen_pos().y()};
|
||||
|
||||
for (c = 0; c < 20; c++) {
|
||||
Point pos2 = {0, screen_pos().y() + 32 + 8};
|
||||
// 24*8 pxstripes
|
||||
for (c = 0; c < (size_t)(screen_width / 24 + 1); c++) {
|
||||
painter.draw_bitmap(
|
||||
pos,
|
||||
bitmap_stripes,
|
||||
Theme::getInstance()->fg_yellow->foreground,
|
||||
Theme::getInstance()->fg_yellow->background);
|
||||
if (c != 9)
|
||||
pos += {24, 0};
|
||||
else
|
||||
pos = {0, screen_pos().y() + 32 + 8};
|
||||
painter.draw_bitmap(
|
||||
pos2,
|
||||
bitmap_stripes,
|
||||
Theme::getInstance()->fg_yellow->foreground,
|
||||
Theme::getInstance()->fg_yellow->background);
|
||||
pos += {24, 0};
|
||||
pos2 += {24, 0};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,16 +229,16 @@ TransmitterView2::TransmitterView2(Point pos, bool short_ui) {
|
||||
text_labels.set(short_ui ? "G: A:" : "Gain: Amp:");
|
||||
text_labels.set_parent_rect(
|
||||
short_ui
|
||||
? Rect{0 * 8, 0 * 16, 7 * 8, 1 * 16}
|
||||
: Rect{0 * 8, 0 * 16, 12 * 8, 1 * 16});
|
||||
? Rect{UI_POS_X(0), UI_POS_Y(0), 7 * 8, 1 * 16}
|
||||
: Rect{UI_POS_X(0), UI_POS_Y(0), 12 * 8, 1 * 16});
|
||||
field_gain.set_parent_rect(
|
||||
short_ui
|
||||
? Rect{2 * 8, 0 * 16, 2 * 8, 1 * 16}
|
||||
: Rect{5 * 8, 0 * 16, 2 * 8, 1 * 16});
|
||||
? Rect{2 * 8, UI_POS_Y(0), 2 * 8, 1 * 16}
|
||||
: Rect{5 * 8, UI_POS_Y(0), 2 * 8, 1 * 16});
|
||||
field_amp.set_parent_rect(
|
||||
short_ui
|
||||
? Rect{7 * 8, 0 * 16, 2 * 8, 1 * 16}
|
||||
: Rect{12 * 8, 0 * 16, 2 * 8, 1 * 16});
|
||||
? Rect{7 * 8, UI_POS_Y(0), 2 * 8, 1 * 16}
|
||||
: Rect{12 * 8, UI_POS_Y(0), 2 * 8, 1 * 16});
|
||||
|
||||
field_gain.set_value(transmitter_model.tx_gain());
|
||||
field_gain.on_change = [this](uint32_t tx_gain) {
|
||||
|
||||
@@ -115,7 +115,7 @@ class TransmitterView : public View {
|
||||
' '};
|
||||
|
||||
Button button_start{
|
||||
{21 * 8, 1 * 8, 9 * 8, 32},
|
||||
{UI_POS_X_RIGHT(9), 1 * 8, 9 * 8, 32},
|
||||
"START"};
|
||||
|
||||
FrequencyStepView field_frequency_step{
|
||||
|
||||
@@ -50,11 +50,11 @@ class TimeScopeView : public View {
|
||||
int16_t audio_spectrum[128]{0};
|
||||
|
||||
/*Labels labels {
|
||||
{ { 6 * 8, 0 * 16 }, "Hz", Theme::getInstance()->fg_light->foreground }
|
||||
{ { 6 * 8,UI_POS_Y(0) }, "Hz", Theme::getInstance()->fg_light->foreground }
|
||||
};*/
|
||||
/*
|
||||
NumberField field_frequency {
|
||||
{ 0 * 8, 0 * 16 },
|
||||
{ 0 * 8,UI_POS_Y(0) },
|
||||
5,
|
||||
{ 0, 48000 },
|
||||
48000 / 240,
|
||||
@@ -108,7 +108,7 @@ class TVWidget : public View {
|
||||
|
||||
void paint(Painter& painter) override;
|
||||
NumberField field_xcorr{
|
||||
{0 * 8, 0 * 16},
|
||||
{UI_POS_X(0), UI_POS_Y(0)},
|
||||
5,
|
||||
{0, 128},
|
||||
1,
|
||||
@@ -117,7 +117,7 @@ class TVWidget : public View {
|
||||
private:
|
||||
void update_widgets_rect();
|
||||
|
||||
const Rect audio_spectrum_view_rect{0 * 8, 0 * 16, screen_width, 2 * 16 + 20};
|
||||
const Rect audio_spectrum_view_rect{UI_POS_X(0), UI_POS_Y(0), screen_width, 2 * 16 + 20};
|
||||
static constexpr Dim audio_spectrum_height = 16 * 2 + 20;
|
||||
static constexpr Dim scale_height = 20;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user