mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2026-09-13 18:19:33 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 75ece38725 | |||
| b53032a8a5 | |||
| e7f8952ece | |||
| 82a6ae0791 | |||
| d303098e35 | |||
| 1a69ce2d97 | |||
| eedebe1c52 |
@@ -36,7 +36,12 @@ jobs:
|
||||
uses: actions/checkout@master
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: next
|
||||
#ref: next
|
||||
# The branch, tag or SHA to checkout. When checking out the repository that
|
||||
# triggered a workflow, this defaults to the reference or SHA for that event.
|
||||
# Otherwise, uses the default branch.
|
||||
# https://github.com/actions/checkout
|
||||
# So scheduled runs will use the default branch (next) but its now possible to trigger a workflow from another branch
|
||||
submodules: true
|
||||
- name: Git Sumbodule Update
|
||||
run: |
|
||||
@@ -56,9 +61,6 @@ jobs:
|
||||
- name: Unzip world map
|
||||
run: |
|
||||
unzip world_map.zip -d sdcard/ADSB
|
||||
- name: Create Firmware TAR
|
||||
run: |
|
||||
mkdir -p firmware_tar/FIRMWARE && cp build/firmware/portapack-h1_h2-mayhem.bin firmware_tar/FIRMWARE/portapack-mayhem_${{ steps.version_date.outputs.date }}.bin && mkdir -p firmware_tar/APPS && cp build/firmware/application/*.ppma firmware_tar/APPS && cd firmware_tar && tar -cvaf ../portapack-mayhem.ppfw.tar *
|
||||
- name: Create Firmware ZIP
|
||||
run: |
|
||||
zip -j firmware.zip build/firmware/portapack-h1_h2-mayhem.bin && cd flashing && zip -r ../firmware.zip *
|
||||
@@ -98,7 +100,7 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./portapack-mayhem.ppfw.tar
|
||||
asset_path: build/firmware/portapack-mayhem.ppfw.tar
|
||||
asset_name: mayhem_nightly_${{ steps.version_date.outputs.date }}_OCI.ppfw.tar
|
||||
asset_content_type: application/x-tar
|
||||
- name: Upload Firmware Asset
|
||||
|
||||
@@ -14,7 +14,12 @@ jobs:
|
||||
uses: actions/checkout@master
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: next
|
||||
#ref: next
|
||||
# The branch, tag or SHA to checkout. When checking out the repository that
|
||||
# triggered a workflow, this defaults to the reference or SHA for that event.
|
||||
# Otherwise, uses the default branch.
|
||||
# https://github.com/actions/checkout
|
||||
# So scheduled runs will use the default branch (next) but its now possible to trigger a workflow from another branch
|
||||
submodules: true
|
||||
- name: Git Sumbodule Update
|
||||
run: |
|
||||
@@ -40,9 +45,6 @@ jobs:
|
||||
- name: Unzip world map
|
||||
run: |
|
||||
unzip world_map.zip -d sdcard/ADSB
|
||||
- name: Create Firmware TAR
|
||||
run: |
|
||||
mkdir -p firmware_tar/FIRMWARE && cp build/firmware/portapack-h1_h2-mayhem.bin firmware_tar/FIRMWARE/portapack-mayhem_${{ steps.version_date.outputs.date }}.bin && mkdir -p firmware_tar/APPS && cp build/firmware/application/*.ppma firmware_tar/APPS && cd firmware_tar && tar -cvaf ../portapack-mayhem.ppfw.tar *
|
||||
- name: Create Firmware ZIP
|
||||
run: |
|
||||
zip -j firmware.zip build/firmware/portapack-h1_h2-mayhem.bin && cd flashing && zip -r ../firmware.zip *
|
||||
@@ -92,7 +94,7 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./portapack-mayhem.ppfw.tar
|
||||
asset_path: build/firmware/portapack-mayhem.ppfw.tar
|
||||
asset_name: mayhem_${{ steps.version.outputs.version }}_OCI.ppfw.tar
|
||||
asset_content_type: application/x-tar
|
||||
- name: Upload Firmware Asset
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
> [!IMPORTANT]
|
||||
> *Shortly*, this repository **will be moved** from my personal GitHub [eried/portapack-mayhem](https://github.com/eried/portapack-mayhem) to an organization: [portapack-mayhem/portapack-mayhem](https://github.com/portapack-mayhem/portapack-mayhem). Please keep this in mind to **update your links** accordingly.
|
||||
|
||||
# PortaPack Mayhem
|
||||
|
||||
[](https://travis-ci.com/eried/portapack-mayhem) [](https://github.com/eried/portapack-mayhem/actions/workflows/create_nightly_release.yml) [](https://codescene.io/projects/8381) [](https://github.com/eried/portapack-mayhem/releases) [](https://github.com/eried/portapack-mayhem/releases/latest) [](https://hub.docker.com/r/eried/portapack) [](https://discord.gg/tuwVMv3)
|
||||
|
||||
+22
-14
@@ -10,32 +10,40 @@ VOLUME /havoc
|
||||
WORKDIR /havoc/firmware
|
||||
|
||||
# Fetch dependencies from APT
|
||||
RUN apt-get update && \
|
||||
apt-get install -y git tar wget dfu-util cmake python3 ccache bzip2 liblz4-tool curl && \
|
||||
apt-get -qy autoremove
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y git tar wget dfu-util cmake python3 ccache bzip2 liblz4-tool curl ninja-build \
|
||||
&& apt-get -qy autoremove \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
#Install current pip from PyPa
|
||||
RUN curl https://bootstrap.pypa.io/pip/3.4/get-pip.py -o get-pip.py && \
|
||||
python3 get-pip.py
|
||||
|
||||
#Fetch additional dependencies from Python 3.x pip
|
||||
RUN pip install pyyaml
|
||||
RUN ln -s /usr/bin/python3 /usr/bin/python && \
|
||||
ln -s /usr/bin/pip3 /usr/bin/pip
|
||||
RUN pip install pyyaml \
|
||||
&& ln -s /usr/bin/python3 /usr/bin/python \
|
||||
&& ln -s /usr/bin/pip3 /usr/bin/pip
|
||||
|
||||
ENV LANG C.UTF-8
|
||||
ENV LC_ALL C.UTF-8
|
||||
|
||||
# Grab the GNU ARM toolchain from arm.com
|
||||
# Then extract contents to /opt/build/armbin/
|
||||
RUN mkdir /opt/build && cd /opt/build && \
|
||||
wget -O gcc-arm-none-eabi $ARMBINURL && \
|
||||
mkdir armbin && \
|
||||
tar --strip=1 -xjvf gcc-arm-none-eabi -C armbin
|
||||
RUN mkdir /opt/build \
|
||||
&& cd /opt/build \
|
||||
&& wget -O gcc-arm-none-eabi $ARMBINURL \
|
||||
&& mkdir armbin \
|
||||
&& tar --strip=1 -xjvf gcc-arm-none-eabi -C armbin
|
||||
|
||||
# Configure CCACHE
|
||||
RUN mkdir ~/bin && cd ~/bin && \
|
||||
for tool in gcc g++ cpp c++;do ln -s $(which ccache) arm-none-eabi-$tool;done
|
||||
RUN mkdir ~/bin \
|
||||
&& cd ~/bin \
|
||||
&& for tool in gcc g++ cpp c++; do \
|
||||
ln -s $(which ccache) arm-none-eabi-$tool \
|
||||
; done
|
||||
|
||||
CMD cd .. && cd build && \
|
||||
cmake .. && make firmware
|
||||
ADD firmware/tools/docker-entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||
|
||||
# replace make with ninja temporarily while building your image if you prefer to use that by default
|
||||
CMD ["make"]
|
||||
|
||||
@@ -24,4 +24,4 @@ RUN mkdir ~/bin && cd ~/bin && \
|
||||
for tool in gcc g++ cpp c++;do ln -s $(which ccache) arm-none-eabi-$tool;done
|
||||
|
||||
CMD cd .. && cd build && \
|
||||
cmake .. && make firmware
|
||||
cmake .. && make ppfw
|
||||
|
||||
+22
-14
@@ -10,32 +10,40 @@ VOLUME /havoc
|
||||
WORKDIR /havoc/firmware
|
||||
|
||||
# Fetch dependencies from APT
|
||||
RUN apt-get update && \
|
||||
apt-get install -y git tar wget dfu-util cmake python3 ccache bzip2 liblz4-tool curl && \
|
||||
apt-get -qy autoremove
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y git tar wget dfu-util cmake python3 ccache bzip2 liblz4-tool curl ninja-build \
|
||||
&& apt-get -qy autoremove \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
#Install current pip from PyPa
|
||||
RUN curl https://bootstrap.pypa.io/pip/3.4/get-pip.py -o get-pip.py && \
|
||||
python3 get-pip.py
|
||||
|
||||
#Fetch additional dependencies from Python 3.x pip
|
||||
RUN pip install pyyaml
|
||||
RUN ln -s /usr/bin/python3 /usr/bin/python && \
|
||||
ln -s /usr/bin/pip3 /usr/bin/pip
|
||||
RUN pip install pyyaml \
|
||||
&& ln -s /usr/bin/python3 /usr/bin/python \
|
||||
&& ln -s /usr/bin/pip3 /usr/bin/pip
|
||||
|
||||
ENV LANG C.UTF-8
|
||||
ENV LC_ALL C.UTF-8
|
||||
|
||||
# Grab the GNU ARM toolchain from arm.com
|
||||
# Then extract contents to /opt/build/armbin/
|
||||
RUN mkdir /opt/build && cd /opt/build && \
|
||||
wget -O gcc-arm-none-eabi $ARMBINURL && \
|
||||
mkdir armbin && \
|
||||
tar --strip=1 -xjvf gcc-arm-none-eabi -C armbin
|
||||
RUN mkdir /opt/build \
|
||||
&& cd /opt/build \
|
||||
&& wget -O gcc-arm-none-eabi $ARMBINURL \
|
||||
&& mkdir armbin \
|
||||
&& tar --strip=1 -xjvf gcc-arm-none-eabi -C armbin
|
||||
|
||||
# Configure CCACHE
|
||||
RUN mkdir ~/bin && cd ~/bin && \
|
||||
for tool in gcc g++ cpp c++;do ln -s $(which ccache) arm-none-eabi-$tool;done
|
||||
RUN mkdir ~/bin \
|
||||
&& cd ~/bin \
|
||||
&& for tool in gcc g++ cpp c++; do \
|
||||
ln -s $(which ccache) arm-none-eabi-$tool \
|
||||
; done
|
||||
|
||||
CMD cd .. && cd build && \
|
||||
cmake .. && make firmware
|
||||
ADD firmware/tools/docker-entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||
|
||||
# replace make with ninja temporarily while building your image if you prefer to use that by default
|
||||
CMD ["make"]
|
||||
|
||||
@@ -265,7 +265,7 @@ set(CPPSRC
|
||||
apps/ble_tx_app.cpp
|
||||
apps/capture_app.cpp
|
||||
apps/ert_app.cpp
|
||||
apps/gps_sim_app.cpp
|
||||
# apps/gps_sim_app.cpp
|
||||
# apps/lge_app.cpp
|
||||
apps/pocsag_app.cpp
|
||||
# apps/replay_app.cpp
|
||||
@@ -311,9 +311,9 @@ set(CPPSRC
|
||||
apps/ui_settings.cpp
|
||||
apps/ui_siggen.cpp
|
||||
apps/ui_sonde.cpp
|
||||
apps/ui_spectrum_painter_image.cpp
|
||||
apps/ui_spectrum_painter_text.cpp
|
||||
apps/ui_spectrum_painter.cpp
|
||||
# apps/ui_spectrum_painter_image.cpp
|
||||
# apps/ui_spectrum_painter_text.cpp
|
||||
# apps/ui_spectrum_painter.cpp
|
||||
apps/ui_ss_viewer.cpp
|
||||
apps/ui_sstvtx.cpp
|
||||
apps/ui_subghzd.cpp
|
||||
|
||||
@@ -293,6 +293,7 @@ AISRecentEntryDetailView::AISRecentEntryDetailView(NavigationView& nav) {
|
||||
ais::format::text(entry_.name),
|
||||
0,
|
||||
GeoPos::alt_unit::METERS,
|
||||
GeoPos::spd_unit::NONE,
|
||||
ais::format::latlon_float(entry_.last_position.latitude.normalized()),
|
||||
ais::format::latlon_float(entry_.last_position.longitude.normalized()),
|
||||
entry_.last_position.true_heading,
|
||||
@@ -315,7 +316,7 @@ AISRecentEntryDetailView& AISRecentEntryDetailView::operator=(const AISRecentEnt
|
||||
|
||||
void AISRecentEntryDetailView::update_position() {
|
||||
if (send_updates)
|
||||
geomap_view->update_position(ais::format::latlon_float(entry_.last_position.latitude.normalized()), ais::format::latlon_float(entry_.last_position.longitude.normalized()), (float)entry_.last_position.true_heading, 0);
|
||||
geomap_view->update_position(ais::format::latlon_float(entry_.last_position.latitude.normalized()), ais::format::latlon_float(entry_.last_position.longitude.normalized()), (float)entry_.last_position.true_heading, 0, entry_.last_position.speed_over_ground);
|
||||
}
|
||||
|
||||
void AISRecentEntryDetailView::focus() {
|
||||
|
||||
@@ -266,6 +266,7 @@ ADSBRxDetailsView::ADSBRxDetailsView(
|
||||
get_map_tag(entry_),
|
||||
entry_.pos.altitude,
|
||||
GeoPos::alt_unit::FEET,
|
||||
GeoPos::spd_unit::MPH,
|
||||
entry_.pos.latitude,
|
||||
entry_.pos.longitude,
|
||||
entry_.velo.heading);
|
||||
@@ -290,7 +291,7 @@ void ADSBRxDetailsView::update(const AircraftRecentEntry& entry) {
|
||||
} else if (geomap_view_) {
|
||||
// Map is showing, update the current item.
|
||||
geomap_view_->update_tag(get_map_tag(entry_));
|
||||
geomap_view_->update_position(entry.pos.latitude, entry.pos.longitude, entry.velo.heading, entry.pos.altitude);
|
||||
geomap_view_->update_position(entry.pos.latitude, entry.pos.longitude, entry.velo.heading, entry.pos.altitude, entry.velo.speed);
|
||||
} else {
|
||||
// Details is showing, update details.
|
||||
refresh_ui();
|
||||
|
||||
@@ -85,10 +85,12 @@ ADSBPositionView::ADSBPositionView(
|
||||
nav.push<GeoMapView>(
|
||||
geopos.altitude(),
|
||||
GeoPos::alt_unit::FEET,
|
||||
GeoPos::spd_unit::HIDDEN,
|
||||
geopos.lat(),
|
||||
geopos.lon(),
|
||||
[this](int32_t altitude, float lat, float lon) {
|
||||
[this](int32_t altitude, float lat, float lon, int32_t speed) {
|
||||
geopos.set_altitude(altitude);
|
||||
geopos.set_speed(speed);
|
||||
geopos.set_lat(lat);
|
||||
geopos.set_lon(lon);
|
||||
});
|
||||
|
||||
@@ -58,7 +58,8 @@ class ADSBPositionView : public OptionTabView {
|
||||
private:
|
||||
GeoPos geopos{
|
||||
{0, 2 * 16},
|
||||
GeoPos::FEET};
|
||||
GeoPos::FEET,
|
||||
GeoPos::HIDDEN};
|
||||
|
||||
Button button_set_map{
|
||||
{8 * 8, 6 * 16, 14 * 8, 2 * 16},
|
||||
|
||||
@@ -317,7 +317,7 @@ void APRSDetailsView::update() {
|
||||
}
|
||||
|
||||
if (send_updates)
|
||||
geomap_view->update_position(entry_copy.pos.latitude, entry_copy.pos.longitude, 0, 0);
|
||||
geomap_view->update_position(entry_copy.pos.latitude, entry_copy.pos.longitude, 0, 0, 0);
|
||||
}
|
||||
|
||||
APRSDetailsView::~APRSDetailsView() {
|
||||
@@ -339,6 +339,7 @@ APRSDetailsView::APRSDetailsView(
|
||||
entry_copy.source_formatted,
|
||||
0, // entry_copy.pos.altitude,
|
||||
GeoPos::alt_unit::FEET,
|
||||
GeoPos::spd_unit::HIDDEN,
|
||||
entry_copy.pos.latitude,
|
||||
entry_copy.pos.longitude,
|
||||
0, /*entry_copy.velo.heading,*/
|
||||
|
||||
@@ -78,8 +78,6 @@ void NuoptixView::transmit(bool setup) {
|
||||
}
|
||||
|
||||
transmitter_model.set_rf_amp(true);
|
||||
transmitter_model.set_lna(40);
|
||||
transmitter_model.set_vga(40);
|
||||
transmitter_model.enable();
|
||||
|
||||
dtmf_message[0] = '*'; // "Pre-tone for restart" method #1
|
||||
@@ -136,6 +134,7 @@ void NuoptixView::transmit(bool setup) {
|
||||
shared_memory.bb_data.tones_data.silence = NUOPTIX_TONE_LENGTH; // 49ms tone, 49ms space
|
||||
|
||||
audio::set_rate(audio::Rate::Hz_24000);
|
||||
|
||||
baseband::set_tones_config(transmitter_model.channel_bandwidth(), 0, 6 * 2, true, true);
|
||||
|
||||
timecode++;
|
||||
@@ -156,7 +155,7 @@ NuoptixView::NuoptixView(
|
||||
tx_view.on_edit_frequency = [this, &nav]() {
|
||||
auto new_view = nav.push<FrequencyKeypadView>(transmitter_model.target_frequency());
|
||||
new_view->on_changed = [this](rf::Frequency f) {
|
||||
transmitter_model.target_frequency(f);
|
||||
transmitter_model.set_target_frequency(f);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -94,6 +94,7 @@ SondeView::SondeView(NavigationView& nav)
|
||||
sonde_id,
|
||||
gps_info.alt,
|
||||
GeoPos::alt_unit::METERS,
|
||||
GeoPos::spd_unit::HIDDEN,
|
||||
gps_info.lat,
|
||||
gps_info.lon,
|
||||
999); // set a dummy heading out of range to draw a cross...probably not ideal?
|
||||
|
||||
@@ -162,7 +162,8 @@ class SondeView : public View {
|
||||
|
||||
GeoPos geopos{
|
||||
{0, 12 * 16},
|
||||
GeoPos::alt_unit::METERS};
|
||||
GeoPos::alt_unit::METERS,
|
||||
GeoPos::spd_unit::HIDDEN};
|
||||
|
||||
Button button_see_qr{
|
||||
{2 * 8, 15 * 16, 12 * 8, 3 * 16},
|
||||
|
||||
@@ -274,6 +274,14 @@ void EventDispatcher::on_touch_event(ui::TouchEvent event) {
|
||||
}
|
||||
}
|
||||
|
||||
ui::Widget* EventDispatcher::getTopWidget() {
|
||||
return top_widget;
|
||||
}
|
||||
|
||||
ui::Widget* EventDispatcher::getFocusedWidget() {
|
||||
return context.focus_manager().focus_widget();
|
||||
}
|
||||
|
||||
void EventDispatcher::handle_lcd_frame_sync() {
|
||||
DisplayFrameSyncMessage message;
|
||||
message_map.send(&message);
|
||||
|
||||
@@ -89,6 +89,9 @@ class EventDispatcher {
|
||||
void emulateTouch(ui::TouchEvent event);
|
||||
void emulateKeyboard(ui::KeyboardEvent event);
|
||||
|
||||
ui::Widget* getTopWidget();
|
||||
ui::Widget* getFocusedWidget();
|
||||
|
||||
private:
|
||||
static Thread* thread_event_loop;
|
||||
|
||||
|
||||
+12
@@ -44,6 +44,16 @@ set(EXTCPPSRC
|
||||
#lcr
|
||||
external/jammer/main.cpp
|
||||
external/jammer/ui_jammer.cpp
|
||||
|
||||
#gpssim
|
||||
external/gpssim/main.cpp
|
||||
external/gpssim/gps_sim_app.cpp
|
||||
|
||||
#spainter
|
||||
external/spainter/main.cpp
|
||||
external/spainter/ui_spectrum_painter.cpp
|
||||
external/spainter/ui_spectrum_painter_text.cpp
|
||||
external/spainter/ui_spectrum_painter_image.cpp
|
||||
)
|
||||
|
||||
set(EXTAPPLIST
|
||||
@@ -58,4 +68,6 @@ set(EXTAPPLIST
|
||||
lge
|
||||
lcr
|
||||
jammer
|
||||
gpssim
|
||||
spainter
|
||||
)
|
||||
|
||||
+16
-2
@@ -28,6 +28,8 @@ MEMORY
|
||||
ram_external_app_lge(rwx) : org = 0xEEF10000, len = 32k
|
||||
ram_external_app_lcr(rwx) : org = 0xEEF20000, len = 32k
|
||||
ram_external_app_jammer(rwx) : org = 0xEEF30000, len = 32k
|
||||
ram_external_app_gpssim(rwx) : org = 0xEEF40000, len = 32k
|
||||
ram_external_app_spainter(rwx) : org = 0xEEF50000, len = 32k
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
@@ -88,18 +90,30 @@ SECTIONS
|
||||
} > ram_external_app_lge
|
||||
|
||||
|
||||
.external_app_lcr : ALIGN(4) SUBALIGN(4)
|
||||
.external_app_lcr : ALIGN(4) SUBALIGN(4)
|
||||
{
|
||||
KEEP(*(.external_app.app_lcr.application_information));
|
||||
*(*ui*external_app*lcr*);
|
||||
} > ram_external_app_lcr
|
||||
|
||||
|
||||
.external_app_jammer : ALIGN(4) SUBALIGN(4)
|
||||
.external_app_jammer : ALIGN(4) SUBALIGN(4)
|
||||
{
|
||||
KEEP(*(.external_app.app_jammer.application_information));
|
||||
*(*ui*external_app*jammer*);
|
||||
} > ram_external_app_jammer
|
||||
|
||||
.external_app_gpssim : ALIGN(4) SUBALIGN(4)
|
||||
{
|
||||
KEEP(*(.external_app.app_gpssim.application_information));
|
||||
*(*ui*external_app*gpssim*);
|
||||
} > ram_external_app_gpssim
|
||||
|
||||
|
||||
.external_app_spainter : ALIGN(4) SUBALIGN(4)
|
||||
{
|
||||
KEEP(*(.external_app.app_spainter.application_information));
|
||||
*(*ui*external_app*spainter*);
|
||||
} > ram_external_app_spainter
|
||||
|
||||
}
|
||||
|
||||
Vendored
+4
-3
@@ -36,7 +36,7 @@
|
||||
using namespace portapack;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace ui {
|
||||
namespace ui::external_app::gpssim {
|
||||
|
||||
void GpsSimAppView::set_ready() {
|
||||
ready_signal = true;
|
||||
@@ -161,7 +161,8 @@ void GpsSimAppView::handle_replay_thread_done(const uint32_t return_code) {
|
||||
GpsSimAppView::GpsSimAppView(
|
||||
NavigationView& nav)
|
||||
: nav_(nav) {
|
||||
baseband::run_image(portapack::spi_flash::image_tag_gps);
|
||||
// baseband::run_image(portapack::spi_flash::image_tag_gps);
|
||||
baseband::run_prepared_image(portapack::memory::map::m4_code.base());
|
||||
|
||||
add_children({
|
||||
&button_open,
|
||||
@@ -211,4 +212,4 @@ void GpsSimAppView::set_parent_rect(const Rect new_parent_rect) {
|
||||
waterfall.set_parent_rect(waterfall_rect);
|
||||
}
|
||||
|
||||
} /* namespace ui */
|
||||
} /* namespace ui::external_app::gpssim */
|
||||
Vendored
+4
-3
@@ -25,6 +25,7 @@
|
||||
#define __GPS_SIM_APP_HPP__
|
||||
|
||||
#include "app_settings.hpp"
|
||||
#include "ui_language.hpp"
|
||||
#include "radio_state.hpp"
|
||||
#include "ui_widget.hpp"
|
||||
#include "ui_navigation.hpp"
|
||||
@@ -37,7 +38,7 @@
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
namespace ui {
|
||||
namespace ui::external_app::gpssim {
|
||||
|
||||
class GpsSimAppView : public View {
|
||||
public:
|
||||
@@ -108,7 +109,7 @@ class GpsSimAppView : public View {
|
||||
Checkbox check_loop{
|
||||
{21 * 8, 2 * 16},
|
||||
4,
|
||||
"Loop",
|
||||
LanguageHelper::currentMessages[LANG_LOOP],
|
||||
true};
|
||||
ImageButton button_play{
|
||||
{28 * 8, 2 * 16, 2 * 8, 1 * 16},
|
||||
@@ -142,6 +143,6 @@ class GpsSimAppView : public View {
|
||||
}};
|
||||
};
|
||||
|
||||
} /* namespace ui */
|
||||
} /* namespace ui::external_app::gpssim */
|
||||
|
||||
#endif /*__GPS_SIM_APP_HPP__*/
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Bernd Herzog
|
||||
*
|
||||
* 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.hpp"
|
||||
#include "gps_sim_app.hpp"
|
||||
#include "ui_navigation.hpp"
|
||||
#include "external_app.hpp"
|
||||
|
||||
namespace ui::external_app::gpssim {
|
||||
void initialize_app(ui::NavigationView& nav) {
|
||||
nav.push<GpsSimAppView>();
|
||||
}
|
||||
} // namespace ui::external_app::gpssim
|
||||
|
||||
extern "C" {
|
||||
|
||||
__attribute__((section(".external_app.app_gpssim.application_information"), used)) application_information_t _application_information_gpssim = {
|
||||
/*.memory_location = */ (uint8_t*)0x00000000,
|
||||
/*.externalAppEntry = */ ui::external_app::gpssim::initialize_app,
|
||||
/*.header_version = */ CURRENT_HEADER_VERSION,
|
||||
/*.app_version = */ VERSION_MD5,
|
||||
|
||||
/*.app_name = */ "GPSSim",
|
||||
/*.bitmap_data = */ {
|
||||
0xC0,
|
||||
0x07,
|
||||
0xE0,
|
||||
0x0F,
|
||||
0x70,
|
||||
0x1F,
|
||||
0x78,
|
||||
0x3E,
|
||||
0x78,
|
||||
0x3C,
|
||||
0x78,
|
||||
0x38,
|
||||
0x78,
|
||||
0x30,
|
||||
0x78,
|
||||
0x38,
|
||||
0x78,
|
||||
0x3C,
|
||||
0x70,
|
||||
0x1E,
|
||||
0x70,
|
||||
0x1F,
|
||||
0xE0,
|
||||
0x0F,
|
||||
0xC0,
|
||||
0x07,
|
||||
0x80,
|
||||
0x03,
|
||||
0x20,
|
||||
0x09,
|
||||
0x50,
|
||||
0x14,
|
||||
},
|
||||
/*.icon_color = */ ui::Color::green().v,
|
||||
/*.menu_location = */ app_location_t::TX,
|
||||
|
||||
/*.m4_app_tag = portapack::spi_flash::image_tag_gpssim */ {'P', 'G', 'P', 'S'},
|
||||
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time
|
||||
};
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Bernd Herzog
|
||||
*
|
||||
* 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.hpp"
|
||||
#include "ui_spectrum_painter.hpp"
|
||||
#include "ui_navigation.hpp"
|
||||
#include "external_app.hpp"
|
||||
|
||||
namespace ui::external_app::spainter {
|
||||
void initialize_app(ui::NavigationView& nav) {
|
||||
nav.push<SpectrumPainterView>();
|
||||
}
|
||||
} // namespace ui::external_app::spainter
|
||||
|
||||
extern "C" {
|
||||
|
||||
__attribute__((section(".external_app.app_spainter.application_information"), used)) application_information_t _application_information_spainter = {
|
||||
/*.memory_location = */ (uint8_t*)0x00000000,
|
||||
/*.externalAppEntry = */ ui::external_app::spainter::initialize_app,
|
||||
/*.header_version = */ CURRENT_HEADER_VERSION,
|
||||
/*.app_version = */ VERSION_MD5,
|
||||
|
||||
/*.app_name = */ "S.Painter",
|
||||
/*.bitmap_data = */ {
|
||||
0xFE,
|
||||
0x3F,
|
||||
0xFF,
|
||||
0x3F,
|
||||
0xFF,
|
||||
0xFF,
|
||||
0xFF,
|
||||
0xBF,
|
||||
0xFE,
|
||||
0xBF,
|
||||
0x00,
|
||||
0x80,
|
||||
0x80,
|
||||
0xFF,
|
||||
0x80,
|
||||
0x00,
|
||||
0x80,
|
||||
0x00,
|
||||
0xC0,
|
||||
0x01,
|
||||
0xC0,
|
||||
0x01,
|
||||
0xC0,
|
||||
0x01,
|
||||
0xC0,
|
||||
0x01,
|
||||
0xC0,
|
||||
0x01,
|
||||
0xC0,
|
||||
0x01,
|
||||
0xC0,
|
||||
0x01,
|
||||
},
|
||||
/*.icon_color = */ ui::Color::orange().v,
|
||||
/*.menu_location = */ app_location_t::TX,
|
||||
|
||||
/*.m4_app_tag = portapack::spi_flash::image_tag_spainter */ {'P', 'S', 'P', 'T'},
|
||||
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time
|
||||
};
|
||||
}
|
||||
+4
-3
@@ -31,12 +31,13 @@
|
||||
|
||||
using namespace portapack;
|
||||
|
||||
namespace ui {
|
||||
namespace ui::external_app::spainter {
|
||||
|
||||
SpectrumPainterView::SpectrumPainterView(
|
||||
NavigationView& nav)
|
||||
: nav_(nav) {
|
||||
baseband::run_image(spi_flash::image_tag_spectrum_painter);
|
||||
// baseband::run_image(spi_flash::image_tag_spectrum_painter);
|
||||
baseband::run_prepared_image(portapack::memory::map::m4_code.base());
|
||||
|
||||
add_children({
|
||||
&labels,
|
||||
@@ -198,4 +199,4 @@ void SpectrumPainterView::paint(Painter& painter) {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
} // namespace ui::external_app::spainter
|
||||
+4
-3
@@ -22,6 +22,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "ui.hpp"
|
||||
#include "ui_language.hpp"
|
||||
#include "ui_widget.hpp"
|
||||
|
||||
#include "ui_navigation.hpp"
|
||||
@@ -37,7 +38,7 @@
|
||||
#include "ui_spectrum_painter_image.hpp"
|
||||
#include "ui_spectrum_painter_text.hpp"
|
||||
|
||||
namespace ui {
|
||||
namespace ui::external_app::spainter {
|
||||
|
||||
class SpectrumPainterView : public View {
|
||||
public:
|
||||
@@ -115,7 +116,7 @@ class SpectrumPainterView : public View {
|
||||
Checkbox check_loop{
|
||||
{21 * 8, footer_location + 1 * 16},
|
||||
4,
|
||||
"Loop",
|
||||
LanguageHelper::currentMessages[LANG_LOOP],
|
||||
true};
|
||||
|
||||
ImageButton button_play{
|
||||
@@ -163,4 +164,4 @@ class SpectrumPainterView : public View {
|
||||
}};
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
} // namespace ui::external_app::spainter
|
||||
+2
-2
@@ -29,7 +29,7 @@
|
||||
#include "file.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
|
||||
namespace ui {
|
||||
namespace ui::external_app::spainter {
|
||||
|
||||
SpectrumInputImageView::SpectrumInputImageView(NavigationView& nav) {
|
||||
hidden(true);
|
||||
@@ -254,4 +254,4 @@ void SpectrumInputImageView::paint(Painter& painter) {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
} // namespace ui::external_app::spainter
|
||||
+2
-2
@@ -32,7 +32,7 @@
|
||||
#include "portapack.hpp"
|
||||
#include "message.hpp"
|
||||
|
||||
namespace ui {
|
||||
namespace ui::external_app::spainter {
|
||||
|
||||
class SpectrumInputImageView : public View {
|
||||
public:
|
||||
@@ -63,4 +63,4 @@ class SpectrumInputImageView : public View {
|
||||
bool drawBMP_scaled(const ui::Rect r, const std::string file);
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
} // namespace ui::external_app::spainter
|
||||
+2
-2
@@ -30,7 +30,7 @@
|
||||
#include "file.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
|
||||
namespace ui {
|
||||
namespace ui::external_app::spainter {
|
||||
|
||||
SpectrumInputTextView::SpectrumInputTextView(NavigationView& nav) {
|
||||
hidden(true);
|
||||
@@ -105,4 +105,4 @@ std::vector<uint8_t> SpectrumInputTextView::get_line(uint16_t y) {
|
||||
|
||||
return data;
|
||||
}
|
||||
} // namespace ui
|
||||
} // namespace ui::external_app::spainter
|
||||
+2
-2
@@ -32,7 +32,7 @@
|
||||
#include "portapack.hpp"
|
||||
#include "message.hpp"
|
||||
|
||||
namespace ui {
|
||||
namespace ui::external_app::spainter {
|
||||
|
||||
class SpectrumInputTextView : public View {
|
||||
public:
|
||||
@@ -109,4 +109,4 @@ class SpectrumInputTextView : public View {
|
||||
"Set message"};
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
} // namespace ui::external_app::spainter
|
||||
@@ -38,13 +38,17 @@ namespace ui {
|
||||
|
||||
GeoPos::GeoPos(
|
||||
const Point pos,
|
||||
const alt_unit altitude_unit)
|
||||
: altitude_unit_(altitude_unit) {
|
||||
const alt_unit altitude_unit,
|
||||
const spd_unit speed_unit)
|
||||
: altitude_unit_(altitude_unit), speed_unit_(speed_unit) {
|
||||
set_parent_rect({pos, {30 * 8, 3 * 16}});
|
||||
|
||||
add_children({&labels_position,
|
||||
&label_spd_position,
|
||||
&field_altitude,
|
||||
&field_speed,
|
||||
&text_alt_unit,
|
||||
&text_speed_unit,
|
||||
&field_lat_degrees,
|
||||
&field_lat_minutes,
|
||||
&field_lat_seconds,
|
||||
@@ -56,6 +60,7 @@ GeoPos::GeoPos(
|
||||
|
||||
// Defaults
|
||||
set_altitude(0);
|
||||
set_speed(0);
|
||||
set_lat(0);
|
||||
set_lon(0);
|
||||
|
||||
@@ -67,10 +72,11 @@ GeoPos::GeoPos(
|
||||
text_lon_decimal.set(to_string_decimal(lon_value, 5));
|
||||
|
||||
if (on_change && report_change)
|
||||
on_change(altitude(), lat_value, lon_value);
|
||||
on_change(altitude(), lat_value, lon_value, speed());
|
||||
};
|
||||
|
||||
field_altitude.on_change = changed_fn;
|
||||
field_speed.on_change = changed_fn;
|
||||
field_lat_degrees.on_change = changed_fn;
|
||||
field_lat_minutes.on_change = changed_fn;
|
||||
field_lat_seconds.on_change = changed_fn;
|
||||
@@ -79,11 +85,19 @@ GeoPos::GeoPos(
|
||||
field_lon_seconds.on_change = changed_fn;
|
||||
|
||||
text_alt_unit.set(altitude_unit_ ? "m" : "ft");
|
||||
if (speed_unit_ == KMPH) text_speed_unit.set("kmph");
|
||||
if (speed_unit_ == MPH) text_speed_unit.set("mph");
|
||||
if (speed_unit_ == HIDDEN) {
|
||||
text_speed_unit.hidden(true);
|
||||
label_spd_position.hidden(true);
|
||||
field_speed.hidden(true);
|
||||
}
|
||||
}
|
||||
|
||||
void GeoPos::set_read_only(bool v) {
|
||||
// only setting altitude to read-only (allow manual panning via lat/lon fields)
|
||||
field_altitude.set_focusable(!v);
|
||||
field_speed.set_focusable(!v);
|
||||
}
|
||||
|
||||
// Stupid hack to avoid an event loop
|
||||
@@ -98,14 +112,18 @@ void GeoPos::focus() {
|
||||
field_lat_degrees.focus();
|
||||
}
|
||||
|
||||
void GeoPos::hide_altitude() {
|
||||
void GeoPos::hide_altandspeed() {
|
||||
// Color altitude grey to indicate it's not updated in manual panning mode
|
||||
field_altitude.set_style(&Styles::grey);
|
||||
field_speed.set_style(&Styles::grey);
|
||||
}
|
||||
|
||||
void GeoPos::set_altitude(int32_t altitude) {
|
||||
field_altitude.set_value(altitude);
|
||||
}
|
||||
void GeoPos::set_speed(int32_t speed) {
|
||||
field_speed.set_value(speed);
|
||||
}
|
||||
|
||||
void GeoPos::set_lat(float lat) {
|
||||
field_lat_degrees.set_value(lat);
|
||||
@@ -139,6 +157,10 @@ int32_t GeoPos::altitude() {
|
||||
return field_altitude.value();
|
||||
};
|
||||
|
||||
int32_t GeoPos::speed() {
|
||||
return field_speed.value();
|
||||
};
|
||||
|
||||
GeoMap::GeoMap(
|
||||
Rect parent_rect)
|
||||
: Widget{parent_rect}, markerListLen(0) {
|
||||
@@ -458,7 +480,7 @@ void GeoMapView::focus() {
|
||||
nav_.display_modal("No map", "No world_map.bin file in\n/ADSB/ directory", ABORT);
|
||||
}
|
||||
|
||||
void GeoMapView::update_position(float lat, float lon, uint16_t angle, int32_t altitude) {
|
||||
void GeoMapView::update_position(float lat, float lon, uint16_t angle, int32_t altitude, int32_t speed) {
|
||||
if (geomap.manual_panning()) {
|
||||
geomap.set_dirty();
|
||||
return;
|
||||
@@ -467,12 +489,14 @@ void GeoMapView::update_position(float lat, float lon, uint16_t angle, int32_t a
|
||||
lat_ = lat;
|
||||
lon_ = lon;
|
||||
altitude_ = altitude;
|
||||
speed_ = speed;
|
||||
|
||||
// Stupid hack to avoid an event loop
|
||||
geopos.set_report_change(false);
|
||||
geopos.set_lat(lat_);
|
||||
geopos.set_lon(lon_);
|
||||
geopos.set_altitude(altitude_);
|
||||
geopos.set_speed(speed_);
|
||||
geopos.set_report_change(true);
|
||||
|
||||
geomap.set_angle(angle);
|
||||
@@ -491,11 +515,12 @@ void GeoMapView::setup() {
|
||||
geopos.set_lat(lat_);
|
||||
geopos.set_lon(lon_);
|
||||
|
||||
geopos.on_change = [this](int32_t altitude, float lat, float lon) {
|
||||
geopos.on_change = [this](int32_t altitude, float lat, float lon, int32_t speed) {
|
||||
altitude_ = altitude;
|
||||
lat_ = lat;
|
||||
lon_ = lon;
|
||||
geopos.hide_altitude();
|
||||
speed_ = speed;
|
||||
geopos.hide_altandspeed();
|
||||
geomap.set_manual_panning(true);
|
||||
geomap.move(lon_, lat_);
|
||||
geomap.set_dirty();
|
||||
@@ -527,6 +552,7 @@ GeoMapView::GeoMapView(
|
||||
const std::string& tag,
|
||||
int32_t altitude,
|
||||
GeoPos::alt_unit altitude_unit,
|
||||
GeoPos::spd_unit speed_unit,
|
||||
float lat,
|
||||
float lon,
|
||||
uint16_t angle,
|
||||
@@ -534,6 +560,7 @@ GeoMapView::GeoMapView(
|
||||
: nav_(nav),
|
||||
altitude_(altitude),
|
||||
altitude_unit_(altitude_unit),
|
||||
speed_unit_(speed_unit),
|
||||
lat_(lat),
|
||||
lon_(lon),
|
||||
angle_(angle),
|
||||
@@ -561,12 +588,14 @@ GeoMapView::GeoMapView(
|
||||
NavigationView& nav,
|
||||
int32_t altitude,
|
||||
GeoPos::alt_unit altitude_unit,
|
||||
GeoPos::spd_unit speed_unit,
|
||||
float lat,
|
||||
float lon,
|
||||
const std::function<void(int32_t, float, float)> on_done)
|
||||
const std::function<void(int32_t, float, float, int32_t)> on_done)
|
||||
: nav_(nav),
|
||||
altitude_(altitude),
|
||||
altitude_unit_(altitude_unit),
|
||||
speed_unit_(speed_unit),
|
||||
lat_(lat),
|
||||
lon_(lon) {
|
||||
mode_ = PROMPT;
|
||||
@@ -585,7 +614,7 @@ GeoMapView::GeoMapView(
|
||||
|
||||
button_ok.on_select = [this, on_done, &nav](Button&) {
|
||||
if (on_done)
|
||||
on_done(altitude_, lat_, lon_);
|
||||
on_done(altitude_, lat_, lon_, speed_);
|
||||
nav.pop();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -62,19 +62,27 @@ class GeoPos : public View {
|
||||
FEET = 0,
|
||||
METERS
|
||||
};
|
||||
enum spd_unit {
|
||||
NONE = 0,
|
||||
MPH,
|
||||
KMPH,
|
||||
HIDDEN = 255
|
||||
};
|
||||
|
||||
std::function<void(int32_t, float, float)> on_change{};
|
||||
std::function<void(int32_t, float, float, int32_t)> on_change{};
|
||||
|
||||
GeoPos(const Point pos, const alt_unit altitude_unit);
|
||||
GeoPos(const Point pos, const alt_unit altitude_unit, const spd_unit speed_unit);
|
||||
|
||||
void focus() override;
|
||||
|
||||
void set_read_only(bool v);
|
||||
void set_altitude(int32_t altitude);
|
||||
void set_speed(int32_t speed);
|
||||
void set_lat(float lat);
|
||||
void set_lon(float lon);
|
||||
int32_t altitude();
|
||||
void hide_altitude();
|
||||
int32_t speed();
|
||||
void hide_altandspeed();
|
||||
float lat();
|
||||
float lon();
|
||||
|
||||
@@ -84,22 +92,35 @@ class GeoPos : public View {
|
||||
bool read_only{false};
|
||||
bool report_change{true};
|
||||
alt_unit altitude_unit_{};
|
||||
spd_unit speed_unit_{};
|
||||
|
||||
Labels labels_position{
|
||||
{{1 * 8, 0 * 16}, "Alt:", Color::light_grey()},
|
||||
{{1 * 8, 1 * 16}, "Lat: \xB0 ' \"", Color::light_grey()}, // 0xB0 is degree ° symbol in our 8x16 font
|
||||
{{1 * 8, 2 * 16}, "Lon: \xB0 ' \"", Color::light_grey()},
|
||||
};
|
||||
|
||||
Labels label_spd_position{
|
||||
{{15 * 8, 0 * 16}, "Spd:", Color::light_grey()},
|
||||
};
|
||||
NumberField field_altitude{
|
||||
{6 * 8, 0 * 16},
|
||||
5,
|
||||
{-1000, 50000},
|
||||
250,
|
||||
' '};
|
||||
|
||||
NumberField field_speed{
|
||||
{19 * 8, 0 * 16},
|
||||
4,
|
||||
{0, 5000},
|
||||
1,
|
||||
' '};
|
||||
Text text_alt_unit{
|
||||
{12 * 8, 0 * 16, 2 * 8, 16},
|
||||
""};
|
||||
Text text_speed_unit{
|
||||
{25 * 8, 0 * 16, 4 * 8, 16},
|
||||
""};
|
||||
|
||||
NumberField field_lat_degrees{
|
||||
{5 * 8, 1 * 16},
|
||||
@@ -224,6 +245,7 @@ class GeoMapView : public View {
|
||||
const std::string& tag,
|
||||
int32_t altitude,
|
||||
GeoPos::alt_unit altitude_unit,
|
||||
GeoPos::spd_unit speed_unit,
|
||||
float lat,
|
||||
float lon,
|
||||
uint16_t angle,
|
||||
@@ -231,9 +253,10 @@ class GeoMapView : public View {
|
||||
GeoMapView(NavigationView& nav,
|
||||
int32_t altitude,
|
||||
GeoPos::alt_unit altitude_unit,
|
||||
GeoPos::spd_unit speed_unit,
|
||||
float lat,
|
||||
float lon,
|
||||
const std::function<void(int32_t, float, float)> on_done);
|
||||
const std::function<void(int32_t, float, float, int32_t)> on_done);
|
||||
~GeoMapView();
|
||||
|
||||
GeoMapView(const GeoMapView&) = delete;
|
||||
@@ -243,7 +266,7 @@ class GeoMapView : public View {
|
||||
|
||||
void focus() override;
|
||||
|
||||
void update_position(float lat, float lon, uint16_t angle, int32_t altitude);
|
||||
void update_position(float lat, float lon, uint16_t angle, int32_t altitude, int32_t speed = 0);
|
||||
|
||||
std::string title() const override { return "Map view"; };
|
||||
|
||||
@@ -257,10 +280,12 @@ class GeoMapView : public View {
|
||||
|
||||
void setup();
|
||||
|
||||
const std::function<void(int32_t, float, float)> on_done{};
|
||||
const std::function<void(int32_t, float, float, int32_t)> on_done{};
|
||||
GeoMapMode mode_{};
|
||||
int32_t altitude_{};
|
||||
int32_t speed_{};
|
||||
GeoPos::alt_unit altitude_unit_{};
|
||||
GeoPos::spd_unit speed_unit_{};
|
||||
float lat_{};
|
||||
float lon_{};
|
||||
uint16_t angle_{};
|
||||
@@ -270,7 +295,8 @@ class GeoMapView : public View {
|
||||
|
||||
GeoPos geopos{
|
||||
{0, 0},
|
||||
altitude_unit_};
|
||||
altitude_unit_,
|
||||
speed_unit_};
|
||||
|
||||
GeoMap geomap{
|
||||
{0, GeoMap::banner_height, GeoMap::geomap_rect_width, GeoMap::geomap_rect_height}};
|
||||
|
||||
@@ -93,6 +93,13 @@ void FrequencyField::set_allow_digit_mode(bool allowed) {
|
||||
}
|
||||
}
|
||||
|
||||
void FrequencyField::getAccessibilityText(std::string& result) {
|
||||
result = to_string_dec_int(value_);
|
||||
}
|
||||
void FrequencyField::getWidgetName(std::string& result) {
|
||||
result = "FrequencyField";
|
||||
}
|
||||
|
||||
void FrequencyField::paint(Painter& painter) {
|
||||
const auto str_value = to_string_short_freq(value_);
|
||||
const auto paint_style = has_focus() ? style().invert() : style();
|
||||
|
||||
@@ -66,6 +66,9 @@ class FrequencyField : public Widget {
|
||||
void on_focus() override;
|
||||
void on_blur() override;
|
||||
|
||||
void getAccessibilityText(std::string& result) override;
|
||||
void getWidgetName(std::string& result) override;
|
||||
|
||||
private:
|
||||
const size_t length_;
|
||||
range_t range_;
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
#include "ui_settings.hpp"
|
||||
#include "ui_siggen.hpp"
|
||||
#include "ui_sonde.hpp"
|
||||
#include "ui_spectrum_painter.hpp"
|
||||
// #include "ui_spectrum_painter.hpp" //moved to ext app
|
||||
#include "ui_ss_viewer.hpp"
|
||||
#include "ui_sstvtx.hpp"
|
||||
#include "ui_styles.hpp"
|
||||
@@ -93,7 +93,7 @@
|
||||
#include "ble_tx_app.hpp"
|
||||
#include "capture_app.hpp"
|
||||
#include "ert_app.hpp"
|
||||
#include "gps_sim_app.hpp"
|
||||
// #include "gps_sim_app.hpp" //moved to ext
|
||||
// #include "lge_app.hpp" //moved to ext
|
||||
#include "pocsag_app.hpp"
|
||||
#include "replay_app.hpp"
|
||||
@@ -607,7 +607,7 @@ TransmittersMenuView::TransmittersMenuView(NavigationView& nav) {
|
||||
{"BHT Xy/EP", ui::Color::green(), &bitmap_icon_bht, [&nav]() { nav.push<BHTView>(); }},
|
||||
{"BLE Tx", ui::Color::green(), &bitmap_icon_btle, [&nav]() { nav.push<BLETxView>(); }},
|
||||
// {"BurgerPgr", ui::Color::yellow(), &bitmap_icon_burger, [&nav]() { nav.push<CoasterPagerView>(); }}, //moved to ext
|
||||
{"GPS Sim", ui::Color::green(), &bitmap_icon_gps_sim, [&nav]() { nav.push<GpsSimAppView>(); }},
|
||||
//{"GPS Sim", ui::Color::green(), &bitmap_icon_gps_sim, [&nav]() { nav.push<GpsSimAppView>(); }}, //moved to ext
|
||||
//{"Jammer", ui::Color::green(), &bitmap_icon_jammer, [&nav]() { nav.push<JammerView>(); }}, //moved to ext
|
||||
// { "Key fob", ui::Color::orange(), &bitmap_icon_keyfob, [&nav](){ nav.push<KeyfobView>(); }},
|
||||
// {"LGE", ui::Color::yellow(), &bitmap_icon_lge, [&nav]() { nav.push<LGEView>(); }}, //moved to ext
|
||||
@@ -617,7 +617,7 @@ TransmittersMenuView::TransmittersMenuView(NavigationView& nav) {
|
||||
{"POCSAG TX", ui::Color::green(), &bitmap_icon_pocsag, [&nav]() { nav.push<POCSAGTXView>(); }},
|
||||
{"RDS", ui::Color::green(), &bitmap_icon_rds, [&nav]() { nav.push<RDSView>(); }},
|
||||
{"Soundbrd", ui::Color::green(), &bitmap_icon_soundboard, [&nav]() { nav.push<SoundBoardView>(); }},
|
||||
{"S.Painter", ui::Color::orange(), &bitmap_icon_paint, [&nav]() { nav.push<SpectrumPainterView>(); }},
|
||||
//{"S.Painter", ui::Color::orange(), &bitmap_icon_paint, [&nav]() { nav.push<SpectrumPainterView>(); }},
|
||||
{"SSTV", ui::Color::green(), &bitmap_icon_sstv, [&nav]() { nav.push<SSTVTXView>(); }},
|
||||
// {"TEDI/LCR", ui::Color::yellow(), &bitmap_icon_lcr, [&nav]() { nav.push<LCRView>(); }}, //moved to ext
|
||||
{"TouchTune", ui::Color::green(), &bitmap_icon_touchtunes, [&nav]() { nav.push<TouchTunesView>(); }},
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "chprintf.h"
|
||||
#include "chqueues.h"
|
||||
#include "untar.hpp"
|
||||
#include "ui_widget.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <codecvt>
|
||||
@@ -730,6 +731,87 @@ static void cpld_info(BaseSequentialStream* chp, int argc, char* argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
// walks throught the given widget's childs in recurse to get all support text and pass it to a callback function
|
||||
static void widget_collect_accessibility(BaseSequentialStream* chp, ui::Widget* w, void (*callback)(BaseSequentialStream*, const std::string&, const std::string&), ui::Widget* focusedWidget) {
|
||||
for (auto child : w->children()) {
|
||||
if (!child->hidden()) {
|
||||
std::string res = "";
|
||||
child->getAccessibilityText(res);
|
||||
std::string strtype = "";
|
||||
child->getWidgetName(strtype);
|
||||
if (child == focusedWidget) strtype += "*";
|
||||
if (callback != NULL && !res.empty()) callback(chp, res, strtype);
|
||||
widget_collect_accessibility(chp, child, callback, focusedWidget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// callback when it found any response from a widget
|
||||
static void accessibility_callback(BaseSequentialStream* chp, const std::string& strResult, const std::string& wgType) {
|
||||
if (!wgType.empty()) {
|
||||
chprintf(chp, "[");
|
||||
chprintf(chp, wgType.c_str());
|
||||
chprintf(chp, "] ");
|
||||
}
|
||||
chprintf(chp, "%s\r\n", strResult.c_str());
|
||||
}
|
||||
|
||||
// gets all widget's accessibility helper text
|
||||
static void cmd_accessibility_readall(BaseSequentialStream* chp, int argc, char* argv[]) {
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
auto evtd = getEventDispatcherInstance();
|
||||
if (evtd == NULL) {
|
||||
chprintf(chp, "error Can't get Event Dispatcherr\n");
|
||||
return;
|
||||
}
|
||||
auto wg = evtd->getTopWidget();
|
||||
if (wg == NULL) {
|
||||
chprintf(chp, "error Can't get top Widget\r\n");
|
||||
return;
|
||||
}
|
||||
auto focused = evtd->getFocusedWidget();
|
||||
widget_collect_accessibility(chp, wg, accessibility_callback, focused);
|
||||
chprintf(chp, "ok\r\n");
|
||||
}
|
||||
|
||||
// gets focused widget's accessibility helper text
|
||||
static void cmd_accessibility_readcurr(BaseSequentialStream* chp, int argc, char* argv[]) {
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
auto evtd = getEventDispatcherInstance();
|
||||
if (evtd == NULL) {
|
||||
chprintf(chp, "error Can't get Event Dispatcher\r\n");
|
||||
return;
|
||||
}
|
||||
auto wg = evtd->getFocusedWidget();
|
||||
if (wg == NULL) {
|
||||
chprintf(chp, "error Can't get focused Widget\r\n");
|
||||
return;
|
||||
}
|
||||
std::string res = "";
|
||||
wg->getAccessibilityText(res);
|
||||
if (res.empty()) {
|
||||
// try with parent
|
||||
wg = wg->parent();
|
||||
if (wg == NULL) {
|
||||
chprintf(chp, "error Widget not providing accessibility info\r\n");
|
||||
return;
|
||||
}
|
||||
wg->getAccessibilityText(res);
|
||||
if (res.empty()) {
|
||||
chprintf(chp, "error Widget not providing accessibility info\r\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
std::string strtype = "";
|
||||
wg->getWidgetName(strtype);
|
||||
accessibility_callback(chp, res, strtype);
|
||||
chprintf(chp, "\r\nok\r\n");
|
||||
}
|
||||
|
||||
static void cmd_cpld_read(BaseSequentialStream* chp, int argc, char* argv[]) {
|
||||
const char* usage =
|
||||
"usage: cpld_read <device> <target>\r\n"
|
||||
@@ -915,6 +997,8 @@ static const ShellCommand commands[] = {
|
||||
{"filesize", cmd_sd_filesize},
|
||||
{"cpld_info", cpld_info},
|
||||
{"cpld_read", cmd_cpld_read},
|
||||
{"accessibility_readall", cmd_accessibility_readall},
|
||||
{"accessibility_readcurr", cmd_accessibility_readcurr},
|
||||
{NULL, NULL}};
|
||||
|
||||
static const ShellConfig shell_cfg1 = {
|
||||
|
||||
@@ -476,13 +476,6 @@ set(MODE_CPPSRC
|
||||
)
|
||||
DeclareTargets(PREP replay)
|
||||
|
||||
### GPS Simulator
|
||||
|
||||
set(MODE_CPPSRC
|
||||
proc_gps_sim.cpp
|
||||
)
|
||||
DeclareTargets(PGPS gps_sim)
|
||||
|
||||
### Signal generator
|
||||
|
||||
set(MODE_CPPSRC
|
||||
@@ -490,12 +483,6 @@ set(MODE_CPPSRC
|
||||
)
|
||||
DeclareTargets(PSIG siggen)
|
||||
|
||||
### Spectrum painter
|
||||
|
||||
set(MODE_CPPSRC
|
||||
proc_spectrum_painter.cpp
|
||||
)
|
||||
DeclareTargets(PSPT spectrum_painter)
|
||||
|
||||
### SSTV TX
|
||||
|
||||
@@ -637,6 +624,20 @@ set(MODE_CPPSRC
|
||||
)
|
||||
DeclareTargets(PAMT am_tv)
|
||||
|
||||
### GPS Simulator
|
||||
|
||||
set(MODE_CPPSRC
|
||||
proc_gps_sim.cpp
|
||||
)
|
||||
DeclareTargets(PGPS gps_sim)
|
||||
|
||||
### Spectrum painter
|
||||
|
||||
set(MODE_CPPSRC
|
||||
proc_spectrum_painter.cpp
|
||||
)
|
||||
DeclareTargets(PSPT spectrum_painter)
|
||||
|
||||
### Test
|
||||
|
||||
set(MODE_CPPSRC
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "ui_language.hpp"
|
||||
|
||||
const char* LanguageHelper::englishMessages[] = {"OK", "Cancel", "Error", "Modem setup", "Debug", "Log", "Done", "Start", "Stop", "Scan", "Clear", "Ready", "Data:"};
|
||||
const char* LanguageHelper::englishMessages[] = {"OK", "Cancel", "Error", "Modem setup", "Debug", "Log", "Done", "Start", "Stop", "Scan", "Clear", "Ready", "Data:", "Loop"};
|
||||
|
||||
const char** LanguageHelper::currentMessages = englishMessages;
|
||||
|
||||
|
||||
@@ -18,7 +18,8 @@ enum LangConsts {
|
||||
LANG_SCAN,
|
||||
LANG_CLEAR,
|
||||
LANG_READY,
|
||||
LANG_DATADP
|
||||
LANG_DATADP,
|
||||
LANG_LOOP
|
||||
};
|
||||
|
||||
class LanguageHelper {
|
||||
|
||||
@@ -237,6 +237,12 @@ void Widget::dirty_overlapping_children_in_rect(const Rect& child_rect) {
|
||||
}
|
||||
}
|
||||
|
||||
void Widget::getAccessibilityText(std::string& result) {
|
||||
result = "";
|
||||
}
|
||||
void Widget::getWidgetName(std::string& result) {
|
||||
result = "";
|
||||
}
|
||||
/* View ******************************************************************/
|
||||
|
||||
void View::paint(Painter& painter) {
|
||||
@@ -367,6 +373,12 @@ void Text::set(std::string_view value) {
|
||||
set_dirty();
|
||||
}
|
||||
|
||||
void Text::getAccessibilityText(std::string& result) {
|
||||
result = text;
|
||||
}
|
||||
void Text::getWidgetName(std::string& result) {
|
||||
result = "Text";
|
||||
}
|
||||
void Text::paint(Painter& painter) {
|
||||
const auto rect = screen_rect();
|
||||
auto s = has_focus() ? style().invert() : style();
|
||||
@@ -407,6 +419,17 @@ void Labels::paint(Painter& painter) {
|
||||
}
|
||||
}
|
||||
|
||||
void Labels::getAccessibilityText(std::string& result) {
|
||||
result = "";
|
||||
for (auto& label : labels_) {
|
||||
result += label.text;
|
||||
result += ", ";
|
||||
}
|
||||
}
|
||||
void Labels::getWidgetName(std::string& result) {
|
||||
result = "Labels";
|
||||
}
|
||||
|
||||
/* LiveDateTime **********************************************************/
|
||||
|
||||
void LiveDateTime::on_tick_second() {
|
||||
@@ -579,6 +602,13 @@ void ProgressBar::set_value(const uint32_t value) {
|
||||
set_dirty();
|
||||
}
|
||||
|
||||
void ProgressBar::getAccessibilityText(std::string& result) {
|
||||
result = to_string_dec_uint(_value) + " / " + to_string_dec_uint(_max);
|
||||
}
|
||||
void ProgressBar::getWidgetName(std::string& result) {
|
||||
result = "ProgressBar";
|
||||
}
|
||||
|
||||
void ProgressBar::paint(Painter& painter) {
|
||||
int v_scaled;
|
||||
|
||||
@@ -679,6 +709,13 @@ void Console::write(std::string message) {
|
||||
}
|
||||
}
|
||||
|
||||
void Console::getAccessibilityText(std::string& result) {
|
||||
result = "{" + buffer + "}";
|
||||
}
|
||||
void Console::getWidgetName(std::string& result) {
|
||||
result = "Console";
|
||||
}
|
||||
|
||||
void Console::writeln(std::string message) {
|
||||
write(message + "\n");
|
||||
}
|
||||
@@ -787,6 +824,13 @@ bool Checkbox::set_value(const bool value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Checkbox::getAccessibilityText(std::string& result) {
|
||||
result = text_ + ((value_) ? " checked" : " unchecked");
|
||||
}
|
||||
void Checkbox::getWidgetName(std::string& result) {
|
||||
result = "Checkbox";
|
||||
}
|
||||
|
||||
bool Checkbox::value() const {
|
||||
return value_;
|
||||
}
|
||||
@@ -904,6 +948,13 @@ std::string Button::text() const {
|
||||
return text_;
|
||||
}
|
||||
|
||||
void Button::getAccessibilityText(std::string& result) {
|
||||
result = text_;
|
||||
}
|
||||
void Button::getWidgetName(std::string& result) {
|
||||
result = "Button";
|
||||
}
|
||||
|
||||
void Button::paint(Painter& painter) {
|
||||
Color bg, fg;
|
||||
const auto r = screen_rect();
|
||||
@@ -1050,6 +1101,13 @@ std::string ButtonWithEncoder::text() const {
|
||||
return text_;
|
||||
}
|
||||
|
||||
void ButtonWithEncoder::getAccessibilityText(std::string& result) {
|
||||
result = text_;
|
||||
}
|
||||
void ButtonWithEncoder::getWidgetName(std::string& result) {
|
||||
result = "ButtonWithEncoder";
|
||||
}
|
||||
|
||||
void ButtonWithEncoder::paint(Painter& painter) {
|
||||
Color bg, fg;
|
||||
const auto r = screen_rect();
|
||||
@@ -1205,6 +1263,13 @@ void NewButton::set_text(const std::string value) {
|
||||
set_dirty();
|
||||
}
|
||||
|
||||
void NewButton::getAccessibilityText(std::string& result) {
|
||||
result = text_;
|
||||
}
|
||||
void NewButton::getWidgetName(std::string& result) {
|
||||
result = "NewButton";
|
||||
}
|
||||
|
||||
std::string NewButton::text() const {
|
||||
return text_;
|
||||
}
|
||||
@@ -1399,6 +1464,13 @@ ImageButton::ImageButton(
|
||||
set_focusable(true);
|
||||
}
|
||||
|
||||
void ImageButton::getAccessibilityText(std::string& result) {
|
||||
result = "image";
|
||||
}
|
||||
void ImageButton::getWidgetName(std::string& result) {
|
||||
result = "ImageButton";
|
||||
}
|
||||
|
||||
bool ImageButton::on_key(const KeyEvent key) {
|
||||
if (key == KeyEvent::Select) {
|
||||
if (on_select) {
|
||||
@@ -1489,6 +1561,13 @@ bool ImageToggle::value() const {
|
||||
return value_;
|
||||
}
|
||||
|
||||
void ImageToggle::getAccessibilityText(std::string& result) {
|
||||
result = value_ ? "checked" : "unchecked";
|
||||
}
|
||||
void ImageToggle::getWidgetName(std::string& result) {
|
||||
result = "ImageToggle";
|
||||
}
|
||||
|
||||
void ImageToggle::set_value(bool b) {
|
||||
if (b == value_)
|
||||
return;
|
||||
@@ -1524,6 +1603,13 @@ size_t ImageOptionsField::selected_index_value() const {
|
||||
return options[selected_index_].second;
|
||||
}
|
||||
|
||||
void ImageOptionsField::getAccessibilityText(std::string& result) {
|
||||
result = "selected index: " + to_string_dec_uint(selected_index_);
|
||||
}
|
||||
void ImageOptionsField::getWidgetName(std::string& result) {
|
||||
result = "ImageOptionsField";
|
||||
}
|
||||
|
||||
void ImageOptionsField::set_selected_index(const size_t new_index) {
|
||||
if (new_index < options.size()) {
|
||||
if (new_index != selected_index()) {
|
||||
@@ -1623,6 +1709,20 @@ const OptionsField::value_t& OptionsField::selected_index_value() const {
|
||||
return options_[selected_index_].second;
|
||||
}
|
||||
|
||||
void OptionsField::getAccessibilityText(std::string& result) {
|
||||
result = "options: ";
|
||||
bool first = true;
|
||||
for (const auto& option : options_) {
|
||||
if (!first) result += " ,";
|
||||
first = false;
|
||||
result += option.first;
|
||||
}
|
||||
result += "; selected: " + selected_index_name();
|
||||
}
|
||||
void OptionsField::getWidgetName(std::string& result) {
|
||||
result = "OptionsField";
|
||||
}
|
||||
|
||||
void OptionsField::set_selected_index(const size_t new_index, bool trigger_change) {
|
||||
if (new_index < options_.size()) {
|
||||
if (new_index != selected_index() || trigger_change) {
|
||||
@@ -1741,6 +1841,13 @@ const std::string& TextEdit::value() const {
|
||||
return text_;
|
||||
}
|
||||
|
||||
void TextEdit::getAccessibilityText(std::string& result) {
|
||||
result = text_;
|
||||
}
|
||||
void TextEdit::getWidgetName(std::string& result) {
|
||||
result = "TextEdit";
|
||||
}
|
||||
|
||||
void TextEdit::set_cursor(uint32_t pos) {
|
||||
cursor_pos_ = std::min<size_t>(pos, text_.length());
|
||||
set_dirty();
|
||||
@@ -1890,6 +1997,13 @@ const std::string& TextField::get_text() const {
|
||||
return text;
|
||||
}
|
||||
|
||||
void TextField::getAccessibilityText(std::string& result) {
|
||||
result = text;
|
||||
}
|
||||
void TextField::getWidgetName(std::string& result) {
|
||||
result = "TextField";
|
||||
}
|
||||
|
||||
void TextField::set_text(std::string_view value) {
|
||||
set(value);
|
||||
if (on_change)
|
||||
@@ -1945,6 +2059,13 @@ int32_t NumberField::value() const {
|
||||
return value_;
|
||||
}
|
||||
|
||||
void NumberField::getAccessibilityText(std::string& result) {
|
||||
result = to_string_dec_int(value_);
|
||||
}
|
||||
void NumberField::getWidgetName(std::string& result) {
|
||||
result = "NumberField";
|
||||
}
|
||||
|
||||
void NumberField::set_value(int32_t new_value, bool trigger_change) {
|
||||
if (can_loop) {
|
||||
if (new_value >= range.first)
|
||||
@@ -2155,6 +2276,12 @@ const std::string& SymField::to_string() const {
|
||||
return value_;
|
||||
}
|
||||
|
||||
void SymField::getAccessibilityText(std::string& result) {
|
||||
result = value_;
|
||||
}
|
||||
void SymField::getWidgetName(std::string& result) {
|
||||
result = "SymField";
|
||||
}
|
||||
void SymField::paint(Painter& painter) {
|
||||
Point p = screen_pos();
|
||||
|
||||
|
||||
@@ -106,6 +106,9 @@ class Widget {
|
||||
|
||||
virtual Context& context() const;
|
||||
|
||||
virtual void getAccessibilityText(std::string& result);
|
||||
virtual void getWidgetName(std::string& result);
|
||||
|
||||
void set_style(const Style* new_style);
|
||||
|
||||
const Style& style() const;
|
||||
@@ -207,6 +210,8 @@ class Text : public Widget {
|
||||
void set(std::string_view value);
|
||||
|
||||
void paint(Painter& painter) override;
|
||||
void getAccessibilityText(std::string& result) override;
|
||||
void getWidgetName(std::string& result) override;
|
||||
|
||||
protected:
|
||||
// NB: Don't truncate this string. The UI will only render
|
||||
@@ -234,6 +239,8 @@ class Labels : public Widget {
|
||||
void set_labels(std::initializer_list<Label> labels);
|
||||
|
||||
void paint(Painter& painter) override;
|
||||
void getAccessibilityText(std::string& result) override;
|
||||
void getWidgetName(std::string& result) override;
|
||||
|
||||
private:
|
||||
std::vector<Label> labels_;
|
||||
@@ -312,6 +319,8 @@ class ProgressBar : public Widget {
|
||||
void set_value(const uint32_t value);
|
||||
|
||||
void paint(Painter& painter) override;
|
||||
void getAccessibilityText(std::string& result) override;
|
||||
void getWidgetName(std::string& result) override;
|
||||
|
||||
private:
|
||||
uint32_t _value = 0;
|
||||
@@ -345,6 +354,8 @@ class Console : public Widget {
|
||||
void enable_scrolling(bool enable);
|
||||
void on_show() override;
|
||||
void on_hide() override;
|
||||
void getAccessibilityText(std::string& result) override;
|
||||
void getWidgetName(std::string& result) override;
|
||||
|
||||
private:
|
||||
Point pos{0, 0};
|
||||
@@ -385,6 +396,8 @@ class Checkbox : public Widget {
|
||||
bool on_key(const KeyEvent key) override;
|
||||
bool on_keyboard(const KeyboardEvent key) override;
|
||||
bool on_touch(const TouchEvent event) override;
|
||||
void getAccessibilityText(std::string& result) override;
|
||||
void getWidgetName(std::string& result) override;
|
||||
|
||||
private:
|
||||
std::string text_;
|
||||
@@ -421,6 +434,8 @@ class Button : public Widget {
|
||||
bool on_key(const KeyEvent key) override;
|
||||
bool on_touch(const TouchEvent event) override;
|
||||
bool on_keyboard(const KeyboardEvent event) override;
|
||||
void getAccessibilityText(std::string& result) override;
|
||||
void getWidgetName(std::string& result) override;
|
||||
|
||||
private:
|
||||
std::string text_;
|
||||
@@ -461,6 +476,9 @@ class ButtonWithEncoder : public Widget {
|
||||
bool on_encoder(const EncoderEvent delta) override;
|
||||
bool on_keyboard(const KeyboardEvent event) override;
|
||||
|
||||
void getAccessibilityText(std::string& result) override;
|
||||
void getWidgetName(std::string& result) override;
|
||||
|
||||
private:
|
||||
std::string text_;
|
||||
int32_t encoder_delta = 0;
|
||||
@@ -496,6 +514,9 @@ class NewButton : public Widget {
|
||||
bool on_touch(const TouchEvent event) override;
|
||||
bool on_keyboard(const KeyboardEvent event) override;
|
||||
|
||||
void getAccessibilityText(std::string& result) override;
|
||||
void getWidgetName(std::string& result) override;
|
||||
|
||||
void paint(Painter& painter) override;
|
||||
|
||||
protected:
|
||||
@@ -550,6 +571,8 @@ class ImageButton : public Image {
|
||||
bool on_key(const KeyEvent key) override;
|
||||
bool on_touch(const TouchEvent event) override;
|
||||
bool on_keyboard(const KeyboardEvent event) override;
|
||||
void getAccessibilityText(std::string& result) override;
|
||||
void getWidgetName(std::string& result) override;
|
||||
};
|
||||
|
||||
/* A button that toggles between two images when set. */
|
||||
@@ -583,6 +606,9 @@ class ImageToggle : public ImageButton {
|
||||
bool value() const;
|
||||
void set_value(bool b);
|
||||
|
||||
void getAccessibilityText(std::string& result) override;
|
||||
void getWidgetName(std::string& result) override;
|
||||
|
||||
private:
|
||||
// Hide this field.
|
||||
using ImageButton::on_select;
|
||||
@@ -628,6 +654,8 @@ class ImageOptionsField : public Widget {
|
||||
bool on_encoder(const EncoderEvent delta) override;
|
||||
bool on_touch(const TouchEvent event) override;
|
||||
bool on_keyboard(const KeyboardEvent event) override;
|
||||
void getAccessibilityText(std::string& result) override;
|
||||
void getWidgetName(std::string& result) override;
|
||||
|
||||
private:
|
||||
options_t options;
|
||||
@@ -667,6 +695,9 @@ class OptionsField : public Widget {
|
||||
bool on_touch(const TouchEvent event) override;
|
||||
bool on_keyboard(const KeyboardEvent event) override;
|
||||
|
||||
void getAccessibilityText(std::string& result) override;
|
||||
void getWidgetName(std::string& result) override;
|
||||
|
||||
private:
|
||||
const size_t length_;
|
||||
options_t options_;
|
||||
@@ -712,6 +743,9 @@ class TextEdit : public Widget {
|
||||
bool on_touch(const TouchEvent event) override;
|
||||
bool on_keyboard(const KeyboardEvent event) override;
|
||||
|
||||
void getAccessibilityText(std::string& result) override;
|
||||
void getWidgetName(std::string& result) override;
|
||||
|
||||
void on_focus() override;
|
||||
void on_blur() override;
|
||||
|
||||
@@ -738,6 +772,9 @@ class TextField : public Text {
|
||||
bool on_encoder(EncoderEvent delta) override;
|
||||
bool on_touch(TouchEvent event) override;
|
||||
|
||||
void getAccessibilityText(std::string& result) override;
|
||||
void getWidgetName(std::string& result) override;
|
||||
|
||||
private:
|
||||
using Text::set;
|
||||
};
|
||||
@@ -774,6 +811,9 @@ class NumberField : public Widget {
|
||||
bool on_touch(const TouchEvent event) override;
|
||||
bool on_keyboard(const KeyboardEvent event) override;
|
||||
|
||||
void getAccessibilityText(std::string& result) override;
|
||||
void getWidgetName(std::string& result) override;
|
||||
|
||||
private:
|
||||
range_t range;
|
||||
int32_t step;
|
||||
@@ -849,6 +889,9 @@ class SymField : public Widget {
|
||||
bool on_encoder(EncoderEvent delta) override;
|
||||
bool on_touch(TouchEvent event) override;
|
||||
|
||||
void getAccessibilityText(std::string& result) override;
|
||||
void getWidgetName(std::string& result) override;
|
||||
|
||||
private:
|
||||
/* Ensure the specified symbol is in the symbol list. */
|
||||
char ensure_valid(char symbol) const;
|
||||
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e # exit immediatelly on any failure
|
||||
|
||||
build_make() {
|
||||
cd ..
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake ..
|
||||
make "$@"
|
||||
exit 0 # Report success :)
|
||||
}
|
||||
|
||||
build_ninja() {
|
||||
cd ..
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -G Ninja ..
|
||||
ninja "$@"
|
||||
exit 0 # Report success :)
|
||||
}
|
||||
|
||||
if [ "$1" = 'make' ]; then # build the default (or specified) target with make
|
||||
shift # remove the first item from $@ as we consumed it, we can then pass the rest on to make
|
||||
build_make "$@"
|
||||
elif [[ $1 == -j* ]]; then # allow passing -j without typing make_default
|
||||
# dont shift here as we wanna pass the -j
|
||||
build_make "$@"
|
||||
elif [ "$1" = 'ninja' ]; then # build the default (or specified) target with ninja
|
||||
shift # remove the first item from $@ as we consumed it, we can then pass the rest on to make
|
||||
build_ninja "$@"
|
||||
fi
|
||||
|
||||
exec "$@"
|
||||
Reference in New Issue
Block a user