diff --git a/companion/src/firmwares/opentx/opentxGruvin9xsimulator.cpp b/companion/src/firmwares/opentx/opentxGruvin9xsimulator.cpp index e1dd2d5d0c..320c97fa9c 100644 --- a/companion/src/firmwares/opentx/opentxGruvin9xsimulator.cpp +++ b/companion/src/firmwares/opentx/opentxGruvin9xsimulator.cpp @@ -76,17 +76,17 @@ namespace Open9xGruvin9x { #include "radio/src/vario.cpp" #include "radio/src/gui/menus.cpp" #include "radio/src/gui/menu_model.cpp" -#include "radio/src/gui/menu_model_select.cpp" -#include "radio/src/gui/menu_model_setup.cpp" +#include "radio/src/gui/9X/menu_model_select.cpp" +#include "radio/src/gui/9X/menu_model_setup.cpp" #include "radio/src/gui/menu_model_heli.cpp" -#include "radio/src/gui/menu_model_flightmodes.cpp" -#include "radio/src/gui/menu_model_inputs_mixes.cpp" -#include "radio/src/gui/menu_model_logical_switches.cpp" -#include "radio/src/gui/menu_model_custom_functions.cpp" -#include "radio/src/gui/menu_model_curves.cpp" -#include "radio/src/gui/menu_model_limits.cpp" -#include "radio/src/gui/menu_model_telemetry.cpp" -#include "radio/src/gui/menu_model_templates.cpp" +#include "radio/src/gui/9X/menu_model_flightmodes.cpp" +#include "radio/src/gui/9X/menu_model_inputs_mixes.cpp" +#include "radio/src/gui/9X/menu_model_logical_switches.cpp" +#include "radio/src/gui/9X/menu_model_custom_functions.cpp" +#include "radio/src/gui/9X/menu_model_curves.cpp" +#include "radio/src/gui/9X/menu_model_limits.cpp" +#include "radio/src/gui/9X/menu_model_telemetry.cpp" +#include "radio/src/gui/9X/menu_model_templates.cpp" #include "radio/src/gui/menu_general.cpp" #include "radio/src/gui/menu_general_setup.cpp" #include "radio/src/gui/menu_general_trainer.cpp" @@ -94,7 +94,7 @@ namespace Open9xGruvin9x { #include "radio/src/gui/menu_general_diagkeys.cpp" #include "radio/src/gui/menu_general_diaganas.cpp" #include "radio/src/gui/menu_general_calib.cpp" -#include "radio/src/gui/view_main.cpp" +#include "radio/src/gui/9X/view_main.cpp" #include "radio/src/gui/view_statistics.cpp" #include "radio/src/gui/view_telemetry.cpp" #include "radio/src/lcd_common.cpp" diff --git a/companion/src/firmwares/opentx/opentxM128simulator.cpp b/companion/src/firmwares/opentx/opentxM128simulator.cpp index 5a5ea43a70..3f4fdaf323 100644 --- a/companion/src/firmwares/opentx/opentxM128simulator.cpp +++ b/companion/src/firmwares/opentx/opentxM128simulator.cpp @@ -77,17 +77,17 @@ namespace OpenTxM128 { #include "radio/src/vario.cpp" #include "radio/src/gui/menus.cpp" #include "radio/src/gui/menu_model.cpp" -#include "radio/src/gui/menu_model_select.cpp" -#include "radio/src/gui/menu_model_setup.cpp" +#include "radio/src/gui/9X/menu_model_select.cpp" +#include "radio/src/gui/9X/menu_model_setup.cpp" #include "radio/src/gui/menu_model_heli.cpp" -#include "radio/src/gui/menu_model_flightmodes.cpp" -#include "radio/src/gui/menu_model_inputs_mixes.cpp" -#include "radio/src/gui/menu_model_curves.cpp" -#include "radio/src/gui/menu_model_logical_switches.cpp" -#include "radio/src/gui/menu_model_custom_functions.cpp" -#include "radio/src/gui/menu_model_limits.cpp" -#include "radio/src/gui/menu_model_telemetry.cpp" -#include "radio/src/gui/menu_model_templates.cpp" +#include "radio/src/gui/9X/menu_model_flightmodes.cpp" +#include "radio/src/gui/9X/menu_model_inputs_mixes.cpp" +#include "radio/src/gui/9X/menu_model_curves.cpp" +#include "radio/src/gui/9X/menu_model_logical_switches.cpp" +#include "radio/src/gui/9X/menu_model_custom_functions.cpp" +#include "radio/src/gui/9X/menu_model_limits.cpp" +#include "radio/src/gui/9X/menu_model_telemetry.cpp" +#include "radio/src/gui/9X/menu_model_templates.cpp" #include "radio/src/gui/menu_general.cpp" #include "radio/src/gui/menu_general_setup.cpp" #include "radio/src/gui/menu_general_trainer.cpp" @@ -95,7 +95,7 @@ namespace OpenTxM128 { #include "radio/src/gui/menu_general_diagkeys.cpp" #include "radio/src/gui/menu_general_diaganas.cpp" #include "radio/src/gui/menu_general_calib.cpp" -#include "radio/src/gui/view_main.cpp" +#include "radio/src/gui/9X/view_main.cpp" #include "radio/src/gui/view_statistics.cpp" #include "radio/src/gui/view_telemetry.cpp" #include "radio/src/lcd_common.cpp" diff --git a/companion/src/firmwares/opentx/opentxM64simulator.cpp b/companion/src/firmwares/opentx/opentxM64simulator.cpp index abc0007da2..b2eb0f52dc 100644 --- a/companion/src/firmwares/opentx/opentxM64simulator.cpp +++ b/companion/src/firmwares/opentx/opentxM64simulator.cpp @@ -80,17 +80,17 @@ namespace OpenTxM64 { #include "radio/src/vario.cpp" #include "radio/src/gui/menus.cpp" #include "radio/src/gui/menu_model.cpp" -#include "radio/src/gui/menu_model_select.cpp" -#include "radio/src/gui/menu_model_setup.cpp" +#include "radio/src/gui/9X/menu_model_select.cpp" +#include "radio/src/gui/9X/menu_model_setup.cpp" #include "radio/src/gui/menu_model_heli.cpp" -#include "radio/src/gui/menu_model_flightmodes.cpp" -#include "radio/src/gui/menu_model_inputs_mixes.cpp" -#include "radio/src/gui/menu_model_curves.cpp" -#include "radio/src/gui/menu_model_logical_switches.cpp" -#include "radio/src/gui/menu_model_custom_functions.cpp" -#include "radio/src/gui/menu_model_limits.cpp" -#include "radio/src/gui/menu_model_telemetry.cpp" -#include "radio/src/gui/menu_model_templates.cpp" +#include "radio/src/gui/9X/menu_model_flightmodes.cpp" +#include "radio/src/gui/9X/menu_model_inputs_mixes.cpp" +#include "radio/src/gui/9X/menu_model_curves.cpp" +#include "radio/src/gui/9X/menu_model_logical_switches.cpp" +#include "radio/src/gui/9X/menu_model_custom_functions.cpp" +#include "radio/src/gui/9X/menu_model_limits.cpp" +#include "radio/src/gui/9X/menu_model_telemetry.cpp" +#include "radio/src/gui/9X/menu_model_templates.cpp" #include "radio/src/gui/menu_general.cpp" #include "radio/src/gui/menu_general_setup.cpp" #include "radio/src/gui/menu_general_trainer.cpp" @@ -98,7 +98,7 @@ namespace OpenTxM64 { #include "radio/src/gui/menu_general_diagkeys.cpp" #include "radio/src/gui/menu_general_diaganas.cpp" #include "radio/src/gui/menu_general_calib.cpp" -#include "radio/src/gui/view_main.cpp" +#include "radio/src/gui/9X/view_main.cpp" #include "radio/src/gui/view_statistics.cpp" #include "radio/src/gui/view_telemetry.cpp" #include "radio/src/lcd_common.cpp" diff --git a/companion/src/firmwares/opentx/opentxSky9xsimulator.cpp b/companion/src/firmwares/opentx/opentxSky9xsimulator.cpp index 8a1fd55a30..7da0280286 100644 --- a/companion/src/firmwares/opentx/opentxSky9xsimulator.cpp +++ b/companion/src/firmwares/opentx/opentxSky9xsimulator.cpp @@ -89,19 +89,20 @@ namespace Open9xSky9x { #include "radio/src/stamp.cpp" #include "radio/src/maths.cpp" #include "radio/src/vario.cpp" +#include "radio/src/sdcard.cpp" #include "radio/src/gui/menus.cpp" #include "radio/src/gui/menu_model.cpp" -#include "radio/src/gui/menu_model_select.cpp" -#include "radio/src/gui/menu_model_setup.cpp" +#include "radio/src/gui/9X/menu_model_select.cpp" +#include "radio/src/gui/9X/menu_model_setup.cpp" #include "radio/src/gui/menu_model_heli.cpp" -#include "radio/src/gui/menu_model_flightmodes.cpp" -#include "radio/src/gui/menu_model_inputs_mixes.cpp" -#include "radio/src/gui/menu_model_curves.cpp" -#include "radio/src/gui/menu_model_logical_switches.cpp" -#include "radio/src/gui/menu_model_custom_functions.cpp" -#include "radio/src/gui/menu_model_limits.cpp" -#include "radio/src/gui/menu_model_telemetry.cpp" -#include "radio/src/gui/menu_model_templates.cpp" +#include "radio/src/gui/9X/menu_model_flightmodes.cpp" +#include "radio/src/gui/9X/menu_model_inputs_mixes.cpp" +#include "radio/src/gui/9X/menu_model_curves.cpp" +#include "radio/src/gui/9X/menu_model_logical_switches.cpp" +#include "radio/src/gui/9X/menu_model_custom_functions.cpp" +#include "radio/src/gui/9X/menu_model_limits.cpp" +#include "radio/src/gui/9X/menu_model_telemetry.cpp" +#include "radio/src/gui/9X/menu_model_templates.cpp" #include "radio/src/gui/menu_general.cpp" #include "radio/src/gui/menu_general_setup.cpp" #include "radio/src/gui/menu_general_sdmanager.cpp" @@ -111,7 +112,7 @@ namespace Open9xSky9x { #include "radio/src/gui/menu_general_diaganas.cpp" #include "radio/src/gui/menu_general_hardware.cpp" #include "radio/src/gui/menu_general_calib.cpp" -#include "radio/src/gui/view_main.cpp" +#include "radio/src/gui/9X/view_main.cpp" #include "radio/src/gui/view_statistics.cpp" #include "radio/src/gui/view_telemetry.cpp" #include "radio/src/gui/view_about.cpp" diff --git a/companion/src/firmwares/opentx/opentxTaranisSimulator.cpp b/companion/src/firmwares/opentx/opentxTaranisSimulator.cpp index 27c92e70e7..c7cf7ef8db 100644 --- a/companion/src/firmwares/opentx/opentxTaranisSimulator.cpp +++ b/companion/src/firmwares/opentx/opentxTaranisSimulator.cpp @@ -85,6 +85,7 @@ inline int geteepromsize() { #include "radio/src/functions.cpp" #include "radio/src/curves.cpp" #include "radio/src/mixer.cpp" +#include "radio/src/sdcard.cpp" #include "radio/src/targets/taranis/pulses_driver.cpp" #include "radio/src/targets/taranis/rtc_driver.cpp" #include "radio/src/targets/taranis/trainer_driver.cpp" @@ -96,18 +97,18 @@ inline int geteepromsize() { #include "radio/src/vario.cpp" #include "radio/src/gui/menus.cpp" #include "radio/src/gui/menu_model.cpp" -#include "radio/src/gui/menu_model_select.cpp" +#include "radio/src/gui/Taranis/menu_model_select.cpp" #include "radio/src/gui/Taranis/menu_model_setup.cpp" #include "radio/src/gui/menu_model_heli.cpp" #include "radio/src/gui/Taranis/menu_model_flightmodes.cpp" -#include "radio/src/gui/menu_model_inputs_mixes.cpp" -#include "radio/src/gui/menu_model_curves.cpp" +#include "radio/src/gui/Taranis/menu_model_inputs_mixes.cpp" +#include "radio/src/gui/Taranis/menu_model_curves.cpp" #include "radio/src/gui/Taranis/menu_model_logical_switches.cpp" -#include "radio/src/gui/menu_model_custom_functions.cpp" +#include "radio/src/gui/Taranis/menu_model_custom_functions.cpp" #include "radio/src/gui/menu_model_custom_scripts.cpp" #include "radio/src/gui/menu_model_gvars.cpp" #include "radio/src/gui/Taranis/menu_model_limits.cpp" -#include "radio/src/gui/menu_model_telemetry.cpp" +#include "radio/src/gui/Taranis/menu_model_telemetry.cpp" #include "radio/src/gui/menu_general.cpp" #include "radio/src/gui/menu_general_setup.cpp" #include "radio/src/gui/menu_general_sdmanager.cpp" diff --git a/companion/src/firmwares/opentx/opentxTaranisX9ESimulator.cpp b/companion/src/firmwares/opentx/opentxTaranisX9ESimulator.cpp index d8e1a2a6fb..64c66406b8 100755 --- a/companion/src/firmwares/opentx/opentxTaranisX9ESimulator.cpp +++ b/companion/src/firmwares/opentx/opentxTaranisX9ESimulator.cpp @@ -86,6 +86,7 @@ inline int geteepromsize() { #include "radio/src/functions.cpp" #include "radio/src/curves.cpp" #include "radio/src/mixer.cpp" +#include "radio/src/sdcard.cpp" #include "radio/src/targets/taranis/pulses_driver.cpp" #include "radio/src/targets/taranis/rtc_driver.cpp" #include "radio/src/targets/taranis/rotenc_driver.cpp" @@ -98,18 +99,18 @@ inline int geteepromsize() { #include "radio/src/vario.cpp" #include "radio/src/gui/menus.cpp" #include "radio/src/gui/menu_model.cpp" -#include "radio/src/gui/menu_model_select.cpp" +#include "radio/src/gui/Taranis/menu_model_select.cpp" #include "radio/src/gui/Taranis/menu_model_setup.cpp" #include "radio/src/gui/menu_model_heli.cpp" #include "radio/src/gui/Taranis/menu_model_flightmodes.cpp" -#include "radio/src/gui/menu_model_inputs_mixes.cpp" -#include "radio/src/gui/Taranis/menu_model_limits.cpp" -#include "radio/src/gui/menu_model_curves.cpp" +#include "radio/src/gui/Taranis/menu_model_inputs_mixes.cpp" +#include "radio/src/gui/Taranis/menu_model_curves.cpp" #include "radio/src/gui/Taranis/menu_model_logical_switches.cpp" -#include "radio/src/gui/menu_model_custom_functions.cpp" +#include "radio/src/gui/Taranis/menu_model_custom_functions.cpp" #include "radio/src/gui/menu_model_custom_scripts.cpp" #include "radio/src/gui/menu_model_gvars.cpp" -#include "radio/src/gui/menu_model_telemetry.cpp" +#include "radio/src/gui/Taranis/menu_model_limits.cpp" +#include "radio/src/gui/Taranis/menu_model_telemetry.cpp" #include "radio/src/gui/menu_general.cpp" #include "radio/src/gui/menu_general_setup.cpp" #include "radio/src/gui/menu_general_sdmanager.cpp" diff --git a/radio/src/Makefile b/radio/src/Makefile index d05badd026..5886ad355a 100644 --- a/radio/src/Makefile +++ b/radio/src/Makefile @@ -365,12 +365,7 @@ M128_VARIANT = +32768 M2561_VARIANT = +16384 EEPROM_VARIANT = 0 -ifeq ($(PCB), TARANIS) - GUIMODELSRC = gui/menu_model.cpp gui/menu_model_select.cpp gui/Taranis/menu_model_setup.cpp gui/menu_model_inputs_mixes.cpp gui/Taranis/menu_model_limits.cpp gui/Taranis/menu_model_logical_switches.cpp gui/menu_model_custom_functions.cpp gui/menu_model_telemetry.cpp -else - GUIMODELSRC = gui/menu_model.cpp gui/menu_model_select.cpp gui/menu_model_setup.cpp gui/menu_model_inputs_mixes.cpp gui/menu_model_limits.cpp gui/menu_model_logical_switches.cpp gui/menu_model_custom_functions.cpp gui/menu_model_telemetry.cpp -endif - +GUIMODELSRC = gui/menu_model.cpp gui/$(GUIDIRECTORY)/menu_model_select.cpp gui/$(GUIDIRECTORY)/menu_model_setup.cpp gui/$(GUIDIRECTORY)/menu_model_inputs_mixes.cpp gui/$(GUIDIRECTORY)/menu_model_limits.cpp gui/$(GUIDIRECTORY)/menu_model_logical_switches.cpp gui/$(GUIDIRECTORY)/menu_model_custom_functions.cpp gui/$(GUIDIRECTORY)/menu_model_telemetry.cpp GUIGENERALSRC = gui/menu_general.cpp gui/menu_general_setup.cpp gui/menu_general_trainer.cpp gui/menu_general_version.cpp gui/menu_general_diagkeys.cpp gui/menu_general_diaganas.cpp gui/menu_general_calib.cpp BITMAPS = bitmaps/sticks.lbm @@ -379,6 +374,7 @@ FONTS = $(patsubst %.png,%.lbm,$(wildcard fonts/std/*.png)) ifeq ($(PCB), $(filter $(PCB), STD 9X 9XR)) # 9x/9xr radio + GUIDIRECTORY = 9X ARCH = AVR LCDSIZE = 128 TRGT = avr- @@ -447,6 +443,7 @@ endif ifeq ($(PCB), $(filter $(PCB), STD128 9X128 9XR128)) # 9X/9XR radio with ATmega64 replaced by ATmega128 + GUIDIRECTORY = 9X ARCH = AVR LCDSIZE = 128 TRGT = avr- @@ -512,6 +509,7 @@ endif ifeq ($(PCB), $(filter $(PCB), 9X2561)) # 9X/9XR radio with ATmega64 replaced by ATmega2561 + GUIDIRECTORY = 9X ARCH = AVR LCDSIZE = 128 TRGT = avr- @@ -573,6 +571,7 @@ endif ifeq ($(PCB), GRUVIN9X) # 9x radio with a gruvin9x replacement board + GUIDIRECTORY = 9X FLAVOUR = gruvin9x ARCH = AVR LCDSIZE = 128 @@ -598,8 +597,8 @@ ifeq ($(PCB), GRUVIN9X) BITMAPS += bitmaps/9X/splash.lbm bitmaps/9X/asterisk.lbm bitmaps/9X/about.lbm ifeq ($(SDCARD), YES) - CPPDEFS += -DRTCLOCK - CPPSRC += rtc.cpp targets/gruvin9x/rtc_driver.cpp + CPPDEFS += -DRTCLOCK -DSDCARD + CPPSRC += rtc.cpp sdcard.cpp logs.cpp targets/gruvin9x/rtc_driver.cpp GUIGENERALSRC += gui/menu_general_sdmanager.cpp EXTRABOARDSRC += FatFs/ff.c FatFs/fattime.c FatFs/option/ccsbcs.c targets/gruvin9x/diskio.cpp endif @@ -622,6 +621,7 @@ endif ifeq ($(PCB), MEGA2560) # ARDUINO2560 DIY RADIO + GUIDIRECTORY = 9X FLAVOUR = mega2560 ARCH = AVR LCDSIZE = 128 @@ -648,9 +648,9 @@ ifeq ($(PCB), MEGA2560) ifeq ($(SDCARD), YES) EXTRABOARDSRC += FatFs/ff.c FatFs/fattime.c FatFs/option/ccsbcs.c targets/gruvin9x/diskio.cpp - CPPDEFS += -DRTCLOCK + CPPDEFS += -DSDCARD -DRTCLOCK GUIGENERALSRC += gui/menu_general_sdmanager.cpp - CPPSRC += rtc.cpp targets/gruvin9x/rtc_driver.cpp + CPPSRC += rtc.cpp sdcard.cpp logs.cpp targets/gruvin9x/rtc_driver.cpp endif ifeq ($(BUZZER), YES) @@ -671,6 +671,7 @@ endif ifeq ($(PCB), $(filter $(PCB), SKY9X 9XRPRO)) # 9x/9XR radio with a sky9x replacement board + GUIDIRECTORY = 9X ARCH = ARM LCDSIZE = 128 CPPDEFS = -Dat91sam3s4 @@ -726,8 +727,9 @@ ifeq ($(PCB), $(filter $(PCB), SKY9X 9XRPRO)) CPPSRC += loadboot.cpp debug.cpp BITMAPS += bitmaps/9X/splash.lbm bitmaps/9X/asterisk.lbm bitmaps/9X/about.lbm ifeq ($(SDCARD), YES) - CPPDEFS += -DVOICE + CPPDEFS += -DSDCARD -DVOICE INCDIRS += FatFs FatFs/option + CPPSRC += sdcard.cpp logs.cpp GUIGENERALSRC += gui/menu_general_sdmanager.cpp EXTRABOARDSRC += FatFs/ff.c FatFs/fattime.c FatFs/option/ccsbcs.c targets/sky9x/diskio.cpp endif @@ -752,6 +754,7 @@ ifeq ($(PCB), TARANIS) # TARANIS radio ARCH = ARM LCDSIZE = 212 + GUIDIRECTORY = Taranis ifeq ($(PCBREV), REV9E) FLAVOUR = taranis-x9e CPPDEFS = -DREVPLUS -DREV9E @@ -882,16 +885,11 @@ ifeq ($(PCB), TARANIS) CPPSRC += bin_allocator.cpp endif endif - ifeq ($(SDCARD), YES) - EXTRABOARDSRC += FatFs/ff.c FatFs/fattime.c FatFs/option/ccsbcs.c targets/taranis/diskio.cpp - GUIGENERALSRC += gui/menu_general_sdmanager.cpp - CPPDEFS += -DVOICE - INCDIRS += FatFs FatFs/option - endif - ifeq ($(RTCLOCK), YES) - CPPDEFS += -DRTCLOCK - CPPSRC += rtc.cpp targets/taranis/rtc_driver.cpp - endif + EXTRABOARDSRC += FatFs/ff.c FatFs/fattime.c FatFs/option/ccsbcs.c targets/taranis/diskio.cpp + CPPSRC += sdcard.cpp logs.cpp rtc.cpp targets/taranis/rtc_driver.cpp + GUIGENERALSRC += gui/menu_general_sdmanager.cpp + CPPDEFS += -DSDCARD -DVOICE -DRTCLOCK + INCDIRS += FatFs FatFs/option ifeq ($(DSM2), PPM) CPPSRC += pulses/dsm2_arm.cpp endif @@ -943,11 +941,7 @@ else TTS_SRC = $(shell sh -c "if test -f $(STD_TTS_SRC); then echo $(STD_TTS_SRC); else echo translations/tts_en.cpp; fi") endif -ifeq ($(PCB), TARANIS) - GUISRC = gui/menus.cpp $(GUIMODELSRC) $(GUIGENERALSRC) gui/Taranis/view_main.cpp gui/view_statistics.cpp -else - GUISRC = gui/menus.cpp $(GUIMODELSRC) $(GUIGENERALSRC) gui/view_main.cpp gui/view_statistics.cpp -endif +GUISRC = gui/menus.cpp $(GUIMODELSRC) $(GUIGENERALSRC) gui/$(GUIDIRECTORY)/view_main.cpp gui/view_statistics.cpp CPPSRC += opentx.cpp functions.cpp strhelpers.cpp $(PULSESSRC) switches.cpp curves.cpp mixer.cpp stamp.cpp $(GUISRC) $(EEPROMSRC) $(LCDSRC) keys.cpp maths.cpp translations.cpp fonts.cpp $(TTS_SRC) @@ -1054,16 +1048,12 @@ endif ifeq ($(FLIGHT_MODES), YES) CPPDEFS += -DFLIGHT_MODES - ifeq ($(PCB), TARANIS) - GUIMODELSRC += gui/Taranis/menu_model_flightmodes.cpp - else - GUIMODELSRC += gui/menu_model_flightmodes.cpp - endif + GUIMODELSRC += gui/$(GUIDIRECTORY)/menu_model_flightmodes.cpp endif ifeq ($(CURVES), YES) CPPDEFS += -DCURVES - GUIMODELSRC += gui/menu_model_curves.cpp + GUIMODELSRC += gui/$(GUIDIRECTORY)/menu_model_curves.cpp endif ifeq ($(GVARS), YES) @@ -1167,11 +1157,6 @@ ifeq ($(EEPROM_PROGRESS_BAR), YES) CPPDEFS += -DEEPROM_PROGRESS_BAR endif -ifeq ($(SDCARD), YES) - CPPDEFS += -DSDCARD - CPPSRC += logs.cpp -endif - RUN_FROM_FLASH = 1 ### Global Build-Option Directives ### @@ -1220,7 +1205,7 @@ ifeq ($(TEMPLATES), YES) ifneq ($(PCB), $(filter $(PCB), TARANIS)) CPPDEFS += -DTEMPLATES CPPSRC += templates.cpp - GUIMODELSRC += gui/menu_model_templates.cpp + GUIMODELSRC += gui/$(GUIDIRECTORY)/menu_model_templates.cpp endif endif diff --git a/radio/src/eeprom_common.cpp b/radio/src/eeprom_common.cpp index 33380a3216..e74980ac2a 100644 --- a/radio/src/eeprom_common.cpp +++ b/radio/src/eeprom_common.cpp @@ -48,6 +48,27 @@ void eeDirty(uint8_t msk) s_eeDirtyTime10ms = get_tmr10ms() ; } +uint8_t eeFindEmptyModel(uint8_t id, bool down) +{ + uint8_t i = id; + for (;;) { + i = (MAX_MODELS + (down ? i+1 : i-1)) % MAX_MODELS; + if (!eeModelExists(i)) break; + if (i == id) return 0xff; // no free space in directory left + } + return i; +} + +void selectModel(uint8_t sub) +{ + displayPopup(STR_LOADINGMODEL); + saveTimers(); + eeCheck(true); // force writing of current model data before this is changed + g_eeGeneral.currModel = sub; + eeDirty(EE_GENERAL); + eeLoadModel(sub); +} + #if defined(CPUARM) ModelHeader modelHeaders[MAX_MODELS]; void eeLoadModelHeaders() diff --git a/radio/src/eeprom_common.h b/radio/src/eeprom_common.h index 463c1fd65d..9f0b364335 100644 --- a/radio/src/eeprom_common.h +++ b/radio/src/eeprom_common.h @@ -59,6 +59,8 @@ void eeLoadModelName(uint8_t id, char *name); void eeLoadModel(uint8_t id); bool eeConvert(); void ConvertModel(int id, int version); +uint8_t eeFindEmptyModel(uint8_t id, bool down); +void selectModel(uint8_t sub); #if defined(CPUARM) extern ModelHeader modelHeaders[MAX_MODELS]; diff --git a/radio/src/eeprom_rlc.cpp b/radio/src/eeprom_rlc.cpp index fe5a1a3e6f..eb9203fb59 100644 --- a/radio/src/eeprom_rlc.cpp +++ b/radio/src/eeprom_rlc.cpp @@ -868,8 +868,8 @@ void RlcFile::DisplayProgressBar(uint8_t x) { if (s_eeDirtyMsk || isWriting() || eeprom_buffer_size) { uint8_t len = s_eeDirtyMsk ? 1 : limit((uint8_t)1, (uint8_t)(7 - (m_rlc_len/m_ratio)), (uint8_t)7); - lcd_filled_rect(x+1, 0, 5, FH, SOLID, ERASE); - lcd_filled_rect(x+2, 7-len, 3, len); + drawFilledRect(x+1, 0, 5, FH, SOLID, ERASE); + drawFilledRect(x+2, 7-len, 3, len); } } #endif diff --git a/radio/src/gui/9X/menu_model_curves.cpp b/radio/src/gui/9X/menu_model_curves.cpp new file mode 100644 index 0000000000..2650602f66 --- /dev/null +++ b/radio/src/gui/9X/menu_model_curves.cpp @@ -0,0 +1,274 @@ +/* + * Authors (alphabetical order) + * - Andre Bernet + * - Andreas Weitl + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Gabriel Birkus + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Thomas Husterer + * + * opentx is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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. + * + */ + +#include "../../opentx.h" + +uint8_t s_curveChan; + +int16_t curveFn(int16_t x) +{ + return applyCustomCurve(x, s_curveChan); +} + +struct point_t { + coord_t x; + coord_t y; +}; + +point_t getPoint(uint8_t i) +{ + point_t result = {0, 0}; + CurveInfo crv = curveInfo(s_curveChan); + int8_t *points = crv.crv; + bool custom = crv.custom; + uint8_t count = crv.points; + if (i < count) { + result.x = X0-1-WCHART+i*WCHART/(count/2); + result.y = (LCD_H-1) - (100 + points[i]) * (LCD_H-1) / 200; + if (custom && i>0 && i NUM_POINTS-5*MAX_CURVES) { + AUDIO_WARNING2(); + return false; + } + + int8_t *crv = curveAddress(index); + if (shift < 0) { + for (uint8_t i=0; i 4) + m_posHorz = -4; + for (uint8_t i=0; i 0) { + if (--s_editMode == 0) + m_posHorz = 0; + } + else { + popMenu(); + } + break; + + /* CASE_EVT_ROTARY_LEFT */ + case EVT_KEY_REPT(KEY_LEFT): + case EVT_KEY_FIRST(KEY_LEFT): + if (s_editMode==1 && m_posHorz>0) m_posHorz--; + if (s_editMode <= 0) { + if (crv.custom) { + moveCurve(s_curveChan, -crv.points+2); + } + else if (crv.points > MIN_POINTS) { + moveCurve(s_curveChan, -1, (crv.points+1)/2); + } + else { + AUDIO_WARNING2(); + } + return; + } + break; + + /* CASE_EVT_ROTARY_RIGHT */ + case EVT_KEY_REPT(KEY_RIGHT): + case EVT_KEY_FIRST(KEY_RIGHT): + if (s_editMode==1 && m_posHorz<(crv.points-1)) m_posHorz++; + if (s_editMode <= 0) { + if (!crv.custom) { + moveCurve(s_curveChan, crv.points-2, crv.points); + } + else if (crv.points < MAX_POINTS) { + if (moveCurve(s_curveChan, 1)) { + for (int8_t i=crv.points+crv.points-2; i>=0; i--) { + if (i%2) + crv.crv[i] = (crv.crv[i/2] + crv.crv[1+i/2]) / 2; + else + crv.crv[i] = crv.crv[i/2]; + } + } + } + else { + AUDIO_WARNING2(); + } + } + break; + } + + lcd_putsLeft(7*FH, STR_TYPE); + uint8_t attr = (s_editMode <= 0 ? INVERS : 0); + lcd_outdezAtt(5*FW-2, 7*FH, crv.points, LEFT|attr); + lcd_putsAtt(lcdLastPos, 7*FH, crv.custom ? PSTR("pt'") : PSTR("pt"), attr); + + DrawCurve(); + + if (s_editMode>0) { + uint8_t i = m_posHorz; + point_t point = getPoint(i); + + if (s_editMode==1 || !BLINK_ON_PHASE) { + // do selection square + drawFilledRect(point.x-1, point.y-2, 5, 5, SOLID, FORCE); + drawFilledRect(point.x, point.y-1, 3, 3, SOLID); + } + + int8_t x = -100 + 200*i/(crv.points-1); + if (crv.custom && i>0 && i= 212 - #define MODEL_CUSTOM_FUNC_1ST_COLUMN (4*FW+2) - #define MODEL_CUSTOM_FUNC_2ND_COLUMN (8*FW+2) - #define MODEL_CUSTOM_FUNC_3RD_COLUMN (21*FW) - #define MODEL_CUSTOM_FUNC_4TH_COLUMN (33*FW-3) - #define MODEL_CUSTOM_FUNC_4TH_COLUMN_ONOFF (34*FW-3) +#define MODEL_CUSTOM_FUNC_1ST_COLUMN (3) +#define MODEL_CUSTOM_FUNC_2ND_COLUMN (5*FW-2) +#define MODEL_CUSTOM_FUNC_3RD_COLUMN (15*FW+2) +#define MODEL_CUSTOM_FUNC_4TH_COLUMN (20*FW) +#if defined(GRAPHICS) + #define MODEL_CUSTOM_FUNC_4TH_COLUMN_ONOFF (20*FW) #else - #define MODEL_CUSTOM_FUNC_1ST_COLUMN (3) - #define MODEL_CUSTOM_FUNC_2ND_COLUMN (5*FW-2) - #define MODEL_CUSTOM_FUNC_3RD_COLUMN (15*FW+2) - #define MODEL_CUSTOM_FUNC_4TH_COLUMN (20*FW) - #if defined(GRAPHICS) - #define MODEL_CUSTOM_FUNC_4TH_COLUMN_ONOFF (20*FW) - #else - #define MODEL_CUSTOM_FUNC_4TH_COLUMN_ONOFF (18*FW+2) - #endif + #define MODEL_CUSTOM_FUNC_4TH_COLUMN_ONOFF (18*FW+2) #endif #if defined(CPUARM) && defined(SDCARD) @@ -78,50 +70,6 @@ void onCustomFunctionsFileSelectionMenu(const char *result) // The user choosed a file in the list memcpy(cf->play.name, result, sizeof(cf->play.name)); eeDirty(EE_MODEL); - if (func == FUNC_PLAY_SCRIPT) { - LUA_LOAD_MODEL_SCRIPTS(); - } - } -} -#endif - -#if defined(PCBTARANIS) -void onCustomFunctionsMenu(const char *result) -{ - int8_t sub = m_posVert-1; - CustomFunctionData * cfn; - uint8_t eeFlags; - - if (g_menuStack[g_menuStackPtr] == menuModelCustomFunctions) { - cfn = &g_model.customFn[sub]; - eeFlags = EE_MODEL; - } - else { - cfn = &g_eeGeneral.customFn[sub]; - eeFlags = EE_GENERAL; - } - - if (result == STR_COPY) { - clipboard.type = CLIPBOARD_TYPE_CUSTOM_FUNCTION; - clipboard.data.cfn = *cfn; - } - else if (result == STR_PASTE) { - *cfn = clipboard.data.cfn; - eeDirty(eeFlags); - } - else if (result == STR_CLEAR) { - memset(cfn, 0, sizeof(CustomFunctionData)); - eeDirty(eeFlags); - } - else if (result == STR_INSERT) { - memmove(cfn+1, cfn, (NUM_CFN-sub-1)*sizeof(CustomFunctionData)); - memset(cfn, 0, sizeof(CustomFunctionData)); - eeDirty(eeFlags); - } - else if (result == STR_DELETE) { - memmove(cfn, cfn+1, (NUM_CFN-sub-1)*sizeof(CustomFunctionData)); - memset(&g_model.customFn[NUM_CFN-1], 0, sizeof(CustomFunctionData)); - eeDirty(eeFlags); } } #endif @@ -136,36 +84,10 @@ void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFu uint8_t eeFlags = EE_MODEL; #endif -#if defined(PCBTARANIS) - if (sub>=0 && m_posHorz<0 && event==EVT_KEY_LONG(KEY_ENTER) && !READ_ONLY()) { - killEvents(event); - CustomFunctionData *cfn = &functions[sub]; - if (!CFN_EMPTY(cfn)) - MENU_ADD_ITEM(STR_COPY); - if (clipboard.type == CLIPBOARD_TYPE_CUSTOM_FUNCTION) - MENU_ADD_ITEM(STR_PASTE); - if (!CFN_EMPTY(cfn) && CFN_EMPTY(&functions[NUM_CFN-1])) - MENU_ADD_ITEM(STR_INSERT); - if (!CFN_EMPTY(cfn)) - MENU_ADD_ITEM(STR_CLEAR); - for (int i=sub+1; i= 212 - putsStrIdx(0, y, functions == g_model.customFn ? STR_SF : STR_GF, k+1, (sub==k && m_posHorz<0) ? INVERS : 0); -#endif - CustomFunctionData *cfn = &functions[k]; uint8_t func = CFN_FUNC(cfn); for (uint8_t j=0; j<5; j++) { @@ -296,11 +218,7 @@ void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFu #endif #if defined(CPUARM) && defined(SDCARD) else if (func == FUNC_PLAY_TRACK || func == FUNC_BACKGND_MUSIC || func == FUNC_PLAY_SCRIPT) { -#if LCD_W >= 212 - coord_t x = MODEL_CUSTOM_FUNC_3RD_COLUMN; -#else coord_t x = (func == FUNC_PLAY_TRACK ? MODEL_CUSTOM_FUNC_2ND_COLUMN + FW + FW*strlen(TR_PLAY_TRACK) : MODEL_CUSTOM_FUNC_3RD_COLUMN); -#endif if (ZEXIST(cfn->play.name)) lcd_putsnAtt(x, y, cfn->play.name, sizeof(cfn->play.name), attr); else @@ -379,14 +297,6 @@ void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFu } } #endif -#if defined(PCBTARANIS) && defined(REVPLUS) - else if (func == FUNC_BACKLIGHT) { - displaySlider(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, CFN_PARAM(cfn), 100, attr); - INCDEC_SET_FLAG(eeFlags | NO_INCDEC_MARKS); - val_min = 0; - val_max = 100; - } -#endif #if defined(GVARS) else if (func == FUNC_ADJUST_GVAR) { switch (CFN_GVAR_MODE(cfn)) { @@ -444,27 +354,15 @@ void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFu } else if (HAS_REPEAT_PARAM(func)) { if (CFN_PLAY_REPEAT(cfn) == 0) { -#if LCD_W >= 212 - lcd_putsAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2, y, "1x", attr); -#else lcd_putcAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN_ONOFF+3, y, '-', attr); -#endif } #if defined(CPUARM) else if (CFN_PLAY_REPEAT(cfn) == CFN_PLAY_REPEAT_NOSTART) { -#if LCD_W >= 212 - lcd_putcAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN-1, y, '!', attr); - lcd_putsAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2, y, "1x", attr); -#else lcd_putsAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN_ONOFF, y, "!-", attr); -#endif } #endif else { lcd_outdezAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2+FW, y, CFN_PLAY_REPEAT(cfn)*CFN_PLAY_REPEAT_MUL, attr); -#if LCD_W >= 212 - lcd_putcAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2+FW, y, 's', attr); -#endif } #if defined(CPUARM) if (active) CFN_PLAY_REPEAT(cfn) = checkIncDec(event, CFN_PLAY_REPEAT(cfn)==CFN_PLAY_REPEAT_NOSTART?-1:CFN_PLAY_REPEAT(cfn), -1, 60/CFN_PLAY_REPEAT_MUL, eeFlags); diff --git a/radio/src/gui/menu_model_flightmodes.cpp b/radio/src/gui/9X/menu_model_flightmodes.cpp old mode 100755 new mode 100644 similarity index 99% rename from radio/src/gui/menu_model_flightmodes.cpp rename to radio/src/gui/9X/menu_model_flightmodes.cpp index fa68c52b11..2e3f23cc56 --- a/radio/src/gui/menu_model_flightmodes.cpp +++ b/radio/src/gui/9X/menu_model_flightmodes.cpp @@ -33,7 +33,7 @@ * */ -#include "../opentx.h" +#include "../../opentx.h" void displayFlightModes(coord_t x, coord_t y, FlightModesType value) diff --git a/radio/src/gui/menu_model_inputs_mixes.cpp b/radio/src/gui/9X/menu_model_inputs_mixes.cpp old mode 100755 new mode 100644 similarity index 77% rename from radio/src/gui/menu_model_inputs_mixes.cpp rename to radio/src/gui/9X/menu_model_inputs_mixes.cpp index 65dcf33f58..77cbbc8ec8 --- a/radio/src/gui/menu_model_inputs_mixes.cpp +++ b/radio/src/gui/9X/menu_model_inputs_mixes.cpp @@ -33,15 +33,10 @@ * */ -#include "../opentx.h" +#include "../../opentx.h" -#if LCD_W >= 212 - #define EXPO_ONE_2ND_COLUMN (LCD_W-8*FW-90) - #define EXPO_ONE_FM_WIDTH (9*FW) -#else - #define EXPO_ONE_2ND_COLUMN (7*FW+3*FW+2) - #define EXPO_ONE_FM_WIDTH (5*FW) -#endif +#define EXPO_ONE_2ND_COLUMN (7*FW+3*FW+2) +#define EXPO_ONE_FM_WIDTH (5*FW) #if defined(FLIGHT_MODES) void displayFlightModes(coord_t x, coord_t y, FlightModesType value); @@ -51,28 +46,16 @@ FlightModesType editFlightModes(coord_t x, coord_t y, uint8_t event, FlightModes uint8_t posHorz = m_posHorz; -#if defined(CPUARM) && LCD_W < 212 +#if defined(CPUARM) bool expoMenu = (x==EXPO_ONE_2ND_COLUMN-5*FW); #endif for (uint8_t p=0; p EXPO_ONE_2ND_COLUMN-FW))) continue; #endif -#if defined(PCBTARANIS) - LcdFlags flags = 0; - if (attr) { - flags |= INVERS; - if (posHorz==p) flags |= BLINK; - } - if (value & (1<srcRaw, x); -#else anas[ed->chn] = x; applyExpos(anas, e_perout_mode_inactive_flight_mode); -#endif return anas[ed->chn]; } @@ -155,16 +134,8 @@ void deleteExpoMix(uint8_t expo, uint8_t idx) pauseMixerCalculations(); if (expo) { ExpoData *expo = expoAddress(idx); -#if defined(PCBTARANIS) - int input = expo->chn; -#endif memmove(expo, expo+1, (MAX_EXPOS-(idx+1))*sizeof(ExpoData)); memclear(&g_model.expoData[MAX_EXPOS-1], sizeof(ExpoData)); -#if defined(PCBTARANIS) - if (!isInputAvailable(input)) { - memclear(&g_model.inputNames[input], LEN_INPUT_NAME); - } -#endif } else { MixData *mix = mixAddress(idx); @@ -184,10 +155,6 @@ void insertExpoMix(uint8_t expo, uint8_t idx) ExpoData *expo = expoAddress(idx); memmove(expo+1, expo, (MAX_EXPOS-(idx+1))*sizeof(ExpoData)); memclear(expo, sizeof(ExpoData)); -#if defined(PCBTARANIS) - expo->srcRaw = (s_currCh > 4 ? MIXSRC_Rud - 1 + s_currCh : MIXSRC_Rud - 1 + channel_order(s_currCh)); - expo->curve.type = CURVE_REF_EXPO; -#endif expo->mode = 3; // pos&neg expo->chn = s_currCh - 1; expo->weight = 100; @@ -197,13 +164,7 @@ void insertExpoMix(uint8_t expo, uint8_t idx) memmove(mix+1, mix, (MAX_MIXERS-(idx+1))*sizeof(MixData)); memclear(mix, sizeof(MixData)); mix->destCh = s_currCh-1; -#if defined(PCBTARANIS) - mix->srcRaw = s_currCh; - if (!isSourceAvailable(mix->srcRaw)) - mix->srcRaw = (s_currCh > 4 ? MIXSRC_Rud - 1 + s_currCh : MIXSRC_Rud - 1 + channel_order(s_currCh)); -#else mix->srcRaw = (s_currCh > 4 ? MIXSRC_Rud - 1 + s_currCh : MIXSRC_Rud - 1 + channel_order(s_currCh)); -#endif mix->weight = 100; } resumeMixerCalculations(); @@ -319,44 +280,24 @@ bool swapExpoMix(uint8_t expo, uint8_t &idx, uint8_t up) } enum ExposFields { - CASE_PCBTARANIS(EXPO_FIELD_INPUT_NAME) CASE_CPUARM(EXPO_FIELD_NAME) - CASE_PCBTARANIS(EXPO_FIELD_SOURCE) - CASE_PCBTARANIS(EXPO_FIELD_SCALE) EXPO_FIELD_WEIGHT, - CASE_PCBTARANIS(EXPO_FIELD_OFFSET) CASE_9X(EXPO_FIELD_EXPO) CASE_CURVES(EXPO_FIELD_CURVE) CASE_FLIGHT_MODES(EXPO_FIELD_FLIGHT_MODES) EXPO_FIELD_SWITCH, EXPO_FIELD_SIDE, - CASE_PCBTARANIS(EXPO_FIELD_TRIM) EXPO_FIELD_MAX }; -#if defined(PCBTARANIS) - #define CURVE_ROWS 1 -#else - #define CURVE_ROWS 0 -#endif +#define CURVE_ROWS 0 void menuModelExpoOne(uint8_t event) { -#if defined(PCBTARANIS) - if (event == EVT_KEY_LONG(KEY_MENU)) { - pushMenu(menuChannelsView); - killEvents(event); - } -#endif - ExpoData *ed = expoAddress(s_currIdx); -#if defined(PCBTARANIS) - putsMixerSource(7*FW+FW/2, 0, MIXSRC_FIRST_INPUT+ed->chn, 0); -#else putsMixerSource(7*FW+FW/2, 0, MIXSRC_Rud+ed->chn, 0); -#endif - SUBMENU(STR_MENUINPUTS, EXPO_FIELD_MAX, {CASE_PCBTARANIS(0) CASE_CPUARM(0) CASE_PCBTARANIS(0) CASE_PCBTARANIS((ed->srcRaw >= MIXSRC_FIRST_TELEM ? (uint8_t)0 : (uint8_t)HIDDEN_ROW)) 0, CASE_PCBTARANIS(0) CASE_9X(0) CASE_CURVES(CURVE_ROWS) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0 /*, ...*/}); + SUBMENU(STR_MENUINPUTS, EXPO_FIELD_MAX, {CASE_CPUARM(0) 0, 0, CASE_CURVES(CURVE_ROWS) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0 /*, ...*/}); SET_SCROLLBAR_X(EXPO_ONE_2ND_COLUMN+10*FW); @@ -364,59 +305,21 @@ void menuModelExpoOne(uint8_t event) coord_t y = MENU_TITLE_HEIGHT + 1; -#if defined(PCBTARANIS) - for (unsigned int k=0; k0 ? BLINK|INVERS : INVERS) : 0); switch(i) { -#if defined(PCBTARANIS) - case EXPO_FIELD_INPUT_NAME: - editSingleName(EXPO_ONE_2ND_COLUMN, y, STR_INPUTNAME, g_model.inputNames[ed->chn], sizeof(g_model.inputNames[ed->chn]), event, attr); - break; -#endif - #if defined(CPUARM) case EXPO_FIELD_NAME: editSingleName(EXPO_ONE_2ND_COLUMN-IF_9X(sizeof(ed->name)*FW), y, STR_EXPONAME, ed->name, sizeof(ed->name), event, attr); break; #endif -#if defined(PCBTARANIS) - case EXPO_FIELD_SOURCE: - lcd_putsLeft(y, NO_INDENT(STR_SOURCE)); - putsMixerSource(EXPO_ONE_2ND_COLUMN, y, ed->srcRaw, STREXPANDED|attr); - if (attr) ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isInputSourceAvailable); - break; - - case EXPO_FIELD_SCALE: - lcd_putsLeft(y, STR_SCALE); - putsTelemetryChannelValue(EXPO_ONE_2ND_COLUMN, y, ed->srcRaw - MIXSRC_FIRST_TELEM, convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale), LEFT|attr); - if (attr) ed->scale = checkIncDec(event, ed->scale, 0, maxTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1), EE_MODEL); - break; -#endif - case EXPO_FIELD_WEIGHT: lcd_putsLeft(y, STR_WEIGHT); - ed->weight = GVAR_MENU_ITEM(EXPO_ONE_2ND_COLUMN, y, ed->weight, MIN_EXPO_WEIGHT, 100, IF_PCBTARANIS(LEFT)|attr, 0, event); + ed->weight = GVAR_MENU_ITEM(EXPO_ONE_2ND_COLUMN, y, ed->weight, MIN_EXPO_WEIGHT, 100, attr, 0, event); break; -#if defined(PCBTARANIS) - case EXPO_FIELD_OFFSET: - lcd_putsLeft(y, NO_INDENT(STR_OFFSET)); - ed->offset = GVAR_MENU_ITEM(EXPO_ONE_2ND_COLUMN, y, ed->offset, -100, 100, LEFT|attr, 0, event); - break; -#endif - -#if !defined(PCBTARANIS) case EXPO_FIELD_EXPO: lcd_putsLeft(y, STR_EXPO); if (ed->curveMode==MODE_EXPO || ed->curveParam==0) { @@ -427,14 +330,10 @@ void menuModelExpoOne(uint8_t event) lcd_putsAtt(EXPO_ONE_2ND_COLUMN-3*FW, y, STR_NA, attr); } break; -#endif #if defined(CURVES) case EXPO_FIELD_CURVE: lcd_putsLeft(y, STR_CURVE); -#if defined(PCBTARANIS) - editCurveRef(EXPO_ONE_2ND_COLUMN, y, ed->curve, event, attr); -#else if (ed->curveMode!=MODE_EXPO || ed->curveParam==0) { putsCurve(EXPO_ONE_2ND_COLUMN-3*FW, y, ed->curveParam, attr); if (attr) { @@ -449,7 +348,6 @@ void menuModelExpoOne(uint8_t event) else { lcd_putsAtt(EXPO_ONE_2ND_COLUMN-3*FW, y, STR_NA, attr); } -#endif break; #endif @@ -466,41 +364,16 @@ void menuModelExpoOne(uint8_t event) case EXPO_FIELD_SIDE: ed->mode = 4 - selectMenuItem(EXPO_ONE_2ND_COLUMN-IF_9X(3*FW), y, STR_SIDE, STR_VSIDE, 4-ed->mode, 1, 3, attr, event); break; - -#if defined(PCBTARANIS) - case EXPO_FIELD_TRIM: - uint8_t not_stick = (ed->srcRaw > MIXSRC_Ail); - int8_t carryTrim = -ed->carryTrim; - lcd_putsLeft(y, STR_TRIM); - lcd_putsiAtt(EXPO_ONE_2ND_COLUMN, y, STR_VMIXTRIMS, (not_stick && carryTrim == 0) ? 0 : carryTrim+1, m_posHorz==0 ? attr : 0); - if (attr) ed->carryTrim = -checkIncDecModel(event, carryTrim, not_stick ? TRIM_ON : -TRIM_OFF, -TRIM_AIL); - break; -#endif } y += FH; } DrawFunction(expoFn); -#if defined(PCBTARANIS) - int x512 = getValue(ed->srcRaw); - if (ed->srcRaw >= MIXSRC_FIRST_TELEM) { - putsTelemetryChannelValue(LCD_W-8, 6*FH, ed->srcRaw - MIXSRC_FIRST_TELEM, x512, 0); - if (ed->scale > 0) x512 = (x512 * 1024) / convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale); - } - else { - lcd_outdezAtt(LCD_W-8, 6*FH, calcRESXto1000(x512), PREC1); - } - x512 = limit(-1024, x512, 1024); - int y512 = expoFn(x512); - y512 = limit(-1024, y512, 1024); - lcd_outdezAtt(LCD_W-8-6*FW, 1*FH, calcRESXto1000(y512), PREC1); -#else int16_t x512 = calibratedStick[ed->chn]; lcd_outdezAtt(LCD_W-8, 6*FH, calcRESXto100(x512), 0); int16_t y512 = expoFn(x512); lcd_outdezAtt(LCD_W-8-6*FW, 1*FH, calcRESXto100(y512), 0); -#endif #if defined(CPUARM) x512 = X0+x512/(RESX/WCHART); @@ -569,7 +442,7 @@ void drawOffsetBar(uint8_t x, uint8_t y, MixData * md) if (barMin <= barMax) { int8_t right = (barMax * GAUGE_WIDTH) / 200; int8_t left = ((barMin * GAUGE_WIDTH) / 200)-1; - lcd_filled_rect(x+GAUGE_WIDTH/2+left, y+2, right-left, GAUGE_HEIGHT-3); + drawFilledRect(x+GAUGE_WIDTH/2+left, y+2, right-left, GAUGE_HEIGHT-3); } lcd_vline(x+GAUGE_WIDTH/2-1, y, GAUGE_HEIGHT+1); if (barMin == -101) { @@ -591,13 +464,6 @@ void drawOffsetBar(uint8_t x, uint8_t y, MixData * md) void menuModelMixOne(uint8_t event) { -#if defined(PCBTARANIS) - if (event == EVT_KEY_LONG(KEY_MENU)) { - pushMenu(menuChannelsView); - killEvents(event); - } -#endif - TITLE(s_currCh ? STR_INSERTMIX : STR_EDITMIX); MixData *md2 = mixAddress(s_currIdx) ; putsChn(lcdLastPos+1*FW, 0, md2->destCh+1,0); @@ -612,7 +478,7 @@ void menuModelMixOne(uint8_t event) else SUBMENU_NOTITLE(MIX_FIELD_COUNT, {CASE_CPUARM(0) 0, 0, 0, CASE_9X(1) CASE_CURVES(1) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0, 0 /*, ...*/}); #else - SUBMENU_NOTITLE(MIX_FIELD_COUNT, {CASE_CPUARM(0) 0, 0, 0, CASE_9X(1) CASE_PCBTARANIS(0) CASE_CURVES(1) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0, 0 /*, ...*/}); + SUBMENU_NOTITLE(MIX_FIELD_COUNT, {CASE_CPUARM(0) 0, 0, 0, CASE_9X(1) CASE_CURVES(1) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0, 0 /*, ...*/}); #endif #if MENU_COLUMNS > 1 @@ -670,13 +536,6 @@ void menuModelMixOne(uint8_t event) break; } -#if defined(PCBTARANIS) - case MIX_FIELD_TRIM: - lcd_putsColumnLeft(COLUMN_X, y, STR_TRIM); - menu_lcd_onoff(COLUMN_X+MIXES_2ND_COLUMN, y, !md2->carryTrim, attr); - if (attr) md2->carryTrim = !checkIncDecModel(event, !md2->carryTrim, 0, 1); - break; -#else case MIX_FIELD_TRIM: { uint8_t not_stick = (md2->srcRaw > NUM_STICKS); @@ -694,15 +553,11 @@ void menuModelMixOne(uint8_t event) } break; } -#endif #if defined(CURVES) case MIX_FIELD_CURVE: { lcd_putsColumnLeft(COLUMN_X, y, STR_CURVE); -#if defined(PCBTARANIS) - editCurveRef(COLUMN_X+MIXES_2ND_COLUMN, y, md2->curve, event, attr); -#else int8_t curveParam = md2->curveParam; if (md2->curveMode == MODE_CURVE) { putsCurve(COLUMN_X+MIXES_2ND_COLUMN, y, curveParam, attr); @@ -715,11 +570,6 @@ void menuModelMixOne(uint8_t event) CHECK_INCDEC_MODELVAR(event, md2->curveParam, -MAX_CURVES, CURVE_BASE+MAX_CURVES-1); if (md2->curveParam == 0) md2->curveMode = MODE_DIFFERENTIAL; -#if defined(ROTARY_ENCODER_NAVIGATION) || defined(PCBTARANIS) - MOVE_CURSOR_FROM_HERE(); -#else - m_posHorz = 0; -#endif } } } @@ -735,7 +585,6 @@ void menuModelMixOne(uint8_t event) } } } -#endif break; } #endif @@ -781,23 +630,7 @@ static uint8_t s_copySrcCh; #define _STR_MAX(x) PSTR("/" #x) #define STR_MAX(x) _STR_MAX(x) -#if LCD_W >= 212 - #define EXPO_LINE_WEIGHT_POS 8*FW+8 - #define EXPO_LINE_SRC_POS 9*FW+3 - #define EXPO_LINE_CURVE_POS 12*FW+11 - #define EXPO_LINE_TRIM_POS 19*FW-4 - #define EXPO_LINE_SWITCH_POS 20*FW-1 - #define EXPO_LINE_SIDE_POS 25*FW - #define EXPO_LINE_FM_POS 12*FW+11 - #define EXPO_LINE_SELECT_POS 5*FW+2 - #define EXPO_LINE_NAME_POS LCD_W-LEN_EXPOMIX_NAME*FW-MENUS_SCROLLBAR_WIDTH - #define MIX_LINE_WEIGHT_POS 6*FW+8 - #define MIX_LINE_SRC_POS 7*FW+3 - #define MIX_LINE_CURVE_POS 13*FW+3 - #define MIX_LINE_SWITCH_POS 19*FW+1 - #define MIX_LINE_FM_POS 13*FW+3 - #define MIX_LINE_DELAY_POS 24*FW+3 -#elif defined(CPUARM) +#if defined(CPUARM) #define EXPO_LINE_WEIGHT_POS 7*FW+1 #define EXPO_LINE_EXPO_POS 10*FW+5 #define EXPO_LINE_SWITCH_POS 11*FW+2 @@ -857,49 +690,21 @@ void onExpoMixMenu(const char *result) } #endif -#if LCD_W >= 212 -void displayHeaderChannelName(uint8_t ch) -{ - uint8_t len = zlen(g_model.limitData[ch-1].name, sizeof(g_model.limitData[ch-1].name)); - if (len) { - lcd_putc(17*FW, 0, ' '); - lcd_putsnAtt(lcdNextPos, 0, g_model.limitData[ch-1].name, len, ZCHAR); - lcd_putc(lcdNextPos, 0, ' '); - } -} -#endif - void displayMixInfos(coord_t y, MixData *md) { -#if defined(PCBTARANIS) - putsCurveRef(MIX_LINE_CURVE_POS, y, md->curve, 0); -#else if (md->curveParam) { if (md->curveMode == MODE_CURVE) putsCurve(MIX_LINE_CURVE_POS, y, md->curveParam); else displayGVar(MIX_LINE_CURVE_POS+3*FW, y, md->curveParam, -100, 100); } -#endif if (md->swtch) { putsSwitches(MIX_LINE_SWITCH_POS, y, md->swtch); } } -#if defined(PCBTARANIS) -void displayMixLine(coord_t y, MixData *md) -{ - if (md->name[0]) { - lcd_putsnAtt(EXPO_LINE_NAME_POS, y, md->name, sizeof(md->name), ZCHAR); - } - - if (!md->flightModes || ((md->curve.value || md->swtch) && ((get_tmr10ms() / 200) & 1))) - displayMixInfos(y, md); - else - displayFlightModes(MIX_LINE_FM_POS, y, md->flightModes); -} -#elif defined(CPUARM) +#if defined(CPUARM) void displayMixLine(coord_t y, MixData *md) { if (md->name[0]) { @@ -915,55 +720,15 @@ void displayMixLine(coord_t y, MixData *md) void displayExpoInfos(coord_t y, ExpoData *ed) { -#if defined(PCBTARANIS) - putsCurveRef(EXPO_LINE_CURVE_POS, y, ed->curve, 0); -#else if (ed->curveMode == MODE_CURVE) putsCurve(EXPO_LINE_EXPO_POS-3*FW, y, ed->curveParam); else displayGVar(EXPO_LINE_EXPO_POS, y, ed->curveParam, -100, 100); -#endif putsSwitches(EXPO_LINE_SWITCH_POS, y, ed->swtch, 0); } -#if defined(PCBHORUS) -void displayExpoLine(coord_t y, ExpoData *ed) -{ - putsMixerSource(EXPO_LINE_SRC_POS, y, ed->srcRaw, 0); - - if (ed->carryTrim != TRIM_ON) { - lcd_putc(EXPO_LINE_TRIM_POS, y, ed->carryTrim > 0 ? '-' : STR_RETA123[-ed->carryTrim]); - } - - if (!ed->flightModes || ((ed->curve.value || ed->swtch) && ((get_tmr10ms() / 200) & 1))) - displayExpoInfos(y, ed); - else - displayFlightModes(EXPO_LINE_FM_POS, y, ed->flightModes); - - if (ed->name[0]) { - lcd_putsnAtt(EXPO_LINE_NAME_POS, y, ed->name, sizeof(ed->name), ZCHAR); - } -} -#elif defined(PCBTARANIS) -void displayExpoLine(coord_t y, ExpoData *ed) -{ - putsMixerSource(EXPO_LINE_SRC_POS, y, ed->srcRaw, 0); - - if (ed->carryTrim != TRIM_ON) { - lcd_putc(EXPO_LINE_TRIM_POS, y, ed->carryTrim > 0 ? '-' : STR_RETA123[-ed->carryTrim]); - } - - if (!ed->flightModes || ((ed->curve.value || ed->swtch) && ((get_tmr10ms() / 200) & 1))) - displayExpoInfos(y, ed); - else - displayFlightModes(EXPO_LINE_FM_POS, y, ed->flightModes); - - if (ed->name[0]) { - lcd_putsnAtt(EXPO_LINE_NAME_POS, y, ed->name, sizeof(ed->name), ZCHAR); - } -} -#elif defined(CPUARM) +#if defined(CPUARM) void displayExpoLine(coord_t y, ExpoData *ed) { displayExpoInfos(y, ed); @@ -1129,18 +894,11 @@ void menuModelExpoMix(uint8_t expo, uint8_t event) break; } -#if !defined(PCBHORUS) lcd_outdezAtt(FW*max(sizeof(TR_MENUINPUTS), sizeof(TR_MIXER))+FW+FW/2, 0, getExpoMixCount(expo)); lcd_puts(FW*max(sizeof(TR_MENUINPUTS), sizeof(TR_MIXER))+FW+FW/2, 0, expo ? STR_MAX(MAX_EXPOS) : STR_MAX(MAX_MIXERS)); -#endif SIMPLE_MENU(expo ? STR_MENUINPUTS : STR_MIXER, menuTabModel, expo ? e_InputsAll : e_MixAll, s_maxLines); -#if defined(PCBHORUS) - lcd_outdezAtt(15+10*max(sizeof(TR_MENUINPUTS), sizeof(TR_MIXER)), 6, getExpoMixCount(expo), MIDSIZE|WHITE); - lcd_putsAtt(15+10*max(sizeof(TR_MENUINPUTS), sizeof(TR_MIXER)), 6, expo ? STR_MAX(MAX_EXPOS) : STR_MAX(MAX_MIXERS), MIDSIZE|WHITE); -#endif - sub = m_posVert; s_currCh = 0; uint8_t cur = 1; @@ -1152,11 +910,7 @@ void menuModelExpoMix(uint8_t expo, uint8_t event) if (expo ? (ichn+1 == ch && EXPO_VALID(ed)) : (isrcRaw && md->destCh+1 == ch)) { if (s_pgOfs < cur && cur-s_pgOfs < LCD_LINES) { if (expo) { -#if defined(PCBTARANIS) - putsMixerSource(0, y, ch, 0); -#else putsMixerSource(0, y, MIXSRC_Rud+ch-1, 0); -#endif } else { putsChn(0, y, ch, 0); // show CHx @@ -1187,12 +941,6 @@ void menuModelExpoMix(uint8_t expo, uint8_t event) } } else { -#if LCD_W >= 212 - if (attr) { - displayHeaderChannelName(ch); - } -#endif - if (mixCnt > 0) lcd_putsiAtt(FW, y, STR_VMLTPX2, md->mltpx, 0); putsMixerSource(MIX_LINE_SRC_POS, y, md->srcRaw, 0); @@ -1215,7 +963,7 @@ void menuModelExpoMix(uint8_t expo, uint8_t event) } if (cur == sub) { /* invert the raw when it's the current one */ - lcd_filled_rect(expo ? EXPO_LINE_SELECT_POS+1 : 23, y, expo ? (LCD_W-EXPO_LINE_SELECT_POS-2) : (LCD_W-24), 7); + drawFilledRect(expo ? EXPO_LINE_SELECT_POS+1 : 23, y, expo ? (LCD_W-EXPO_LINE_SELECT_POS-2) : (LCD_W-24), 7); } } } @@ -1237,19 +985,10 @@ void menuModelExpoMix(uint8_t expo, uint8_t event) } if (s_pgOfs < cur && cur-s_pgOfs < LCD_LINES) { if (expo) { -#if defined(PCBTARANIS) - putsMixerSource(0, y, ch, attr); -#else putsMixerSource(0, y, MIXSRC_Rud+ch-1, attr); -#endif } else { putsChn(0, y, ch, attr); // show CHx -#if LCD_W >= 212 - if (attr) { - displayHeaderChannelName(ch); - } -#endif } if (s_copyMode == MOVE_MODE && s_copySrcCh == ch) { lcd_rect(expo ? EXPO_LINE_SELECT_POS : 22, y-1, expo ? (LCD_W-EXPO_LINE_SELECT_POS) : (LCD_W-22), 9, DOTTED); diff --git a/radio/src/gui/menu_model_limits.cpp b/radio/src/gui/9X/menu_model_limits.cpp old mode 100755 new mode 100644 similarity index 99% rename from radio/src/gui/menu_model_limits.cpp rename to radio/src/gui/9X/menu_model_limits.cpp index 5876bc98d2..e2911c0607 --- a/radio/src/gui/menu_model_limits.cpp +++ b/radio/src/gui/9X/menu_model_limits.cpp @@ -33,7 +33,7 @@ * */ -#include "../opentx.h" +#include "../../opentx.h" bool isThrottleOutput(uint8_t ch) { diff --git a/radio/src/gui/menu_model_logical_switches.cpp b/radio/src/gui/9X/menu_model_logical_switches.cpp old mode 100755 new mode 100644 similarity index 99% rename from radio/src/gui/menu_model_logical_switches.cpp rename to radio/src/gui/9X/menu_model_logical_switches.cpp index cf4f626979..75f85f05b5 --- a/radio/src/gui/menu_model_logical_switches.cpp +++ b/radio/src/gui/9X/menu_model_logical_switches.cpp @@ -33,7 +33,7 @@ * */ -#include "../opentx.h" +#include "../../opentx.h" enum LogicalSwitchFields { LS_FIELD_FUNCTION, diff --git a/radio/src/gui/menu_model_select.cpp b/radio/src/gui/9X/menu_model_select.cpp old mode 100755 new mode 100644 similarity index 57% rename from radio/src/gui/menu_model_select.cpp rename to radio/src/gui/9X/menu_model_select.cpp index aae55068ca..b135769887 --- a/radio/src/gui/menu_model_select.cpp +++ b/radio/src/gui/9X/menu_model_select.cpp @@ -33,183 +33,10 @@ * */ -#include "../opentx.h" +#include "../../opentx.h" -uint8_t eeFindEmptyModel(uint8_t id, bool down) -{ - uint8_t i = id; - for (;;) { - i = (MAX_MODELS + (down ? i+1 : i-1)) % MAX_MODELS; - if (!eeModelExists(i)) break; - if (i == id) return 0xff; // no free space in directory left - } - return i; -} - -void selectModel(uint8_t sub) -{ - displayPopup(STR_LOADINGMODEL); - saveTimers(); - eeCheck(true); // force writing of current model data before this is changed - g_eeGeneral.currModel = sub; - eeDirty(EE_GENERAL); - eeLoadModel(sub); -} - -#if defined(SDCARD) -#define LIST_NONE_SD_FILE 1 -bool listSdFiles(const char *path, const char *extension, const uint8_t maxlen, const char *selection, uint8_t flags=0) -{ - FILINFO fno; - DIR dir; - char *fn; /* This function is assuming non-Unicode cfg. */ -#if _USE_LFN - TCHAR lfn[_MAX_LFN + 1]; - fno.lfname = lfn; - fno.lfsize = sizeof(lfn); -#endif - - static uint16_t s_last_menu_offset = 0; - -#if defined(CPUARM) - static uint8_t s_last_flags; - - if (selection) { - s_last_flags = flags; - memset(reusableBuffer.modelsel.menu_bss, 0, sizeof(reusableBuffer.modelsel.menu_bss)); - strcpy(reusableBuffer.modelsel.menu_bss[0], path); - strcat(reusableBuffer.modelsel.menu_bss[0], "/"); - strncat(reusableBuffer.modelsel.menu_bss[0], selection, maxlen); - strcat(reusableBuffer.modelsel.menu_bss[0], extension); - if (f_stat(reusableBuffer.modelsel.menu_bss[0], &fno) != FR_OK) { - selection = NULL; - } - } - else { - flags = s_last_flags; - } -#endif - - if (s_menu_offset == 0) { - s_last_menu_offset = 0; - memset(reusableBuffer.modelsel.menu_bss, 0, sizeof(reusableBuffer.modelsel.menu_bss)); - } - else if (s_menu_offset == s_menu_count - MENU_MAX_LINES) { - s_last_menu_offset = 0xffff; - memset(reusableBuffer.modelsel.menu_bss, 0, sizeof(reusableBuffer.modelsel.menu_bss)); - } - else if (s_menu_offset == s_last_menu_offset) { - // should not happen, only there because of Murphy's law - return true; - } - else if (s_menu_offset > s_last_menu_offset) { - memmove(reusableBuffer.modelsel.menu_bss[0], reusableBuffer.modelsel.menu_bss[1], (MENU_MAX_LINES-1)*MENU_LINE_LENGTH); - memset(reusableBuffer.modelsel.menu_bss[MENU_MAX_LINES-1], 0xff, MENU_LINE_LENGTH); - } - else { - memmove(reusableBuffer.modelsel.menu_bss[1], reusableBuffer.modelsel.menu_bss[0], (MENU_MAX_LINES-1)*MENU_LINE_LENGTH); - memset(reusableBuffer.modelsel.menu_bss[0], 0, MENU_LINE_LENGTH); - } - - s_menu_count = 0; - s_menu_flags = BSS; - - FRESULT res = f_opendir(&dir, path); /* Open the directory */ - if (res == FR_OK) { - - if (flags & LIST_NONE_SD_FILE) { - s_menu_count++; - if (selection) { - s_last_menu_offset++; - } - else if (s_menu_offset==0 || s_menu_offset < s_last_menu_offset) { - char *line = reusableBuffer.modelsel.menu_bss[0]; - memset(line, 0, MENU_LINE_LENGTH); - strcpy(line, "---"); - s_menu[0] = line; - } - } - - for (;;) { - res = f_readdir(&dir, &fno); /* Read a directory item */ - if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ - -#if _USE_LFN - fn = *fno.lfname ? fno.lfname : fno.fname; -#else - fn = fno.fname; -#endif - - uint8_t len = strlen(fn); - if (len < 5 || len > maxlen+4 || strcasecmp(fn+len-4, extension) || (fno.fattrib & AM_DIR)) continue; - - s_menu_count++; - fn[len-4] = '\0'; - - if (s_menu_offset == 0) { - if (selection && strncasecmp(fn, selection, maxlen) < 0) { - s_last_menu_offset++; - } - else { - for (uint8_t i=0; i=0; i--) { - char *line = reusableBuffer.modelsel.menu_bss[i]; - if (line[0] == '\0' || strcasecmp(fn, line) > 0) { - if (i > 0) memmove(reusableBuffer.modelsel.menu_bss[0], reusableBuffer.modelsel.menu_bss[1], sizeof(reusableBuffer.modelsel.menu_bss[i]) * i); - memset(line, 0, MENU_LINE_LENGTH); - strcpy(line, fn); - break; - } - } - for (uint8_t i=0; i s_last_menu_offset) { - if (strcasecmp(fn, reusableBuffer.modelsel.menu_bss[MENU_MAX_LINES-2]) > 0 && strcasecmp(fn, reusableBuffer.modelsel.menu_bss[MENU_MAX_LINES-1]) < 0) { - memset(reusableBuffer.modelsel.menu_bss[MENU_MAX_LINES-1], 0, MENU_LINE_LENGTH); - strcpy(reusableBuffer.modelsel.menu_bss[MENU_MAX_LINES-1], fn); - } - } - else { - if (strcasecmp(fn, reusableBuffer.modelsel.menu_bss[1]) < 0 && strcasecmp(fn, reusableBuffer.modelsel.menu_bss[0]) > 0) { - memset(reusableBuffer.modelsel.menu_bss[0], 0, MENU_LINE_LENGTH); - strcpy(reusableBuffer.modelsel.menu_bss[0], fn); - } - } - } - } - - if (s_menu_offset > 0) - s_last_menu_offset = s_menu_offset; - else - s_menu_offset = s_last_menu_offset; - - return s_menu_count; -} -#endif - -#if defined(PCBTARANIS) - static int8_t modelselBitmapIdx; - static uint8_t modelselBitmap[MODEL_BITMAP_SIZE]; - #define MODELSEL_W 133 - #define BMP_DIRTY() modelselBitmapIdx = -1 -#else - #define MODELSEL_W LCD_W - #define BMP_DIRTY() -#endif +#define MODELSIZE_POS_X 170 +#define MODELSEL_W LCD_W #if defined(NAVIGATION_MENUS) void onModelSelectMenu(const char *result) @@ -255,7 +82,6 @@ void onModelSelectMenu(const char *result) else { // The user choosed a file on SD to restore POPUP_WARNING(eeRestoreModel(sub, (char *)result)); - BMP_DIRTY(); if (!s_warning && g_eeGeneral.currModel == sub) eeLoadModel(sub); } @@ -270,18 +96,12 @@ void menuModelSelect(uint8_t event) eeDeleteModel(m_posVert); // delete file s_copyMode = 0; event = EVT_ENTRY_UP; - BMP_DIRTY(); } uint8_t _event_ = (IS_ROTARY_BREAK(event) || IS_ROTARY_LONG(event) ? 0 : event); -#if defined(PCBTARANIS) if ((s_copyMode && EVT_KEY_MASK(event) == KEY_EXIT) || event == EVT_KEY_BREAK(KEY_EXIT)) _event_ -= KEY_EXIT; -#else - if (s_copyMode && EVT_KEY_MASK(event) == KEY_EXIT) - _event_ -= KEY_EXIT; -#endif int8_t oldSub = m_posVert; @@ -310,7 +130,6 @@ void menuModelSelect(uint8_t event) if (sub >= LCD_LINES-1) s_pgOfs = sub-LCD_LINES+2; s_copyMode = 0; s_editMode = EDIT_MODE_INIT; - BMP_DIRTY(); eeCheck(true); break; case EVT_KEY_LONG(KEY_EXIT): @@ -346,17 +165,6 @@ void menuModelSelect(uint8_t event) sub = m_posVert = (s_copyMode == MOVE_MODE || s_copySrcRow<0) ? (MAX_MODELS+sub+s_copyTgtOfs) % MAX_MODELS : s_copySrcRow; s_copyMode = 0; } -#if defined(PCBTARANIS) - else { - if (m_posVert != g_eeGeneral.currModel) { - m_posVert = g_eeGeneral.currModel; - s_pgOfs = 0; - } - else if (event != EVT_KEY_LONG(KEY_EXIT)) { - popMenu(); - } - } -#endif break; #if defined(ROTARY_ENCODER_NAVIGATION) case EVT_ROTARY_BREAK: @@ -381,10 +189,9 @@ void menuModelSelect(uint8_t event) uint8_t cur = (MAX_MODELS + sub + s_copyTgtOfs) % MAX_MODELS; if (s_copyMode == COPY_MODE) { - if (eeCopyModel(cur, s_copySrcRow)) - BMP_DIRTY(); - else + if (!eeCopyModel(cur, s_copySrcRow)) { cur = sub; + } } s_copySrcRow = g_eeGeneral.currModel; // to update the currModel value @@ -392,7 +199,6 @@ void menuModelSelect(uint8_t event) uint8_t src = cur; cur = (s_copyTgtOfs > 0 ? cur+MAX_MODELS-1 : cur+1) % MAX_MODELS; eeSwapModels(src, cur); - BMP_DIRTY(); if (src == s_copySrcRow) s_copySrcRow = cur; else if (cur == s_copySrcRow) @@ -407,11 +213,7 @@ void menuModelSelect(uint8_t event) s_copyMode = 0; event = EVT_ENTRY_UP; } - else if (event == EVT_KEY_LONG(KEY_ENTER) -#if !defined(PCBTARANIS) - || IS_ROTARY_BREAK(event) -#endif - ) { + else if (event == EVT_KEY_LONG(KEY_ENTER) || IS_ROTARY_BREAK(event)) { s_copyMode = 0; killEvents(event); #if defined(NAVIGATION_MENUS) @@ -451,13 +253,6 @@ void menuModelSelect(uint8_t event) } break; -#if defined(PCBTARANIS) - case EVT_KEY_BREAK(KEY_PAGE): - case EVT_KEY_LONG(KEY_PAGE): - chainMenu(event == EVT_KEY_BREAK(KEY_PAGE) ? menuModelSetup : menuTabModel[DIM(menuTabModel)-1]); - killEvents(event); - break; -#else #if defined(ROTARY_ENCODER_NAVIGATION) case EVT_ROTARY_LEFT: case EVT_ROTARY_RIGHT: @@ -477,7 +272,6 @@ void menuModelSelect(uint8_t event) #if defined(ROTARY_ENCODER_NAVIGATION) } // no break -#endif #endif case EVT_KEY_FIRST(KEY_MOVE_UP): @@ -507,24 +301,13 @@ void menuModelSelect(uint8_t event) break; } -#if defined(PCBHORUS) -#elif defined(PCBTARANIS) - lcd_puts(27*FW-(LEN_FREE-4)*FW, 0, STR_FREE); - if (event) reusableBuffer.modelsel.eepromfree = EeFsGetFree(); - lcd_outdezAtt(20*FW, 0, reusableBuffer.modelsel.eepromfree, 0); - lcd_puts(21*FW, 0, STR_BYTES); -#elif !defined(PCBSKY9X) +#if !defined(PCBSKY9X) lcd_puts(9*FW-(LEN_FREE-4)*FW, 0, STR_FREE); if (event) reusableBuffer.modelsel.eepromfree = EeFsGetFree(); lcd_outdezAtt(17*FW, 0, reusableBuffer.modelsel.eepromfree, 0); #endif -#if defined(PCBHORUS) - // nothing -#elif defined(PCBTARANIS) - displayScreenIndex(e_ModelSelect, DIM(menuTabModel), 0); - lcd_filled_rect(0, 0, LCD_W, FH, SOLID, FILL_WHITE|GREY_DEFAULT); -#elif defined(ROTARY_ENCODER_NAVIGATION) +#if defined(ROTARY_ENCODER_NAVIGATION) displayScreenIndex(e_ModelSelect, DIM(menuTabModel), (sub == g_eeGeneral.currModel) ? ((IS_RE_NAVIGATION_ENABLE() && s_editMode < 0) ? INVERS|BLINK : INVERS) : 0); #else displayScreenIndex(e_ModelSelect, DIM(menuTabModel), (sub == g_eeGeneral.currModel) ? INVERS : 0); @@ -535,6 +318,7 @@ void menuModelSelect(uint8_t event) for (uint8_t i=0; i= 0)) { @@ -558,34 +342,19 @@ void menuModelSelect(uint8_t event) if (eeModelExists(k)) { #if defined(PCBSKY9X) putsModelName(4*FW, y, modelHeaders[k].name, k, 0); -#elif defined(CPUARM) - putsModelName(4*FW, y, modelHeaders[k].name, k, 0); - lcd_outdezAtt(20*FW, y, eeModelSize(k), 0); #else char * name = reusableBuffer.modelsel.listnames[i]; if (event) eeLoadModelName(k, name); putsModelName(4*FW, y, name, k, 0); lcd_outdezAtt(20*FW, y, eeModelSize(k), 0); #endif - if (k==g_eeGeneral.currModel && (s_copyMode!=COPY_MODE || s_copySrcRow<0 || i+s_pgOfs!=(vertpos_t)sub)) lcd_putc(1, y, '*'); + if (k==g_eeGeneral.currModel && (s_copyMode!=COPY_MODE || s_copySrcRow<0 || i+s_pgOfs!=(vertpos_t)sub)) + lcd_putc(1, y, '*'); } if (s_copyMode && (vertpos_t)sub==i+s_pgOfs) { - lcd_filled_rect(9, y, MODELSEL_W-1-9, 7); + drawFilledRect(9, y, MODELSEL_W-1-9, 7); lcd_rect(8, y-1, MODELSEL_W-1-7, 9, s_copyMode == COPY_MODE ? SOLID : DOTTED); } } - -#if defined(PCBTARANIS) - if (modelselBitmapIdx != m_posVert) { - modelselBitmapIdx = m_posVert; - if (modelselBitmapIdx == g_eeGeneral.currModel) - memcpy(modelselBitmap, modelBitmap, MODEL_BITMAP_SIZE); - else - loadModelBitmap(modelHeaders[sub].bitmap, modelselBitmap); - } -#if !defined(PCBHORUS) - lcd_bmp(22*FW+2, 2*FH+FH/2, modelselBitmap); -#endif -#endif } diff --git a/radio/src/gui/menu_model_setup.cpp b/radio/src/gui/9X/menu_model_setup.cpp old mode 100755 new mode 100644 similarity index 99% rename from radio/src/gui/menu_model_setup.cpp rename to radio/src/gui/9X/menu_model_setup.cpp index 960a3b3980..8476a1584a --- a/radio/src/gui/menu_model_setup.cpp +++ b/radio/src/gui/9X/menu_model_setup.cpp @@ -33,7 +33,7 @@ * */ -#include "../opentx.h" +#include "../../opentx.h" #if defined(CPUARM) uint8_t g_moduleIdx; @@ -651,7 +651,7 @@ void menuModelSetup(uint8_t event) } } else { - lcd_filled_rect(MODEL_SETUP_2ND_COLUMN, y, LCD_W-MODEL_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8); + drawFilledRect(MODEL_SETUP_2ND_COLUMN, y, LCD_W-MODEL_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8); } } } diff --git a/radio/src/gui/menu_model_telemetry.cpp b/radio/src/gui/9X/menu_model_telemetry.cpp old mode 100755 new mode 100644 similarity index 84% rename from radio/src/gui/menu_model_telemetry.cpp rename to radio/src/gui/9X/menu_model_telemetry.cpp index 725718fea7..47ba5c371d --- a/radio/src/gui/menu_model_telemetry.cpp +++ b/radio/src/gui/9X/menu_model_telemetry.cpp @@ -33,7 +33,7 @@ * */ -#include "../opentx.h" +#include "../../opentx.h" enum menuModelTelemetryItems { CASE_CPUARM(ITEM_TELEMETRY_PROTOCOL_TYPE) @@ -70,24 +70,6 @@ enum menuModelTelemetryItems { ITEM_TELEMETRY_SENSOR14, ITEM_TELEMETRY_SENSOR15, ITEM_TELEMETRY_SENSOR16, -#if defined(PCBTARANIS) - ITEM_TELEMETRY_SENSOR17, - ITEM_TELEMETRY_SENSOR18, - ITEM_TELEMETRY_SENSOR19, - ITEM_TELEMETRY_SENSOR20, - ITEM_TELEMETRY_SENSOR21, - ITEM_TELEMETRY_SENSOR22, - ITEM_TELEMETRY_SENSOR23, - ITEM_TELEMETRY_SENSOR24, - ITEM_TELEMETRY_SENSOR25, - ITEM_TELEMETRY_SENSOR26, - ITEM_TELEMETRY_SENSOR27, - ITEM_TELEMETRY_SENSOR28, - ITEM_TELEMETRY_SENSOR29, - ITEM_TELEMETRY_SENSOR30, - ITEM_TELEMETRY_SENSOR31, - ITEM_TELEMETRY_SENSOR32, -#endif ITEM_TELEMETRY_NEWSENSOR, #endif #if !defined(CPUARM) @@ -107,11 +89,6 @@ enum menuModelTelemetryItems { ITEM_TELEMETRY_VARIO_SOURCE, #endif CASE_VARIO(ITEM_TELEMETRY_VARIO_RANGE) -#if defined(PCBTARANIS) - ITEM_TELEMETRY_TOP_BAR_LABEL, - ITEM_TELEMETRY_TOP_BAR_VOLTAGE, - ITEM_TELEMETRY_TOP_BAR_ALTITUDE, -#endif ITEM_TELEMETRY_SCREEN_LABEL1, ITEM_TELEMETRY_SCREEN_LINE1, ITEM_TELEMETRY_SCREEN_LINE2, @@ -138,14 +115,6 @@ enum menuModelTelemetryItems { }; #if defined(FRSKY) -#if LCD_W >= 212 - #define TELEM_COL1 (1*FW) - #define TELEM_COL2 (16*FW) - #define TELEM_COL3 (28*FW) - #define TELEM_BARS_COLMIN TELEM_COL2 - #define TELEM_BARS_COLMAX TELEM_COL3 - #define TELEM_SCRTYPE_COL TELEM_COL2 -#else #define TELEM_COL1 INDENT_WIDTH #if defined(TRANSLATIONS_FR) || defined(TRANSLATIONS_CZ) #define TELEM_COL2 (9*FW) @@ -155,15 +124,10 @@ enum menuModelTelemetryItems { #define TELEM_BARS_COLMIN (56-3*FW) #define TELEM_BARS_COLMAX (14*FW-3) #define TELEM_SCRTYPE_COL TELEM_COL2 -#endif #define IS_RANGE_DEFINED(k) (g_model.frsky.channels[k].ratio > 0) -#if defined(PCBTARANIS) - #define CHANNELS_ROWS - #define SENSOR_ROWS(x) (isTelemetryFieldAvailable(x) ? (uint8_t)0 : HIDDEN_ROW) - #define SENSORS_ROWS LABEL(Sensors), SENSOR_ROWS(0), SENSOR_ROWS(1), SENSOR_ROWS(2), SENSOR_ROWS(3), SENSOR_ROWS(4), SENSOR_ROWS(5), SENSOR_ROWS(6), SENSOR_ROWS(7), SENSOR_ROWS(8), SENSOR_ROWS(9), SENSOR_ROWS(10), SENSOR_ROWS(11), SENSOR_ROWS(12), SENSOR_ROWS(13), SENSOR_ROWS(14), SENSOR_ROWS(15), SENSOR_ROWS(16), SENSOR_ROWS(17), SENSOR_ROWS(18), SENSOR_ROWS(19), SENSOR_ROWS(20), SENSOR_ROWS(21), SENSOR_ROWS(22), SENSOR_ROWS(23), SENSOR_ROWS(24), SENSOR_ROWS(25), SENSOR_ROWS(26), SENSOR_ROWS(27), SENSOR_ROWS(28), SENSOR_ROWS(29), SENSOR_ROWS(30), SENSOR_ROWS(31), 0, -#elif defined(CPUARM) +#if defined(CPUARM) #define CHANNELS_ROWS #define SENSOR_ROWS(x) (isTelemetryFieldAvailable(x) ? (uint8_t)0 : HIDDEN_ROW) #define SENSORS_ROWS LABEL(Sensors), SENSOR_ROWS(0), SENSOR_ROWS(1), SENSOR_ROWS(2), SENSOR_ROWS(3), SENSOR_ROWS(4), SENSOR_ROWS(5), SENSOR_ROWS(6), SENSOR_ROWS(7), SENSOR_ROWS(8), SENSOR_ROWS(9), SENSOR_ROWS(10), SENSOR_ROWS(11), SENSOR_ROWS(12), SENSOR_ROWS(13), SENSOR_ROWS(14), SENSOR_ROWS(15), 0, @@ -187,15 +151,9 @@ enum menuModelTelemetryItems { #define USRDATA_ROWS 0, 0, IF_FAS_OFFSET(0) #endif -#if defined(PCBTARANIS) - #define RSSI_ROWS LABEL(RSSI), 0, 0, -#else - #define RSSI_ROWS LABEL(RSSI), 1, 1, -#endif +#define RSSI_ROWS LABEL(RSSI), 1, 1, -#if defined(LUA) - #define SCREEN_TYPE_ROWS 1 -#elif defined(CPUARM) || defined(GAUGES) +#if defined(CPUARM) || defined(GAUGES) #define SCREEN_TYPE_ROWS 0 #else #define SCREEN_TYPE_ROWS LABEL(SCREEN) @@ -207,20 +165,14 @@ enum menuModelTelemetryItems { #define VARIO_RANGE_ROWS 3 #endif -#if defined(PCBTARANIS) - #define TELEMETRY_TYPE_ROWS (g_model.moduleData[INTERNAL_MODULE].rfProtocol == RF_PROTO_OFF && g_model.externalModule == MODULE_TYPE_PPM) ? (uint8_t)0 : HIDDEN_ROW, -#elif defined(CPUARM) +#if defined(CPUARM) #define TELEMETRY_TYPE_ROWS 0, #else #define TELEMETRY_TYPE_ROWS #endif #if defined(CPUARM) - #if defined(LUA) - #define TELEMETRY_SCREEN_LINE(x) ((TELEMETRY_SCREEN_TYPE(x) == TELEMETRY_SCREEN_TYPE_NONE || TELEMETRY_SCREEN_TYPE(x) == TELEMETRY_SCREEN_TYPE_SCRIPT) ? HIDDEN_ROW : (uint8_t)2) - #else - #define TELEMETRY_SCREEN_LINE(x) (TELEMETRY_SCREEN_TYPE(x) == TELEMETRY_SCREEN_TYPE_NONE ? HIDDEN_ROW : (uint8_t)2) - #endif + #define TELEMETRY_SCREEN_LINE(x) (TELEMETRY_SCREEN_TYPE(x) == TELEMETRY_SCREEN_TYPE_NONE ? HIDDEN_ROW : (uint8_t)2) #define TELEMETRY_SCREEN_ROWS(x) SCREEN_TYPE_ROWS, TELEMETRY_SCREEN_LINE(x), TELEMETRY_SCREEN_LINE(x), TELEMETRY_SCREEN_LINE(x), TELEMETRY_SCREEN_LINE(x) #define TELEMETRY_CURRENT_EDIT_SCREEN(k) (k < ITEM_TELEMETRY_SCREEN_LABEL2 ? 0 : (k < ITEM_TELEMETRY_SCREEN_LABEL3 ? 1 : (k < ITEM_TELEMETRY_SCREEN_LABEL4 ? 2 : 3))) #else @@ -507,34 +459,12 @@ void onSensorMenu(const char *result) } #endif -#if defined(LUA) -void onTelemetryScriptFileSelectionMenu(const char *result) -{ - int8_t sub = m_posVert - 1; - uint8_t screenIndex = TELEMETRY_CURRENT_EDIT_SCREEN(sub); - - if (result == STR_UPDATE_LIST) { - if (!listSdFiles(SCRIPTS_TELEM_PATH, SCRIPTS_EXT, sizeof(g_model.frsky.screens[screenIndex].script.file), NULL)) { - POPUP_WARNING(STR_NO_SCRIPTS_ON_SD); - s_menu_flags = 0; - } - } - else { - // The user choosed a file in the list - memcpy(g_model.frsky.screens[screenIndex].script.file, result, sizeof(g_model.frsky.screens[screenIndex].script.file)); - eeDirty(EE_MODEL); - LUA_LOAD_MODEL_SCRIPTS(); - } -} -#endif - void menuModelTelemetry(uint8_t event) { - MENU(STR_MENUTELEMETRY, menuTabModel, e_Telemetry, ITEM_TELEMETRY_MAX+1, {0, TELEMETRY_TYPE_ROWS CHANNELS_ROWS RSSI_ROWS SENSORS_ROWS USRDATA_ROWS CASE_VARIO(LABEL(Vario)) CASE_VARIO(0) CASE_VARIO(VARIO_RANGE_ROWS) CASE_PCBTARANIS(LABEL(TopBar)) CASE_PCBTARANIS(0) CASE_PCBTARANIS(0) TELEMETRY_SCREEN_ROWS(0), TELEMETRY_SCREEN_ROWS(1), CASE_CPUARM(TELEMETRY_SCREEN_ROWS(2)) CASE_CPUARM(TELEMETRY_SCREEN_ROWS(3))}); + MENU(STR_MENUTELEMETRY, menuTabModel, e_Telemetry, ITEM_TELEMETRY_MAX+1, {0, TELEMETRY_TYPE_ROWS CHANNELS_ROWS RSSI_ROWS SENSORS_ROWS USRDATA_ROWS CASE_VARIO(LABEL(Vario)) CASE_VARIO(0) CASE_VARIO(VARIO_RANGE_ROWS) TELEMETRY_SCREEN_ROWS(0), TELEMETRY_SCREEN_ROWS(1), CASE_CPUARM(TELEMETRY_SCREEN_ROWS(2)) CASE_CPUARM(TELEMETRY_SCREEN_ROWS(3))}); uint8_t sub = m_posVert - 1; -#if !defined(PCBTARANIS) switch (event) { case EVT_KEY_BREAK(KEY_DOWN): case EVT_KEY_BREAK(KEY_UP): @@ -544,7 +474,6 @@ void menuModelTelemetry(uint8_t event) frskySendAlarms(); // update FrSky module when edit mode exited break; } -#endif for (uint8_t i=0; i0 || p1valdiff)) { - CHECK_INCDEC_MODELVAR(event, g_model.frsky.rssiAlarms[alarm].value, -30, 30); - } -#else lcd_putsLeft(y, STR_ALARM); lcd_putsiAtt(TELEM_COL2, y, STR_VALARM, ((2+alarm+g_model.frsky.rssiAlarms[alarm].level)%4), m_posHorz<=0 ? attr : 0); lcd_putc(TELEM_COL2+4*FW, y, '<'); @@ -731,7 +653,6 @@ void menuModelTelemetry(uint8_t event) break; } } -#endif break; } @@ -835,28 +756,6 @@ void menuModelTelemetry(uint8_t event) break; #endif -#if defined(PCBTARANIS) - case ITEM_TELEMETRY_TOP_BAR_LABEL: - lcd_putsLeft(y, STR_TOP_BAR); - break; - - case ITEM_TELEMETRY_TOP_BAR_VOLTAGE: - lcd_putsLeft(y, STR_VOLTAGE); - putsMixerSource(TELEM_COL2, y, g_model.frsky.voltsSource ? MIXSRC_FIRST_TELEM+3*(g_model.frsky.voltsSource-1) : 0, attr); - if (attr) { - g_model.frsky.voltsSource = checkIncDec(event, g_model.frsky.voltsSource, 0, TELEM_VALUES_MAX, EE_MODEL|NO_INCDEC_MARKS, isVoltsSensor); - } - break; - - case ITEM_TELEMETRY_TOP_BAR_ALTITUDE: - lcd_putsLeft(y, STR_ALTITUDE); - putsMixerSource(TELEM_COL2, y, g_model.frsky.altitudeSource ? MIXSRC_FIRST_TELEM+3*(g_model.frsky.altitudeSource-1) : 0, attr); - if (attr) { - g_model.frsky.altitudeSource = checkIncDec(event, g_model.frsky.altitudeSource, 0, TELEM_VALUES_MAX, EE_MODEL|NO_INCDEC_MARKS, isAltSensor); - } - break; -#endif - case ITEM_TELEMETRY_SCREEN_LABEL1: case ITEM_TELEMETRY_SCREEN_LABEL2: #if defined(CPUARM) @@ -871,32 +770,6 @@ void menuModelTelemetry(uint8_t event) g_model.frsky.screensType = (g_model.frsky.screensType & (~(0x03 << (2*screenIndex)))) | (newScreenType << (2*screenIndex)); memset(&g_model.frsky.screens[screenIndex], 0, sizeof(g_model.frsky.screens[screenIndex])); } -#if defined(LUA) - if (newScreenType == TELEMETRY_SCREEN_TYPE_SCRIPT) { - TelemetryScriptData & scriptData = g_model.frsky.screens[screenIndex].script; - - // TODO better function name for --- - // TODO function for these lines - if (ZEXIST(scriptData.file)) - lcd_putsnAtt(TELEM_SCRTYPE_COL+7*FW, y, scriptData.file, sizeof(scriptData.file), (m_posHorz==1 ? attr : 0)); - else - lcd_putsiAtt(TELEM_SCRTYPE_COL+7*FW, y, STR_VCSWFUNC, 0, (m_posHorz==1 ? attr : 0)); - - if (m_posHorz==1 && attr && event==EVT_KEY_BREAK(KEY_ENTER) && READ_ONLY_UNLOCKED()) { - s_editMode = 0; - if (listSdFiles(SCRIPTS_TELEM_PATH, SCRIPTS_EXT, sizeof(g_model.frsky.screens[screenIndex].script.file), g_model.frsky.screens[screenIndex].script.file)) { - menuHandler = onTelemetryScriptFileSelectionMenu; - } - else { - POPUP_WARNING(STR_NO_SCRIPTS_ON_SD); - s_menu_flags = 0; - } - } - } - else if (attr) { - MOVE_CURSOR_FROM_HERE(); - } -#endif break; } #else @@ -1012,11 +885,7 @@ void menuModelTelemetry(uint8_t event) for (uint8_t c=0; c0 || p1valdiff)) { diff --git a/radio/src/gui/menu_model_templates.cpp b/radio/src/gui/9X/menu_model_templates.cpp old mode 100755 new mode 100644 similarity index 98% rename from radio/src/gui/menu_model_templates.cpp rename to radio/src/gui/9X/menu_model_templates.cpp index 1c0200d538..5552d107e5 --- a/radio/src/gui/menu_model_templates.cpp +++ b/radio/src/gui/9X/menu_model_templates.cpp @@ -34,7 +34,7 @@ * */ -#include "../opentx.h" +#include "../../opentx.h" void menuModelTemplates(uint8_t event) { diff --git a/radio/src/gui/view_main.cpp b/radio/src/gui/9X/view_main.cpp similarity index 95% rename from radio/src/gui/view_main.cpp rename to radio/src/gui/9X/view_main.cpp index 8dd0b8b7e0..30e831f8fe 100644 --- a/radio/src/gui/view_main.cpp +++ b/radio/src/gui/9X/view_main.cpp @@ -34,7 +34,7 @@ * */ -#include "../opentx.h" +#include "../../opentx.h" #define BIGSIZE DBLSIZE #define BOX_WIDTH 23 @@ -134,7 +134,7 @@ void displayTrims(uint8_t phase) } ym -= val; #if !defined(CPUM64) || !defined(FRSKY) - lcd_filled_rect(xm-3, ym-3, 7, 7, SOLID, att|ERASE); + drawFilledRect(xm-3, ym-3, 7, 7, SOLID, att|ERASE); if (dir >= 0) { lcd_hline(xm-1, ym-1, 3); } @@ -153,7 +153,7 @@ void displayTrims(uint8_t phase) lcd_hline(xm-1, ym+1, 3); xm += val; #if !defined(CPUM64) || !defined(FRSKY) - lcd_filled_rect(xm-3, ym-3, 7, 7, SOLID, att|ERASE); + drawFilledRect(xm-3, ym-3, 7, 7, SOLID, att|ERASE); if (dir >= 0) { lcd_vline(xm+1, ym-1, 3); } @@ -202,13 +202,13 @@ void displayBattVoltage() { #if defined(BATTGRAPH) putsVBat(VBATT_X-8, VBATT_Y+1, 0); - lcd_filled_rect(VBATT_X-25, VBATT_Y+9, 22, 5); + drawFilledRect(VBATT_X-25, VBATT_Y+9, 22, 5); lcd_vline(VBATT_X-3, VBATT_Y+10, 3); uint8_t count = limit(2, 20 * (g_vbat100mV - g_eeGeneral.vBatMin - 90) / (30 + g_eeGeneral.vBatMax - g_eeGeneral.vBatMin), 20); for (uint8_t i=0; i g_eeGeneral.vBatWarn || BLINK_ON_PHASE) - lcd_filled_rect(VBATT_X-26, VBATT_Y, 25, 15); + drawFilledRect(VBATT_X-26, VBATT_Y, 25, 15); #else LcdFlags att = (g_vbat100mV <= g_eeGeneral.vBatWarn ? BLINK|INVERS : 0) | BIGSIZE; putsVBat(VBATT_X-1, VBATT_Y, att|NO_UNIT); diff --git a/radio/src/gui/menu_model_curves.cpp b/radio/src/gui/Taranis/menu_model_curves.cpp old mode 100755 new mode 100644 similarity index 64% rename from radio/src/gui/menu_model_curves.cpp rename to radio/src/gui/Taranis/menu_model_curves.cpp index 0e8433939f..f06a2d8cd7 --- a/radio/src/gui/menu_model_curves.cpp +++ b/radio/src/gui/Taranis/menu_model_curves.cpp @@ -33,7 +33,7 @@ * */ -#include "../opentx.h" +#include "../../opentx.h" uint8_t s_curveChan; @@ -50,23 +50,12 @@ struct point_t { point_t getPoint(uint8_t i) { point_t result = {0, 0}; -#if defined(PCBTARANIS) CurveInfo &crv = g_model.curves[s_curveChan]; int8_t *points = curveAddress(s_curveChan); bool custom = (crv.type == CURVE_TYPE_CUSTOM); uint8_t count = 5+crv.points; -#else - CurveInfo crv = curveInfo(s_curveChan); - int8_t *points = crv.crv; - bool custom = crv.custom; - uint8_t count = crv.points; -#endif if (i < count) { -#if defined(PCBTARANIS) result.x = X0-1-WCHART+i*WCHART*2/(count-1); -#else - result.x = X0-1-WCHART+i*WCHART/(count/2); -#endif result.y = (LCD_H-1) - (100 + points[i]) * (LCD_H-1) / 200; if (custom && i>0 && i NUM_POINTS-5*MAX_CURVES) { - AUDIO_WARNING2(); - return false; - } - int8_t *crv = curveAddress(index); - if (shift < 0) { - for (uint8_t i=0; i 0) { // do selection square - lcd_filled_rect(point.x-FW-1, point.y-2, 5, 5, SOLID, FORCE); - lcd_filled_rect(point.x-FW, point.y-1, 3, 3, SOLID); + drawFilledRect(point.x-FW-1, point.y-2, 5, 5, SOLID, FORCE); + drawFilledRect(point.x-FW, point.y-1, 3, 3, SOLID); if (s_editMode > 0) { if (selectionMode == 1) CHECK_INCDEC_MODELVAR(event, points[5+crv.points+i-1], i==1 ? -100 : points[5+crv.points+i-2], i==5+crv.points-2 ? 100 : points[5+crv.points+i]); // edit X @@ -297,124 +257,7 @@ void menuModelCurveOne(uint8_t event) } } } -#else -void menuModelCurveOne(uint8_t event) -{ - TITLE(STR_MENUCURVE); - lcd_outdezAtt(PSIZE(TR_MENUCURVE)*FW+1, 0, s_curveChan+1, INVERS|LEFT); - DISPLAY_PROGRESS_BAR(20*FW+1); - CurveInfo crv = curveInfo(s_curveChan); - - switch(event) { - case EVT_ENTRY: - s_editMode = 1; - break; - CASE_EVT_ROTARY_BREAK - case EVT_KEY_BREAK(KEY_ENTER): - if (s_editMode <= 0) - m_posHorz = 0; - if (s_editMode == 1 && crv.custom) - s_editMode = 2; - else - s_editMode = 1; - break; - case EVT_KEY_LONG(KEY_ENTER): - if (s_editMode <= 0) { - if (int8_t(++m_posHorz) > 4) - m_posHorz = -4; - for (uint8_t i=0; i 0) { - if (--s_editMode == 0) - m_posHorz = 0; - } - else { - popMenu(); - } - break; - - /* CASE_EVT_ROTARY_LEFT */ - case EVT_KEY_REPT(KEY_LEFT): - case EVT_KEY_FIRST(KEY_LEFT): - if (s_editMode==1 && m_posHorz>0) m_posHorz--; - if (s_editMode <= 0) { - if (crv.custom) { - moveCurve(s_curveChan, -crv.points+2); - } - else if (crv.points > MIN_POINTS) { - moveCurve(s_curveChan, -1, (crv.points+1)/2); - } - else { - AUDIO_WARNING2(); - } - return; - } - break; - - /* CASE_EVT_ROTARY_RIGHT */ - case EVT_KEY_REPT(KEY_RIGHT): - case EVT_KEY_FIRST(KEY_RIGHT): - if (s_editMode==1 && m_posHorz<(crv.points-1)) m_posHorz++; - if (s_editMode <= 0) { - if (!crv.custom) { - moveCurve(s_curveChan, crv.points-2, crv.points); - } - else if (crv.points < MAX_POINTS) { - if (moveCurve(s_curveChan, 1)) { - for (int8_t i=crv.points+crv.points-2; i>=0; i--) { - if (i%2) - crv.crv[i] = (crv.crv[i/2] + crv.crv[1+i/2]) / 2; - else - crv.crv[i] = crv.crv[i/2]; - } - } - } - else { - AUDIO_WARNING2(); - } - } - break; - } - - lcd_putsLeft(7*FH, STR_TYPE); - uint8_t attr = (s_editMode <= 0 ? INVERS : 0); - lcd_outdezAtt(5*FW-2, 7*FH, crv.points, LEFT|attr); - lcd_putsAtt(lcdLastPos, 7*FH, crv.custom ? PSTR("pt'") : PSTR("pt"), attr); - - DrawCurve(); - - if (s_editMode>0) { - uint8_t i = m_posHorz; - point_t point = getPoint(i); - - if (s_editMode==1 || !BLINK_ON_PHASE) { - // do selection square - lcd_filled_rect(point.x-1, point.y-2, 5, 5, SOLID, FORCE); - lcd_filled_rect(point.x, point.y-1, 3, 3, SOLID); - } - - int8_t x = -100 + 200*i/(crv.points-1); - if (crv.custom && i>0 && i= 0 && sub < MAX_CURVES) @@ -456,24 +298,12 @@ void editCurveRef(coord_t x, coord_t y, CurveRef & curve, uint8_t event, uint8_t void menuModelCurvesAll(uint8_t event) { -#if defined(GVARS) && defined(PCBSTD) - SIMPLE_MENU(STR_MENUCURVES, menuTabModel, e_CurvesAll, 1+MAX_CURVES+MAX_GVARS); -#else SIMPLE_MENU(STR_MENUCURVES, menuTabModel, e_CurvesAll, 1+MAX_CURVES); -#endif int8_t sub = m_posVert - 1; switch (event) { -#if defined(ROTARY_ENCODER_NAVIGATION) - case EVT_ROTARY_BREAK: -#endif -#if defined(PCBTARANIS) case EVT_KEY_BREAK(KEY_ENTER): -#else - case EVT_KEY_FIRST(KEY_RIGHT): - case EVT_KEY_FIRST(KEY_ENTER): -#endif if (CURVE_SELECTED() && !READ_ONLY()) { s_curveChan = sub; pushMenu(menuModelCurveOne); @@ -485,25 +315,12 @@ void menuModelCurvesAll(uint8_t event) coord_t y = MENU_TITLE_HEIGHT + 1 + i*FH; uint8_t k = i + s_pgOfs; uint8_t attr = (sub == k ? INVERS : 0); -#if defined(GVARS) && defined(PCBSTD) - if (k >= MAX_CURVES) { - putsStrIdx(0, y, STR_GV, k-MAX_CURVES+1); - if (GVAR_SELECTED()) { - if (attr && s_editMode>0) attr |= BLINK; - lcd_outdezAtt(10*FW, y, GVAR_VALUE(k-MAX_CURVES, -1), attr); - if (attr) g_model.gvars[k-MAX_CURVES] = checkIncDec(event, g_model.gvars[k-MAX_CURVES], -1000, 1000, EE_MODEL); - } - } - else -#endif { putsStrIdx(0, y, STR_CV, k+1, attr); -#if defined(PCBTARANIS) editName(4*FW, y, g_model.curveNames[k], sizeof(g_model.curveNames[k]), 0, 0); CurveInfo & crv = g_model.curves[k]; lcd_outdezAtt(11*FW, y, 5+crv.points, LEFT); lcd_putsAtt(lcdLastPos, y, STR_PTS, 0); -#endif } } diff --git a/radio/src/gui/Taranis/menu_model_custom_functions.cpp b/radio/src/gui/Taranis/menu_model_custom_functions.cpp new file mode 100644 index 0000000000..b40aed2947 --- /dev/null +++ b/radio/src/gui/Taranis/menu_model_custom_functions.cpp @@ -0,0 +1,377 @@ +/* + * Authors (alphabetical order) + * - Andre Bernet + * - Andreas Weitl + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Gabriel Birkus + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Thomas Husterer + * + * opentx is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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. + * + */ + +#include "../../opentx.h" + +#define MODEL_CUSTOM_FUNC_1ST_COLUMN (4*FW+2) +#define MODEL_CUSTOM_FUNC_2ND_COLUMN (8*FW+2) +#define MODEL_CUSTOM_FUNC_3RD_COLUMN (21*FW) +#define MODEL_CUSTOM_FUNC_4TH_COLUMN (33*FW-3) +#define MODEL_CUSTOM_FUNC_4TH_COLUMN_ONOFF (34*FW-3) + +void onCustomFunctionsFileSelectionMenu(const char *result) +{ + int8_t sub = m_posVert - 1; + CustomFunctionData * cf = &g_model.customFn[sub]; + uint8_t func = CFN_FUNC(cf); + + if (result == STR_UPDATE_LIST) { + char directory[256]; + if (func == FUNC_PLAY_SCRIPT) { + strcpy(directory, SCRIPTS_FUNCS_PATH); + } + else { + strcpy(directory, SOUNDS_PATH); + strncpy(directory+SOUNDS_PATH_LNG_OFS, currentLanguagePack->id, 2); + } + if (!listSdFiles(directory, func==FUNC_PLAY_SCRIPT ? SCRIPTS_EXT : SOUNDS_EXT, sizeof(cf->play.name), NULL)) { + POPUP_WARNING(func==FUNC_PLAY_SCRIPT ? STR_NO_SCRIPTS_ON_SD : STR_NO_SOUNDS_ON_SD); + s_menu_flags = 0; + } + } + else { + // The user choosed a file in the list + memcpy(cf->play.name, result, sizeof(cf->play.name)); + eeDirty(EE_MODEL); + if (func == FUNC_PLAY_SCRIPT) { + LUA_LOAD_MODEL_SCRIPTS(); + } + } +} + +void onCustomFunctionsMenu(const char *result) +{ + int8_t sub = m_posVert-1; + CustomFunctionData * cfn; + uint8_t eeFlags; + + if (g_menuStack[g_menuStackPtr] == menuModelCustomFunctions) { + cfn = &g_model.customFn[sub]; + eeFlags = EE_MODEL; + } + else { + cfn = &g_eeGeneral.customFn[sub]; + eeFlags = EE_GENERAL; + } + + if (result == STR_COPY) { + clipboard.type = CLIPBOARD_TYPE_CUSTOM_FUNCTION; + clipboard.data.cfn = *cfn; + } + else if (result == STR_PASTE) { + *cfn = clipboard.data.cfn; + eeDirty(eeFlags); + } + else if (result == STR_CLEAR) { + memset(cfn, 0, sizeof(CustomFunctionData)); + eeDirty(eeFlags); + } + else if (result == STR_INSERT) { + memmove(cfn+1, cfn, (NUM_CFN-sub-1)*sizeof(CustomFunctionData)); + memset(cfn, 0, sizeof(CustomFunctionData)); + eeDirty(eeFlags); + } + else if (result == STR_DELETE) { + memmove(cfn, cfn+1, (NUM_CFN-sub-1)*sizeof(CustomFunctionData)); + memset(&g_model.customFn[NUM_CFN-1], 0, sizeof(CustomFunctionData)); + eeDirty(eeFlags); + } +} + +void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFunctionsContext & functionsContext) +{ + int8_t sub = m_posVert - 1; + + uint8_t eeFlags = (functions == g_model.customFn) ? EE_MODEL : EE_GENERAL; + + if (sub>=0 && m_posHorz<0 && event==EVT_KEY_LONG(KEY_ENTER) && !READ_ONLY()) { + killEvents(event); + CustomFunctionData *cfn = &functions[sub]; + if (!CFN_EMPTY(cfn)) + MENU_ADD_ITEM(STR_COPY); + if (clipboard.type == CLIPBOARD_TYPE_CUSTOM_FUNCTION) + MENU_ADD_ITEM(STR_PASTE); + if (!CFN_EMPTY(cfn) && CFN_EMPTY(&functions[NUM_CFN-1])) + MENU_ADD_ITEM(STR_INSERT); + if (!CFN_EMPTY(cfn)) + MENU_ADD_ITEM(STR_CLEAR); + for (int i=sub+1; i0) ? BLINK|INVERS : INVERS) : 0); + uint8_t active = (attr && (s_editMode>0 || p1valdiff)); + switch (j) { + case 0: + putsSwitches(MODEL_CUSTOM_FUNC_1ST_COLUMN, y, CFN_SWITCH(cfn), attr | ((functionsContext.activeSwitches & ((MASK_CFN_TYPE)1 << k)) ? BOLD : 0)); + if (active || AUTOSWITCH_ENTER_LONG()) CHECK_INCDEC_SWITCH(event, CFN_SWITCH(cfn), SWSRC_FIRST, SWSRC_LAST, eeFlags, isSwitchAvailableInCustomFunctions); + break; + + case 1: + if (CFN_SWITCH(cfn)) { + if (active && func == FUNC_OVERRIDE_CHANNEL) { + func = CFN_FUNC(cfn) = checkIncDec(event, CFN_FUNC(cfn), 0, FUNC_MAX-1, eeFlags, isAssignableFunctionAvailable); + } + lcd_putsiAtt(MODEL_CUSTOM_FUNC_2ND_COLUMN, y, STR_VFSWFUNC, func, attr); + if (active) { + CFN_FUNC(cfn) = checkIncDec(event, CFN_FUNC(cfn), 0, FUNC_MAX-1, eeFlags, isAssignableFunctionAvailable); + if (checkIncDec_Ret) CFN_RESET(cfn); + } + } + else { + j = 4; // skip other fields + if (sub==k && m_posHorz > 0) { + REPEAT_LAST_CURSOR_MOVE(); + } + } + break; + + case 2: + { + int8_t maxParam = NUM_CHNOUT-1; +#if defined(OVERRIDE_CHANNEL_FUNCTION) + if (func == FUNC_OVERRIDE_CHANNEL) { + putsChn(lcdNextPos, y, CFN_CH_INDEX(cfn)+1, attr); + } + else +#endif + if (func == FUNC_TRAINER) { + maxParam = 4; + putsMixerSource(lcdNextPos, y, CFN_CH_INDEX(cfn)==0 ? 0 : MIXSRC_Rud+CFN_CH_INDEX(cfn)-1, attr); + } +#if defined(GVARS) + else if (func == FUNC_ADJUST_GVAR) { + maxParam = MAX_GVARS-1; + putsStrIdx(lcdNextPos, y, STR_GV, CFN_GVAR_INDEX(cfn)+1, attr); + if (active) CFN_GVAR_INDEX(cfn) = checkIncDec(event, CFN_GVAR_INDEX(cfn), 0, maxParam, eeFlags); + break; + } +#endif + else if (func == FUNC_SET_TIMER) { + maxParam = MAX_TIMERS-1; + putsStrIdx(lcdNextPos, y, STR_TIMER, CFN_TIMER_INDEX(cfn)+1, attr); + if (active) CFN_TIMER_INDEX(cfn) = checkIncDec(event, CFN_TIMER_INDEX(cfn), 0, maxParam, eeFlags); + break; + } + else if (attr) { + REPEAT_LAST_CURSOR_MOVE(); + } + if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_CH_INDEX(cfn), maxParam); + break; + } + + case 3: + { + INCDEC_DECLARE_VARS(eeFlags); + int16_t val_displayed = CFN_PARAM(cfn); + int16_t val_min = 0; + int16_t val_max = 255; + if (func == FUNC_RESET) { + val_max = FUNC_RESET_PARAM_LAST; + lcd_putsiAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, STR_VFSWRESET, CFN_PARAM(cfn), attr); + } +#if defined(OVERRIDE_CHANNEL_FUNCTION) + else if (func == FUNC_OVERRIDE_CHANNEL) { + val_min = -LIMIT_EXT_PERCENT; val_max = +LIMIT_EXT_PERCENT; + lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT); + } +#endif +#if defined(DANGEROUS_MODULE_FUNCTIONS) + else if (func >= FUNC_RANGECHECK && func <= FUNC_MODULE_OFF) { + val_max = NUM_MODULES-1; + lcd_putsiAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, "\004Int.Ext.", CFN_PARAM(cfn), attr); + } +#endif + else if (func == FUNC_SET_TIMER) { + val_max = 59*60+59; + putsTimer(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT, attr); + } + else if (func == FUNC_PLAY_SOUND) { + val_max = AU_FRSKY_LAST-AU_FRSKY_FIRST-1; + lcd_putsiAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, STR_FUNCSOUNDS, val_displayed, attr); + } +#if defined(HAPTIC) + else if (func == FUNC_HAPTIC) { + val_max = 3; + lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT); + } +#endif +#if defined(SDCARD) + else if (func == FUNC_PLAY_TRACK || func == FUNC_BACKGND_MUSIC || func == FUNC_PLAY_SCRIPT) { + coord_t x = MODEL_CUSTOM_FUNC_3RD_COLUMN; + if (ZEXIST(cfn->play.name)) + lcd_putsnAtt(x, y, cfn->play.name, sizeof(cfn->play.name), attr); + else + lcd_putsiAtt(x, y, STR_VCSWFUNC, 0, attr); + if (active && event==EVT_KEY_BREAK(KEY_ENTER)) { + s_editMode = 0; + char directory[256]; + if (func==FUNC_PLAY_SCRIPT) { + strcpy(directory, SCRIPTS_FUNCS_PATH); + } + else { + strcpy(directory, SOUNDS_PATH); + strncpy(directory+SOUNDS_PATH_LNG_OFS, currentLanguagePack->id, 2); + } + if (listSdFiles(directory, func==FUNC_PLAY_SCRIPT ? SCRIPTS_EXT : SOUNDS_EXT, sizeof(cfn->play.name), cfn->play.name)) { + menuHandler = onCustomFunctionsFileSelectionMenu; + } + else { + POPUP_WARNING(func==FUNC_PLAY_SCRIPT ? STR_NO_SCRIPTS_ON_SD : STR_NO_SOUNDS_ON_SD); + s_menu_flags = 0; + } + } + break; + } + else if (func == FUNC_PLAY_VALUE) { + val_max = MIXSRC_LAST_TELEM; + putsMixerSource(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr); + INCDEC_ENABLE_CHECK(isSourceAvailable); + } +#endif + else if (func == FUNC_VOLUME) { + val_max = MIXSRC_LAST_CH; + putsMixerSource(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr); + INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE); + INCDEC_ENABLE_CHECK(isSourceAvailable); + } + else if (func == FUNC_LOGS) { + if (val_displayed) { + lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr|PREC1|LEFT); + lcd_putc(lcdLastPos, y, 's'); + } + else { + lcd_putsiAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, STR_MMMINV, 0, attr); + } + } +#if defined(REVPLUS) + else if (func == FUNC_BACKLIGHT) { + displaySlider(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, CFN_PARAM(cfn), 100, attr); + INCDEC_SET_FLAG(eeFlags | NO_INCDEC_MARKS); + val_min = 0; + val_max = 100; + } +#endif +#if defined(GVARS) + else if (func == FUNC_ADJUST_GVAR) { + switch (CFN_GVAR_MODE(cfn)) { + case FUNC_ADJUST_GVAR_CONSTANT: + val_displayed = (int16_t)CFN_PARAM(cfn); + val_min = -CFN_GVAR_CST_MAX; val_max = +CFN_GVAR_CST_MAX; + lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT); + break; + case FUNC_ADJUST_GVAR_SOURCE: + val_max = MIXSRC_LAST_CH; + putsMixerSource(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr); + INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE); + INCDEC_ENABLE_CHECK(isSourceAvailable); + break; + case FUNC_ADJUST_GVAR_GVAR: + val_max = MAX_GVARS-1; + putsStrIdx(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, STR_GV, val_displayed+1, attr); + break; + default: // FUNC_ADJUST_GVAR_INC + val_max = 1; + lcd_putsiAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, PSTR("\003-=1+=1"), val_displayed, attr); + break; + } + + if (attr && event==EVT_KEY_LONG(KEY_ENTER)) { + killEvents(event); + s_editMode = !s_editMode; + active = true; + CFN_GVAR_MODE(cfn) += 1; + CFN_GVAR_MODE(cfn) &= 0x03; + val_displayed = 0; + } + } +#endif + else if (attr) { + REPEAT_LAST_CURSOR_MOVE(); + } + + if (active) { + CFN_PARAM(cfn) = CHECK_INCDEC_PARAM(event, val_displayed, val_min, val_max); + } + break; + } + + case 4: + if (HAS_ENABLE_PARAM(func)) { + menu_lcd_onoff(MODEL_CUSTOM_FUNC_4TH_COLUMN_ONOFF, y, CFN_ACTIVE(cfn), attr); + if (active) CFN_ACTIVE(cfn) = checkIncDec(event, CFN_ACTIVE(cfn), 0, 1, eeFlags); + } + else if (HAS_REPEAT_PARAM(func)) { + if (CFN_PLAY_REPEAT(cfn) == 0) { + lcd_putsAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2, y, "1x", attr); + } + else if (CFN_PLAY_REPEAT(cfn) == CFN_PLAY_REPEAT_NOSTART) { + lcd_putcAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN-1, y, '!', attr); + lcd_putsAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2, y, "1x", attr); + } + else { + lcd_outdezAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2+FW, y, CFN_PLAY_REPEAT(cfn)*CFN_PLAY_REPEAT_MUL, attr); + lcd_putcAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2+FW, y, 's', attr); + } + if (active) CFN_PLAY_REPEAT(cfn) = checkIncDec(event, CFN_PLAY_REPEAT(cfn)==CFN_PLAY_REPEAT_NOSTART?-1:CFN_PLAY_REPEAT(cfn), -1, 60/CFN_PLAY_REPEAT_MUL, eeFlags); + } + else if (attr) { + REPEAT_LAST_CURSOR_MOVE(); + } + break; + } + } + } +} + +void menuModelCustomFunctions(uint8_t event) +{ + MENU(STR_MENUCUSTOMFUNC, menuTabModel, e_CustomFunctions, NUM_CFN+1, {0, NAVIGATION_LINE_BY_LINE|4/*repeated*/}); + return menuCustomFunctions(event, g_model.customFn, modelFunctionsContext); +} diff --git a/radio/src/gui/Taranis/menu_model_inputs_mixes.cpp b/radio/src/gui/Taranis/menu_model_inputs_mixes.cpp new file mode 100644 index 0000000000..6857734010 --- /dev/null +++ b/radio/src/gui/Taranis/menu_model_inputs_mixes.cpp @@ -0,0 +1,947 @@ +/* + * Authors (alphabetical order) + * - Andre Bernet + * - Andreas Weitl + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Gabriel Birkus + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Thomas Husterer + * + * opentx is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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. + * + */ + +#include "../../opentx.h" + +#define EXPO_ONE_2ND_COLUMN (LCD_W-8*FW-90) +#define EXPO_ONE_FM_WIDTH (9*FW) + +#if defined(FLIGHT_MODES) +void displayFlightModes(coord_t x, coord_t y, FlightModesType value); +FlightModesType editFlightModes(coord_t x, coord_t y, uint8_t event, FlightModesType value, uint8_t attr) +{ + lcd_putsColumnLeft(x, y, STR_FLMODE); + + uint8_t posHorz = m_posHorz; + + for (uint8_t p=0; psrcRaw, x); + return anas[ed->chn]; +} + +void DrawFunction(FnFuncP fn, uint8_t offset) +{ + lcd_vlineStip(X0-offset, 0/*TODO Y0-WCHART*/, WCHART*2, 0xee); + lcd_hlineStip(X0-WCHART-offset, Y0, WCHART*2, 0xee); + + coord_t prev_yv = (coord_t)-1; + + for (int8_t xv=-WCHART; xv<=WCHART; xv++) { + coord_t yv = (LCD_H-1) - (((uint16_t)RESX + fn(xv * (RESX/WCHART))) / 2 * (LCD_H-1) / RESX); + if (prev_yv != (coord_t)-1) { + if (abs((int8_t)yv-prev_yv) <= 1) { + lcd_plot(X0+xv-offset-1, prev_yv, FORCE); + } + else { + uint8_t tmp = (prev_yv < yv ? 0 : 1); + lcd_vline(X0+xv-offset-1, yv+tmp, prev_yv-yv); + } + } + prev_yv = yv; + } +} + +uint8_t getExpoMixCount(uint8_t expo) +{ + uint8_t count = 0; + uint8_t ch ; + + for(int8_t i=(expo ? MAX_EXPOS-1 : MAX_MIXERS-1); i>=0; i--) { + ch = (expo ? EXPO_VALID(expoAddress(i)) : mixAddress(i)->srcRaw); + if (ch != 0) { + count++; + } + } + return count; +} + +bool reachExpoMixCountLimit(uint8_t expo) +{ + // check mixers count limit + if (getExpoMixCount(expo) >= (expo ? MAX_EXPOS : MAX_MIXERS)) { + POPUP_WARNING(expo ? STR_NOFREEEXPO : STR_NOFREEMIXER); + return true; + } + return false; +} + +void deleteExpoMix(uint8_t expo, uint8_t idx) +{ + pauseMixerCalculations(); + if (expo) { + ExpoData *expo = expoAddress(idx); + int input = expo->chn; + memmove(expo, expo+1, (MAX_EXPOS-(idx+1))*sizeof(ExpoData)); + memclear(&g_model.expoData[MAX_EXPOS-1], sizeof(ExpoData)); + if (!isInputAvailable(input)) { + memclear(&g_model.inputNames[input], LEN_INPUT_NAME); + } + } + else { + MixData *mix = mixAddress(idx); + memmove(mix, mix+1, (MAX_MIXERS-(idx+1))*sizeof(MixData)); + memclear(&g_model.mixData[MAX_MIXERS-1], sizeof(MixData)); + } + resumeMixerCalculations(); + eeDirty(EE_MODEL); +} + +// TODO avoid this global s_currCh on ARM boards ... +int8_t s_currCh; +void insertExpoMix(uint8_t expo, uint8_t idx) +{ + pauseMixerCalculations(); + if (expo) { + ExpoData *expo = expoAddress(idx); + memmove(expo+1, expo, (MAX_EXPOS-(idx+1))*sizeof(ExpoData)); + memclear(expo, sizeof(ExpoData)); + expo->srcRaw = (s_currCh > 4 ? MIXSRC_Rud - 1 + s_currCh : MIXSRC_Rud - 1 + channel_order(s_currCh)); + expo->curve.type = CURVE_REF_EXPO; + expo->mode = 3; // pos&neg + expo->chn = s_currCh - 1; + expo->weight = 100; + } + else { + MixData *mix = mixAddress(idx); + memmove(mix+1, mix, (MAX_MIXERS-(idx+1))*sizeof(MixData)); + memclear(mix, sizeof(MixData)); + mix->destCh = s_currCh-1; + mix->srcRaw = s_currCh; + if (!isSourceAvailable(mix->srcRaw)) + mix->srcRaw = (s_currCh > 4 ? MIXSRC_Rud - 1 + s_currCh : MIXSRC_Rud - 1 + channel_order(s_currCh)); + mix->weight = 100; + } + resumeMixerCalculations(); + eeDirty(EE_MODEL); +} + +void copyExpoMix(uint8_t expo, uint8_t idx) +{ + pauseMixerCalculations(); + if (expo) { + ExpoData *expo = expoAddress(idx); + memmove(expo+1, expo, (MAX_EXPOS-(idx+1))*sizeof(ExpoData)); + } + else { + MixData *mix = mixAddress(idx); + memmove(mix+1, mix, (MAX_MIXERS-(idx+1))*sizeof(MixData)); + } + resumeMixerCalculations(); + eeDirty(EE_MODEL); +} + +void memswap(void *a, void *b, uint8_t size) +{ + uint8_t *x = (uint8_t*)a; + uint8_t *y = (uint8_t*)b; + uint8_t temp ; + + while (size--) { + temp = *x; + *x++ = *y; + *y++ = temp; + } +} + +bool swapExpoMix(uint8_t expo, uint8_t &idx, uint8_t up) +{ + void *x, *y; + uint8_t size; + int8_t tgt_idx = (up ? idx-1 : idx+1); + + if (expo) { + x = (ExpoData *)expoAddress(idx); + + if (tgt_idx < 0) { + if (((ExpoData *)x)->chn == 0) + return false; + ((ExpoData *)x)->chn--; + return true; + } + + if (tgt_idx == MAX_EXPOS) { + if (((ExpoData *)x)->chn == NUM_INPUTS-1) + return false; + ((ExpoData *)x)->chn++; + return true; + } + + y = (ExpoData *)expoAddress(tgt_idx); + if(((ExpoData *)x)->chn != ((ExpoData *)y)->chn || !EXPO_VALID((ExpoData *)y)) { + if (up) { + if (((ExpoData *)x)->chn>0) ((ExpoData *)x)->chn--; + else return false; + } + else { + if (((ExpoData *)x)->chnchn++; + else return false; + } + return true; + } + + size = sizeof(ExpoData); + } + else { + x = (MixData *)mixAddress(idx); + + if (tgt_idx < 0) { + if (((MixData *)x)->destCh == 0) + return false; + ((MixData *)x)->destCh--; + return true; + } + + if (tgt_idx == MAX_MIXERS) { + if (((MixData *)x)->destCh == NUM_CHNOUT-1) + return false; + ((MixData *)x)->destCh++; + return true; + } + + y = (MixData *)mixAddress(tgt_idx); + uint8_t destCh = ((MixData *)x)->destCh; + if(!((MixData *)y)->srcRaw || destCh != ((MixData *)y)->destCh) { + if (up) { + if (destCh>0) ((MixData *)x)->destCh--; + else return false; + } + else { + if (destChdestCh++; + else return false; + } + return true; + } + + size = sizeof(MixData); + } + + pauseMixerCalculations(); + memswap(x, y, size); + resumeMixerCalculations(); + + idx = tgt_idx; + return true; +} + +enum ExposFields { + EXPO_FIELD_INPUT_NAME, + EXPO_FIELD_NAME, + EXPO_FIELD_SOURCE, + EXPO_FIELD_SCALE, + EXPO_FIELD_WEIGHT, + EXPO_FIELD_OFFSET, + CASE_CURVES(EXPO_FIELD_CURVE) + CASE_FLIGHT_MODES(EXPO_FIELD_FLIGHT_MODES) + EXPO_FIELD_SWITCH, + EXPO_FIELD_SIDE, + EXPO_FIELD_TRIM, + EXPO_FIELD_MAX +}; + +#define CURVE_ROWS 1 + +void menuModelExpoOne(uint8_t event) +{ + if (event == EVT_KEY_LONG(KEY_MENU)) { + pushMenu(menuChannelsView); + killEvents(event); + } + + ExpoData *ed = expoAddress(s_currIdx); + putsMixerSource(7*FW+FW/2, 0, MIXSRC_FIRST_INPUT+ed->chn, 0); + + SUBMENU(STR_MENUINPUTS, EXPO_FIELD_MAX, {0, 0, 0, ed->srcRaw >= MIXSRC_FIRST_TELEM ? (uint8_t)0 : (uint8_t)HIDDEN_ROW, 0, 0, CASE_CURVES(CURVE_ROWS) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0 /*, ...*/}); + + SET_SCROLLBAR_X(EXPO_ONE_2ND_COLUMN+10*FW); + + int8_t sub = m_posVert; + + coord_t y = MENU_TITLE_HEIGHT + 1; + + for (unsigned int k=0; k0 ? BLINK|INVERS : INVERS) : 0); + switch(i) + { + case EXPO_FIELD_INPUT_NAME: + editSingleName(EXPO_ONE_2ND_COLUMN, y, STR_INPUTNAME, g_model.inputNames[ed->chn], sizeof(g_model.inputNames[ed->chn]), event, attr); + break; + + case EXPO_FIELD_NAME: + editSingleName(EXPO_ONE_2ND_COLUMN-IF_9X(sizeof(ed->name)*FW), y, STR_EXPONAME, ed->name, sizeof(ed->name), event, attr); + break; + + case EXPO_FIELD_SOURCE: + lcd_putsLeft(y, NO_INDENT(STR_SOURCE)); + putsMixerSource(EXPO_ONE_2ND_COLUMN, y, ed->srcRaw, STREXPANDED|attr); + if (attr) ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isInputSourceAvailable); + break; + + case EXPO_FIELD_SCALE: + lcd_putsLeft(y, STR_SCALE); + putsTelemetryChannelValue(EXPO_ONE_2ND_COLUMN, y, ed->srcRaw - MIXSRC_FIRST_TELEM, convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale), LEFT|attr); + if (attr) ed->scale = checkIncDec(event, ed->scale, 0, maxTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1), EE_MODEL); + break; + + case EXPO_FIELD_WEIGHT: + lcd_putsLeft(y, STR_WEIGHT); + ed->weight = GVAR_MENU_ITEM(EXPO_ONE_2ND_COLUMN, y, ed->weight, MIN_EXPO_WEIGHT, 100, LEFT|attr, 0, event); + break; + + case EXPO_FIELD_OFFSET: + lcd_putsLeft(y, NO_INDENT(STR_OFFSET)); + ed->offset = GVAR_MENU_ITEM(EXPO_ONE_2ND_COLUMN, y, ed->offset, -100, 100, LEFT|attr, 0, event); + break; + +#if defined(CURVES) + case EXPO_FIELD_CURVE: + lcd_putsLeft(y, STR_CURVE); + editCurveRef(EXPO_ONE_2ND_COLUMN, y, ed->curve, event, attr); + break; +#endif + +#if defined(FLIGHT_MODES) + case EXPO_FIELD_FLIGHT_MODES: + ed->flightModes = editFlightModes(EXPO_ONE_2ND_COLUMN-IF_9X(EXPO_ONE_FM_WIDTH), y, event, ed->flightModes, attr); + break; +#endif + + case EXPO_FIELD_SWITCH: + ed->swtch = switchMenuItem(EXPO_ONE_2ND_COLUMN-IF_9X(3*FW), y, ed->swtch, attr, event); + break; + + case EXPO_FIELD_SIDE: + ed->mode = 4 - selectMenuItem(EXPO_ONE_2ND_COLUMN-IF_9X(3*FW), y, STR_SIDE, STR_VSIDE, 4-ed->mode, 1, 3, attr, event); + break; + + case EXPO_FIELD_TRIM: + uint8_t not_stick = (ed->srcRaw > MIXSRC_Ail); + int8_t carryTrim = -ed->carryTrim; + lcd_putsLeft(y, STR_TRIM); + lcd_putsiAtt(EXPO_ONE_2ND_COLUMN, y, STR_VMIXTRIMS, (not_stick && carryTrim == 0) ? 0 : carryTrim+1, m_posHorz==0 ? attr : 0); + if (attr) ed->carryTrim = -checkIncDecModel(event, carryTrim, not_stick ? TRIM_ON : -TRIM_OFF, -TRIM_AIL); + break; + } + y += FH; + } + + DrawFunction(expoFn); + + int x512 = getValue(ed->srcRaw); + if (ed->srcRaw >= MIXSRC_FIRST_TELEM) { + putsTelemetryChannelValue(LCD_W-8, 6*FH, ed->srcRaw - MIXSRC_FIRST_TELEM, x512, 0); + if (ed->scale > 0) x512 = (x512 * 1024) / convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale); + } + else { + lcd_outdezAtt(LCD_W-8, 6*FH, calcRESXto1000(x512), PREC1); + } + x512 = limit(-1024, x512, 1024); + int y512 = expoFn(x512); + y512 = limit(-1024, y512, 1024); + lcd_outdezAtt(LCD_W-8-6*FW, 1*FH, calcRESXto1000(y512), PREC1); + + x512 = X0+x512/(RESX/WCHART); + y512 = (LCD_H-1) - ((y512+RESX)/2) * (LCD_H-1) / RESX; + + lcd_vline(x512, y512-3, 3*2+1); + lcd_hline(x512-3, y512, 3*2+1); +} + +enum MixFields { + MIX_FIELD_NAME, + MIX_FIELD_SOURCE, + MIX_FIELD_WEIGHT, + MIX_FIELD_OFFSET, + MIX_FIELD_TRIM, + CASE_CURVES(MIX_FIELD_CURVE) + CASE_FLIGHT_MODES(MIX_FIELD_FLIGHT_PHASE) + MIX_FIELD_SWITCH, + MIX_FIELD_WARNING, + MIX_FIELD_MLTPX, + MIX_FIELD_DELAY_UP, + MIX_FIELD_DELAY_DOWN, + MIX_FIELD_SLOW_UP, + MIX_FIELD_SLOW_DOWN, + MIX_FIELD_COUNT +}; + +void gvarWeightItem(coord_t x, coord_t y, MixData *md, uint8_t attr, uint8_t event) +{ + u_int8int16_t weight; + MD_WEIGHT_TO_UNION(md, weight); + weight.word = GVAR_MENU_ITEM(x, y, weight.word, GV_RANGELARGE_WEIGHT_NEG, GV_RANGELARGE_WEIGHT, attr, 0, event); + MD_UNION_TO_WEIGHT(weight, md); +} + +#define GAUGE_WIDTH 33 +#define GAUGE_HEIGHT 6 +void drawOffsetBar(uint8_t x, uint8_t y, MixData * md) +{ + int offset = GET_GVAR(MD_OFFSET(md), GV_RANGELARGE_NEG, GV_RANGELARGE, mixerCurrentFlightMode); + int weight = abs(GET_GVAR(MD_WEIGHT(md), GV_RANGELARGE_NEG, GV_RANGELARGE, mixerCurrentFlightMode)); + int barMin = offset - weight; + int barMax = offset + weight; + if (y > 15) { + lcd_outdezAtt(x-((barMin >= 0) ? 2 : 3), y-6, barMin, TINSIZE|LEFT); + lcd_outdezAtt(x+GAUGE_WIDTH+1, y-6, barMax, TINSIZE); + } + if (barMin < -101) + barMin = -101; + if (barMax > 101) + barMax = 101; + lcd_hlineStip(x-2, y, GAUGE_WIDTH+2, DOTTED); + lcd_hlineStip(x-2, y+GAUGE_HEIGHT, GAUGE_WIDTH+2, DOTTED); + lcd_vline(x-2, y+1, GAUGE_HEIGHT-1); + lcd_vline(x+GAUGE_WIDTH-1, y+1, GAUGE_HEIGHT-1); + if (barMin <= barMax) { + int8_t right = (barMax * GAUGE_WIDTH) / 200; + int8_t left = ((barMin * GAUGE_WIDTH) / 200)-1; + drawFilledRect(x+GAUGE_WIDTH/2+left, y+2, right-left, GAUGE_HEIGHT-3); + } + lcd_vline(x+GAUGE_WIDTH/2-1, y, GAUGE_HEIGHT+1); + if (barMin == -101) { + for (uint8_t i=0; i<3; ++i) { + lcd_plot(x+i, y+4-i); + lcd_plot(x+3+i, y+4-i); + } + } + if (barMax == 101) { + for (uint8_t i=0; i<3; ++i) { + lcd_plot(x+GAUGE_WIDTH-8+i, y+4-i); + lcd_plot(x+GAUGE_WIDTH-5+i, y+4-i); + } + } +} +#undef GAUGE_WIDTH +#undef GAUGE_HEIGHT + +void menuModelMixOne(uint8_t event) +{ + if (event == EVT_KEY_LONG(KEY_MENU)) { + pushMenu(menuChannelsView); + killEvents(event); + } + + TITLE(s_currCh ? STR_INSERTMIX : STR_EDITMIX); + MixData *md2 = mixAddress(s_currIdx) ; + putsChn(lcdLastPos+1*FW, 0, md2->destCh+1,0); + + SUBMENU_NOTITLE(MIX_FIELD_COUNT, {0, 0, 0, 0, 0, CASE_CURVES(1) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0, 0 /*, ...*/}); + + lcd_vline(MENU_COLUMN2_X-4, FH+1, LCD_H-FH-1); + + int8_t sub = m_posVert; + int8_t editMode = s_editMode; + + for (uint8_t k=0; k= LCD_LINES-1) { + y = 1 + (k-LCD_LINES+2)*FH; + COLUMN_X = MENU_COLUMN2_X; + } + else { + y = 1 + (k+1)*FH; + COLUMN_X = 0; + } + int8_t i = k; + + uint8_t attr = (sub==i ? (editMode>0 ? BLINK|INVERS : INVERS) : 0); + switch(i) { + case MIX_FIELD_NAME: + editSingleName(COLUMN_X+MIXES_2ND_COLUMN, y, STR_MIXNAME, md2->name, sizeof(md2->name), event, attr); + break; + case MIX_FIELD_SOURCE: + lcd_putsColumnLeft(COLUMN_X, y, NO_INDENT(STR_SOURCE)); + putsMixerSource(COLUMN_X+MIXES_2ND_COLUMN, y, md2->srcRaw, STREXPANDED|attr); + if (attr) CHECK_INCDEC_MODELSOURCE(event, md2->srcRaw, 1, MIXSRC_LAST); + break; + case MIX_FIELD_WEIGHT: + lcd_putsColumnLeft(COLUMN_X, y, STR_WEIGHT); + gvarWeightItem(COLUMN_X+MIXES_2ND_COLUMN, y, md2, attr|LEFT, event); + break; + case MIX_FIELD_OFFSET: + { + lcd_putsColumnLeft(COLUMN_X, y, NO_INDENT(STR_OFFSET)); + u_int8int16_t offset; + MD_OFFSET_TO_UNION(md2, offset); + offset.word = GVAR_MENU_ITEM(COLUMN_X+MIXES_2ND_COLUMN, y, offset.word, GV_RANGELARGE_OFFSET_NEG, GV_RANGELARGE_OFFSET, attr|LEFT, 0, event); + MD_UNION_TO_OFFSET(offset, md2); + drawOffsetBar(COLUMN_X+MIXES_2ND_COLUMN+22, y, md2); + break; + } + + case MIX_FIELD_TRIM: + lcd_putsColumnLeft(COLUMN_X, y, STR_TRIM); + menu_lcd_onoff(COLUMN_X+MIXES_2ND_COLUMN, y, !md2->carryTrim, attr); + if (attr) md2->carryTrim = !checkIncDecModel(event, !md2->carryTrim, 0, 1); + break; + +#if defined(CURVES) + case MIX_FIELD_CURVE: + { + lcd_putsColumnLeft(COLUMN_X, y, STR_CURVE); + editCurveRef(COLUMN_X+MIXES_2ND_COLUMN, y, md2->curve, event, attr); + break; + } +#endif +#if defined(FLIGHT_MODES) + case MIX_FIELD_FLIGHT_PHASE: + md2->flightModes = editFlightModes(COLUMN_X+MIXES_2ND_COLUMN, y, event, md2->flightModes, attr); + break; +#endif + case MIX_FIELD_SWITCH: + md2->swtch = switchMenuItem(COLUMN_X+MIXES_2ND_COLUMN, y, md2->swtch, attr, event); + break; + case MIX_FIELD_WARNING: + lcd_putsColumnLeft(COLUMN_X+MIXES_2ND_COLUMN, y, STR_MIXWARNING); + if (md2->mixWarn) + lcd_outdezAtt(COLUMN_X+MIXES_2ND_COLUMN, y, md2->mixWarn, attr|LEFT); + else + lcd_putsAtt(COLUMN_X+MIXES_2ND_COLUMN, y, STR_OFF, attr); + if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, md2->mixWarn, 3); + break; + case MIX_FIELD_MLTPX: + md2->mltpx = selectMenuItem(COLUMN_X+MIXES_2ND_COLUMN, y, STR_MULTPX, STR_VMLTPX, md2->mltpx, 0, 2, attr, event); + break; + case MIX_FIELD_DELAY_UP: + md2->delayUp = EDIT_DELAY(COLUMN_X, y, event, attr, STR_DELAYUP, md2->delayUp); + break; + case MIX_FIELD_DELAY_DOWN: + md2->delayDown = EDIT_DELAY(COLUMN_X, y, event, attr, STR_DELAYDOWN, md2->delayDown); + break; + case MIX_FIELD_SLOW_UP: + md2->speedUp = EDIT_DELAY(COLUMN_X, y, event, attr, STR_SLOWUP, md2->speedUp); + break; + case MIX_FIELD_SLOW_DOWN: + md2->speedDown = EDIT_DELAY(COLUMN_X, y, event, attr, STR_SLOWDOWN, md2->speedDown); + break; + } + } +} + +static uint8_t s_maxLines = 8; +static uint8_t s_copySrcIdx; +static uint8_t s_copySrcCh; + +#define _STR_MAX(x) PSTR("/" #x) +#define STR_MAX(x) _STR_MAX(x) + +#define EXPO_LINE_WEIGHT_POS 8*FW+8 +#define EXPO_LINE_SRC_POS 9*FW+3 +#define EXPO_LINE_CURVE_POS 12*FW+11 +#define EXPO_LINE_TRIM_POS 19*FW-4 +#define EXPO_LINE_SWITCH_POS 20*FW-1 +#define EXPO_LINE_SIDE_POS 25*FW +#define EXPO_LINE_FM_POS 12*FW+11 +#define EXPO_LINE_SELECT_POS 5*FW+2 +#define EXPO_LINE_NAME_POS LCD_W-LEN_EXPOMIX_NAME*FW-MENUS_SCROLLBAR_WIDTH +#define MIX_LINE_WEIGHT_POS 6*FW+8 +#define MIX_LINE_SRC_POS 7*FW+3 +#define MIX_LINE_CURVE_POS 13*FW+3 +#define MIX_LINE_SWITCH_POS 19*FW+1 +#define MIX_LINE_FM_POS 13*FW+3 +#define MIX_LINE_DELAY_POS 24*FW+3 + +void onExpoMixMenu(const char *result) +{ + bool expo = (g_menuStack[g_menuStackPtr] == menuModelExposAll); + uint8_t chn = (expo ? expoAddress(s_currIdx)->chn+1 : mixAddress(s_currIdx)->destCh+1); + + if (result == STR_EDIT) { + pushMenu(expo ? menuModelExpoOne : menuModelMixOne); + } + else if (result == STR_INSERT_BEFORE || result == STR_INSERT_AFTER) { + if (!reachExpoMixCountLimit(expo)) { + s_currCh = chn; + if (result == STR_INSERT_AFTER) { s_currIdx++; m_posVert++; } + insertExpoMix(expo, s_currIdx); + pushMenu(expo ? menuModelExpoOne : menuModelMixOne); + } + } + else if (result == STR_COPY || result == STR_MOVE) { + s_copyMode = (result == STR_COPY ? COPY_MODE : MOVE_MODE); + s_copySrcIdx = s_currIdx; + s_copySrcCh = chn; + s_copySrcRow = m_posVert; + } + else if (result == STR_DELETE) { + deleteExpoMix(expo, s_currIdx); + } +} + +void displayHeaderChannelName(uint8_t ch) +{ + uint8_t len = zlen(g_model.limitData[ch-1].name, sizeof(g_model.limitData[ch-1].name)); + if (len) { + lcd_putc(17*FW, 0, ' '); + lcd_putsnAtt(lcdNextPos, 0, g_model.limitData[ch-1].name, len, ZCHAR); + lcd_putc(lcdNextPos, 0, ' '); + } +} + +void displayMixInfos(coord_t y, MixData *md) +{ + putsCurveRef(MIX_LINE_CURVE_POS, y, md->curve, 0); + + if (md->swtch) { + putsSwitches(MIX_LINE_SWITCH_POS, y, md->swtch); + } +} + +void displayMixLine(coord_t y, MixData *md) +{ + if (md->name[0]) + lcd_putsnAtt(EXPO_LINE_NAME_POS, y, md->name, sizeof(md->name), ZCHAR); + if (!md->flightModes || ((md->curve.value || md->swtch) && ((get_tmr10ms() / 200) & 1))) + displayMixInfos(y, md); + else + displayFlightModes(MIX_LINE_FM_POS, y, md->flightModes); +} + +void displayExpoInfos(coord_t y, ExpoData *ed) +{ + putsCurveRef(EXPO_LINE_CURVE_POS, y, ed->curve, 0); + putsSwitches(EXPO_LINE_SWITCH_POS, y, ed->swtch, 0); +} + +void displayExpoLine(coord_t y, ExpoData *ed) +{ + putsMixerSource(EXPO_LINE_SRC_POS, y, ed->srcRaw, 0); + + if (ed->carryTrim != TRIM_ON) { + lcd_putc(EXPO_LINE_TRIM_POS, y, ed->carryTrim > 0 ? '-' : STR_RETA123[-ed->carryTrim]); + } + + if (!ed->flightModes || ((ed->curve.value || ed->swtch) && ((get_tmr10ms() / 200) & 1))) + displayExpoInfos(y, ed); + else + displayFlightModes(EXPO_LINE_FM_POS, y, ed->flightModes); + + if (ed->name[0]) { + lcd_putsnAtt(EXPO_LINE_NAME_POS, y, ed->name, sizeof(ed->name), ZCHAR); + } +} + +void menuModelExpoMix(uint8_t expo, uint8_t event) +{ + uint8_t sub = m_posVert; + + if (s_editMode > 0) + s_editMode = 0; + + uint8_t chn = (expo ? expoAddress(s_currIdx)->chn+1 : mixAddress(s_currIdx)->destCh+1); + + switch (event) + { + case EVT_ENTRY: + case EVT_ENTRY_UP: + s_copyMode = 0; + s_copyTgtOfs = 0; + break; + case EVT_KEY_LONG(KEY_EXIT): + if (s_copyMode && s_copyTgtOfs == 0) { + deleteExpoMix(expo, s_currIdx); + killEvents(event); + event = 0; + } + // no break + case EVT_KEY_BREAK(KEY_EXIT): + if (s_copyMode) { + if (s_copyTgtOfs) { + // cancel the current copy / move operation + if (s_copyMode == COPY_MODE) { + deleteExpoMix(expo, s_currIdx); + } + else { + do { + swapExpoMix(expo, s_currIdx, s_copyTgtOfs > 0); + s_copyTgtOfs += (s_copyTgtOfs < 0 ? +1 : -1); + } while (s_copyTgtOfs != 0); + eeDirty(EE_MODEL); + } + m_posVert = s_copySrcRow; + s_copyTgtOfs = 0; + } + s_copyMode = 0; + event = 0; + } + break; + case EVT_KEY_BREAK(KEY_ENTER): + if (sub != 0 && (!s_currCh || (s_copyMode && !s_copyTgtOfs)) && !READ_ONLY()) { + s_copyMode = (s_copyMode == COPY_MODE ? MOVE_MODE : COPY_MODE); + s_copySrcIdx = s_currIdx; + s_copySrcCh = chn; + s_copySrcRow = sub; + break; + } + // no break + + CASE_EVT_ROTARY_BREAK + case EVT_KEY_LONG(KEY_ENTER): + killEvents(event); + if (s_copyTgtOfs) { + s_copyMode = 0; + s_copyTgtOfs = 0; + } + else if (sub != 0) { + if (READ_ONLY()) { + if (!s_currCh) { + pushMenu(expo ? menuModelExpoOne : menuModelMixOne); + } + } + else { + if (s_copyMode) s_currCh = 0; + if (s_currCh) { + if (reachExpoMixCountLimit(expo)) break; + insertExpoMix(expo, s_currIdx); + pushMenu(expo ? menuModelExpoOne : menuModelMixOne); + s_copyMode = 0; + } + else { + event = 0; + s_copyMode = 0; + MENU_ADD_ITEM(STR_EDIT); + MENU_ADD_ITEM(STR_INSERT_BEFORE); + MENU_ADD_ITEM(STR_INSERT_AFTER); + MENU_ADD_ITEM(STR_COPY); + MENU_ADD_ITEM(STR_MOVE); + MENU_ADD_ITEM(STR_DELETE); + menuHandler = onExpoMixMenu; + } + } + } + break; + case EVT_KEY_LONG(KEY_LEFT): + case EVT_KEY_LONG(KEY_RIGHT): + if (s_copyMode && !s_copyTgtOfs) { + if (reachExpoMixCountLimit(expo)) break; + s_currCh = chn; + if (event == EVT_KEY_LONG(KEY_RIGHT)) { s_currIdx++; m_posVert++; } + insertExpoMix(expo, s_currIdx); + pushMenu(expo ? menuModelExpoOne : menuModelMixOne); + s_copyMode = 0; + killEvents(event); + } + break; + case EVT_KEY_FIRST(KEY_MOVE_UP): + case EVT_KEY_REPT(KEY_MOVE_UP): + case EVT_KEY_FIRST(KEY_MOVE_DOWN): + case EVT_KEY_REPT(KEY_MOVE_DOWN): + if (s_copyMode) { + uint8_t key = (event & 0x1f); + uint8_t next_ofs = ((IS_ROTARY_UP(event) || key==KEY_MOVE_UP) ? s_copyTgtOfs - 1 : s_copyTgtOfs + 1); + + if (s_copyTgtOfs==0 && s_copyMode==COPY_MODE) { + // insert a mix on the same channel (just above / just below) + if (reachExpoMixCountLimit(expo)) break; + copyExpoMix(expo, s_currIdx); + if (IS_ROTARY_DOWN(event) || key==KEY_MOVE_DOWN) s_currIdx++; + else if (sub-s_pgOfs >= 6) s_pgOfs++; + } + else if (next_ofs==0 && s_copyMode==COPY_MODE) { + // delete the mix + deleteExpoMix(expo, s_currIdx); + if (IS_ROTARY_UP(event) || key==KEY_MOVE_UP) s_currIdx--; + } + else { + // only swap the mix with its neighbor + if (!swapExpoMix(expo, s_currIdx, IS_ROTARY_UP(event) || key==KEY_MOVE_UP)) break; + eeDirty(EE_MODEL); + } + + s_copyTgtOfs = next_ofs; + } + break; + } + + lcd_outdezAtt(FW*max(sizeof(TR_MENUINPUTS), sizeof(TR_MIXER))+FW+FW/2, 0, getExpoMixCount(expo)); + lcd_puts(FW*max(sizeof(TR_MENUINPUTS), sizeof(TR_MIXER))+FW+FW/2, 0, expo ? STR_MAX(MAX_EXPOS) : STR_MAX(MAX_MIXERS)); + + SIMPLE_MENU(expo ? STR_MENUINPUTS : STR_MIXER, menuTabModel, expo ? e_InputsAll : e_MixAll, s_maxLines); + + sub = m_posVert; + s_currCh = 0; + uint8_t cur = 1; + uint8_t i = 0; + + for (uint8_t ch=1; ch<=(expo ? NUM_INPUTS : NUM_CHNOUT); ch++) { + void *pointer = NULL; MixData * &md = (MixData * &)pointer; ExpoData * &ed = (ExpoData * &)pointer; + coord_t y = MENU_TITLE_HEIGHT-FH+1+(cur-s_pgOfs)*FH; + if (expo ? (ichn+1 == ch && EXPO_VALID(ed)) : (isrcRaw && md->destCh+1 == ch)) { + if (s_pgOfs < cur && cur-s_pgOfs < LCD_LINES) { + if (expo) { + putsMixerSource(0, y, ch, 0); + } + else { + putsChn(0, y, ch, 0); // show CHx + } + } + uint8_t mixCnt = 0; + do { + if (s_copyMode) { + if (s_copyMode == MOVE_MODE && s_pgOfs < cur && cur-s_pgOfs < 8 && s_copySrcCh == ch && s_copyTgtOfs != 0 && i == (s_copySrcIdx + (s_copyTgtOfs<0))) { + lcd_rect(expo ? 18 : 22, y-1, expo ? LCD_W-18 : LCD_W-22, 9, DOTTED); + cur++; y+=FH; + } + if (s_currIdx == i) { + sub = m_posVert = cur; + s_currCh = ch; + } + } + else if (sub == cur) { + s_currIdx = i; + } + if (s_pgOfs < cur && cur-s_pgOfs < 8) { + uint8_t attr = ((s_copyMode || sub != cur) ? 0 : INVERS); + if (expo) { + ed->weight = GVAR_MENU_ITEM(EXPO_LINE_WEIGHT_POS, y, ed->weight, MIN_EXPO_WEIGHT, 100, attr | (isExpoActive(i) ? BOLD : 0), 0, event); + displayExpoLine(y, ed); + if (ed->mode!=3) { + lcd_putc(EXPO_LINE_SIDE_POS, y, ed->mode == 2 ? 126 : 127); + } + } + else { + if (attr) { + displayHeaderChannelName(ch); + } + + if (mixCnt > 0) lcd_putsiAtt(FW, y, STR_VMLTPX2, md->mltpx, 0); + + putsMixerSource(MIX_LINE_SRC_POS, y, md->srcRaw, 0); + + gvarWeightItem(MIX_LINE_WEIGHT_POS, y, md, attr | (isMixActive(i) ? BOLD : 0), event); + + displayMixLine(y, md); + + char cs = ' '; + if (md->speedDown || md->speedUp) + cs = 'S'; + if (md->delayUp || md->delayDown) + cs = (cs =='S' ? '*' : 'D'); + lcd_putc(MIX_LINE_DELAY_POS, y, cs); + } + if (s_copyMode) { + if ((s_copyMode==COPY_MODE || s_copyTgtOfs == 0) && s_copySrcCh == ch && i == (s_copySrcIdx + (s_copyTgtOfs<0))) { + /* draw a border around the raw on selection mode (copy/move) */ + lcd_rect(expo ? EXPO_LINE_SELECT_POS : 22, y-1, expo ? (LCD_W-EXPO_LINE_SELECT_POS) : (LCD_W-22), 9, s_copyMode == COPY_MODE ? SOLID : DOTTED); + } + if (cur == sub) { + /* invert the raw when it's the current one */ + drawFilledRect(expo ? EXPO_LINE_SELECT_POS+1 : 23, y, expo ? (LCD_W-EXPO_LINE_SELECT_POS-2) : (LCD_W-24), 7); + } + } + } + cur++; y+=FH; mixCnt++; i++; if (expo) ed++; else md++; + } while (expo ? (ichn+1 == ch && EXPO_VALID(ed)) : (isrcRaw && md->destCh+1 == ch)); + if (s_copyMode == MOVE_MODE && s_pgOfs < cur && cur-s_pgOfs < LCD_LINES && s_copySrcCh == ch && i == (s_copySrcIdx + (s_copyTgtOfs<0))) { + lcd_rect(expo ? EXPO_LINE_SELECT_POS : 22, y-1, expo ? LCD_W-EXPO_LINE_SELECT_POS : LCD_W-22, 9, DOTTED); + cur++; y+=FH; + } + } + else { + uint8_t attr = 0; + if (sub == cur) { + s_currIdx = i; + s_currCh = ch; + if (!s_copyMode) { + attr = INVERS; + } + } + if (s_pgOfs < cur && cur-s_pgOfs < LCD_LINES) { + if (expo) { + putsMixerSource(0, y, ch, attr); + } + else { + putsChn(0, y, ch, attr); // show CHx + if (attr) { + displayHeaderChannelName(ch); + } + } + if (s_copyMode == MOVE_MODE && s_copySrcCh == ch) { + lcd_rect(expo ? EXPO_LINE_SELECT_POS : 22, y-1, expo ? (LCD_W-EXPO_LINE_SELECT_POS) : (LCD_W-22), 9, DOTTED); + } + } + cur++; y+=FH; + } + } + s_maxLines = cur; + if (sub >= s_maxLines-1) m_posVert = s_maxLines-1; +} + +void menuModelExposAll(uint8_t event) +{ + return menuModelExpoMix(1, event); +} + +void menuModelMixAll(uint8_t event) +{ + return menuModelExpoMix(0, event); +} diff --git a/radio/src/gui/Taranis/menu_model_select.cpp b/radio/src/gui/Taranis/menu_model_select.cpp new file mode 100644 index 0000000000..6010300fdc --- /dev/null +++ b/radio/src/gui/Taranis/menu_model_select.cpp @@ -0,0 +1,300 @@ +/* + * Authors (alphabetical order) + * - Andre Bernet + * - Andreas Weitl + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Gabriel Birkus + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Thomas Husterer + * + * opentx is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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. + * + */ + +#include "../../opentx.h" + +#define MODELSIZE_POS_X 170 + +static int8_t modelselBitmapIdx; +static uint8_t modelselBitmap[MODEL_BITMAP_SIZE]; +#define MODELSEL_W 133 +#define BMP_DIRTY() modelselBitmapIdx = -1 + +void onModelSelectMenu(const char *result) +{ + int8_t sub = m_posVert; + + if (result == STR_SELECT_MODEL || result == STR_CREATE_MODEL) { + selectModel(sub); + } + else if (result == STR_COPY_MODEL) { + s_copyMode = COPY_MODE; + s_copyTgtOfs = 0; + s_copySrcRow = -1; + } + else if (result == STR_MOVE_MODEL) { + s_copyMode = MOVE_MODE; + s_copyTgtOfs = 0; + s_copySrcRow = -1; + } + else if (result == STR_BACKUP_MODEL) { + eeCheck(true); // force writing of current model data before this is changed + POPUP_WARNING(eeBackupModel(sub)); + } + else if (result == STR_RESTORE_MODEL || result == STR_UPDATE_LIST) { + if (!listSdFiles(MODELS_PATH, MODELS_EXT, MENU_LINE_LENGTH-1, NULL)) { + POPUP_WARNING(STR_NO_MODELS_ON_SD); + s_menu_flags = 0; + } + } + else if (result == STR_DELETE_MODEL) { + POPUP_CONFIRMATION(STR_DELETEMODEL); + SET_WARNING_INFO(modelHeaders[sub].name, sizeof(g_model.header.name), ZCHAR); + } + else { + // The user choosed a file on SD to restore + POPUP_WARNING(eeRestoreModel(sub, (char *)result)); + BMP_DIRTY(); + if (!s_warning && g_eeGeneral.currModel == sub) + eeLoadModel(sub); + } +} + +void menuModelSelect(uint8_t event) +{ + if (s_warning_result) { + s_warning_result = 0; + eeDeleteModel(m_posVert); // delete file + s_copyMode = 0; + event = EVT_ENTRY_UP; + BMP_DIRTY(); + } + + uint8_t _event_ = (IS_ROTARY_BREAK(event) || IS_ROTARY_LONG(event) ? 0 : event); + + if ((s_copyMode && EVT_KEY_MASK(event) == KEY_EXIT) || event == EVT_KEY_BREAK(KEY_EXIT)) + _event_ -= KEY_EXIT; + + int8_t oldSub = m_posVert; + + check_submenu_simple(_event_, MAX_MODELS-1); + + if (s_editMode > 0) s_editMode = 0; + + int8_t sub = m_posVert; + + switch (event) + { + case EVT_ENTRY: + m_posVert = sub = g_eeGeneral.currModel; + if (sub >= NUM_BODY_LINES) s_pgOfs = sub-(NUM_BODY_LINES-1); + s_copyMode = 0; + s_editMode = EDIT_MODE_INIT; + BMP_DIRTY(); + eeCheck(true); + break; + case EVT_KEY_LONG(KEY_EXIT): + if (s_copyMode && s_copyTgtOfs == 0 && g_eeGeneral.currModel != sub && eeModelExists(sub)) { + POPUP_CONFIRMATION(STR_DELETEMODEL); + SET_WARNING_INFO(modelHeaders[sub].name, sizeof(g_model.header.name), ZCHAR); + killEvents(event); + break; + } + // no break + case EVT_KEY_BREAK(KEY_EXIT): + if (s_copyMode) { + sub = m_posVert = (s_copyMode == MOVE_MODE || s_copySrcRow<0) ? (MAX_MODELS+sub+s_copyTgtOfs) % MAX_MODELS : s_copySrcRow; + s_copyMode = 0; + } + else { + if (m_posVert != g_eeGeneral.currModel) { + m_posVert = g_eeGeneral.currModel; + s_pgOfs = 0; + } + else if (event != EVT_KEY_LONG(KEY_EXIT)) { + popMenu(); + } + } + break; + case EVT_KEY_LONG(KEY_ENTER): + case EVT_KEY_BREAK(KEY_ENTER): + s_editMode = 0; + if (READ_ONLY()) { + if (g_eeGeneral.currModel != sub && eeModelExists(sub)) { + selectModel(sub); + } + } + else if (s_copyMode && (s_copyTgtOfs || s_copySrcRow>=0)) { + displayPopup(s_copyMode==COPY_MODE ? STR_COPYINGMODEL : STR_MOVINGMODEL); + eeCheck(true); // force writing of current model data before this is changed + + uint8_t cur = (MAX_MODELS + sub + s_copyTgtOfs) % MAX_MODELS; + + if (s_copyMode == COPY_MODE) { + if (eeCopyModel(cur, s_copySrcRow)) + BMP_DIRTY(); + else + cur = sub; + } + + s_copySrcRow = g_eeGeneral.currModel; // to update the currModel value + while (sub != cur) { + uint8_t src = cur; + cur = (s_copyTgtOfs > 0 ? cur+MAX_MODELS-1 : cur+1) % MAX_MODELS; + eeSwapModels(src, cur); + BMP_DIRTY(); + if (src == s_copySrcRow) + s_copySrcRow = cur; + else if (cur == s_copySrcRow) + s_copySrcRow = src; + } + + if (s_copySrcRow != g_eeGeneral.currModel) { + g_eeGeneral.currModel = s_copySrcRow; + eeDirty(EE_GENERAL); + } + + s_copyMode = 0; + event = EVT_ENTRY_UP; + } + else if (event == EVT_KEY_LONG(KEY_ENTER)) { + s_copyMode = 0; + killEvents(event); + if (g_eeGeneral.currModel != sub) { + if (eeModelExists(sub)) { + MENU_ADD_ITEM(STR_SELECT_MODEL); + MENU_ADD_SD_ITEM(STR_BACKUP_MODEL); + MENU_ADD_ITEM(STR_COPY_MODEL); + MENU_ADD_ITEM(STR_MOVE_MODEL); + MENU_ADD_ITEM(STR_DELETE_MODEL); + } + else { + MENU_ADD_ITEM(STR_CREATE_MODEL); + MENU_ADD_ITEM(STR_RESTORE_MODEL); + } + } + else { + MENU_ADD_SD_ITEM(STR_BACKUP_MODEL); + MENU_ADD_ITEM(STR_COPY_MODEL); + MENU_ADD_ITEM(STR_MOVE_MODEL); + } + menuHandler = onModelSelectMenu; + } + else if (eeModelExists(sub)) { + s_copyMode = (s_copyMode == COPY_MODE ? MOVE_MODE : COPY_MODE); + s_copyTgtOfs = 0; + s_copySrcRow = -1; + } + break; + + case EVT_KEY_BREAK(KEY_PAGE): + case EVT_KEY_LONG(KEY_PAGE): + chainMenu(event == EVT_KEY_BREAK(KEY_PAGE) ? menuModelSetup : menuTabModel[DIM(menuTabModel)-1]); + killEvents(event); + break; + + case EVT_KEY_FIRST(KEY_MOVE_UP): + case EVT_KEY_REPT(KEY_MOVE_UP): + case EVT_KEY_FIRST(KEY_MOVE_DOWN): + case EVT_KEY_REPT(KEY_MOVE_DOWN): + if (s_copyMode) { + int8_t next_ofs = s_copyTgtOfs + oldSub - m_posVert; + if (next_ofs == MAX_MODELS || next_ofs == -MAX_MODELS) + next_ofs = 0; + + if (s_copySrcRow < 0 && s_copyMode==COPY_MODE) { + s_copySrcRow = oldSub; + // find a hole (in the first empty slot above / below) + sub = eeFindEmptyModel(s_copySrcRow, IS_ROTARY_DOWN(event) || event==EVT_KEY_FIRST(KEY_MOVE_DOWN)); + if (sub < 0) { + // no free room for duplicating the model + AUDIO_ERROR(); + sub = oldSub; + s_copyMode = 0; + } + next_ofs = 0; + m_posVert = sub; + } + s_copyTgtOfs = next_ofs; + } + break; + } + + lcd_puts(27*FW-(LEN_FREE-4)*FW, 0, STR_FREE); + if (event) reusableBuffer.modelsel.eepromfree = EeFsGetFree(); + lcd_outdezAtt(20*FW, 0, reusableBuffer.modelsel.eepromfree, 0); + lcd_puts(21*FW, 0, STR_BYTES); + + displayScreenIndex(e_ModelSelect, DIM(menuTabModel), 0); + drawFilledRect(0, 0, LCD_W, FH, SOLID, FILL_WHITE|GREY_DEFAULT); + + TITLE(STR_MENUMODELSEL); + + for (uint8_t i=0; i= 0)) { + if (k == sub) { + if (s_copyMode == COPY_MODE) { + k = s_copySrcRow; + lcd_putc(MODELSEL_W-FW, y, '+'); + } + else { + k = sub + s_copyTgtOfs; + } + } + else if (s_copyTgtOfs < 0 && ((k < sub && k >= sub+s_copyTgtOfs) || (k-MAX_MODELS < sub && k-MAX_MODELS >= sub+s_copyTgtOfs))) + k += 1; + else if (s_copyTgtOfs > 0 && ((k > sub && k <= sub+s_copyTgtOfs) || (k+MAX_MODELS > sub && k+MAX_MODELS <= sub+s_copyTgtOfs))) + k += MAX_MODELS-1; + } + + k %= MAX_MODELS; + + if (eeModelExists(k)) { + putsModelName(4*FW, y, modelHeaders[k].name, k, 0); + lcd_outdezAtt(20*FW, y, eeModelSize(k), 0); + if (k==g_eeGeneral.currModel && (s_copyMode!=COPY_MODE || s_copySrcRow<0 || i+s_pgOfs!=(vertpos_t)sub)) + lcd_putc(1, y, '*'); + } + + if (s_copyMode && (vertpos_t)sub==i+s_pgOfs) { + drawFilledRect(9, y, MODELSEL_W-1-9, 7); + lcd_rect(8, y-1, MODELSEL_W-1-7, 9, s_copyMode == COPY_MODE ? SOLID : DOTTED); + } + } + + if (modelselBitmapIdx != m_posVert) { + modelselBitmapIdx = m_posVert; + if (modelselBitmapIdx == g_eeGeneral.currModel) + memcpy(modelselBitmap, modelBitmap, MODEL_BITMAP_SIZE); + else + loadModelBitmap(modelHeaders[sub].bitmap, modelselBitmap); + } + lcd_bmp(22*FW+2, 2*FH+FH/2, modelselBitmap); +} diff --git a/radio/src/gui/Taranis/menu_model_setup.cpp b/radio/src/gui/Taranis/menu_model_setup.cpp index 32036d4b60..aba4e7c86f 100644 --- a/radio/src/gui/Taranis/menu_model_setup.cpp +++ b/radio/src/gui/Taranis/menu_model_setup.cpp @@ -200,7 +200,7 @@ void menuModelSetup(uint8_t event) putsStrIdx(0*FW, y, STR_TIMER, timerIdx+1); putsTimerMode(MODEL_SETUP_2ND_COLUMN, y, timer->mode, m_posHorz==0 ? attr : 0); putsTimer(MODEL_SETUP_2ND_COLUMN+5*FW-2+5*FWNUM+1, y, timer->start, m_posHorz==1 ? attr : 0, m_posHorz==2 ? attr : 0); - if (attr && m_posHorz < 0) lcd_filled_rect(MODEL_SETUP_2ND_COLUMN-1, y-1, LCD_W-MODEL_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH+1, FH+1); + if (attr && m_posHorz < 0) drawFilledRect(MODEL_SETUP_2ND_COLUMN-1, y-1, LCD_W-MODEL_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH+1, FH+1); if (attr && (editMode>0 || p1valdiff)) { div_t qr = div(timer->start, 60); switch (m_posHorz) { @@ -393,7 +393,7 @@ void menuModelSetup(uint8_t event) states >>= 2; } if (attr && m_posHorz < 0) { - lcd_filled_rect(MODEL_SETUP_2ND_COLUMN-1, y-1, 8*(2*FW+1), ONE_2x2POS_DEFINED() ? 2*FH+1 : FH+1); + drawFilledRect(MODEL_SETUP_2ND_COLUMN-1, y-1, 8*(2*FW+1), ONE_2x2POS_DEFINED() ? 2*FH+1 : FH+1); } break; } @@ -663,7 +663,7 @@ void menuModelSetup(uint8_t event) } } else { - lcd_filled_rect(MODEL_SETUP_2ND_COLUMN, y, LCD_W-MODEL_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8); + drawFilledRect(MODEL_SETUP_2ND_COLUMN, y, LCD_W-MODEL_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8); } } } diff --git a/radio/src/gui/Taranis/menu_model_telemetry.cpp b/radio/src/gui/Taranis/menu_model_telemetry.cpp new file mode 100644 index 0000000000..c5aad2c9ce --- /dev/null +++ b/radio/src/gui/Taranis/menu_model_telemetry.cpp @@ -0,0 +1,710 @@ +/* + * Authors (alphabetical order) + * - Andre Bernet + * - Andreas Weitl + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Gabriel Birkus + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Thomas Husterer + * + * opentx is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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. + * + */ + +#include "../../opentx.h" + +enum menuModelTelemetryItems { + ITEM_TELEMETRY_PROTOCOL_TYPE, + ITEM_TELEMETRY_RSSI_LABEL, + ITEM_TELEMETRY_RSSI_ALARM1, + ITEM_TELEMETRY_RSSI_ALARM2, + ITEM_TELEMETRY_SENSORS_LABEL, + ITEM_TELEMETRY_SENSOR1, + ITEM_TELEMETRY_SENSOR2, + ITEM_TELEMETRY_SENSOR3, + ITEM_TELEMETRY_SENSOR4, + ITEM_TELEMETRY_SENSOR5, + ITEM_TELEMETRY_SENSOR6, + ITEM_TELEMETRY_SENSOR7, + ITEM_TELEMETRY_SENSOR8, + ITEM_TELEMETRY_SENSOR9, + ITEM_TELEMETRY_SENSOR10, + ITEM_TELEMETRY_SENSOR11, + ITEM_TELEMETRY_SENSOR12, + ITEM_TELEMETRY_SENSOR13, + ITEM_TELEMETRY_SENSOR14, + ITEM_TELEMETRY_SENSOR15, + ITEM_TELEMETRY_SENSOR16, + ITEM_TELEMETRY_SENSOR17, + ITEM_TELEMETRY_SENSOR18, + ITEM_TELEMETRY_SENSOR19, + ITEM_TELEMETRY_SENSOR20, + ITEM_TELEMETRY_SENSOR21, + ITEM_TELEMETRY_SENSOR22, + ITEM_TELEMETRY_SENSOR23, + ITEM_TELEMETRY_SENSOR24, + ITEM_TELEMETRY_SENSOR25, + ITEM_TELEMETRY_SENSOR26, + ITEM_TELEMETRY_SENSOR27, + ITEM_TELEMETRY_SENSOR28, + ITEM_TELEMETRY_SENSOR29, + ITEM_TELEMETRY_SENSOR30, + ITEM_TELEMETRY_SENSOR31, + ITEM_TELEMETRY_SENSOR32, + ITEM_TELEMETRY_NEWSENSOR, + CASE_VARIO(ITEM_TELEMETRY_VARIO_LABEL) +#if defined(VARIO) + ITEM_TELEMETRY_VARIO_SOURCE, +#endif + CASE_VARIO(ITEM_TELEMETRY_VARIO_RANGE) + ITEM_TELEMETRY_TOP_BAR_LABEL, + ITEM_TELEMETRY_TOP_BAR_VOLTAGE, + ITEM_TELEMETRY_TOP_BAR_ALTITUDE, + ITEM_TELEMETRY_SCREEN_LABEL1, + ITEM_TELEMETRY_SCREEN_LINE1, + ITEM_TELEMETRY_SCREEN_LINE2, + ITEM_TELEMETRY_SCREEN_LINE3, + ITEM_TELEMETRY_SCREEN_LINE4, + ITEM_TELEMETRY_SCREEN_LABEL2, + ITEM_TELEMETRY_SCREEN_LINE5, + ITEM_TELEMETRY_SCREEN_LINE6, + ITEM_TELEMETRY_SCREEN_LINE7, + ITEM_TELEMETRY_SCREEN_LINE8, + ITEM_TELEMETRY_SCREEN_LABEL3, + ITEM_TELEMETRY_SCREEN_LINE9, + ITEM_TELEMETRY_SCREEN_LINE10, + ITEM_TELEMETRY_SCREEN_LINE11, + ITEM_TELEMETRY_SCREEN_LINE12, + ITEM_TELEMETRY_SCREEN_LABEL4, + ITEM_TELEMETRY_SCREEN_LINE13, + ITEM_TELEMETRY_SCREEN_LINE14, + ITEM_TELEMETRY_SCREEN_LINE15, + ITEM_TELEMETRY_SCREEN_LINE16, + ITEM_TELEMETRY_MAX +}; + +#define TELEM_COL1 (1*FW) +#define TELEM_COL2 (16*FW) +#define TELEM_COL3 (28*FW) +#define TELEM_BARS_COLMIN TELEM_COL2 +#define TELEM_BARS_COLMAX TELEM_COL3 +#define TELEM_SCRTYPE_COL TELEM_COL2 + +#define IF_FAS_OFFSET(x) x, +#define IS_RANGE_DEFINED(k) (g_model.frsky.channels[k].ratio > 0) + +#define CHANNELS_ROWS +#define SENSOR_ROWS(x) (isTelemetryFieldAvailable(x) ? (uint8_t)0 : HIDDEN_ROW) +#define SENSORS_ROWS LABEL(Sensors), SENSOR_ROWS(0), SENSOR_ROWS(1), SENSOR_ROWS(2), SENSOR_ROWS(3), SENSOR_ROWS(4), SENSOR_ROWS(5), SENSOR_ROWS(6), SENSOR_ROWS(7), SENSOR_ROWS(8), SENSOR_ROWS(9), SENSOR_ROWS(10), SENSOR_ROWS(11), SENSOR_ROWS(12), SENSOR_ROWS(13), SENSOR_ROWS(14), SENSOR_ROWS(15), SENSOR_ROWS(16), SENSOR_ROWS(17), SENSOR_ROWS(18), SENSOR_ROWS(19), SENSOR_ROWS(20), SENSOR_ROWS(21), SENSOR_ROWS(22), SENSOR_ROWS(23), SENSOR_ROWS(24), SENSOR_ROWS(25), SENSOR_ROWS(26), SENSOR_ROWS(27), SENSOR_ROWS(28), SENSOR_ROWS(29), SENSOR_ROWS(30), SENSOR_ROWS(31), 0, +#define USRDATA_ROWS +#define RSSI_ROWS LABEL(RSSI), 0, 0, +#if defined(LUA) + #define SCREEN_TYPE_ROWS 1 +#else + #define SCREEN_TYPE_ROWS 0 +#endif +#define VARIO_RANGE_ROWS 3 +#define TELEMETRY_TYPE_ROWS (g_model.moduleData[INTERNAL_MODULE].rfProtocol == RF_PROTO_OFF && g_model.externalModule == MODULE_TYPE_PPM) ? (uint8_t)0 : HIDDEN_ROW, + +#if defined(LUA) + #define TELEMETRY_SCREEN_LINE(x) ((TELEMETRY_SCREEN_TYPE(x) == TELEMETRY_SCREEN_TYPE_NONE || TELEMETRY_SCREEN_TYPE(x) == TELEMETRY_SCREEN_TYPE_SCRIPT) ? HIDDEN_ROW : (uint8_t)2) +#else + #define TELEMETRY_SCREEN_LINE(x) (TELEMETRY_SCREEN_TYPE(x) == TELEMETRY_SCREEN_TYPE_NONE ? HIDDEN_ROW : (uint8_t)2) +#endif +#define TELEMETRY_SCREEN_ROWS(x) SCREEN_TYPE_ROWS, TELEMETRY_SCREEN_LINE(x), TELEMETRY_SCREEN_LINE(x), TELEMETRY_SCREEN_LINE(x), TELEMETRY_SCREEN_LINE(x) +#define TELEMETRY_CURRENT_EDIT_SCREEN(k) (k < ITEM_TELEMETRY_SCREEN_LABEL2 ? 0 : (k < ITEM_TELEMETRY_SCREEN_LABEL3 ? 1 : (k < ITEM_TELEMETRY_SCREEN_LABEL4 ? 2 : 3))) + +enum SensorFields { + SENSOR_FIELD_NAME, + SENSOR_FIELD_TYPE, + SENSOR_FIELD_ID, + SENSOR_FIELD_FORMULA=SENSOR_FIELD_ID, + SENSOR_FIELD_UNIT, + SENSOR_FIELD_PRECISION, + SENSOR_FIELD_PARAM1, + SENSOR_FIELD_PARAM2, + SENSOR_FIELD_PARAM3, + SENSOR_FIELD_PARAM4, + SENSOR_FIELD_INPUT_FLAGS, + SENSOR_FIELD_LOGS, + SENSOR_FIELD_MAX +}; + +bool isSensorUnit(int sensor, uint8_t unit) +{ + if (sensor == 0) + return true; + + sensor -= 1; + + return g_model.telemetrySensors[sensor].unit == unit; +} + +bool isCellsSensor(int sensor) +{ + return isSensorUnit(sensor, UNIT_CELLS); +} + +bool isGPSSensor(int sensor) +{ + return isSensorUnit(sensor, UNIT_GPS); +} + +bool isAltSensor(int sensor) +{ + return isSensorUnit(sensor, UNIT_DIST); +} + +bool isVoltsSensor(int sensor) +{ + return isSensorUnit(sensor, UNIT_VOLTS); +} + +bool isCurrentSensor(int sensor) +{ + return isSensorUnit(sensor, UNIT_AMPS); +} + +bool isSensorAvailable(int sensor) +{ + if (sensor == 0) + return true; + else + return isTelemetryFieldAvailable(abs(sensor) - 1); +} + +#define SENSOR_2ND_COLUMN (12*FW) +#define SENSOR_3RD_COLUMN (18*FW) + +#define SENSOR_UNIT_ROWS (sensor->type == TELEM_TYPE_CALCULATED && sensor->formula >= TELEM_FORMULA_CELL) ? HIDDEN_ROW : ((sensor->unit == UNIT_GPS || sensor->unit == UNIT_DATETIME || sensor->unit == UNIT_CELLS) ? HIDDEN_ROW : (uint8_t)0) +#define SENSOR_PREC_ROWS (sensor->type == TELEM_TYPE_CALCULATED && sensor->formula >= TELEM_FORMULA_CELL) ? HIDDEN_ROW : ((sensor->unit == UNIT_GPS || sensor->unit == UNIT_DATETIME) ? HIDDEN_ROW : (uint8_t)0) +#define SENSOR_PARAM1_ROWS (sensor->unit == UNIT_GPS || sensor->unit == UNIT_DATETIME || sensor->unit == UNIT_CELLS) ? HIDDEN_ROW : (uint8_t)0 +#define SENSOR_PARAM2_ROWS (sensor->unit == UNIT_GPS || sensor->unit == UNIT_DATETIME || sensor->unit == UNIT_CELLS || (sensor->type==TELEM_TYPE_CALCULATED && sensor->formula==TELEM_FORMULA_CONSUMPTION)) ? HIDDEN_ROW : (uint8_t)0 +#define SENSOR_PARAM3_ROWS (sensor->type == TELEM_TYPE_CALCULATED && sensor->formula < TELEM_FORMULA_MULTIPLY) ? (uint8_t)0 : HIDDEN_ROW +#define SENSOR_PARAM4_ROWS (sensor->type == TELEM_TYPE_CALCULATED && sensor->formula < TELEM_FORMULA_MULTIPLY) ? (uint8_t)0 : HIDDEN_ROW + +void menuModelSensor(uint8_t event) +{ + TelemetrySensor * sensor = & g_model.telemetrySensors[s_currIdx]; + + SUBMENU(STR_MENUSENSOR, SENSOR_FIELD_MAX, {0, 0, sensor->type == TELEM_TYPE_CALCULATED ? (uint8_t)0 : (uint8_t)1, SENSOR_UNIT_ROWS, SENSOR_PREC_ROWS, SENSOR_PARAM1_ROWS, SENSOR_PARAM2_ROWS, SENSOR_PARAM3_ROWS, SENSOR_PARAM4_ROWS, 0 }); + lcd_outdezAtt(PSIZE(TR_MENUSENSOR)*FW+1, 0, s_currIdx+1, INVERS|LEFT); + + putsTelemetryChannelValue(SENSOR_2ND_COLUMN, 0, s_currIdx, getValue(MIXSRC_FIRST_TELEM+3*s_currIdx), LEFT); + + int8_t sub = m_posVert; + + for (uint8_t i=0; i0 ? BLINK|INVERS : INVERS) : 0); + + switch (k) { + + case SENSOR_FIELD_NAME: + editSingleName(SENSOR_2ND_COLUMN, y, STR_NAME, sensor->label, TELEM_LABEL_LEN, event, attr); + break; + + case SENSOR_FIELD_TYPE: + sensor->type = selectMenuItem(SENSOR_2ND_COLUMN, y, STR_TYPE, "\012Custom\0 Calculated", sensor->type, 0, 1, attr, event); + if (attr && checkIncDec_Ret) { + sensor->instance = 0; + if (sensor->type == TELEM_TYPE_CALCULATED) { + sensor->param = 0; + sensor->inputFlags = 0; + } + } + break; + + case SENSOR_FIELD_ID: + if (sensor->type == TELEM_TYPE_CUSTOM) { + lcd_putsLeft(y, STR_ID); + lcd_outhex4(SENSOR_2ND_COLUMN, y, sensor->id, LEFT|(m_posHorz==0 ? attr : 0)); + lcd_outdezAtt(SENSOR_3RD_COLUMN, y, sensor->instance, LEFT|(m_posHorz==1 ? attr : 0)); + if (attr) { + switch (m_posHorz) { + case 0: + CHECK_INCDEC_MODELVAR_ZERO(event, sensor->id, 0xffff); + break; + + case 1: + CHECK_INCDEC_MODELVAR_ZERO(event, sensor->instance, 0xff); + break; + } + } + } + else { + sensor->formula = selectMenuItem(SENSOR_2ND_COLUMN, y, "Formula", "\010Add\0 Average\0Min\0 Max\0 MultiplyCell\0 ConsumptDistance", sensor->formula, 0, TELEM_FORMULA_DIST, attr, event); + if (attr && checkIncDec_Ret) { + sensor->param = 0; + if (sensor->formula == TELEM_FORMULA_CELL) { + sensor->unit = UNIT_VOLTS; + sensor->prec = 2; + } + else if (sensor->formula == TELEM_FORMULA_DIST) { + sensor->unit = UNIT_DIST; + sensor->prec = 0; + } + else if (sensor->formula == TELEM_FORMULA_CONSUMPTION) { + sensor->unit = UNIT_MAH; + sensor->prec = 0; + } + } + } + break; + + case SENSOR_FIELD_UNIT: + lcd_putsLeft(y, "Unit"); + // TODO flash saving with selectMenuItem where I copied those 2 lines? + lcd_putsiAtt(SENSOR_2ND_COLUMN, y, STR_VTELEMUNIT, sensor->unit, attr); + if (attr) { + CHECK_INCDEC_MODELVAR_ZERO(event, sensor->unit, UNIT_MAX); + if (checkIncDec_Ret) { + telemetryItems[s_currIdx].clear(); + } + } + break; + + case SENSOR_FIELD_PRECISION: + sensor->prec = selectMenuItem(SENSOR_2ND_COLUMN, y, STR_PRECISION, "\005PREC0PREC1PREC2", sensor->prec, 0, 2, attr, event); + if (attr && checkIncDec_Ret) { + telemetryItems[s_currIdx].clear(); + } + break; + + case SENSOR_FIELD_PARAM1: + if (sensor->type == TELEM_TYPE_CALCULATED) { + if (sensor->formula == TELEM_FORMULA_CELL) { + lcd_putsLeft(y, "Cells sensor"); + putsMixerSource(SENSOR_2ND_COLUMN, y, sensor->cell.source ? MIXSRC_FIRST_TELEM+3*(sensor->cell.source-1) : 0, attr); + if (attr) { + sensor->cell.source = checkIncDec(event, sensor->cell.source, 0, TELEM_VALUES_MAX, EE_MODEL|NO_INCDEC_MARKS, isCellsSensor); + } + break; + } + else if (sensor->formula == TELEM_FORMULA_DIST) { + lcd_putsLeft(y, "GPS sensor"); + putsMixerSource(SENSOR_2ND_COLUMN, y, sensor->dist.gps ? MIXSRC_FIRST_TELEM+3*(sensor->dist.gps-1) : 0, attr); + if (attr) { + sensor->dist.gps = checkIncDec(event, sensor->dist.gps, 0, TELEM_VALUES_MAX, EE_MODEL|NO_INCDEC_MARKS, isGPSSensor); + } + break; + } + else if (sensor->formula == TELEM_FORMULA_CONSUMPTION) { + lcd_putsLeft(y, "Amps sensor"); + putsMixerSource(SENSOR_2ND_COLUMN, y, sensor->consumption.source ? MIXSRC_FIRST_TELEM+3*(sensor->consumption.source-1) : 0, attr); + if (attr) { + sensor->consumption.source = checkIncDec(event, sensor->consumption.source, 0, TELEM_VALUES_MAX, EE_MODEL|NO_INCDEC_MARKS, isCurrentSensor); + } + break; + } + } + else { + lcd_putsLeft(y, "Ratio"); + if (attr) CHECK_INCDEC_MODELVAR(event, sensor->custom.ratio, 0, 30000); + if (sensor->custom.ratio == 0) + lcd_putcAtt(SENSOR_2ND_COLUMN, y, '-', attr); + else + lcd_outdezAtt(SENSOR_2ND_COLUMN, y, sensor->custom.ratio, LEFT|attr|PREC1); + break; + } + // no break + + case SENSOR_FIELD_PARAM2: + if (sensor->type == TELEM_TYPE_CALCULATED) { + if (sensor->formula == TELEM_FORMULA_CELL) { + sensor->cell.index = selectMenuItem(SENSOR_2ND_COLUMN, y, "Cell index", "\007Lowest\0001\0 2\0 3\0 4\0 5\0 6\0 HighestDelta\0", sensor->cell.index, 0, 8, attr, event); + break; + } + else if (sensor->formula == TELEM_FORMULA_DIST) { + lcd_putsLeft(y, "Alt sensor"); + putsMixerSource(SENSOR_2ND_COLUMN, y, sensor->dist.alt ? MIXSRC_FIRST_TELEM+3*(sensor->dist.alt-1) : 0, attr); + if (attr) { + sensor->dist.alt = checkIncDec(event, sensor->dist.alt, 0, TELEM_VALUES_MAX, EE_MODEL|NO_INCDEC_MARKS, isAltSensor); + } + break; + } + } + else { + lcd_putsLeft(y, NO_INDENT(STR_OFFSET)); + if (attr) CHECK_INCDEC_MODELVAR(event, sensor->custom.offset, -30000, +30000); + if (sensor->prec > 0) attr |= (sensor->prec == 2 ? PREC2 : PREC1); + lcd_outdezAtt(SENSOR_2ND_COLUMN, y, sensor->custom.offset, LEFT|attr); + break; + } + // no break + + case SENSOR_FIELD_PARAM3: + // no break + + case SENSOR_FIELD_PARAM4: + { + putsStrIdx(0, y, "Source", k-SENSOR_FIELD_PARAM1+1); + int8_t & source = sensor->calc.sources[k-SENSOR_FIELD_PARAM1]; + if (attr) { + source = checkIncDec(event, source, -TELEM_VALUES_MAX, TELEM_VALUES_MAX, EE_MODEL|NO_INCDEC_MARKS, isSensorAvailable); + } + if (source < 0) { + lcd_putcAtt(SENSOR_2ND_COLUMN, y, '-', attr); + putsMixerSource(lcdNextPos, y, MIXSRC_FIRST_TELEM+3*(-1-source), attr); + } + else { + putsMixerSource(SENSOR_2ND_COLUMN, y, source ? MIXSRC_FIRST_TELEM+3*(source-1) : 0, attr); + } + break; + } + + case SENSOR_FIELD_INPUT_FLAGS: + sensor->inputFlags = selectMenuItem(SENSOR_2ND_COLUMN, y, "Options", "\013None\0 ""Auto Offset""Filter\0", sensor->inputFlags, 0, TELEM_INPUT_FLAGS_MAX, attr, event); + break; + + case SENSOR_FIELD_LOGS: + ON_OFF_MENU_ITEM(sensor->logs, SENSOR_2ND_COLUMN, y, "Logs", attr, event); + break; + + } + } +} + +void onSensorMenu(const char *result) +{ + uint8_t index = m_posVert - 1 - ITEM_TELEMETRY_SENSOR1; + + if (index < TELEM_VALUES_MAX) { + if (result == STR_EDIT) { + pushMenu(menuModelSensor); + } + else if (result == STR_DELETE) { + delTelemetryIndex(index); + index += 1; + if (index0) ? BLINK|INVERS : INVERS); + uint8_t attr = (sub == k ? blink : 0); + + if (k>=ITEM_TELEMETRY_SENSOR1 && k= 0) { + s_currIdx = res; + pushMenu(menuModelSensor); + } + } + break; + + case ITEM_TELEMETRY_RSSI_LABEL: + lcd_putsLeft(y, PSTR("RSSI")); + break; + + case ITEM_TELEMETRY_RSSI_ALARM1: + case ITEM_TELEMETRY_RSSI_ALARM2: { + uint8_t alarm = k-ITEM_TELEMETRY_RSSI_ALARM1; + lcd_putsLeft(y, (alarm==0 ? STR_LOWALARM : STR_CRITICALALARM)); + lcd_outdezNAtt(TELEM_COL2, y, getRssiAlarmValue(alarm), LEFT|attr, 3); + if (attr && (s_editMode>0 || p1valdiff)) { + CHECK_INCDEC_MODELVAR(event, g_model.frsky.rssiAlarms[alarm].value, -30, 30); + } + break; + } + +#if defined(VARIO) + case ITEM_TELEMETRY_VARIO_LABEL: + lcd_putsLeft(y, STR_VARIO); + break; + + case ITEM_TELEMETRY_VARIO_SOURCE: + lcd_putsLeft(y, STR_SOURCE); + putsMixerSource(TELEM_COL2, y, g_model.frsky.varioSource ? MIXSRC_FIRST_TELEM+3*(g_model.frsky.varioSource-1) : 0, attr); + if (attr) { + g_model.frsky.varioSource = checkIncDec(event, g_model.frsky.varioSource, 0, TELEM_VALUES_MAX, EE_MODEL|NO_INCDEC_MARKS, isSensorAvailable); + } + break; + + case ITEM_TELEMETRY_VARIO_RANGE: + lcd_putsLeft(y, STR_LIMIT); + lcd_outdezAtt(TELEM_COL2, y, -10+g_model.frsky.varioMin, (m_posHorz<=0 ? attr : 0)|LEFT); + lcd_outdezAtt(TELEM_COL2+7*FW-2, y, -5+g_model.frsky.varioCenterMin, ((CURSOR_ON_LINE() || m_posHorz==1) ? attr : 0)|PREC1); + lcd_outdezAtt(TELEM_COL2+10*FW, y, 5+g_model.frsky.varioCenterMax, ((CURSOR_ON_LINE() || m_posHorz==2) ? attr : 0)|PREC1); + lcd_outdezAtt(TELEM_COL2+13*FW+2, y, 10+g_model.frsky.varioMax, ((CURSOR_ON_LINE() || m_posHorz==3) ? attr : 0)); + if (attr && (s_editMode>0 || p1valdiff)) { + switch (m_posHorz) { + case 0: + CHECK_INCDEC_MODELVAR(event, g_model.frsky.varioMin, -7, 7); + break; + case 1: + CHECK_INCDEC_MODELVAR(event, g_model.frsky.varioCenterMin, -16, 5+min(10, g_model.frsky.varioCenterMax+5)); + break; + case 2: + CHECK_INCDEC_MODELVAR(event, g_model.frsky.varioCenterMax, -5+max(-10, g_model.frsky.varioCenterMin-5), +15); + break; + case 3: + CHECK_INCDEC_MODELVAR(event, g_model.frsky.varioMax, -7, 7); + break; + } + } + break; +#endif + + case ITEM_TELEMETRY_TOP_BAR_LABEL: + lcd_putsLeft(y, STR_TOP_BAR); + break; + + case ITEM_TELEMETRY_TOP_BAR_VOLTAGE: + lcd_putsLeft(y, STR_VOLTAGE); + putsMixerSource(TELEM_COL2, y, g_model.frsky.voltsSource ? MIXSRC_FIRST_TELEM+3*(g_model.frsky.voltsSource-1) : 0, attr); + if (attr) { + g_model.frsky.voltsSource = checkIncDec(event, g_model.frsky.voltsSource, 0, TELEM_VALUES_MAX, EE_MODEL|NO_INCDEC_MARKS, isVoltsSensor); + } + break; + + case ITEM_TELEMETRY_TOP_BAR_ALTITUDE: + lcd_putsLeft(y, STR_ALTITUDE); + putsMixerSource(TELEM_COL2, y, g_model.frsky.altitudeSource ? MIXSRC_FIRST_TELEM+3*(g_model.frsky.altitudeSource-1) : 0, attr); + if (attr) { + g_model.frsky.altitudeSource = checkIncDec(event, g_model.frsky.altitudeSource, 0, TELEM_VALUES_MAX, EE_MODEL|NO_INCDEC_MARKS, isAltSensor); + } + break; + + case ITEM_TELEMETRY_SCREEN_LABEL1: + case ITEM_TELEMETRY_SCREEN_LABEL2: + case ITEM_TELEMETRY_SCREEN_LABEL3: + case ITEM_TELEMETRY_SCREEN_LABEL4: + { + uint8_t screenIndex = TELEMETRY_CURRENT_EDIT_SCREEN(k); + putsStrIdx(0*FW, y, STR_SCREEN, screenIndex+1); + TelemetryScreenType oldScreenType = TELEMETRY_SCREEN_TYPE(screenIndex); + TelemetryScreenType newScreenType = (TelemetryScreenType)selectMenuItem(TELEM_SCRTYPE_COL, y, PSTR(""), STR_VTELEMSCREENTYPE, oldScreenType, 0, TELEMETRY_SCREEN_TYPE_MAX, (m_posHorz==0 ? attr : 0), event); + if (newScreenType != oldScreenType) { + g_model.frsky.screensType = (g_model.frsky.screensType & (~(0x03 << (2*screenIndex)))) | (newScreenType << (2*screenIndex)); + memset(&g_model.frsky.screens[screenIndex], 0, sizeof(g_model.frsky.screens[screenIndex])); + } +#if defined(LUA) + if (newScreenType == TELEMETRY_SCREEN_TYPE_SCRIPT) { + TelemetryScriptData & scriptData = g_model.frsky.screens[screenIndex].script; + + // TODO better function name for --- + // TODO function for these lines + if (ZEXIST(scriptData.file)) + lcd_putsnAtt(TELEM_SCRTYPE_COL+7*FW, y, scriptData.file, sizeof(scriptData.file), (m_posHorz==1 ? attr : 0)); + else + lcd_putsiAtt(TELEM_SCRTYPE_COL+7*FW, y, STR_VCSWFUNC, 0, (m_posHorz==1 ? attr : 0)); + + if (m_posHorz==1 && attr && event==EVT_KEY_BREAK(KEY_ENTER) && READ_ONLY_UNLOCKED()) { + s_editMode = 0; + if (listSdFiles(SCRIPTS_TELEM_PATH, SCRIPTS_EXT, sizeof(g_model.frsky.screens[screenIndex].script.file), g_model.frsky.screens[screenIndex].script.file)) { + menuHandler = onTelemetryScriptFileSelectionMenu; + } + else { + POPUP_WARNING(STR_NO_SCRIPTS_ON_SD); + s_menu_flags = 0; + } + } + } + else if (attr) { + MOVE_CURSOR_FROM_HERE(); + } +#endif + break; + } + + case ITEM_TELEMETRY_SCREEN_LINE1: + case ITEM_TELEMETRY_SCREEN_LINE2: + case ITEM_TELEMETRY_SCREEN_LINE3: + case ITEM_TELEMETRY_SCREEN_LINE4: + case ITEM_TELEMETRY_SCREEN_LINE5: + case ITEM_TELEMETRY_SCREEN_LINE6: + case ITEM_TELEMETRY_SCREEN_LINE7: + case ITEM_TELEMETRY_SCREEN_LINE8: + case ITEM_TELEMETRY_SCREEN_LINE9: + case ITEM_TELEMETRY_SCREEN_LINE10: + case ITEM_TELEMETRY_SCREEN_LINE11: + case ITEM_TELEMETRY_SCREEN_LINE12: + case ITEM_TELEMETRY_SCREEN_LINE13: + case ITEM_TELEMETRY_SCREEN_LINE14: + case ITEM_TELEMETRY_SCREEN_LINE15: + case ITEM_TELEMETRY_SCREEN_LINE16: + { + uint8_t screenIndex, lineIndex; + if (k < ITEM_TELEMETRY_SCREEN_LABEL2) { + screenIndex = 0; + lineIndex = k-ITEM_TELEMETRY_SCREEN_LINE1; + } + else if (k >= ITEM_TELEMETRY_SCREEN_LABEL4) { + screenIndex = 3; + lineIndex = k-ITEM_TELEMETRY_SCREEN_LINE13; + } + else if (k >= ITEM_TELEMETRY_SCREEN_LABEL3) { + screenIndex = 2; + lineIndex = k-ITEM_TELEMETRY_SCREEN_LINE9; + } + else { + screenIndex = 1; + lineIndex = k-ITEM_TELEMETRY_SCREEN_LINE5; + } + +#if defined(GAUGES) + if (IS_BARS_SCREEN(screenIndex)) { + FrSkyBarData & bar = g_model.frsky.screens[screenIndex].bars[lineIndex]; + source_t barSource = bar.source; + putsMixerSource(TELEM_COL1, y, barSource, m_posHorz==0 ? attr : 0); + if (barSource) { + putsChannelValue(TELEM_BARS_COLMIN, y, barSource, bar.barMin, (m_posHorz==1 ? attr : 0) | LEFT); + putsChannelValue(TELEM_BARS_COLMAX, y, barSource, bar.barMax, (m_posHorz==2 ? attr : 0) | LEFT); + } + else if (attr) { + MOVE_CURSOR_FROM_HERE(); + } + if (attr && (s_editMode>0 || p1valdiff)) { + switch (m_posHorz) { + case 0: + bar.source = CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, barSource, MIXSRC_LAST_TELEM, isSourceAvailable); + if (checkIncDec_Ret) { + bar.barMin = 0; + bar.barMax = 0; + } + break; + case 1: + bar.barMin = checkIncDec(event, bar.barMin, -30000, bar.barMax, EE_MODEL|NO_INCDEC_MARKS); + break; + case 2: + bar.barMax = checkIncDec(event, bar.barMax, bar.barMin, 30000, EE_MODEL|NO_INCDEC_MARKS); + break; + } + } + } + else +#endif + { + for (uint8_t c=0; c0 || p1valdiff)) { + CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, value, MIXSRC_LAST_TELEM, isSourceAvailable); + } + } + if (attr && m_posHorz == NUM_LINE_ITEMS) { + REPEAT_LAST_CURSOR_MOVE(); + } + } + break; + } + } + } +} diff --git a/radio/src/gui/Taranis/view_main.cpp b/radio/src/gui/Taranis/view_main.cpp index 1f2348839b..024f1ef59c 100755 --- a/radio/src/gui/Taranis/view_main.cpp +++ b/radio/src/gui/Taranis/view_main.cpp @@ -158,7 +158,7 @@ void displayTrims(uint8_t phase) lcd_vline(xm+1, ym-1, 3); } ym -= val; - lcd_filled_rect(xm-3, ym-3, 7, 7, SOLID, att|ERASE); + drawFilledRect(xm-3, ym-3, 7, 7, SOLID, att|ERASE); if (dir >= 0) { lcd_hline(xm-1, ym-1, 3); } @@ -180,7 +180,7 @@ void displayTrims(uint8_t phase) lcd_hline(xm-1, ym-1, 3); lcd_hline(xm-1, ym+1, 3); xm += val; - lcd_filled_rect(xm-3, ym-3, 7, 7, SOLID, att|ERASE); + drawFilledRect(xm-3, ym-3, 7, 7, SOLID, att|ERASE); if (dir >= 0) { lcd_vline(xm+1, ym-1, 3); } @@ -232,7 +232,7 @@ void displaySliders() void displayTopBarGauge(coord_t x, int count, bool blinking=false) { if (!blinking || BLINK_ON_PHASE) - lcd_filled_rect(x+1, BAR_Y+2, 11, 5, SOLID, ERASE); + drawFilledRect(x+1, BAR_Y+2, 11, 5, SOLID, ERASE); count = min(10, count); for (int i=0; i 0) { s_gvar_timer--; - lcd_filled_rect(BITMAP_X, BITMAP_Y, 64, 32, SOLID, ERASE); + drawFilledRect(BITMAP_X, BITMAP_Y, 64, 32, SOLID, ERASE); lcd_rect(BITMAP_X, BITMAP_Y, 64, 32); putsStrIdx(BITMAP_X+FW, BITMAP_Y+FH-1, STR_GV, s_gvar_last+1); lcd_putsnAtt(BITMAP_X+4*FW+FW/2, BITMAP_Y+FH-1, g_model.gvars[s_gvar_last].name, LEN_GVAR_NAME, ZCHAR); diff --git a/radio/src/gui/menu_general_setup.cpp b/radio/src/gui/menu_general_setup.cpp index 3a101fcb61..eae7587c70 100755 --- a/radio/src/gui/menu_general_setup.cpp +++ b/radio/src/gui/menu_general_setup.cpp @@ -189,7 +189,7 @@ void menuGeneralSetup(uint8_t event) } } #if defined(PCBTARANIS) - if (attr && m_posHorz < 0) lcd_filled_rect(RADIO_SETUP_2ND_COLUMN, y, LCD_W-RADIO_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8); + if (attr && m_posHorz < 0) drawFilledRect(RADIO_SETUP_2ND_COLUMN, y, LCD_W-RADIO_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8); #endif if (attr && checkIncDec_Ret) { g_rtcTime = gmktime(&t); // update local timestamp and get wday calculated @@ -217,7 +217,7 @@ void menuGeneralSetup(uint8_t event) } } #if defined(PCBTARANIS) - if (attr && m_posHorz < 0) lcd_filled_rect(RADIO_SETUP_2ND_COLUMN, y, LCD_W-RADIO_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8); + if (attr && m_posHorz < 0) drawFilledRect(RADIO_SETUP_2ND_COLUMN, y, LCD_W-RADIO_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8); #endif if (attr && checkIncDec_Ret) g_rtcTime = gmktime(&t); // update local timestamp and get wday calculated @@ -231,7 +231,7 @@ void menuGeneralSetup(uint8_t event) lcd_putc(lcdLastPos, y, '-'); putsVolts(lcdLastPos+FW, y, 120+g_eeGeneral.vBatMax, (m_posHorz>0 ? attr : 0)|LEFT|NO_UNIT); #if defined(PCBTARANIS) - if (attr && m_posHorz < 0) lcd_filled_rect(RADIO_SETUP_2ND_COLUMN, y, LCD_W-RADIO_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8); + if (attr && m_posHorz < 0) drawFilledRect(RADIO_SETUP_2ND_COLUMN, y, LCD_W-RADIO_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8); #endif if (attr && s_editMode>0) { if (m_posHorz==0) @@ -583,7 +583,7 @@ void menuGeneralSetup(uint8_t event) lcd_img((6+4*i)*FW, y, sticks, i, 0); #if defined(FRSKY_STICKS) if (g_eeGeneral.stickReverse & (1<= 5 ? MENU_Y - FH - 1 : MENU_Y); - lcd_filled_rect(MENU_X, y, MENU_W, display_count * (FH+1) + 2, SOLID, ERASE); + drawFilledRect(MENU_X, y, MENU_W, display_count * (FH+1) + 2, SOLID, ERASE); lcd_rect(MENU_X, y, MENU_W, display_count * (FH+1) + 2); for (uint8_t i=0; i display_count) { @@ -1472,9 +1472,9 @@ void drawStatusLine() statusLineTime = 0; } - lcd_filled_rect(0, LCD_H-statusLineHeight, LCD_W, FH, SOLID, ERASE); + drawFilledRect(0, LCD_H-statusLineHeight, LCD_W, FH, SOLID, ERASE); lcd_putsAtt(5, LCD_H+1-statusLineHeight, statusLineMsg, BSS); - lcd_filled_rect(0, LCD_H-statusLineHeight, LCD_W, FH, SOLID); + drawFilledRect(0, LCD_H-statusLineHeight, LCD_W, FH, SOLID); } } #endif diff --git a/radio/src/gui/view_telemetry.cpp b/radio/src/gui/view_telemetry.cpp index 184d8b34bd..32a175b503 100644 --- a/radio/src/gui/view_telemetry.cpp +++ b/radio/src/gui/view_telemetry.cpp @@ -65,7 +65,7 @@ void displayRssiLine() uint8_t rssi = min((uint8_t)99, TELEMETRY_RSSI()); lcd_putsn(0, STATUS_BAR_Y, STR_RX, 2); lcd_outdezNAtt(4*FW, STATUS_BAR_Y, rssi, LEADING0, 2); lcd_rect(BAR_LEFT, 57, 78, 7); - lcd_filled_rect(BAR_LEFT+1, 58, 19*rssi/25, 5, (rssi < getRssiAlarmValue(0)) ? DOTTED : SOLID); + drawFilledRect(BAR_LEFT+1, 58, 19*rssi/25, 5, (rssi < getRssiAlarmValue(0)) ? DOTTED : SOLID); } else { lcd_putsAtt(7*FW, STATUS_BAR_Y, STR_NODATA, BLINK); @@ -82,13 +82,13 @@ void displayRssiLine() rssi = min((uint8_t)99, frskyData.rssi[1].value); lcd_putsLeft(STATUS_BAR_Y, STR_TX); lcd_outdezNAtt(4*FW+1, STATUS_BAR_Y, rssi, LEADING0, 2); lcd_rect(BAR_LEFT+1, 57, 38, 7); - lcd_filled_rect(BAR_LEFT+1, 58, 4*rssi/11, 5, (rssi < getRssiAlarmValue(0)) ? DOTTED : SOLID); + drawFilledRect(BAR_LEFT+1, 58, 4*rssi/11, 5, (rssi < getRssiAlarmValue(0)) ? DOTTED : SOLID); #endif rssi = min((uint8_t)99, TELEMETRY_RSSI()); lcd_puts(104, STATUS_BAR_Y, STR_RX); lcd_outdezNAtt(105+4*FW, STATUS_BAR_Y, rssi, LEADING0, 2); lcd_rect(65, 57, 38, 7); uint8_t v = 4*rssi/11; - lcd_filled_rect(66+36-v, 58, v, 5, (rssi < getRssiAlarmValue(0)) ? DOTTED : SOLID); + drawFilledRect(66+36-v, 58, v, 5, (rssi < getRssiAlarmValue(0)) ? DOTTED : SOLID); } else { lcd_putsAtt(7*FW, STATUS_BAR_Y, STR_NODATA, BLINK); @@ -330,7 +330,7 @@ bool displayGaugesTelemetryScreen(FrSkyScreenData & screen) } #endif - lcd_filled_rect(BAR_LEFT+1, y+1, width, barHeight, barShade); + drawFilledRect(BAR_LEFT+1, y+1, width, barHeight, barShade); for (uint8_t j=24; j<99; j+=25) { if (j>thresholdX || j>width) { diff --git a/radio/src/lcd.h b/radio/src/lcd.h index 7e79068462..2c05031170 100644 --- a/radio/src/lcd.h +++ b/radio/src/lcd.h @@ -270,7 +270,7 @@ void lcd_vline(coord_t x, scoord_t y, scoord_t h); void lcd_line(coord_t x1, coord_t y1, coord_t x2, coord_t y2, uint8_t pat=SOLID, LcdFlags att=0); #endif -void lcd_filled_rect(coord_t x, scoord_t y, coord_t w, coord_t h, uint8_t pat=SOLID, LcdFlags att=0); +void drawFilledRect(coord_t x, scoord_t y, coord_t w, coord_t h, uint8_t pat=SOLID, LcdFlags att=0); void lcd_rect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat=SOLID, LcdFlags att=0); void lcd_invert_line(int8_t line); diff --git a/radio/src/lcd_common.cpp b/radio/src/lcd_common.cpp index 944e550edf..2a8a5fd64a 100644 --- a/radio/src/lcd_common.cpp +++ b/radio/src/lcd_common.cpp @@ -509,7 +509,7 @@ void lcd_outdezNAtt(coord_t x, coord_t y, lcdint_t val, LcdFlags flags, uint8_t } else { // TODO needed on CPUAVR? y &= ~0x07; - lcd_filled_rect(xn, y+2*FH-3, ln, 2); + drawFilledRect(xn, y+2*FH-3, ln, 2); } } if (neg) lcd_putcAtt(x, y, '-', flags); @@ -581,7 +581,7 @@ void lcd_rect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat, LcdFlags } #if !defined(BOOT) -void lcd_filled_rect(coord_t x, scoord_t y, coord_t w, coord_t h, uint8_t pat, LcdFlags att) +void drawFilledRect(coord_t x, scoord_t y, coord_t w, coord_t h, uint8_t pat, LcdFlags att) { #if defined(CPUM64) for (scoord_t i=y; i= 212 - lcd_filled_rect(MESSAGE_LCD_OFFSET, 0, LCD_W-MESSAGE_LCD_OFFSET, 32); + drawFilledRect(MESSAGE_LCD_OFFSET, 0, LCD_W-MESSAGE_LCD_OFFSET, 32); if (t) lcd_puts(MESSAGE_LCD_OFFSET, 5*FH, t); if (last) { lcd_puts(MESSAGE_LCD_OFFSET, 7*FH, last); AUDIO_ERROR_MESSAGE(sound); } #else - lcd_filled_rect(0, 0, LCD_W, 32); + drawFilledRect(0, 0, LCD_W, 32); if (t) lcd_putsLeft(5*FH, t); if (last) { lcd_putsLeft(7*FH, last); diff --git a/radio/src/sdcard.cpp b/radio/src/sdcard.cpp new file mode 100644 index 0000000000..e8bb710cb0 --- /dev/null +++ b/radio/src/sdcard.cpp @@ -0,0 +1,143 @@ +#define LIST_NONE_SD_FILE 1 + +bool listSdFiles(const char *path, const char *extension, const uint8_t maxlen, const char *selection, uint8_t flags=0) +{ + FILINFO fno; + DIR dir; + char *fn; /* This function is assuming non-Unicode cfg. */ +#if _USE_LFN + TCHAR lfn[_MAX_LFN + 1]; + fno.lfname = lfn; + fno.lfsize = sizeof(lfn); +#endif + + static uint16_t s_last_menu_offset = 0; + +#if defined(CPUARM) + static uint8_t s_last_flags; + + if (selection) { + s_last_flags = flags; + memset(reusableBuffer.modelsel.menu_bss, 0, sizeof(reusableBuffer.modelsel.menu_bss)); + strcpy(reusableBuffer.modelsel.menu_bss[0], path); + strcat(reusableBuffer.modelsel.menu_bss[0], "/"); + strncat(reusableBuffer.modelsel.menu_bss[0], selection, maxlen); + strcat(reusableBuffer.modelsel.menu_bss[0], extension); + if (f_stat(reusableBuffer.modelsel.menu_bss[0], &fno) != FR_OK) { + selection = NULL; + } + } + else { + flags = s_last_flags; + } +#endif + + if (s_menu_offset == 0) { + s_last_menu_offset = 0; + memset(reusableBuffer.modelsel.menu_bss, 0, sizeof(reusableBuffer.modelsel.menu_bss)); + } + else if (s_menu_offset == s_menu_count - MENU_MAX_LINES) { + s_last_menu_offset = 0xffff; + memset(reusableBuffer.modelsel.menu_bss, 0, sizeof(reusableBuffer.modelsel.menu_bss)); + } + else if (s_menu_offset == s_last_menu_offset) { + // should not happen, only there because of Murphy's law + return true; + } + else if (s_menu_offset > s_last_menu_offset) { + memmove(reusableBuffer.modelsel.menu_bss[0], reusableBuffer.modelsel.menu_bss[1], (MENU_MAX_LINES-1)*MENU_LINE_LENGTH); + memset(reusableBuffer.modelsel.menu_bss[MENU_MAX_LINES-1], 0xff, MENU_LINE_LENGTH); + } + else { + memmove(reusableBuffer.modelsel.menu_bss[1], reusableBuffer.modelsel.menu_bss[0], (MENU_MAX_LINES-1)*MENU_LINE_LENGTH); + memset(reusableBuffer.modelsel.menu_bss[0], 0, MENU_LINE_LENGTH); + } + + s_menu_count = 0; + s_menu_flags = BSS; + + FRESULT res = f_opendir(&dir, path); /* Open the directory */ + if (res == FR_OK) { + + if (flags & LIST_NONE_SD_FILE) { + s_menu_count++; + if (selection) { + s_last_menu_offset++; + } + else if (s_menu_offset==0 || s_menu_offset < s_last_menu_offset) { + char *line = reusableBuffer.modelsel.menu_bss[0]; + memset(line, 0, MENU_LINE_LENGTH); + strcpy(line, "---"); + s_menu[0] = line; + } + } + + for (;;) { + res = f_readdir(&dir, &fno); /* Read a directory item */ + if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ + +#if _USE_LFN + fn = *fno.lfname ? fno.lfname : fno.fname; +#else + fn = fno.fname; +#endif + + uint8_t len = strlen(fn); + if (len < 5 || len > maxlen+4 || strcasecmp(fn+len-4, extension) || (fno.fattrib & AM_DIR)) continue; + + s_menu_count++; + fn[len-4] = '\0'; + + if (s_menu_offset == 0) { + if (selection && strncasecmp(fn, selection, maxlen) < 0) { + s_last_menu_offset++; + } + else { + for (uint8_t i=0; i=0; i--) { + char *line = reusableBuffer.modelsel.menu_bss[i]; + if (line[0] == '\0' || strcasecmp(fn, line) > 0) { + if (i > 0) memmove(reusableBuffer.modelsel.menu_bss[0], reusableBuffer.modelsel.menu_bss[1], sizeof(reusableBuffer.modelsel.menu_bss[i]) * i); + memset(line, 0, MENU_LINE_LENGTH); + strcpy(line, fn); + break; + } + } + for (uint8_t i=0; i s_last_menu_offset) { + if (strcasecmp(fn, reusableBuffer.modelsel.menu_bss[MENU_MAX_LINES-2]) > 0 && strcasecmp(fn, reusableBuffer.modelsel.menu_bss[MENU_MAX_LINES-1]) < 0) { + memset(reusableBuffer.modelsel.menu_bss[MENU_MAX_LINES-1], 0, MENU_LINE_LENGTH); + strcpy(reusableBuffer.modelsel.menu_bss[MENU_MAX_LINES-1], fn); + } + } + else { + if (strcasecmp(fn, reusableBuffer.modelsel.menu_bss[1]) < 0 && strcasecmp(fn, reusableBuffer.modelsel.menu_bss[0]) > 0) { + memset(reusableBuffer.modelsel.menu_bss[0], 0, MENU_LINE_LENGTH); + strcpy(reusableBuffer.modelsel.menu_bss[0], fn); + } + } + } + } + + if (s_menu_offset > 0) + s_last_menu_offset = s_menu_offset; + else + s_menu_offset = s_last_menu_offset; + + return s_menu_count; +} diff --git a/radio/src/tests/lcd.cpp b/radio/src/tests/lcd.cpp index 937ee86b37..d95cb054da 100644 --- a/radio/src/tests/lcd.cpp +++ b/radio/src/tests/lcd.cpp @@ -208,7 +208,7 @@ TEST(Lcd, Smlsize) lcd_clear(); lcd_putsAtt(0, 0, "TESTgy,", SMLSIZE); lcd_putsAtt(10, 22, "TESTgy,", SMLSIZE|INVERS); - lcd_filled_rect(8, 40, 100, 20); + drawFilledRect(8, 40, 100, 20); lcd_putsAtt(10, 42, "TESTgy,", SMLSIZE); bool invert = false; @@ -225,7 +225,7 @@ TEST(Lcd, Stdsize) lcd_clear(); lcd_putsAtt(0, 0, "TEST", 0); lcd_putsAtt(10, 22, "TEST", INVERS); - lcd_filled_rect(8, 40, 100, 20); + drawFilledRect(8, 40, 100, 20); lcd_putsAtt(10, 42, "TEST", 0); bool invert = false; @@ -242,7 +242,7 @@ TEST(Lcd, Midsize) lcd_clear(); lcd_putsAtt(0, 0, "TEST", MIDSIZE); lcd_putsAtt(10, 22, "TEST", MIDSIZE|INVERS); - lcd_filled_rect(8, 40, 100, 20); + drawFilledRect(8, 40, 100, 20); lcd_putsAtt(10, 42, "TEST", MIDSIZE); bool invert = false; @@ -259,7 +259,7 @@ TEST(Lcd, Dblsize) lcd_clear(); lcd_putsAtt(2, 10, "TST", DBLSIZE); lcd_putsAtt(42, 10, "TST", DBLSIZE|INVERS); - lcd_filled_rect(80, 8, 46, 24); + drawFilledRect(80, 8, 46, 24); lcd_putsAtt(82, 10, "TST", DBLSIZE); bool invert = false;