[Horus] UI continued
This commit is contained in:
@@ -84,6 +84,8 @@ add_dependencies(opentx-taranisx9e${SUFFIX}-simulator ${dependencies_taranis} lu
|
||||
|
||||
add_dependencies(opentx-horus${SUFFIX}-simulator horus_bitmaps horus_fonts firmware_translations lua_export_horus)
|
||||
|
||||
add_definitions(-std=c++11)
|
||||
|
||||
set(OPENTX_LIBRARIES
|
||||
opentx-9x${SUFFIX}-simulator
|
||||
opentx-9xr${SUFFIX}-simulator
|
||||
@@ -165,7 +167,7 @@ target_compile_definitions(opentx-taranisx9e${SUFFIX}-simulator PRIVATE PCBTARAN
|
||||
target_link_libraries(opentx-taranisx9e${SUFFIX}-simulator PRIVATE ${COMMON_LIBRARIES})
|
||||
|
||||
# Horus
|
||||
target_include_directories(opentx-horus${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/horus PRIVATE ${RADIO_SRC_DIRECTORY}/fonts/horus PRIVATE ${CMAKE_BINARY_DIR}/radio/src/bitmaps/horus)
|
||||
target_include_directories(opentx-horus${SUFFIX}-simulator PRIVATE ${RADIO_SRC_DIRECTORY}/targets/horus PRIVATE ${RADIO_SRC_DIRECTORY}/gui/horus PRIVATE ${RADIO_SRC_DIRECTORY}/fonts/horus PRIVATE ${CMAKE_BINARY_DIR}/radio/src/bitmaps/horus)
|
||||
target_compile_definitions(opentx-horus${SUFFIX}-simulator PRIVATE PCBHORUS CPUARM CPUSTM32 STM32F40_41xxx COLORLCD VOICE SDCARD ${COMMON_DEFINITIONS})
|
||||
target_link_libraries(opentx-horus${SUFFIX}-simulator PRIVATE ${COMMON_LIBRARIES})
|
||||
|
||||
|
||||
@@ -172,6 +172,15 @@ namespace NAMESPACE {
|
||||
#include "radio/src/gui/horus/view_about.cpp"
|
||||
#include "radio/src/gui/horus/lcd.cpp"
|
||||
#include "radio/src/gui/horus/splash.cpp"
|
||||
#include "radio/src/gui/horus/widget.cpp"
|
||||
#include "radio/src/gui/horus/layout.cpp"
|
||||
#include "radio/src/gui/horus/layouts/layout2+1.cpp"
|
||||
#include "radio/src/gui/horus/layouts/layout2x2.cpp"
|
||||
#include "radio/src/gui/horus/layouts/layout2x4.cpp"
|
||||
#include "radio/src/gui/horus/widgets/gauge.cpp"
|
||||
#include "radio/src/gui/horus/widgets/modelpanel.cpp"
|
||||
#include "radio/src/gui/horus/widgets/text.cpp"
|
||||
#include "radio/src/gui/horus/widgets/timer.cpp"
|
||||
#elif defined(PCBFLAMENCO)
|
||||
#include "radio/src/gui/Flamenco/fonts.cpp"
|
||||
#include "radio/src/gui/Flamenco/widgets.cpp"
|
||||
|
||||
@@ -21,6 +21,7 @@ option(JITTER_FILTER "Enable ADC jitter filtering" ON)
|
||||
|
||||
enable_language(ASM)
|
||||
set(OPT s)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
|
||||
set(THIRDPARTY_DIR thirdparty)
|
||||
set(LUA_DIR ${THIRDPARTY_DIR}/Lua/src)
|
||||
@@ -64,7 +65,9 @@ if(PCB STREQUAL HORUS)
|
||||
add_definitions(-DPCBHORUS -DCOLORLCD -DSTM32F429_439xx -DPPM_PIN_HW_SERIAL)
|
||||
add_definitions(-DEEPROM_VARIANT=0 -DAUDIO -DVOICE -DRTCLOCK)
|
||||
add_definitions(-DLUAINPUTS -DXCURVES -DVARIO)
|
||||
include_directories(${RADIO_SRC_DIRECTORY}/fonts/horus)
|
||||
include_directories(${RADIO_SRC_DIRECTORY}/fonts/horus gui/${GUI_DIR})
|
||||
file(GLOB LAYOUTS_SRC RELATIVE ${RADIO_SRC_DIRECTORY}/gui/horus ${RADIO_SRC_DIRECTORY}/gui/horus/layouts/*.cpp)
|
||||
file(GLOB WIDGETS_SRC RELATIVE ${RADIO_SRC_DIRECTORY}/gui/horus ${RADIO_SRC_DIRECTORY}/gui/horus/widgets/*.cpp)
|
||||
set(GUI_SRC
|
||||
${GUI_SRC}
|
||||
curves.cpp
|
||||
@@ -76,6 +79,10 @@ if(PCB STREQUAL HORUS)
|
||||
view_about.cpp
|
||||
view_text.cpp
|
||||
screens_setup.cpp
|
||||
widget.cpp
|
||||
layout.cpp
|
||||
${LAYOUTS_SRC}
|
||||
${WIDGETS_SRC}
|
||||
)
|
||||
set(SRC ${SRC} bmp.cpp targets/taranis/rtc_driver.cpp)
|
||||
set(TARGET_SRC ${TARGET_SRC} board_horus.cpp)
|
||||
@@ -777,7 +784,7 @@ set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAG
|
||||
|
||||
if(ARCH STREQUAL ARM)
|
||||
cmake_force_c_compiler(arm-none-eabi-gcc GNU)
|
||||
cmake_force_cxx_compiler(arm-none-eabi-gcc GNU)
|
||||
cmake_force_cxx_compiler(arm-none-eabi-g++ GNU)
|
||||
set(CMAKE_ASM_COMPILER arm-none-eabi-as)
|
||||
|
||||
set(CMAKE_SYSTEM_NAME Generic)
|
||||
@@ -799,6 +806,7 @@ if(ARCH STREQUAL ARM)
|
||||
endif()
|
||||
|
||||
add_executable(firmware ${SRC} ${FIRMWARE_HEADERS})
|
||||
link_libraries(firmware -lstdc++)
|
||||
add_dependencies(firmware ${FIRMWARE_DEPENDENCIES})
|
||||
|
||||
add_custom_command(
|
||||
@@ -845,4 +853,3 @@ if(CPU_FAMILY STREQUAL STM32)
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
@@ -353,7 +353,7 @@ void referenceModelAudioFiles()
|
||||
sdAvailablePhaseAudioFiles = 0;
|
||||
sdAvailableSwitchAudioFiles = 0;
|
||||
sdAvailableLogicalSwitchAudioFiles = 0;
|
||||
|
||||
|
||||
char * filename = getModelAudioPath(path);
|
||||
*(filename-1) = '\0';
|
||||
|
||||
@@ -512,7 +512,7 @@ void audioTask(void * pdata)
|
||||
sdInit();
|
||||
AUDIO_TADA();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
audioQueue.wakeup();
|
||||
@@ -801,7 +801,7 @@ inline unsigned int getToneLength(uint16_t len)
|
||||
void AudioQueue::pause(uint16_t len)
|
||||
{
|
||||
playTone(0, 0, len);
|
||||
}
|
||||
}
|
||||
|
||||
bool AudioQueue::isPlaying(uint8_t id)
|
||||
{
|
||||
@@ -1058,7 +1058,7 @@ void audioEvent(unsigned int index, unsigned int freq)
|
||||
// trim center
|
||||
case AU_TRIM_END:
|
||||
audioQueue.playTone(freq, 80, 20, PLAY_NOW);
|
||||
break;
|
||||
break;
|
||||
// warning one
|
||||
case AU_WARNING1:
|
||||
audioQueue.playTone(BEEP_DEFAULT_FREQ, 80, 20, PLAY_NOW);
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 674 B |
Binary file not shown.
|
After Width: | Height: | Size: 545 B |
Binary file not shown.
|
After Width: | Height: | Size: 257 B |
Binary file not shown.
|
After Width: | Height: | Size: 312 B |
Binary file not shown.
|
After Width: | Height: | Size: 425 B |
@@ -1 +1 @@
|
||||
{ 0,4,14,28,54,76,110,139,146,160,173,193,217,228,242,251,266,289,310,331,352,375,397,420,441,464,487,497,508,532,556,580,598,613,641,665,689,715,736,757,783,808,818,832,859,880,910,935,963,987,1015,1040,1062,1087,1112,1140,1178,1206,1234,1258,1272,1287,1300,1324,1343,1356,1378,1401,1420,1443,1466,1484,1507,1529,1539,1553,1576,1586,1618,1640,1663,1686,1709,1726,1746,1764,1786,1810,1841,1865,1889,1909,1933,1936,1960,1988,2015,2033,2051,2074,2097,2120,2143,2171 }
|
||||
{ 0,4,14,28,54,76,110,139,146,160,173,193,217,228,242,251,266,289,310,331,352,375,397,420,441,464,487,497,508,532,556,580,598,613,641,665,689,715,736,757,783,808,818,832,859,880,910,935,963,987,1015,1040,1062,1087,1112,1140,1178,1206,1234,1258,1272,1287,1300,1324,1343,1356,1378,1401,1420,1443,1466,1484,1507,1529,1539,1553,1576,1586,1618,1640,1663,1686,1709,1726,1746,1764,1786,1810,1841,1865,1889,1909,1933,1936,1960,1988,2015,2033,2051,2074,2097,2120,2143,2171, 2171, 2171, 2171, 2171, 2171, 2171, 2171, 2171, 2171, 2171, 2171, 2171, 2171 }
|
||||
@@ -1 +1 @@
|
||||
{ 0,4,10,20,41,56,80,100,106,115,125,140,159,167,177,184,196,212,227,242,258,274,290,306,322,338,354,361,369,388,407,426,440,451,471,487,505,524,539,553,572,589,595,605,623,638,658,675,695,710,730,747,763,782,799,819,845,864,883,901,910,922,931,950,967,976,991,1006,1020,1036,1052,1064,1080,1095,1101,1110,1125,1131,1154,1169,1185,1200,1216,1227,1241,1253,1268,1285,1306,1323,1340,1354,1373,1376,1395,1416,1437,1452,1467,1484,1501,1518,1535,1557 }
|
||||
{ 0,4,10,20,41,56,80,100,106,115,125,140,159,167,177,184,196,212,227,242,258,274,290,306,322,338,354,361,369,388,407,426,440,451,471,487,505,524,539,553,572,589,595,605,623,638,658,675,695,710,730,747,763,782,799,819,845,864,883,901,910,922,931,950,967,976,991,1006,1020,1036,1052,1064,1080,1095,1101,1110,1125,1131,1154,1169,1185,1200,1216,1227,1241,1253,1268,1285,1306,1323,1340,1354,1373,1376,1395,1416,1437,1452,1467,1484,1501,1518,1535,1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557 }
|
||||
@@ -1 +1 @@
|
||||
{ 0,4,8,13,23,31,44,55,58,63,67,75,85,88,94,97,103,112,120,128,137,146,154,163,171,180,189,192,195,205,215,225,232,238,248,256,266,276,284,291,301,310,313,318,327,335,345,354,365,373,384,393,402,412,421,431,445,455,465,475,479,485,489,499,508,513,521,529,537,546,555,561,570,578,581,586,594,597,609,617,626,634,643,649,657,663,671,680,692,701,710,718,728,729,739,751,763,771,779,789,799,809,819,830 }
|
||||
{ 0,4,8,13,23,31,44,55,58,63,67,75,85,88,94,97,103,112,120,128,137,146,154,163,171,180,189,192,195,205,215,225,232,238,248,256,266,276,284,291,301,310,313,318,327,335,345,354,365,373,384,393,402,412,421,431,445,455,465,475,479,485,489,499,508,513,521,529,537,546,555,561,570,578,581,586,594,597,609,617,626,634,643,649,657,663,671,680,692,701,710,718,728,729,739,751,763,771,779,789,799,809,819,830, 830, 830, 830, 830, 830, 830, 830, 830, 830, 830, 830, 830, 830 }
|
||||
@@ -1 +1 @@
|
||||
{ 0,4,7,12,20,26,36,44,47,51,55,61,69,72,76,79,84,91,97,103,109,116,122,129,135,142,149,151,154,162,170,178,184,189,197,204,211,219,226,232,240,247,250,254,262,268,276,283,291,298,306,313,320,328,335,343,353,360,368,375,379,384,388,396,403,407,413,420,426,432,439,444,450,456,459,463,470,473,482,488,495,502,508,513,519,524,530,537,545,552,559,565,573,574,582,591,600,606,612,619,626,633,640,648 }
|
||||
{ 0,4,7,12,20,26,36,44,47,51,55,61,69,72,76,79,84,91,97,103,109,116,122,129,135,142,149,151,154,162,170,178,184,189,197,204,211,219,226,232,240,247,250,254,262,268,276,283,291,298,306,313,320,328,335,343,353,360,368,375,379,384,388,396,403,407,413,420,426,432,439,444,450,456,459,463,470,473,482,488,495,502,508,513,519,524,530,537,545,552,559,565,573,574,582,591,600,606,612,619,626,633,640,648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648 }
|
||||
@@ -1 +1 @@
|
||||
{ 0,4,12,29,66,93,137,173,181,195,210,235,269,280,296,305,325,353,378,404,431,460,487,515,542,570,598,607,618,652,686,720,743,762,798,827,859,893,920,944,979,1010,1019,1035,1067,1093,1129,1160,1197,1224,1261,1292,1320,1354,1384,1420,1468,1502,1536,1568,1582,1602,1616,1650,1679,1695,1722,1749,1774,1802,1830,1850,1878,1904,1912,1925,1952,1960,2002,2028,2056,2083,2111,2130,2154,2174,2200,2229,2268,2297,2326,2351,2385,2388,2422,2461,2500,2525,2550,2581,2612,2643,2674,2714 }
|
||||
{ 0,4,12,29,66,93,137,173,181,195,210,235,269,280,296,305,325,353,378,404,431,460,487,515,542,570,598,607,618,652,686,720,743,762,798,827,859,893,920,944,979,1010,1019,1035,1067,1093,1129,1160,1197,1224,1261,1292,1320,1354,1384,1420,1468,1502,1536,1568,1582,1602,1616,1650,1679,1695,1722,1749,1774,1802,1830,1850,1878,1904,1912,1925,1952,1960,2002,2028,2056,2083,2111,2130,2154,2174,2200,2229,2268,2297,2326,2351,2385,2388,2422,2461,2500,2525,2550,2581,2612,2643,2674,2714, 2714, 2714, 2714, 2714, 2714, 2714, 2714, 2714, 2714, 2714, 2714, 2714, 2714 }
|
||||
@@ -182,6 +182,10 @@ const uint8_t LBM_TELEMETRY_ICON[] = {
|
||||
#include "mask_telemetry.lbm"
|
||||
};
|
||||
|
||||
const uint8_t LBM_MAINVIEWS_ICON[] = {
|
||||
#include "mask_mainviews.lbm"
|
||||
};
|
||||
|
||||
const uint8_t * const LBM_MODEL_ICONS[] = {
|
||||
LBM_MODEL_ICON,
|
||||
LBM_MODEL_SETUP_ICON,
|
||||
@@ -303,15 +307,3 @@ const uint8_t LBM_SLIDER_POINT_MID[] __DMA = {
|
||||
const uint8_t LBM_SLIDER_POINT_IN[] __DMA = {
|
||||
#include "point_in.lbm"
|
||||
};
|
||||
|
||||
const uint8_t LBM_BUTTON_LEFT[] __DMA = {
|
||||
#include "bmp_left.lbm"
|
||||
};
|
||||
|
||||
const uint8_t LBM_BUTTON_MID[] __DMA = {
|
||||
#include "bmp_mid.lbm"
|
||||
};
|
||||
|
||||
const uint8_t LBM_BUTTON_RIGHT[] __DMA = {
|
||||
#include "bmp_right.lbm"
|
||||
};
|
||||
|
||||
@@ -44,6 +44,14 @@ extern const uint8_t LBM_RSCALE[];
|
||||
// Menu icons
|
||||
extern const uint8_t * const LBM_RADIO_ICONS[];
|
||||
extern const uint8_t * const LBM_MODEL_ICONS[];
|
||||
extern const uint8_t LBM_RADIO_ICON[];
|
||||
extern const uint8_t LBM_SD_BROWSER_ICON[];
|
||||
extern const uint8_t LBM_CALIBRATION_ICON[];
|
||||
extern const uint8_t LBM_INPUTS_ICON[];
|
||||
extern const uint8_t LBM_MIXER_ICON[];
|
||||
extern const uint8_t LBM_CURVES_ICON[];
|
||||
extern const uint8_t LBM_TELEMETRY_ICON[];
|
||||
extern const uint8_t LBM_MAINVIEWS_ICON[];
|
||||
|
||||
// Model selection icons
|
||||
extern const uint8_t LBM_LIBRARY_ICON[];
|
||||
@@ -70,11 +78,6 @@ extern const uint8_t LBM_SHUTDOWN[];
|
||||
extern const uint8_t LBM_SLEEP[];
|
||||
extern const uint8_t LBM_SHUTDOWN_CIRCLE[];
|
||||
|
||||
// Button bitmaps
|
||||
extern const uint8_t LBM_BUTTON_LEFT[];
|
||||
extern const uint8_t LBM_BUTTON_MID[];
|
||||
extern const uint8_t LBM_BUTTON_RIGHT[];
|
||||
|
||||
// Slider bitmaps
|
||||
extern const uint8_t LBM_SLIDER_BAR_LEFT[];
|
||||
extern const uint8_t LBM_SLIDER_BAR_RIGHT[];
|
||||
|
||||
@@ -79,3 +79,6 @@ void drawCurveVerticalScale(int x);
|
||||
void drawCurveHorizontalScale();
|
||||
void drawCurveCoord(int x, int y, const char * text, bool active=false);
|
||||
void drawCurvePoint(int x, int y, LcdFlags color);
|
||||
|
||||
// TODO one screen for now
|
||||
extern Layout * customScreens[MAX_CUSTOM_SCREENS];
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* 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"
|
||||
|
||||
void Layout::setWidget(unsigned int index, const char * name)
|
||||
{
|
||||
memset(persistentData->zones[index].widgetName, 0, sizeof(persistentData->zones[index].widgetName));
|
||||
if (name) {
|
||||
strncpy(persistentData->zones[index].widgetName, name, sizeof(persistentData->zones[index].widgetName));
|
||||
widgets[index] = createWidget(name, getZone(index), &persistentData->zones[index].widgetData);
|
||||
}
|
||||
else {
|
||||
widgets[index] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void Layout::create()
|
||||
{
|
||||
memset(persistentData, 0, sizeof(PersistentData));
|
||||
}
|
||||
|
||||
void Layout::load()
|
||||
{
|
||||
unsigned int count = getZonesCount();
|
||||
for (unsigned int i=0; i<count; i++) {
|
||||
char name[sizeof(persistentData->zones[i].widgetName)+1];
|
||||
memset(name, 0, sizeof(name));
|
||||
strncpy(name, persistentData->zones[i].widgetName, sizeof(persistentData->zones[i].widgetName));
|
||||
widgets[i] = loadWidget(name, getZone(i), &persistentData->zones[i].widgetData);
|
||||
}
|
||||
}
|
||||
|
||||
void Layout::refresh(bool setup)
|
||||
{
|
||||
if (setup) {
|
||||
lcdDrawBlackOverlay();
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_LAYOUT_ZONES; i++) {
|
||||
if (widgets[i]) {
|
||||
widgets[i]->refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const LayoutFactory * registeredLayouts[MAX_REGISTERED_LAYOUTS]; // TODO dynamic
|
||||
unsigned int countRegisteredLayouts = 0;
|
||||
void registerLayout(const LayoutFactory * factory)
|
||||
{
|
||||
if (countRegisteredLayouts < MAX_REGISTERED_LAYOUTS) {
|
||||
registeredLayouts[countRegisteredLayouts++] = factory;
|
||||
}
|
||||
}
|
||||
|
||||
const LayoutFactory * getLayoutFactory(const char * name)
|
||||
{
|
||||
for (unsigned int i=0; i<countRegisteredLayouts; i++) {
|
||||
const LayoutFactory * factory = registeredLayouts[i];
|
||||
if (!strcmp(name, factory->getName())) {
|
||||
return factory;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Layout * createLayout(const char * name, Layout::PersistentData * persistentData)
|
||||
{
|
||||
const LayoutFactory * factory = getLayoutFactory(name);
|
||||
if (factory) {
|
||||
return factory->create(persistentData);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Layout * loadLayout(const char * name, Layout::PersistentData * persistentData)
|
||||
{
|
||||
const LayoutFactory * factory = getLayoutFactory(name);
|
||||
if (factory) {
|
||||
return factory->load(persistentData);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _LAYOUT_H_
|
||||
#define _LAYOUT_H_
|
||||
|
||||
#include "widget.h"
|
||||
|
||||
#define MAX_LAYOUT_ZONES 10
|
||||
#define MAX_LAYOUT_OPTIONS 10
|
||||
|
||||
class LayoutFactory;
|
||||
class Layout
|
||||
{
|
||||
friend class LayoutFactory;
|
||||
|
||||
public:
|
||||
struct ZonePersistentData
|
||||
{
|
||||
char widgetName[10];
|
||||
Widget::PersistentData widgetData;
|
||||
};
|
||||
|
||||
struct PersistentData {
|
||||
ZonePersistentData zones[MAX_LAYOUT_ZONES];
|
||||
ZoneOptionValue options[MAX_LAYOUT_OPTIONS];
|
||||
};
|
||||
|
||||
public:
|
||||
Layout(const LayoutFactory * factory, PersistentData * persistentData):
|
||||
factory(factory),
|
||||
persistentData(persistentData)
|
||||
{
|
||||
memset(widgets, 0, sizeof(widgets));
|
||||
}
|
||||
|
||||
const LayoutFactory * getFactory() const
|
||||
{
|
||||
return factory;
|
||||
}
|
||||
|
||||
Widget * getWidget(unsigned int index)
|
||||
{
|
||||
return widgets[index];
|
||||
}
|
||||
|
||||
void setWidget(unsigned int index, const char * name);
|
||||
|
||||
virtual void create();
|
||||
|
||||
virtual void load();
|
||||
|
||||
ZoneOptionValue getOptionValue(unsigned int index) const
|
||||
{
|
||||
return persistentData->options[index];
|
||||
}
|
||||
|
||||
void setOptionValue(unsigned int index, ZoneOptionValue value) const
|
||||
{
|
||||
persistentData->options[index] = value;
|
||||
}
|
||||
|
||||
virtual unsigned int getZonesCount() const = 0;
|
||||
virtual Zone getZone(unsigned int index) const = 0;
|
||||
|
||||
virtual void refresh(bool setup=false);
|
||||
|
||||
protected:
|
||||
const LayoutFactory * factory;
|
||||
Widget * widgets[MAX_LAYOUT_ZONES];
|
||||
PersistentData * persistentData;
|
||||
};
|
||||
|
||||
void registerLayout(const LayoutFactory * factory);
|
||||
|
||||
class LayoutFactory
|
||||
{
|
||||
public:
|
||||
LayoutFactory(const char * name, const char * bitmap):
|
||||
name(name),
|
||||
bitmap(bitmap)
|
||||
{
|
||||
registerLayout(this);
|
||||
}
|
||||
const char * getName() const { return name; }
|
||||
const char * getBitmap() const { return bitmap; }
|
||||
virtual const ZoneOption * getOptions() const = 0;
|
||||
virtual Layout * create(Layout::PersistentData * persistentData) const = 0;
|
||||
virtual Layout * load(Layout::PersistentData * persistentData) const = 0;
|
||||
|
||||
protected:
|
||||
const char * name;
|
||||
const char * bitmap;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class BaseLayoutFactory: public LayoutFactory
|
||||
{
|
||||
public:
|
||||
BaseLayoutFactory(const char * name, const char * bitmap, const ZoneOption * options):
|
||||
LayoutFactory(name, bitmap),
|
||||
options(options)
|
||||
{
|
||||
}
|
||||
|
||||
virtual const ZoneOption * getOptions() const
|
||||
{
|
||||
return options;
|
||||
}
|
||||
|
||||
virtual Layout * create(Layout::PersistentData * persistentData) const
|
||||
{
|
||||
Layout * layout = new T(this, persistentData);
|
||||
layout->create();
|
||||
return layout;
|
||||
}
|
||||
|
||||
virtual Layout * load(Layout::PersistentData * persistentData) const
|
||||
{
|
||||
Layout * layout = new T(this, persistentData);
|
||||
layout->load();
|
||||
return layout;
|
||||
}
|
||||
|
||||
protected:
|
||||
const ZoneOption * options;
|
||||
};
|
||||
|
||||
#define MAX_REGISTERED_LAYOUTS 10
|
||||
|
||||
extern unsigned int countRegisteredLayouts;
|
||||
extern const LayoutFactory * registeredLayouts[MAX_REGISTERED_LAYOUTS];
|
||||
Layout * createLayout(const char * name, Layout::PersistentData * persistentData);
|
||||
Layout * loadLayout(const char * name, Layout::PersistentData * persistentData);
|
||||
|
||||
#endif // _LAYOUT_H_
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* 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"
|
||||
|
||||
class Layout2P1: public Layout
|
||||
{
|
||||
public:
|
||||
Layout2P1(const LayoutFactory * factory, Layout::PersistentData * persistentData):
|
||||
Layout(factory, persistentData)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void create()
|
||||
{
|
||||
persistentData->options[0].boolValue = true;
|
||||
persistentData->options[1].boolValue = true;
|
||||
persistentData->options[2].boolValue = true;
|
||||
persistentData->options[3].boolValue = true;
|
||||
}
|
||||
|
||||
virtual unsigned int getZonesCount() const
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
virtual Zone getZone(unsigned int index) const
|
||||
{
|
||||
return zones[index];
|
||||
}
|
||||
|
||||
virtual void refresh(bool setup=false);
|
||||
|
||||
static const ZoneOption options[];
|
||||
|
||||
protected:
|
||||
static const Zone zones[3];
|
||||
};
|
||||
|
||||
const Zone Layout2P1::zones[3] = {
|
||||
{ 240, 60, 192, 145 },
|
||||
{ 46, 60, 192, 70 },
|
||||
{ 46, 135, 192, 70 }
|
||||
};
|
||||
|
||||
const ZoneOption Layout2P1::options[] = {
|
||||
{ "Top bar", ZoneOption::Bool },
|
||||
{ "Flight mode", ZoneOption::Bool },
|
||||
{ "Sliders", ZoneOption::Bool },
|
||||
{ "Trims", ZoneOption::Bool },
|
||||
{ NULL, ZoneOption::Bool }
|
||||
};
|
||||
|
||||
void Layout2P1::refresh(bool setup)
|
||||
{
|
||||
lcdDrawBitmap(0, 0, LBM_MAINVIEW_BACKGROUND);
|
||||
|
||||
if (persistentData->options[0].boolValue) {
|
||||
// Top Bar
|
||||
drawMainViewTopBar();
|
||||
}
|
||||
|
||||
if (persistentData->options[1].boolValue) {
|
||||
// Flight mode
|
||||
lcdDrawSizedText(LCD_W / 2 - getTextWidth(g_model.flightModeData[mixerCurrentFlightMode].name,
|
||||
sizeof(g_model.flightModeData[mixerCurrentFlightMode].name),
|
||||
ZCHAR | SMLSIZE) / 2,
|
||||
237,
|
||||
g_model.flightModeData[mixerCurrentFlightMode].name,
|
||||
sizeof(g_model.flightModeData[mixerCurrentFlightMode].name), ZCHAR | SMLSIZE);
|
||||
}
|
||||
|
||||
if (persistentData->options[2].boolValue) {
|
||||
// Pots and rear sliders positions
|
||||
drawMainPots();
|
||||
}
|
||||
|
||||
if (persistentData->options[3].boolValue) {
|
||||
// Trims
|
||||
drawTrims(mixerCurrentFlightMode);
|
||||
}
|
||||
|
||||
Layout::refresh(setup);
|
||||
}
|
||||
|
||||
BaseLayoutFactory<Layout2P1> layout2P1("Layout2P1", "", Layout2P1::options);
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* 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"
|
||||
|
||||
class Layout2x2: public Layout
|
||||
{
|
||||
public:
|
||||
Layout2x2(const LayoutFactory * factory, Layout::PersistentData * persistentData):
|
||||
Layout(factory, persistentData)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void create()
|
||||
{
|
||||
persistentData->options[0].boolValue = true;
|
||||
persistentData->options[1].boolValue = true;
|
||||
persistentData->options[2].boolValue = true;
|
||||
persistentData->options[3].boolValue = true;
|
||||
}
|
||||
|
||||
virtual unsigned int getZonesCount() const
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
virtual Zone getZone(unsigned int index) const
|
||||
{
|
||||
Zone zone;
|
||||
zone.w = (LCD_W-3*10) / 2;
|
||||
zone.x = (index & 1) ? 20 + zone.w : 10;
|
||||
if (persistentData->options[0].boolValue) {
|
||||
zone.h = (LCD_H-MENU_HEADER_HEIGHT-3*10) / 2;
|
||||
zone.y = MENU_HEADER_HEIGHT + 10;
|
||||
}
|
||||
else {
|
||||
zone.h = (LCD_H-3*10) / 2;
|
||||
zone.y = 10;
|
||||
}
|
||||
if (index >= 2) {
|
||||
zone.y += 10 + zone.h;
|
||||
}
|
||||
return zone;
|
||||
}
|
||||
|
||||
virtual void refresh(bool setup=false);
|
||||
|
||||
static const ZoneOption options[];
|
||||
|
||||
};
|
||||
|
||||
const ZoneOption Layout2x2::options[] = {
|
||||
{ "Top bar", ZoneOption::Bool },
|
||||
{ NULL, ZoneOption::Bool }
|
||||
};
|
||||
|
||||
void Layout2x2::refresh(bool setup)
|
||||
{
|
||||
lcdDrawBitmap(0, 0, LBM_MAINVIEW_BACKGROUND);
|
||||
|
||||
if (persistentData->options[0].boolValue) {
|
||||
// Top Bar
|
||||
drawMainViewTopBar();
|
||||
}
|
||||
|
||||
Layout::refresh(setup);
|
||||
}
|
||||
|
||||
BaseLayoutFactory<Layout2x2> layout2x2("Layout2x2", "", Layout2x2::options);
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* 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"
|
||||
|
||||
class Layout2x4: public Layout
|
||||
{
|
||||
public:
|
||||
Layout2x4(const LayoutFactory * factory, Layout::PersistentData * persistentData):
|
||||
Layout(factory, persistentData)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void create()
|
||||
{
|
||||
TRACE("create");
|
||||
persistentData->options[0].boolValue = true;
|
||||
persistentData->options[1].boolValue = true;
|
||||
persistentData->options[2].boolValue = true;
|
||||
persistentData->options[3].boolValue = true;
|
||||
persistentData->options[4].boolValue = true;
|
||||
persistentData->options[5].unsignedValue = RGB(77, 112, 203);
|
||||
persistentData->options[6].boolValue = false;
|
||||
persistentData->options[7].unsignedValue = RGB(77, 112, 203);
|
||||
}
|
||||
|
||||
virtual unsigned int getZonesCount() const
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
virtual Zone getZone(unsigned int index) const
|
||||
{
|
||||
Zone zone;
|
||||
zone.x = (index >= 4) ? 260 : 60;
|
||||
zone.y = 55 + (index % 4) * 40;
|
||||
zone.w = 160;
|
||||
zone.h = 40;
|
||||
return zone;
|
||||
}
|
||||
|
||||
virtual void refresh(bool setup=false);
|
||||
|
||||
static const ZoneOption options[];
|
||||
|
||||
};
|
||||
|
||||
const ZoneOption Layout2x4::options[] = {
|
||||
{ "Top bar", ZoneOption::Bool },
|
||||
{ "Flight mode", ZoneOption::Bool },
|
||||
{ "Sliders", ZoneOption::Bool },
|
||||
{ "Trims", ZoneOption::Bool },
|
||||
{ "Panel1 background", ZoneOption::Bool },
|
||||
{ " Color", ZoneOption::Color },
|
||||
{ "Panel2 background", ZoneOption::Bool },
|
||||
{ " Color", ZoneOption::Color },
|
||||
{ NULL, ZoneOption::Bool }
|
||||
};
|
||||
|
||||
void Layout2x4::refresh(bool setup)
|
||||
{
|
||||
lcdDrawBitmap(0, 0, LBM_MAINVIEW_BACKGROUND);
|
||||
|
||||
if (persistentData->options[0].boolValue) {
|
||||
// Top Bar
|
||||
drawMainViewTopBar();
|
||||
}
|
||||
|
||||
if (persistentData->options[1].boolValue) {
|
||||
// Flight mode
|
||||
lcdDrawSizedText(LCD_W / 2 - getTextWidth(g_model.flightModeData[mixerCurrentFlightMode].name,
|
||||
sizeof(g_model.flightModeData[mixerCurrentFlightMode].name),
|
||||
ZCHAR | SMLSIZE) / 2,
|
||||
237,
|
||||
g_model.flightModeData[mixerCurrentFlightMode].name,
|
||||
sizeof(g_model.flightModeData[mixerCurrentFlightMode].name), ZCHAR | SMLSIZE);
|
||||
}
|
||||
|
||||
if (persistentData->options[2].boolValue) {
|
||||
// Pots and rear sliders positions
|
||||
drawMainPots();
|
||||
}
|
||||
|
||||
if (persistentData->options[3].boolValue) {
|
||||
// Trims
|
||||
drawTrims(mixerCurrentFlightMode);
|
||||
}
|
||||
|
||||
if (persistentData->options[4].boolValue) {
|
||||
lcdSetColor(persistentData->options[5].unsignedValue);
|
||||
lcdDrawSolidFilledRect(50, 50, 180, 170, CUSTOM_COLOR);
|
||||
}
|
||||
|
||||
if (persistentData->options[6].boolValue) {
|
||||
lcdSetColor(persistentData->options[7].unsignedValue);
|
||||
lcdDrawSolidFilledRect(250, 50, 180, 170, CUSTOM_COLOR);
|
||||
}
|
||||
|
||||
Layout::refresh(setup);
|
||||
}
|
||||
|
||||
BaseLayoutFactory<Layout2x4> layout2x4("Layout2x4", "", Layout2x4::options);
|
||||
+118
-97
@@ -104,7 +104,7 @@ void lcdPutFontPattern(coord_t x, coord_t y, const uint8_t * font, const uint16_
|
||||
{
|
||||
coord_t offset = spec[index];
|
||||
coord_t width = spec[index+1] - offset;
|
||||
lcdDrawBitmapPattern(x, y, font, flags, offset, width);
|
||||
if (width > 0) lcdDrawBitmapPattern(x, y, font, flags, offset, width);
|
||||
lcdNextPos = x + width;
|
||||
}
|
||||
|
||||
@@ -152,9 +152,10 @@ int getBitmapScale(const uint8_t * bmp, int dstWidth, int dstHeight)
|
||||
return min(widthScale, heightScale);
|
||||
}
|
||||
|
||||
int getTextWidth(const pm_char * s, int len, LcdFlags flags)
|
||||
int getTextWidth(const char * s, int len, LcdFlags flags)
|
||||
{
|
||||
const uint16_t * specs = fontspecsTable[FONTSIZE(flags) >> 8];
|
||||
|
||||
int result = 0;
|
||||
for (int i=0; len==0 || i<len; ++i) {
|
||||
char c;
|
||||
@@ -179,9 +180,7 @@ void lcdDrawSizedText(coord_t x, coord_t y, const pm_char * s, uint8_t len, LcdF
|
||||
const uint16_t * fontspecs = fontspecsTable[fontindex];
|
||||
|
||||
if ((flags&INVERS) && ((~flags & BLINK) || BLINK_ON_PHASE)) {
|
||||
if (COLOR_IDX(flags) == TEXT_COLOR_INDEX) {
|
||||
flags += TEXT_INVERTED_COLOR - TEXT_COLOR;
|
||||
}
|
||||
flags = TEXT_INVERTED_COLOR | (flags & 0x0ffff);
|
||||
if (FONTSIZE(flags) == TINSIZE)
|
||||
lcdDrawSolidFilledRect(x-INVERT_HORZ_MARGIN+2, y-INVERT_VERT_MARGIN+2, width+2*INVERT_HORZ_MARGIN-5, INVERT_LINE_HEIGHT-7, TEXT_INVERTED_BGCOLOR);
|
||||
else if (FONTSIZE(flags) == SMLSIZE)
|
||||
@@ -382,7 +381,7 @@ void lcdDrawSolidFilledRect(coord_t x, scoord_t y, coord_t w, coord_t h, LcdFlag
|
||||
void lcdDrawFilledRect(coord_t x, scoord_t y, coord_t w, coord_t h, uint8_t pat, LcdFlags att)
|
||||
{
|
||||
for (scoord_t i=y; i<y+h; i++) {
|
||||
if ((att&ROUND) && (i==y || i==y+h-1))
|
||||
if ((att & ROUND) && (i==y || i==y+h-1))
|
||||
lcdDrawHorizontalLine(x+1, i, w-2, pat, att);
|
||||
else
|
||||
lcdDrawHorizontalLine(x, i, w, pat, att);
|
||||
@@ -444,97 +443,6 @@ void putsStickName(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
|
||||
lcdDrawSizedText(x, y, STR_VSRCRAW+2+length*(idx+1), length-1, att);
|
||||
}
|
||||
|
||||
void putsMixerSource(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
|
||||
{
|
||||
if (idx == MIXSRC_NONE) {
|
||||
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, 0, att); // TODO macro
|
||||
}
|
||||
else if (idx <= MIXSRC_LAST_INPUT) {
|
||||
char s[32] = "\314";
|
||||
if (ZEXIST(g_model.inputNames[idx-MIXSRC_FIRST_INPUT])) {
|
||||
zchar2str(s+1, g_model.inputNames[idx-MIXSRC_FIRST_INPUT], LEN_INPUT_NAME);
|
||||
s[1+LEN_INPUT_NAME] = '\0';
|
||||
}
|
||||
else {
|
||||
strAppendUnsigned(s+1, idx, 2);
|
||||
}
|
||||
lcdDrawText(x, y, s, att);
|
||||
}
|
||||
else if (idx <= MIXSRC_LAST_LUA) {
|
||||
#if defined(LUA_MODEL_SCRIPTS)
|
||||
div_t qr = div(idx-MIXSRC_FIRST_LUA, MAX_SCRIPT_OUTPUTS);
|
||||
if (qr.quot < MAX_SCRIPTS && qr.rem < scriptInputsOutputs[qr.quot].outputsCount) {
|
||||
char s[32] = "\322";
|
||||
s[1] = '1'+qr.quot;
|
||||
strncpy(&s[2], scriptInputsOutputs[qr.quot].outputs[qr.rem].name, 32-2);
|
||||
s[31] = '\0';
|
||||
lcdDrawText(x, y, s, att);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (idx <= MIXSRC_LAST_POT) {
|
||||
idx = idx-MIXSRC_Rud;
|
||||
if (ZEXIST(g_eeGeneral.anaNames[idx]))
|
||||
lcdDrawSizedText(x, y, g_eeGeneral.anaNames[idx], LEN_ANA_NAME, ZCHAR|att);
|
||||
else
|
||||
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx+1, att);
|
||||
}
|
||||
else if (idx >= MIXSRC_FIRST_SWITCH && idx < MIXSRC_FIRST_LOGICAL_SWITCH) {
|
||||
idx = idx-MIXSRC_FIRST_SWITCH;
|
||||
if (ZEXIST(g_eeGeneral.switchNames[idx]))
|
||||
lcdDrawSizedText(x, y, g_eeGeneral.switchNames[idx], LEN_SWITCH_NAME, ZCHAR|att);
|
||||
else
|
||||
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx+MIXSRC_FIRST_SWITCH-MIXSRC_Rud+1, att);
|
||||
}
|
||||
else if (idx < MIXSRC_SW1)
|
||||
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx-MIXSRC_Rud+1, att);
|
||||
else if (idx <= MIXSRC_LAST_LOGICAL_SWITCH)
|
||||
putsSwitches(x, y, SWSRC_SW1+idx-MIXSRC_SW1, att);
|
||||
else if (idx < MIXSRC_CH1)
|
||||
drawStringWithIndex(x, y, STR_PPM_TRAINER, idx-MIXSRC_FIRST_TRAINER+1, att);
|
||||
else if (idx <= MIXSRC_LAST_CH) {
|
||||
drawStringWithIndex(x, y, STR_CH, idx-MIXSRC_CH1+1, att);
|
||||
#if 0
|
||||
if (ZEXIST(g_model.limitData[idx-MIXSRC_CH1].name) && (att & STREXPANDED)) {
|
||||
lcdDrawChar(lcdNextPos, y, ' ', att);
|
||||
lcdDrawSizedText(lcdNextPos+3, y, g_model.limitData[idx-MIXSRC_CH1].name, LEN_CHANNEL_NAME, ZCHAR|att);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (idx <= MIXSRC_LAST_GVAR)
|
||||
drawStringWithIndex(x, y, STR_GV, idx-MIXSRC_GVAR1+1, att);
|
||||
else if (idx < MIXSRC_FIRST_TELEM) {
|
||||
lcdDrawTextAtIndex(x, y, STR_VSRCRAW, idx-MIXSRC_Rud+1-NUM_LOGICAL_SWITCH-NUM_TRAINER-NUM_CHNOUT-MAX_GVARS, att);
|
||||
}
|
||||
else {
|
||||
idx -= MIXSRC_FIRST_TELEM;
|
||||
div_t qr = div(idx, 3);
|
||||
char s[32];
|
||||
s[0] = '\321';
|
||||
int pos = 1 + zchar2str(&s[1], g_model.telemetrySensors[qr.quot].label, sizeof(g_model.telemetrySensors[qr.quot].label));
|
||||
if (qr.rem) s[pos++] = (qr.rem==2 ? '+' : '-');
|
||||
s[pos] = '\0';
|
||||
lcdDrawText(x, y, s, att);
|
||||
}
|
||||
}
|
||||
|
||||
void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
|
||||
{
|
||||
lcdDrawTextAtIndex(x, y, STR_RETA123, idx-1, att);
|
||||
}
|
||||
|
||||
void putsModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att)
|
||||
{
|
||||
uint8_t len = sizeof(g_model.header.name);
|
||||
while (len>0 && !name[len-1]) --len;
|
||||
if (len==0) {
|
||||
drawStringWithIndex(x, y, STR_MODEL, id+1, att|LEADING0);
|
||||
}
|
||||
else {
|
||||
lcdDrawSizedText(x, y, name, sizeof(g_model.header.name), ZCHAR|att);
|
||||
}
|
||||
}
|
||||
|
||||
char * getStringAtIndex(char * dest, const char * s, int idx)
|
||||
{
|
||||
uint8_t len = s[0];
|
||||
@@ -603,6 +511,104 @@ char * getSwitchString(char * dest, swsrc_t idx)
|
||||
return dest;
|
||||
}
|
||||
|
||||
char * getSourceString(char * dest, mixsrc_t idx)
|
||||
{
|
||||
if (idx == MIXSRC_NONE) {
|
||||
return getStringAtIndex(dest, STR_VSRCRAW, 0);
|
||||
}
|
||||
else if (idx <= MIXSRC_LAST_INPUT) {
|
||||
idx -= MIXSRC_FIRST_INPUT;
|
||||
*dest++ = '\314';
|
||||
if (ZEXIST(g_model.inputNames[idx])) {
|
||||
zchar2str(dest, g_model.inputNames[idx], LEN_INPUT_NAME);
|
||||
dest[LEN_INPUT_NAME] = '\0';
|
||||
}
|
||||
else {
|
||||
strAppendUnsigned(dest, idx, 2);
|
||||
}
|
||||
}
|
||||
else if (idx <= MIXSRC_LAST_LUA) {
|
||||
#if defined(LUA_MODEL_SCRIPTS)
|
||||
div_t qr = div(idx-MIXSRC_FIRST_LUA, MAX_SCRIPT_OUTPUTS);
|
||||
if (qr.quot < MAX_SCRIPTS && qr.rem < scriptInputsOutputs[qr.quot].outputsCount) {
|
||||
*dest++ = '\322';
|
||||
// *dest++ = '1'+qr.quot;
|
||||
strncpy(dest, scriptInputsOutputs[qr.quot].outputs[qr.rem].name, sizeof(scriptInputsOutputs[qr.quot].outputs[qr.rem].name));
|
||||
dest[sizeof(scriptInputsOutputs[qr.quot].outputs[qr.rem].name)] = '\0';
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (idx <= MIXSRC_LAST_POT) {
|
||||
idx -= MIXSRC_Rud;
|
||||
if (ZEXIST(g_eeGeneral.anaNames[idx])) {
|
||||
zchar2str(dest, g_eeGeneral.anaNames[idx], LEN_ANA_NAME);
|
||||
dest[LEN_ANA_NAME] = '\0';
|
||||
}
|
||||
else {
|
||||
getStringAtIndex(dest, STR_VSRCRAW, idx + 1);
|
||||
}
|
||||
}
|
||||
else if (idx >= MIXSRC_FIRST_SWITCH && idx <= MIXSRC_LAST_SWITCH) {
|
||||
idx -= MIXSRC_FIRST_SWITCH;
|
||||
if (ZEXIST(g_eeGeneral.switchNames[idx])) {
|
||||
zchar2str(dest, g_eeGeneral.switchNames[idx], LEN_SWITCH_NAME);
|
||||
dest[LEN_SWITCH_NAME] = '\0';
|
||||
}
|
||||
else {
|
||||
getStringAtIndex(dest, STR_VSRCRAW, idx + MIXSRC_FIRST_SWITCH - MIXSRC_Rud + 1);
|
||||
}
|
||||
}
|
||||
else if (idx <= MIXSRC_LAST_LOGICAL_SWITCH) {
|
||||
getSwitchString(dest, SWSRC_SW1 + idx - MIXSRC_SW1);
|
||||
}
|
||||
else if (idx <= MIXSRC_LAST_TRAINER) {
|
||||
getStringWithIndex(dest, STR_PPM_TRAINER, idx - MIXSRC_FIRST_TRAINER + 1);
|
||||
}
|
||||
else if (idx <= MIXSRC_LAST_CH) {
|
||||
getStringWithIndex(dest, STR_CH, idx - MIXSRC_CH1 + 1);
|
||||
}
|
||||
else if (idx <= MIXSRC_LAST_GVAR) {
|
||||
getStringWithIndex(dest, STR_GV, idx - MIXSRC_GVAR1 + 1);
|
||||
}
|
||||
else if (idx < MIXSRC_FIRST_TELEM) {
|
||||
getStringAtIndex(dest, STR_VSRCRAW, idx-MIXSRC_Rud+1-NUM_LOGICAL_SWITCH-NUM_TRAINER-NUM_CHNOUT-MAX_GVARS);
|
||||
}
|
||||
else {
|
||||
idx -= MIXSRC_FIRST_TELEM;
|
||||
div_t qr = div(idx, 3);
|
||||
dest[0] = '\321';
|
||||
int pos = 1 + zchar2str(&dest[1], g_model.telemetrySensors[qr.quot].label, sizeof(g_model.telemetrySensors[qr.quot].label));
|
||||
if (qr.rem) dest[pos++] = (qr.rem==2 ? '+' : '-');
|
||||
dest[pos] = '\0';
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
void putsMixerSource(coord_t x, coord_t y, uint8_t idx, LcdFlags flags)
|
||||
{
|
||||
char s[16];
|
||||
getSourceString(s, idx);
|
||||
lcdDrawText(x, y, s, flags);
|
||||
}
|
||||
|
||||
void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
|
||||
{
|
||||
lcdDrawTextAtIndex(x, y, STR_RETA123, idx-1, att);
|
||||
}
|
||||
|
||||
void putsModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att)
|
||||
{
|
||||
uint8_t len = sizeof(g_model.header.name);
|
||||
while (len>0 && !name[len-1]) --len;
|
||||
if (len==0) {
|
||||
drawStringWithIndex(x, y, STR_MODEL, id+1, att|LEADING0);
|
||||
}
|
||||
else {
|
||||
lcdDrawSizedText(x, y, name, sizeof(g_model.header.name), ZCHAR|att);
|
||||
}
|
||||
}
|
||||
|
||||
void putsSwitches(coord_t x, coord_t y, swsrc_t idx, LcdFlags flags)
|
||||
{
|
||||
char s[8];
|
||||
@@ -785,6 +791,21 @@ void lcdSetContrast()
|
||||
lcdSetRefVolt(g_eeGeneral.contrast);
|
||||
}
|
||||
|
||||
void lcdInvertRect(coord_t x, scoord_t y, coord_t w, coord_t h, LcdFlags att)
|
||||
{
|
||||
display_t color = lcdColorTable[COLOR_IDX(att)];
|
||||
COLOR_SPLIT(color, red, green, blue);
|
||||
|
||||
for (int i=y; i<y+h; i++) {
|
||||
display_t * p = PIXEL_PTR(x, i);
|
||||
for (int j=0; j<w; j++) {
|
||||
ASSERT_IN_DISPLAY(p);
|
||||
COLOR_SPLIT(*p, bgRed, bgGreen, bgBlue);
|
||||
lcdDrawPixel(p++, COLOR_JOIN(0b11111 + red - bgRed, 0b111111 + green - bgGreen, 0b11111 + blue - bgBlue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lcdDrawAlphaPixel(display_t * p, uint8_t opacity, uint16_t color)
|
||||
{
|
||||
ASSERT_IN_DISPLAY(p);
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#define LCD_W 480
|
||||
#define LCD_H 272
|
||||
|
||||
#define BOX_WIDTH 81
|
||||
#define coord_t int
|
||||
#define scoord_t int
|
||||
#define CENTER
|
||||
@@ -57,7 +56,7 @@
|
||||
#define MODE(flags) ((((int8_t)(flags) & 0x30) - 0x10) >> 4)
|
||||
|
||||
/* rect, square flags */
|
||||
#define ROUND 0x02
|
||||
#define ROUND 0x04
|
||||
|
||||
/* telemetry flags */
|
||||
#define NO_UNIT 0x40
|
||||
@@ -112,6 +111,7 @@ enum LcdColorIndex
|
||||
CURVE_CURSOR_COLOR_INDEX,
|
||||
HEADER_BGCOLOR_INDEX,
|
||||
TITLE_BGCOLOR_INDEX,
|
||||
CUSTOM_COLOR_INDEX,
|
||||
LCD_COLOR_COUNT
|
||||
};
|
||||
|
||||
@@ -141,6 +141,7 @@ void lcdColorsInit();
|
||||
#define CURVE_CURSOR_COLOR COLOR(CURVE_CURSOR_COLOR_INDEX)
|
||||
#define TITLE_BGCOLOR COLOR(TITLE_BGCOLOR_INDEX)
|
||||
#define HEADER_BGCOLOR COLOR(HEADER_BGCOLOR_INDEX)
|
||||
#define CUSTOM_COLOR COLOR(CUSTOM_COLOR_INDEX)
|
||||
|
||||
#define COLOR_IDX(att) uint8_t((att) >> 16)
|
||||
|
||||
@@ -233,19 +234,26 @@ inline void lcdDrawAlphaPixel(coord_t x, coord_t y, uint8_t opacity, uint16_t co
|
||||
}
|
||||
|
||||
#if !defined(SIMU)
|
||||
inline void lcdDrawSolidFilledRect(coord_t x, scoord_t y, coord_t w, coord_t h, LcdFlags att)
|
||||
inline void lcdDrawSolidFilledRect(coord_t x, scoord_t y, coord_t w, coord_t h, LcdFlags flags)
|
||||
{
|
||||
lcdDrawSolidFilledRectDMA(x, y, w, h, lcdColorTable[COLOR_IDX(att)]);
|
||||
lcdDrawSolidFilledRectDMA(x, y, w, h, lcdColorTable[COLOR_IDX(flags)]);
|
||||
}
|
||||
#else
|
||||
void lcdDrawSolidFilledRect(coord_t x, scoord_t y, coord_t w, coord_t h, LcdFlags att);
|
||||
void lcdDrawSolidFilledRect(coord_t x, scoord_t y, coord_t w, coord_t h, LcdFlags flags);
|
||||
#endif
|
||||
|
||||
inline void lcdSetColor(uint16_t color)
|
||||
{
|
||||
lcdColorTable[CUSTOM_COLOR_INDEX] = color;
|
||||
}
|
||||
|
||||
inline void lcdClear()
|
||||
{
|
||||
lcdDrawSolidFilledRect(0, 0, LCD_W, LCD_H, 0);
|
||||
}
|
||||
|
||||
void lcdInvertRect(coord_t x, scoord_t y, coord_t w, coord_t h, LcdFlags flags);
|
||||
|
||||
inline void lcdDrawSolidHorizontalLine(coord_t x, scoord_t y, coord_t w, LcdFlags att)
|
||||
{
|
||||
lcdDrawSolidFilledRect(x, y, w, 1, att);
|
||||
@@ -265,7 +273,7 @@ inline void lcdDrawSolidRect(coord_t x, scoord_t y, coord_t w, coord_t h, LcdFla
|
||||
lcdDrawSolidHorizontalLine(x, y+h-1, w, att);
|
||||
}
|
||||
|
||||
void lcdDrawFilledRect(coord_t x, scoord_t y, coord_t w, coord_t h, uint8_t pat, LcdFlags att);
|
||||
void lcdDrawFilledRect(coord_t x, scoord_t y, coord_t w, coord_t h, uint8_t pat, LcdFlags att=0);
|
||||
void lcdDrawBlackOverlay();
|
||||
void lcdDrawRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat=SOLID, LcdFlags att=0);
|
||||
void lcdDrawCircle(int x0, int y0, int radius);
|
||||
|
||||
@@ -57,7 +57,7 @@ void drawPots()
|
||||
|
||||
bool menuCommonCalib(evt_t event)
|
||||
{
|
||||
drawSubmenuTemplate(NULL, 0, OPTION_MENU_NO_FOOTER);
|
||||
drawScreenTemplate(NULL, LBM_CALIBRATION_ICON, OPTION_MENU_NO_FOOTER);
|
||||
|
||||
for (uint8_t i=0; i<NUM_STICKS+NUM_POTS; i++) { // get low and high vals for sticks and trims
|
||||
int16_t vt = getAnalogValue(i) >> 1;
|
||||
|
||||
@@ -30,7 +30,7 @@ int lastBitmap;
|
||||
|
||||
bool menuGeneralSdManagerInfo(evt_t event)
|
||||
{
|
||||
SIMPLE_SUBMENU(STR_SD_INFO_TITLE, 1, DEFAULT_SCROLLBAR_X);
|
||||
SIMPLE_SUBMENU(STR_SD_INFO_TITLE, LBM_SD_BROWSER_ICON, 1);
|
||||
|
||||
lcdDrawText(MENUS_MARGIN_LEFT, 2*FH, STR_SD_TYPE);
|
||||
lcdDrawText(100, 2*FH, SD_IS_HC() ? STR_SDHC_CARD : STR_SD_CARD);
|
||||
|
||||
@@ -98,7 +98,7 @@ void displayPresetChoice(evt_t event)
|
||||
}
|
||||
}
|
||||
|
||||
void onCurveOneMenu(const char *result)
|
||||
void onCurveOneMenu(const char * result)
|
||||
{
|
||||
if (result == STR_CURVE_PRESET) {
|
||||
POPUP_INPUT(STR_PRESET, displayPresetChoice, 0, -4, 4);
|
||||
@@ -138,7 +138,7 @@ bool menuModelCurveOne(evt_t event)
|
||||
CurveData & crv = g_model.curves[s_curveChan];
|
||||
int8_t * points = curveAddress(s_curveChan);
|
||||
|
||||
SUBMENU_WITH_OPTIONS(STR_MENUCURVE, crv.type==CURVE_TYPE_CUSTOM ? 6 : 5, OPTION_MENU_NO_FOOTER, 0, { 0, 0, 0, 0, uint8_t(5+crv.points-1), uint8_t(5+crv.points-1) });
|
||||
SUBMENU_WITH_OPTIONS(STR_MENUCURVE, LBM_CURVES_ICON, crv.type==CURVE_TYPE_CUSTOM ? 6 : 5, OPTION_MENU_NO_FOOTER, { 0, 0, 0, 0, uint8_t(5+crv.points-1), uint8_t(5+crv.points-1) });
|
||||
drawStringWithIndex(50, 3+FH, STR_CV, s_curveChan+1, MENU_TITLE_COLOR);
|
||||
lcdDrawSolidFilledRect(0, MENU_FOOTER_TOP, 250, MENU_FOOTER_HEIGHT, HEADER_BGCOLOR);
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ bool menuModelCustomScriptOne(evt_t event)
|
||||
|
||||
// drawStringWithIndex(lcdLastPos+FW, 0, "LUA", s_currIdx+1, 0);
|
||||
|
||||
SUBMENU(STR_MENUCUSTOMSCRIPTS, 3+scriptInputsOutputs[s_currIdx].inputsCount, 0, { 0, 0, LABEL(inputs), 0/*repeated*/ });
|
||||
SUBMENU(STR_MENUCUSTOMSCRIPTS, LBM_LUA_SCRIPTS_ICON, 3+scriptInputsOutputs[s_currIdx].inputsCount, { 0, 0, LABEL(inputs), 0/*repeated*/ });
|
||||
|
||||
int8_t sub = menuVerticalPosition;
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ bool menuModelExpoOne(evt_t event)
|
||||
{
|
||||
ExpoData * ed = expoAddress(s_currIdx);
|
||||
|
||||
SUBMENU_WITH_OPTIONS(STR_MENUINPUTS, EXPO_FIELD_MAX, OPTION_MENU_NO_FOOTER, 0, { 0, 0, (ed->srcRaw >= MIXSRC_FIRST_TELEM ? (uint8_t)1 : (uint8_t)0), 0, 0, CASE_CURVES(CURVE_ROWS) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0 /*, ...*/});
|
||||
SUBMENU_WITH_OPTIONS(STR_MENUINPUTS, LBM_INPUTS_ICON, EXPO_FIELD_MAX, OPTION_MENU_NO_FOOTER|OPTION_MENU_NO_SCROLLBAR, { 0, 0, (ed->srcRaw >= MIXSRC_FIRST_TELEM ? (uint8_t)1 : (uint8_t)0), 0, 0, CASE_CURVES(CURVE_ROWS) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0 /*, ...*/});
|
||||
lcdDrawSizedText(50, 3+FH, g_model.inputNames[ed->chn], LEN_INPUT_NAME, ZCHAR|MENU_TITLE_COLOR);
|
||||
lcdDrawSolidFilledRect(0, MENU_FOOTER_TOP, 230, MENU_FOOTER_HEIGHT, HEADER_BGCOLOR);
|
||||
|
||||
|
||||
@@ -174,7 +174,7 @@ bool menuModelMixOne(evt_t event)
|
||||
{
|
||||
MixData * md2 = mixAddress(s_currIdx) ;
|
||||
|
||||
SUBMENU(STR_MIXER, MIX_FIELD_COUNT, 0, { 0, 0, 0, 0, 0, CASE_CURVES(1) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0 /*, ...*/ });
|
||||
SUBMENU_WITH_OPTIONS(STR_MIXER, LBM_MIXER_ICON, MIX_FIELD_COUNT, OPTION_MENU_NO_SCROLLBAR, { 0, 0, 0, 0, 0, CASE_CURVES(1) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0 /*, ...*/ });
|
||||
putsChn(50, 3+FH, md2->destCh+1, MENU_TITLE_COLOR);
|
||||
|
||||
// The separation line between 2 columns
|
||||
|
||||
@@ -80,8 +80,8 @@ enum menuModelSetupItems {
|
||||
#define FIELD_PROTOCOL_MAX 1
|
||||
|
||||
#define MODEL_SETUP_2ND_COLUMN 200
|
||||
#define MODEL_SETUP_BIND_OFS 40
|
||||
#define MODEL_SETUP_RANGE_OFS 80
|
||||
#define MODEL_SETUP_BIND_OFS 30
|
||||
#define MODEL_SETUP_RANGE_OFS 60
|
||||
#define MODEL_SETUP_SET_FAILSAFE_OFS 100
|
||||
|
||||
void onModelSetupBitmapMenu(const char *result)
|
||||
@@ -615,8 +615,8 @@ bool menuModelSetup(evt_t event)
|
||||
if (IS_MODULE_PPM(moduleIdx)) {
|
||||
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_PPMFRAME);
|
||||
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, (int16_t)moduleData.ppmFrameLength*5 + 225, (menuHorizontalPosition<=0 ? attr : 0) | PREC1|LEFT, 0, NULL, STR_MS);
|
||||
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN+70, y, (moduleData.ppmDelay*50)+300, (CURSOR_ON_LINE() || menuHorizontalPosition==1) ? attr : 0, 0, NULL, "us");
|
||||
lcdDrawText(MODEL_SETUP_2ND_COLUMN+90, y, moduleData.ppmPulsePol ? "+" : "-", (CURSOR_ON_LINE() || menuHorizontalPosition==2) ? attr : 0);
|
||||
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN+90, y, (moduleData.ppmDelay*50)+300, (CURSOR_ON_LINE() || menuHorizontalPosition==1) ? attr : 0, 0, NULL, "us");
|
||||
lcdDrawText(MODEL_SETUP_2ND_COLUMN+120, y, moduleData.ppmPulsePol ? "+" : "-", (CURSOR_ON_LINE() || menuHorizontalPosition==2) ? attr : 0);
|
||||
|
||||
if (attr && s_editMode>0) {
|
||||
switch (menuHorizontalPosition) {
|
||||
@@ -648,8 +648,8 @@ bool menuModelSetup(evt_t event)
|
||||
if (attr && l_posHorz==0 && s_editMode>0) {
|
||||
CHECK_INCDEC_MODELVAR_ZERO(event, g_model.header.modelId[moduleIdx], IS_MODULE_DSM2(moduleIdx) ? 20 : 63);
|
||||
}
|
||||
drawButton(MODEL_SETUP_2ND_COLUMN+xOffsetBind, y-2, STR_MODULE_BIND, l_posHorz==1 ? attr : 0);
|
||||
drawButton(MODEL_SETUP_2ND_COLUMN+MODEL_SETUP_RANGE_OFS+xOffsetBind, y-2, STR_MODULE_RANGE, l_posHorz==2 ? attr : 0);
|
||||
drawButton(MODEL_SETUP_2ND_COLUMN+xOffsetBind, y, STR_MODULE_BIND, l_posHorz==1 ? attr : 0);
|
||||
drawButton(MODEL_SETUP_2ND_COLUMN+MODEL_SETUP_RANGE_OFS+xOffsetBind, y, STR_MODULE_RANGE, l_posHorz==2 ? attr : 0);
|
||||
uint8_t newFlag = 0;
|
||||
if (attr && l_posHorz>0 && s_editMode>0) {
|
||||
if (l_posHorz == 1)
|
||||
|
||||
@@ -127,7 +127,7 @@ bool menuModelSensor(evt_t event)
|
||||
{
|
||||
TelemetrySensor * sensor = &g_model.telemetrySensors[s_currIdx];
|
||||
|
||||
SUBMENU("SENSOR", SENSOR_FIELD_MAX, DEFAULT_SCROLLBAR_X, { 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, 0, 0, 0, 0 });
|
||||
SUBMENU("SENSOR", LBM_TELEMETRY_ICON, 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, 0, 0, 0, 0 });
|
||||
lcdDrawNumber(lcdNextPos, 3, s_currIdx+1, MENU_TITLE_COLOR|LEFT);
|
||||
putsTelemetryChannelValue(50, 3+FH, s_currIdx, getValue(MIXSRC_FIRST_TELEM+3*s_currIdx), MENU_TITLE_COLOR|LEFT);
|
||||
|
||||
|
||||
@@ -266,12 +266,6 @@ bool check_submenu_simple(check_event_t event, uint8_t maxrow);
|
||||
|
||||
#define MENU_TAB(...) const uint8_t mstate_tab[] = __VA_ARGS__
|
||||
|
||||
#define MENU_ONE_PAGE(title, lines_count, scrollbar_X, ...) \
|
||||
MENU_TAB(__VA_ARGS__); \
|
||||
if (event == EVT_ENTRY || event == EVT_ENTRY_UP) TRACE("Menu %s displayed ...", title); \
|
||||
if (!check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, lines_count)) return false; \
|
||||
drawSubmenuTemplate(title, scrollbar_X); \
|
||||
|
||||
#define MENU(title, tab, menu, lines_count, scrollbar_X, ...) \
|
||||
MENU_TAB(__VA_ARGS__); \
|
||||
if (event == EVT_ENTRY || event == EVT_ENTRY_UP) TRACE("Menu %s displayed ...", title); \
|
||||
@@ -283,22 +277,22 @@ bool check_submenu_simple(check_event_t event, uint8_t maxrow);
|
||||
if (!check_simple(event, menu, tab, DIM(tab), lines_count)) return false; \
|
||||
drawMenuTemplate(title, scrollbar_X); \
|
||||
|
||||
#define SUBMENU(title, lines_count, scrollbar_X, ...) \
|
||||
#define SUBMENU(title, icon, lines_count, ...) \
|
||||
MENU_TAB(__VA_ARGS__); \
|
||||
if (!check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, lines_count)) return false; \
|
||||
drawSubmenuTemplate(title, scrollbar_X);
|
||||
drawScreenTemplate(title, icon);
|
||||
|
||||
#define SUBMENU_WITH_OPTIONS(title, lines_count, options, scrollbar_X, ...) \
|
||||
#define SUBMENU_WITH_OPTIONS(title, icon, lines_count, options, ...) \
|
||||
MENU_TAB(__VA_ARGS__); \
|
||||
if (!check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, lines_count)) return false; \
|
||||
drawSubmenuTemplate(title, scrollbar_X, options);
|
||||
drawScreenTemplate(title, icon, options);
|
||||
|
||||
#define SIMPLE_SUBMENU_NOTITLE(lines_count) \
|
||||
if (!check_submenu_simple(event, lines_count)) return false
|
||||
|
||||
#define SIMPLE_SUBMENU(title, lines_count, scrollbar_X) \
|
||||
#define SIMPLE_SUBMENU(title, icon, lines_count) \
|
||||
SIMPLE_SUBMENU_NOTITLE(lines_count); \
|
||||
drawSubmenuTemplate(title, scrollbar_X)
|
||||
drawScreenTemplate(title, icon)
|
||||
|
||||
typedef int select_menu_value_t;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
@@ -18,249 +18,196 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "../../opentx.h"
|
||||
#include "opentx.h"
|
||||
|
||||
#define SETUP_SCREEN_COLUMN2 200
|
||||
#define SETUP_SCREEN_COLUMN3 275
|
||||
#define SETUP_SCREEN_COLUMN4 350
|
||||
Layout * currentScreen;
|
||||
Widget * currentWidget;
|
||||
|
||||
enum menuSetupScreensViewItems
|
||||
#define SCREENS_SETUP_2ND_COLUMN 200
|
||||
|
||||
void onWidgetChoiceMenu(const char * result)
|
||||
{
|
||||
ITEM_SETUP_TOP_BAR_LABEL,
|
||||
ITEM_SETUP_TOP_BAR_VOLTAGE,
|
||||
ITEM_SETUP_TOP_BAR_ALTITUDE,
|
||||
ITEM_SETUP_SCREEN_LABEL1,
|
||||
ITEM_SETUP_SCREEN_LINE1,
|
||||
ITEM_SETUP_SCREEN_LINE2,
|
||||
ITEM_SETUP_SCREEN_LINE3,
|
||||
ITEM_SETUP_SCREEN_LINE4,
|
||||
ITEM_SETUP_SCREEN_LABEL2,
|
||||
ITEM_SETUP_SCREEN_LINE5,
|
||||
ITEM_SETUP_SCREEN_LINE6,
|
||||
ITEM_SETUP_SCREEN_LINE7,
|
||||
ITEM_SETUP_SCREEN_LINE8,
|
||||
ITEM_SETUP_SCREEN_LABEL3,
|
||||
ITEM_SETUP_SCREEN_LINE9,
|
||||
ITEM_SETUP_SCREEN_LINE10,
|
||||
ITEM_SETUP_SCREEN_LINE11,
|
||||
ITEM_SETUP_SCREEN_LINE12,
|
||||
ITEM_SETUP_SCREEN_LABEL4,
|
||||
ITEM_SETUP_SCREEN_LINE13,
|
||||
ITEM_SETUP_SCREEN_LINE14,
|
||||
ITEM_SETUP_SCREEN_LINE15,
|
||||
ITEM_SETUP_SCREEN_LINE16,
|
||||
ITEM_SETUP_SCREEN_MAX
|
||||
};
|
||||
customScreens[0]->setWidget(menuVerticalPosition, result);
|
||||
}
|
||||
|
||||
#if defined(LUA)
|
||||
#define SCREEN_TYPE_ROWS 1
|
||||
#define SETUP_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 SCREEN_TYPE_ROWS 0
|
||||
#define SETUP_SCREEN_LINE(x) (TELEMETRY_SCREEN_TYPE(x) == TELEMETRY_SCREEN_TYPE_NONE ? HIDDEN_ROW : (uint8_t)2)
|
||||
#endif
|
||||
|
||||
#define SETUP_SCREEN_ROWS(x) SCREEN_TYPE_ROWS, SETUP_SCREEN_LINE(x), SETUP_SCREEN_LINE(x), SETUP_SCREEN_LINE(x), SETUP_SCREEN_LINE(x)
|
||||
#define TELEMETRY_CURRENT_SCREEN(k) (k < ITEM_SETUP_SCREEN_LABEL2 ? 0 : (k < ITEM_SETUP_SCREEN_LABEL3 ? 1 : (k < ITEM_SETUP_SCREEN_LABEL4 ? 2 : 3)))
|
||||
|
||||
#if defined(LUA)
|
||||
void onSetupScriptFileSelectionMenu(const char * result)
|
||||
ZoneOptionValue editZoneOption(coord_t y, const ZoneOption * option, ZoneOptionValue value, LcdFlags attr, evt_t event)
|
||||
{
|
||||
int screenIndex = TELEMETRY_CURRENT_SCREEN(menuVerticalPosition);
|
||||
lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, option->name);
|
||||
|
||||
if (result == STR_UPDATE_LIST) {
|
||||
if (!sdListFiles(SCRIPTS_TELEM_PATH, SCRIPTS_EXT, sizeof(g_model.frsky.screens[screenIndex].script.file), NULL)) {
|
||||
POPUP_WARNING(STR_NO_SCRIPTS_ON_SD);
|
||||
if (option->type == ZoneOption::Bool) {
|
||||
value.boolValue = editCheckBox(value.boolValue, SCREENS_SETUP_2ND_COLUMN, y, attr, event);
|
||||
}
|
||||
else if (option->type == ZoneOption::Integer) {
|
||||
lcdDrawNumber(SCREENS_SETUP_2ND_COLUMN, y, value.signedValue, attr | LEFT);
|
||||
if (attr) {
|
||||
CHECK_INCDEC_MODELVAR(event, value.signedValue, -30000, 30000);
|
||||
}
|
||||
}
|
||||
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));
|
||||
storageDirty(EE_MODEL);
|
||||
LUA_LOAD_MODEL_SCRIPTS();
|
||||
else if (option->type == ZoneOption::String) {
|
||||
editName(SCREENS_SETUP_2ND_COLUMN, y, value.stringValue, sizeof(value.stringValue), event, attr|EE_MODEL);
|
||||
}
|
||||
else if (option->type == ZoneOption::TextSize) {
|
||||
lcdDrawTextAtIndex(SCREENS_SETUP_2ND_COLUMN, y, "\010StandardTiny\0 Small\0 Mid\0 Double", value.unsignedValue, attr);
|
||||
if (attr) {
|
||||
value.unsignedValue = checkIncDec(event, value.unsignedValue, 0, 4, EE_MODEL);
|
||||
}
|
||||
}
|
||||
else if (option->type == ZoneOption::Timer) {
|
||||
drawStringWithIndex(SCREENS_SETUP_2ND_COLUMN, y, STR_TIMER, value.unsignedValue + 1, attr);
|
||||
if (attr) {
|
||||
value.unsignedValue = checkIncDec(event, value.unsignedValue, 0, MAX_TIMERS - 1, EE_MODEL);
|
||||
}
|
||||
}
|
||||
else if (option->type == ZoneOption::Source) {
|
||||
putsMixerSource(SCREENS_SETUP_2ND_COLUMN, y, value.unsignedValue, attr);
|
||||
if (attr) {
|
||||
CHECK_INCDEC_MODELSOURCE(event, value.unsignedValue, 1, MIXSRC_LAST);
|
||||
}
|
||||
}
|
||||
else if (option->type == ZoneOption::Color) {
|
||||
lcdSetColor(value.unsignedValue);
|
||||
lcdDrawSolidRect(SCREENS_SETUP_2ND_COLUMN, y, 40, 15, attr ? TEXT_INVERTED_BGCOLOR : TEXT_COLOR);
|
||||
lcdDrawSolidFilledRect(SCREENS_SETUP_2ND_COLUMN + 1, y + 1, 38, 13, CUSTOM_COLOR);
|
||||
if (attr) {
|
||||
CHECK_INCDEC_MODELVAR(event, value.unsignedValue, 0, 65535);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
bool menuWidgetSettings(evt_t event)
|
||||
{
|
||||
linesCount = 0;
|
||||
const ZoneOption * options = currentWidget->getFactory()->getOptions();
|
||||
for (const ZoneOption * option = options; option->name; option++) {
|
||||
linesCount++;
|
||||
}
|
||||
|
||||
SUBMENU_WITH_OPTIONS("Widget settings", LBM_MAINVIEWS_ICON, linesCount, OPTION_MENU_TITLE_BAR, { 0, 0, 0 });
|
||||
|
||||
for (int i=0; i<NUM_BODY_LINES+1; i++) {
|
||||
coord_t y = MENU_CONTENT_TOP + i * FH;
|
||||
int k = i + menuVerticalOffset;
|
||||
LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
|
||||
LcdFlags attr = (menuVerticalPosition == k ? blink : 0);
|
||||
if (k < linesCount) {
|
||||
const ZoneOption * option = &options[k];
|
||||
ZoneOptionValue value = currentWidget->getOptionValue(k);
|
||||
value = editZoneOption(y, option, value, attr, event);
|
||||
if (attr) {
|
||||
currentWidget->setOptionValue(k, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void onZoneMenu(const char * result)
|
||||
{
|
||||
if (result == STR_SELECT_WIDGET) {
|
||||
for (unsigned int i=0; i<countRegisteredWidgets; i++) {
|
||||
POPUP_MENU_ADD_ITEM(registeredWidgets[i]->getName());
|
||||
}
|
||||
popupMenuHandler = onWidgetChoiceMenu;
|
||||
}
|
||||
else if (result == STR_WIDGET_SETTINGS) {
|
||||
currentWidget = currentScreen->getWidget(menuVerticalPosition);
|
||||
pushMenu(menuWidgetSettings);
|
||||
}
|
||||
else if (result == STR_REMOVE_WIDGET) {
|
||||
currentScreen->setWidget(menuVerticalPosition, NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool menuSetupWidgets(evt_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case EVT_ENTRY:
|
||||
menuVerticalPosition = 0;
|
||||
break;
|
||||
case EVT_KEY_BREAK(KEY_EXIT):
|
||||
popMenu();
|
||||
return false;
|
||||
}
|
||||
|
||||
currentScreen->refresh(true);
|
||||
|
||||
for (int i=currentScreen->getZonesCount()-1; i>=0; i--) {
|
||||
Zone zone = currentScreen->getZone(i);
|
||||
if (menuVerticalPosition == i) {
|
||||
lcdDrawSolidRect(zone.x, zone.y, zone.w, zone.h, TEXT_INVERTED_COLOR);
|
||||
lcdDrawSolidRect(zone.x-1, zone.y-1, zone.w+2, zone.h+2, TEXT_INVERTED_COLOR);
|
||||
if (event == EVT_KEY_BREAK(KEY_ENTER)) {
|
||||
Widget * widget = currentScreen->getWidget(i);
|
||||
if (widget) {
|
||||
POPUP_MENU_ADD_ITEM(STR_SELECT_WIDGET);
|
||||
if (widget->getFactory()->getOptions())
|
||||
POPUP_MENU_ADD_ITEM(STR_WIDGET_SETTINGS);
|
||||
POPUP_MENU_ADD_ITEM(STR_REMOVE_WIDGET);
|
||||
popupMenuHandler = onZoneMenu;
|
||||
}
|
||||
else {
|
||||
onZoneMenu(STR_SELECT_WIDGET);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
lcdDrawRect(zone.x, zone.y, zone.w, zone.h, DOTTED, TEXT_INVERTED_COLOR);
|
||||
}
|
||||
}
|
||||
navigate(event, currentScreen->getZonesCount(), currentScreen->getZonesCount(), 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool menuSetupScreensView(evt_t event)
|
||||
{
|
||||
MENU_ONE_PAGE("Setup screens", ITEM_SETUP_SCREEN_MAX, DEFAULT_SCROLLBAR_X, { LABEL(TopBar), 0, 0, SETUP_SCREEN_ROWS(0), SETUP_SCREEN_ROWS(1), SETUP_SCREEN_ROWS(2), SETUP_SCREEN_ROWS(3) });
|
||||
currentScreen = customScreens[0];
|
||||
|
||||
unsigned int layoutIndex = 0;
|
||||
for (unsigned int i=0; i<countRegisteredLayouts; i++) {
|
||||
if (registeredLayouts[i] == currentScreen->getFactory()) {
|
||||
layoutIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
linesCount = 1;
|
||||
const ZoneOption * options = currentScreen->getFactory()->getOptions();
|
||||
for (const ZoneOption * option = options; option->name; option++) {
|
||||
linesCount++;
|
||||
}
|
||||
|
||||
SUBMENU_WITH_OPTIONS("Main views setup", LBM_MAINVIEWS_ICON, linesCount, OPTION_MENU_TITLE_BAR, { 0, 0, 0 });
|
||||
|
||||
for (int i=0; i<NUM_BODY_LINES+1; i++) {
|
||||
coord_t y = MENU_CONTENT_TOP + (i - 1) * FH - 5;
|
||||
coord_t y = MENU_CONTENT_TOP + i * FH;
|
||||
int k = i + menuVerticalOffset;
|
||||
|
||||
for (int j=0; j<k; j++) {
|
||||
if (mstate_tab[j + 1] == HIDDEN_ROW) {
|
||||
if (++k >= (int) DIM(mstate_tab)) {
|
||||
return true;
|
||||
LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
|
||||
LcdFlags attr = (menuVerticalPosition == k ? blink : 0);
|
||||
if (k == 0) {
|
||||
lcdDrawText(MENUS_MARGIN_LEFT, y, "Layout");
|
||||
lcdDrawText(SCREENS_SETUP_2ND_COLUMN, y, currentScreen->getFactory()->getName(), attr);
|
||||
if (attr) {
|
||||
layoutIndex = checkIncDec(event, layoutIndex, 0, countRegisteredLayouts-1, EE_MODEL);
|
||||
if (checkIncDec_Ret) {
|
||||
customScreens[0] = registeredLayouts[layoutIndex]->create(&g_model.screenData[0].layoutData);
|
||||
strncpy(g_model.screenData[0].layoutName, customScreens[0]->getFactory()->getName(), sizeof(g_model.screenData[0].layoutName));
|
||||
}
|
||||
else if (event == EVT_KEY_LONG(KEY_ENTER)) {
|
||||
pushMenu(menuSetupWidgets);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LcdFlags blink = ((s_editMode > 0) ? BLINK | INVERS : INVERS);
|
||||
LcdFlags attr = (menuVerticalPosition == k ? blink : 0);
|
||||
|
||||
switch (k) {
|
||||
case ITEM_SETUP_TOP_BAR_LABEL:
|
||||
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_TOP_BAR);
|
||||
break;
|
||||
|
||||
case ITEM_SETUP_TOP_BAR_VOLTAGE:
|
||||
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_VOLTAGE);
|
||||
putsMixerSource(SETUP_SCREEN_COLUMN2, 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, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isVoltsSensor);
|
||||
}
|
||||
break;
|
||||
|
||||
case ITEM_SETUP_TOP_BAR_ALTITUDE:
|
||||
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_ALTITUDE);
|
||||
putsMixerSource(SETUP_SCREEN_COLUMN2, 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, MAX_SENSORS, EE_MODEL|NO_INCDEC_MARKS, isAltSensor);
|
||||
}
|
||||
break;
|
||||
|
||||
case ITEM_SETUP_SCREEN_LABEL1:
|
||||
case ITEM_SETUP_SCREEN_LABEL2:
|
||||
case ITEM_SETUP_SCREEN_LABEL3:
|
||||
case ITEM_SETUP_SCREEN_LABEL4:
|
||||
{
|
||||
uint8_t screenIndex = TELEMETRY_CURRENT_SCREEN(k);
|
||||
drawStringWithIndex(MENUS_MARGIN_LEFT, y, STR_SCREEN, screenIndex+1);
|
||||
TelemetryScreenType oldScreenType = TELEMETRY_SCREEN_TYPE(screenIndex);
|
||||
TelemetryScreenType newScreenType = (TelemetryScreenType)selectMenuItem(SETUP_SCREEN_COLUMN2, y, STR_VTELEMSCREENTYPE, oldScreenType, 0, TELEMETRY_SCREEN_TYPE_MAX, (menuHorizontalPosition==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))
|
||||
lcdDrawSizedText(SETUP_SCREEN_COLUMN3, y, scriptData.file, sizeof(scriptData.file), (menuHorizontalPosition==1 ? attr : 0));
|
||||
else
|
||||
lcdDrawTextAtIndex(SETUP_SCREEN_COLUMN3, y, STR_VCSWFUNC, 0, (menuHorizontalPosition==1 ? attr : 0));
|
||||
|
||||
if (menuHorizontalPosition==1 && attr && event==EVT_KEY_BREAK(KEY_ENTER) && READ_ONLY_UNLOCKED()) {
|
||||
s_editMode = 0;
|
||||
if (sdListFiles(SCRIPTS_TELEM_PATH, SCRIPTS_EXT, sizeof(g_model.frsky.screens[screenIndex].script.file), g_model.frsky.screens[screenIndex].script.file)) {
|
||||
popupMenuHandler = onSetupScriptFileSelectionMenu;
|
||||
}
|
||||
else {
|
||||
POPUP_WARNING(STR_NO_SCRIPTS_ON_SD);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (attr) {
|
||||
MOVE_CURSOR_FROM_HERE();
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
case ITEM_SETUP_SCREEN_LINE1:
|
||||
case ITEM_SETUP_SCREEN_LINE2:
|
||||
case ITEM_SETUP_SCREEN_LINE3:
|
||||
case ITEM_SETUP_SCREEN_LINE4:
|
||||
case ITEM_SETUP_SCREEN_LINE5:
|
||||
case ITEM_SETUP_SCREEN_LINE6:
|
||||
case ITEM_SETUP_SCREEN_LINE7:
|
||||
case ITEM_SETUP_SCREEN_LINE8:
|
||||
case ITEM_SETUP_SCREEN_LINE9:
|
||||
case ITEM_SETUP_SCREEN_LINE10:
|
||||
case ITEM_SETUP_SCREEN_LINE11:
|
||||
case ITEM_SETUP_SCREEN_LINE12:
|
||||
case ITEM_SETUP_SCREEN_LINE13:
|
||||
case ITEM_SETUP_SCREEN_LINE14:
|
||||
case ITEM_SETUP_SCREEN_LINE15:
|
||||
case ITEM_SETUP_SCREEN_LINE16: {
|
||||
uint8_t screenIndex, lineIndex;
|
||||
if (k < ITEM_SETUP_SCREEN_LABEL2) {
|
||||
screenIndex = 0;
|
||||
lineIndex = k - ITEM_SETUP_SCREEN_LINE1;
|
||||
}
|
||||
else if (k >= ITEM_SETUP_SCREEN_LABEL4) {
|
||||
screenIndex = 3;
|
||||
lineIndex = k - ITEM_SETUP_SCREEN_LINE13;
|
||||
}
|
||||
else if (k >= ITEM_SETUP_SCREEN_LABEL3) {
|
||||
screenIndex = 2;
|
||||
lineIndex = k - ITEM_SETUP_SCREEN_LINE9;
|
||||
}
|
||||
else {
|
||||
screenIndex = 1;
|
||||
lineIndex = k - ITEM_SETUP_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(MENUS_MARGIN_LEFT+INDENT_WIDTH, y, barSource, (menuHorizontalPosition==0 ? attr : 0));
|
||||
int barMax = getMaximumValue(barSource);
|
||||
int barMin = -barMax;
|
||||
if (barSource) {
|
||||
if (barSource <= MIXSRC_LAST_CH) {
|
||||
putsChannelValue(SETUP_SCREEN_COLUMN2, y, barSource, calc100toRESX(bar.barMin), (menuHorizontalPosition==1 ? attr : 0) | LEFT);
|
||||
putsChannelValue(SETUP_SCREEN_COLUMN4, y, barSource, calc100toRESX(bar.barMax), (menuHorizontalPosition==2 ? attr : 0) | LEFT);
|
||||
}
|
||||
else {
|
||||
putsChannelValue(SETUP_SCREEN_COLUMN2, y, barSource, bar.barMin, (menuHorizontalPosition==1 ? attr : 0) | LEFT);
|
||||
putsChannelValue(SETUP_SCREEN_COLUMN4, y, barSource, bar.barMax, (menuHorizontalPosition==2 ? attr : 0) | LEFT);
|
||||
}
|
||||
}
|
||||
else if (attr) {
|
||||
MOVE_CURSOR_FROM_HERE();
|
||||
}
|
||||
if (attr && s_editMode>0) {
|
||||
switch (menuHorizontalPosition) {
|
||||
case 0:
|
||||
bar.source = checkIncDec(event, barSource, 0, MIXSRC_LAST_TELEM, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isSourceAvailable);
|
||||
if (checkIncDec_Ret) {
|
||||
if (barSource <= MIXSRC_LAST_CH) {
|
||||
bar.barMin = -100;
|
||||
bar.barMax = 100;
|
||||
}
|
||||
else {
|
||||
bar.barMin = 0;
|
||||
bar.barMax = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
bar.barMin = checkIncDec(event, bar.barMin, barMin, bar.barMax, EE_MODEL|NO_INCDEC_MARKS);
|
||||
break;
|
||||
case 2:
|
||||
bar.barMax = checkIncDec(event, bar.barMax, bar.barMin, barMax, EE_MODEL|NO_INCDEC_MARKS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
for (int c = 0; c < NUM_LINE_ITEMS; c++) {
|
||||
LcdFlags cellAttr = (menuHorizontalPosition == c ? attr : 0);
|
||||
source_t &value = g_model.frsky.screens[screenIndex].lines[lineIndex].sources[c];
|
||||
const coord_t pos[] = {MENUS_MARGIN_LEFT + INDENT_WIDTH, SETUP_SCREEN_COLUMN2, SETUP_SCREEN_COLUMN4};
|
||||
putsMixerSource(pos[c], y, value, cellAttr);
|
||||
if (cellAttr && s_editMode > 0) {
|
||||
value = checkIncDec(event, value, 0, MIXSRC_LAST_TELEM, EE_MODEL | INCDEC_SOURCE | NO_INCDEC_MARKS,
|
||||
isSourceAvailable);
|
||||
}
|
||||
}
|
||||
if (attr && menuHorizontalPosition == NUM_LINE_ITEMS) {
|
||||
REPEAT_LAST_CURSOR_MOVE(0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
else if (k < linesCount) {
|
||||
const ZoneOption * option = &options[k-1];
|
||||
ZoneOptionValue value = currentScreen->getOptionValue(k-1);
|
||||
value = editZoneOption(y, option, value, attr, event);
|
||||
if (attr) {
|
||||
currentScreen->setOptionValue(k-1, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -29,15 +29,7 @@
|
||||
#define TRIM_LEN 80
|
||||
#define POTS_LINE_Y 252
|
||||
|
||||
#define MODELPANEL_LEFT 240
|
||||
#define MODELPANEL_TOP 68
|
||||
#define MODELPANEL_WIDTH MODEL_BITMAP_WIDTH
|
||||
#define MODELPANEL_HEIGHT 135
|
||||
|
||||
#define TIMER1PANEL_LEFT 46
|
||||
#define TIMER1PANEL_TOP 55
|
||||
#define TIMER2PANEL_LEFT TIMER1PANEL_LEFT
|
||||
#define TIMER2PANEL_TOP 134
|
||||
Layout * customScreens[MAX_CUSTOM_SCREENS];
|
||||
|
||||
void drawMainPots()
|
||||
{
|
||||
@@ -87,25 +79,6 @@ void drawTrims(uint8_t flightMode)
|
||||
}
|
||||
}
|
||||
|
||||
void drawTimer(coord_t x, coord_t y, int index)
|
||||
{
|
||||
TimerData & timerData = g_model.timers[index];
|
||||
TimerState & timerState = timersStates[index];
|
||||
lcdDrawBitmapPattern(x, y, LBM_TIMER_BACKGROUND, TEXT_BGCOLOR);
|
||||
if (timerData.start) {
|
||||
lcdDrawBitmapPatternPie(x+2, y+3, LBM_RSCALE, TITLE_BGCOLOR, 0, timerState.val <= 0 ? 360 : 360*(timerData.start-timerState.val)/timerData.start);
|
||||
}
|
||||
else {
|
||||
lcdDrawBitmapPattern(x+3, y+4, LBM_TIMER, TITLE_BGCOLOR);
|
||||
}
|
||||
putsTimer(x+76, y+31, abs(timerState.val), TEXT_COLOR|DBLSIZE|LEFT);
|
||||
if (ZLEN(timerData.name) > 0) {
|
||||
lcdDrawSizedText(x+78, y+20, timerData.name, LEN_TIMER_NAME, ZCHAR|SMLSIZE|TEXT_COLOR);
|
||||
}
|
||||
drawStringWithIndex(x+137, y+17, "TMR", index+1, SMLSIZE|TEXT_COLOR);
|
||||
}
|
||||
|
||||
|
||||
void drawMainViewTopBar()
|
||||
{
|
||||
const int ALTITUDE_Y = 16;
|
||||
@@ -283,55 +256,9 @@ bool menuMainView(evt_t event)
|
||||
break;
|
||||
}
|
||||
|
||||
// 23ms if 24bits per pixel (with transparency) 5/6/5/8
|
||||
// 6ms if 16bits per pixel 5/6/5 no DMA
|
||||
// 1.2ms with the DMA
|
||||
TIME_MEASURE_START(backgroundbitmap);
|
||||
lcdDrawBitmap(0, 0, LBM_MAINVIEW_BACKGROUND);
|
||||
TIME_MEASURE_STOP(backgroundbitmap);
|
||||
|
||||
// Top Bar
|
||||
drawMainViewTopBar();
|
||||
|
||||
// Flight mode
|
||||
lcdDrawSizedText(LCD_W/2-getTextWidth(g_model.flightModeData[mixerCurrentFlightMode].name, sizeof(g_model.flightModeData[mixerCurrentFlightMode].name), ZCHAR|SMLSIZE)/2, 237, g_model.flightModeData[mixerCurrentFlightMode].name, sizeof(g_model.flightModeData[mixerCurrentFlightMode].name), ZCHAR|SMLSIZE);
|
||||
|
||||
// Pots and rear sliders positions
|
||||
drawMainPots();
|
||||
|
||||
// Trims
|
||||
drawTrims(mixerCurrentFlightMode);
|
||||
|
||||
// Model panel
|
||||
TIME_MEASURE_START(filledRect);
|
||||
lcdDrawFilledRect(MODELPANEL_LEFT, MODELPANEL_TOP, MODELPANEL_WIDTH, MODELPANEL_HEIGHT, SOLID, TEXT_BGCOLOR | OPACITY(5));
|
||||
TIME_MEASURE_STOP(filledRect); // 9ms !
|
||||
|
||||
lcdDrawBitmapPattern(MODELPANEL_LEFT+6, MODELPANEL_TOP+4, LBM_MODEL_ICON, TITLE_BGCOLOR);
|
||||
lcdDrawSizedText(MODELPANEL_LEFT+45, MODELPANEL_TOP+10, g_model.header.name, LEN_MODEL_NAME, ZCHAR|SMLSIZE);
|
||||
lcdDrawSolidHorizontalLine(MODELPANEL_LEFT+39, MODELPANEL_TOP+27, MODELPANEL_WIDTH-48, TITLE_BGCOLOR);
|
||||
int scale = getBitmapScale(modelBitmap, MODEL_BITMAP_WIDTH, MODEL_BITMAP_HEIGHT);
|
||||
int width = getBitmapScaledSize(getBitmapWidth(modelBitmap), scale);
|
||||
int height = getBitmapScaledSize(getBitmapHeight(modelBitmap), scale);
|
||||
lcdDrawBitmap(MODELPANEL_LEFT+(MODEL_BITMAP_WIDTH-width)/2, MODELPANEL_TOP+MODELPANEL_HEIGHT-MODEL_BITMAP_HEIGHT/2-height/2, modelBitmap, 0, 0, scale);
|
||||
|
||||
// Timers
|
||||
if (g_model.timers[0].mode) {
|
||||
drawTimer(TIMER1PANEL_LEFT, TIMER1PANEL_TOP, 0);
|
||||
if (customScreens[0]) {
|
||||
customScreens[0]->refresh();
|
||||
}
|
||||
if (g_model.timers[1].mode) {
|
||||
drawTimer(TIMER2PANEL_LEFT, TIMER2PANEL_TOP, 1);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (gvarDisplayTimer > 0) {
|
||||
gvarDisplayTimer--;
|
||||
displayMessageBox();
|
||||
drawStringWithIndex(WARNING_LINE_X, WARNING_LINE_Y, STR_GV, gvarLastChanged+1, DBLSIZE|YELLOW);
|
||||
lcdDrawSizedText(WARNING_LINE_X+45, WARNING_LINE_Y, g_model.gvars[gvarLastChanged].name, LEN_GVAR_NAME, DBLSIZE|YELLOW|ZCHAR);
|
||||
lcdDrawNumber(WARNING_LINE_X, WARNING_INFOLINE_Y, GVAR_VALUE(gvarLastChanged, getGVarFlightMode(mixerCurrentFlightMode, gvarLastChanged)), DBLSIZE|LEFT);
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ bool menuStatisticsView(evt_t event)
|
||||
return false;
|
||||
}
|
||||
|
||||
drawMenuTemplate("Statistics");
|
||||
drawScreenTemplate("Statistics", LBM_RADIO_ICON, OPTION_MENU_NO_SCROLLBAR);
|
||||
|
||||
lcdDrawText( 10, MENU_CONTENT_TOP + FH*0, "\037\145TOT:\037\317BATT:", HEADER_COLOR);
|
||||
lcdDrawText( 10, MENU_CONTENT_TOP + FH*1, "TM1:\037\145TM2:", HEADER_COLOR);
|
||||
@@ -116,7 +116,7 @@ bool menuStatisticsDebug(evt_t event)
|
||||
return false;
|
||||
}
|
||||
|
||||
drawMenuTemplate(STR_MENUDEBUG);
|
||||
drawScreenTemplate(STR_MENUDEBUG, LBM_RADIO_ICON, OPTION_MENU_NO_SCROLLBAR);
|
||||
|
||||
lcdDrawText(MENUS_MARGIN_LEFT, MENU_DEBUG_Y_FREE_RAM, "Free Mem");
|
||||
lcdDrawNumber(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_FREE_RAM, availableMemory(), LEFT, 0, NULL, "b");
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* 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"
|
||||
|
||||
const WidgetFactory * registeredWidgets[MAX_REGISTERED_WIDGETS]; // TODO dynamic
|
||||
unsigned int countRegisteredWidgets = 0;
|
||||
void registerWidget(const WidgetFactory * factory)
|
||||
{
|
||||
if (countRegisteredWidgets < MAX_REGISTERED_WIDGETS) {
|
||||
registeredWidgets[countRegisteredWidgets++] = factory;
|
||||
}
|
||||
}
|
||||
|
||||
const WidgetFactory * getWidgetFactory(const char * name)
|
||||
{
|
||||
for (unsigned int i=0; i<countRegisteredWidgets; i++) {
|
||||
const WidgetFactory * factory = registeredWidgets[i];
|
||||
if (!strcmp(name, factory->getName())) {
|
||||
return factory;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Widget * createWidget(const char * name, const Zone & zone, Widget::PersistentData * persistentData)
|
||||
{
|
||||
const WidgetFactory * factory = getWidgetFactory(name);
|
||||
if (factory) {
|
||||
return factory->create(zone, persistentData);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Widget * loadWidget(const char * name, const Zone & zone, Widget::PersistentData * persistentData)
|
||||
{
|
||||
const WidgetFactory * factory = getWidgetFactory(name);
|
||||
if (factory) {
|
||||
return factory->load(zone, persistentData);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _WIDGET_H_
|
||||
#define _WIDGET_H_
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#define MAX_WIDGET_OPTIONS 4
|
||||
|
||||
struct Zone
|
||||
{
|
||||
uint16_t x, y, w, h;
|
||||
};
|
||||
|
||||
struct ZoneOption
|
||||
{
|
||||
enum Type {
|
||||
Bool,
|
||||
Integer,
|
||||
String,
|
||||
TextSize,
|
||||
Timer,
|
||||
Source,
|
||||
Switch,
|
||||
Color
|
||||
};
|
||||
|
||||
const char * name;
|
||||
Type type;
|
||||
};
|
||||
|
||||
union ZoneOptionValue
|
||||
{
|
||||
bool boolValue;
|
||||
uint32_t unsignedValue;
|
||||
int32_t signedValue;
|
||||
char stringValue[8];
|
||||
};
|
||||
|
||||
class WidgetFactory;
|
||||
class Widget
|
||||
{
|
||||
public:
|
||||
struct PersistentData {
|
||||
ZoneOptionValue options[MAX_WIDGET_OPTIONS];
|
||||
};
|
||||
|
||||
Widget(const WidgetFactory * factory, const Zone & zone, PersistentData * persistentData):
|
||||
factory(factory),
|
||||
zone(zone),
|
||||
persistentData(persistentData)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void create()
|
||||
{
|
||||
memset(persistentData, 0, sizeof(PersistentData));
|
||||
}
|
||||
|
||||
virtual void load()
|
||||
{
|
||||
}
|
||||
|
||||
const WidgetFactory * getFactory() const
|
||||
{
|
||||
return factory;
|
||||
}
|
||||
|
||||
virtual ZoneOptionValue getOptionValue(unsigned int index) const
|
||||
{
|
||||
return persistentData->options[index];
|
||||
}
|
||||
|
||||
virtual void setOptionValue(unsigned int index, ZoneOptionValue value) const
|
||||
{
|
||||
persistentData->options[index] = value;
|
||||
}
|
||||
|
||||
virtual void refresh() = 0;
|
||||
|
||||
protected:
|
||||
const WidgetFactory * factory;
|
||||
Zone zone;
|
||||
PersistentData * persistentData;
|
||||
};
|
||||
|
||||
void registerWidget(const WidgetFactory * factory);
|
||||
|
||||
class WidgetFactory
|
||||
{
|
||||
public:
|
||||
WidgetFactory(const char * name, const char * bitmap):
|
||||
name(name),
|
||||
bitmap(bitmap)
|
||||
{
|
||||
registerWidget(this);
|
||||
}
|
||||
|
||||
const char * getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
virtual const ZoneOption * getOptions() const = 0;
|
||||
|
||||
virtual Widget * create(const Zone & zone, Widget::PersistentData * persistentData) const = 0;
|
||||
|
||||
virtual Widget * load(const Zone & zone, Widget::PersistentData * persistentData) const = 0;
|
||||
|
||||
protected:
|
||||
const char * name;
|
||||
const char * bitmap;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class BaseWidgetFactory: public WidgetFactory
|
||||
{
|
||||
public:
|
||||
BaseWidgetFactory(const char * name, const char * bitmap, const ZoneOption * options):
|
||||
WidgetFactory(name, bitmap),
|
||||
options(options)
|
||||
{
|
||||
}
|
||||
|
||||
virtual const ZoneOption * getOptions() const
|
||||
{
|
||||
return options;
|
||||
}
|
||||
|
||||
virtual Widget * create(const Zone & zone, Widget::PersistentData * persistentData) const
|
||||
{
|
||||
Widget * widget = new T(this, zone, persistentData);
|
||||
widget->create();
|
||||
return widget;
|
||||
}
|
||||
|
||||
virtual Widget * load(const Zone & zone, Widget::PersistentData * persistentData) const
|
||||
{
|
||||
Widget * widget = new T(this, zone, persistentData);
|
||||
widget->load();
|
||||
return widget;
|
||||
}
|
||||
|
||||
protected:
|
||||
const ZoneOption * options;
|
||||
};
|
||||
|
||||
#define MAX_REGISTERED_WIDGETS 10
|
||||
extern unsigned int countRegisteredWidgets;
|
||||
extern const WidgetFactory * registeredWidgets[MAX_REGISTERED_WIDGETS];
|
||||
Widget * createWidget(const char * name, const Zone & zone, Widget::PersistentData * persistentData);
|
||||
Widget * loadWidget(const char * name, const Zone & zone, Widget::PersistentData * persistentData);
|
||||
|
||||
#endif // _WIDGET_H_
|
||||
@@ -56,13 +56,10 @@ void drawStick(coord_t x, coord_t y, int16_t xval, int16_t yval)
|
||||
|
||||
void drawButton(coord_t x, coord_t y, const char * label, LcdFlags attr)
|
||||
{
|
||||
int width = getTextWidth(label, attr);
|
||||
lcdDrawBitmap(x, y, LBM_BUTTON_LEFT);
|
||||
for (int i=0; i<width; i++) {
|
||||
lcdDrawBitmap(x+20+i, y, LBM_BUTTON_MID);
|
||||
}
|
||||
lcdDrawBitmap(x+20+width, y, LBM_BUTTON_RIGHT);
|
||||
lcdDrawText(x+23, y+1, label, attr);
|
||||
int width = getTextWidth(label, 0, attr);
|
||||
lcdDrawSolidRect(x, y-1, width+16, 20, (attr & INVERS) ? TEXT_INVERTED_BGCOLOR : TEXT_COLOR);
|
||||
lcdDrawSolidRect(x-1, y-2, width+18, 22, (attr & INVERS) ? TEXT_INVERTED_BGCOLOR : TEXT_COLOR);
|
||||
lcdDrawText(x+8, y, label, (attr & INVERS) ? TEXT_INVERTED_BGCOLOR : TEXT_COLOR);
|
||||
}
|
||||
|
||||
void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr)
|
||||
@@ -133,92 +130,74 @@ void drawShadow(coord_t x, coord_t y, coord_t w, coord_t h)
|
||||
lcdDrawSolidHorizontalLine(x+2, y+h+1, w, LINE_COLOR);
|
||||
}
|
||||
|
||||
void drawMenuTemplate(const char * title, uint16_t scrollbar_X, uint32_t options)
|
||||
void drawScreenTemplate(const char * title, const uint8_t * icon, uint32_t options)
|
||||
{
|
||||
uint8_t linesDisplayed;
|
||||
coord_t bodyTop, bodyBottom;
|
||||
|
||||
// Header
|
||||
lcdDrawSolidFilledRect(0, 0, LCD_W, MENU_HEADER_HEIGHT, HEADER_BGCOLOR);
|
||||
lcdDrawBitmapPattern(0, 0, LBM_TOPMENU_POLYGON, TITLE_BGCOLOR);
|
||||
lcdDrawBitmapPattern(5, 7, icon, MENU_TITLE_COLOR);
|
||||
drawTopmenuDatetime();
|
||||
|
||||
if (menuPageCount > 0) {
|
||||
// Menu title bar
|
||||
if (options & OPTION_MENU_TITLE_BAR) {
|
||||
linesDisplayed = NUM_BODY_LINES;
|
||||
bodyTop = MENU_BODY_TOP;
|
||||
lcdDrawSolidFilledRect(0, MENU_HEADER_HEIGHT, LCD_W, MENU_TITLE_TOP - MENU_HEADER_HEIGHT, TEXT_BGCOLOR);
|
||||
lcdDrawSolidFilledRect(0, MENU_TITLE_TOP, LCD_W, MENU_TITLE_HEIGHT, TITLE_BGCOLOR);
|
||||
if (options & OPTION_MENU_NO_FOOTER) {
|
||||
lcdDrawSolidFilledRect(0, MENU_BODY_TOP, LCD_W, MENU_BODY_HEIGHT+MENU_FOOTER_HEIGHT, TEXT_BGCOLOR);
|
||||
}
|
||||
else {
|
||||
lcdDrawSolidFilledRect(0, MENU_BODY_TOP, LCD_W, MENU_BODY_HEIGHT, TEXT_BGCOLOR);
|
||||
lcdDrawSolidFilledRect(0, MENU_FOOTER_TOP, LCD_W, MENU_FOOTER_HEIGHT, HEADER_BGCOLOR);
|
||||
}
|
||||
if (menuVerticalPosition < 0) {
|
||||
lcdDrawBitmapPattern(58+menuPageIndex*MENU_ICONS_SPACING-10, 0, LBM_CURRENT_BG, TITLE_BGCOLOR);
|
||||
}
|
||||
else {
|
||||
lcdDrawSolidFilledRect(58+menuPageIndex*MENU_ICONS_SPACING-9, 0, 32, MENU_HEADER_HEIGHT, TITLE_BGCOLOR);
|
||||
lcdDrawBitmapPattern(58+menuPageIndex*MENU_ICONS_SPACING, MENU_TITLE_TOP-9, LBM_DOT, MENU_TITLE_COLOR);
|
||||
}
|
||||
const uint8_t * const * icons = (menuVerticalPositions[0] == 0 ? LBM_MODEL_ICONS : LBM_RADIO_ICONS);
|
||||
lcdDrawBitmapPattern(5, 7, icons[0], MENU_TITLE_COLOR);
|
||||
for (int i=0; i<menuPageCount; i++) {
|
||||
lcdDrawBitmapPattern(50+i*MENU_ICONS_SPACING, 7, icons[i+1], MENU_TITLE_COLOR);
|
||||
}
|
||||
if (menuVerticalPosition < 0) {
|
||||
lcdDrawBitmapPattern(58+menuPageIndex*MENU_ICONS_SPACING-10, 0, LBM_CURRENT_SHADOW, TEXT_COLOR);
|
||||
lcdDrawBitmapPattern(58+menuPageIndex*MENU_ICONS_SPACING, MENU_TITLE_TOP-9, LBM_CURRENT_DOT, MENU_TITLE_COLOR);
|
||||
}
|
||||
if (title) {
|
||||
lcdDrawText(MENUS_MARGIN_LEFT, MENU_TITLE_TOP+2, title, MENU_TITLE_COLOR);
|
||||
}
|
||||
if (scrollbar_X && linesCount > NUM_BODY_LINES) {
|
||||
drawVerticalScrollbar(scrollbar_X, DEFAULT_SCROLLBAR_Y, DEFAULT_SCROLLBAR_H, menuVerticalOffset, linesCount, NUM_BODY_LINES);
|
||||
}
|
||||
}
|
||||
else {
|
||||
lcdDrawBitmapPattern(4, 10, LBM_TOPMENU_OPENTX, MENU_TITLE_COLOR);
|
||||
linesDisplayed = NUM_BODY_LINES;
|
||||
bodyTop = MENU_HEADER_HEIGHT;
|
||||
if (title) {
|
||||
lcdDrawText(50, 3, title, MENU_TITLE_COLOR|DBLSIZE);
|
||||
}
|
||||
// Body and footer (depending on options)
|
||||
if (options & OPTION_MENU_NO_FOOTER) {
|
||||
lcdDrawSolidFilledRect(0, MENU_HEADER_HEIGHT, LCD_W, LCD_H-MENU_HEADER_HEIGHT, TEXT_BGCOLOR);
|
||||
}
|
||||
else {
|
||||
lcdDrawSolidFilledRect(0, MENU_HEADER_HEIGHT, LCD_W, LCD_H-MENU_HEADER_HEIGHT-MENU_FOOTER_HEIGHT, TEXT_BGCOLOR);
|
||||
lcdDrawSolidFilledRect(0, MENU_FOOTER_TOP, LCD_W, MENU_FOOTER_HEIGHT, HEADER_BGCOLOR);
|
||||
}
|
||||
if (scrollbar_X && linesCount > NUM_BODY_LINES+1) {
|
||||
drawVerticalScrollbar(scrollbar_X, DEFAULT_SCROLLBAR_Y-FH, DEFAULT_SCROLLBAR_H+FH, menuVerticalOffset, linesCount, NUM_BODY_LINES+1);
|
||||
lcdDrawText(50, 3, title, MENU_TITLE_COLOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawSubmenuTemplate(const char * name, uint16_t scrollbar_X, uint32_t options)
|
||||
{
|
||||
// clear the screen
|
||||
lcdDrawSolidFilledRect(0, 0, LCD_W, MENU_HEADER_HEIGHT, HEADER_BGCOLOR);
|
||||
|
||||
// Footer
|
||||
if (options & OPTION_MENU_NO_FOOTER) {
|
||||
lcdDrawSolidFilledRect(0, MENU_HEADER_HEIGHT, LCD_W, LCD_H-MENU_HEADER_HEIGHT, TEXT_BGCOLOR);
|
||||
bodyBottom = LCD_H;
|
||||
}
|
||||
else {
|
||||
lcdDrawSolidFilledRect(0, MENU_HEADER_HEIGHT, LCD_W, LCD_H-MENU_HEADER_HEIGHT-MENU_FOOTER_HEIGHT, TEXT_BGCOLOR);
|
||||
bodyBottom = MENU_FOOTER_TOP;
|
||||
lcdDrawSolidFilledRect(0, MENU_FOOTER_TOP, LCD_W, MENU_FOOTER_HEIGHT, HEADER_BGCOLOR);
|
||||
}
|
||||
|
||||
// Body
|
||||
lcdDrawSolidFilledRect(0, bodyTop, LCD_W, bodyBottom-bodyTop, TEXT_BGCOLOR);
|
||||
|
||||
// Scrollbar
|
||||
if (!(options & OPTION_MENU_NO_SCROLLBAR) && linesCount>linesDisplayed) {
|
||||
drawVerticalScrollbar(DEFAULT_SCROLLBAR_X, bodyTop+3, bodyBottom-bodyTop-6, menuVerticalOffset, linesCount, linesDisplayed);
|
||||
}
|
||||
}
|
||||
|
||||
void drawMenuTemplate(const char * title, uint16_t scrollbar_X, uint32_t options)
|
||||
{
|
||||
const uint8_t * const * icons = (menuVerticalPositions[0] == 0 ? LBM_MODEL_ICONS : LBM_RADIO_ICONS);
|
||||
|
||||
lcdDrawBitmapPattern(0, 0, LBM_TOPMENU_POLYGON, TITLE_BGCOLOR);
|
||||
lcdDrawBitmapPattern(5, 7, icons[menuPageIndex+1], MENU_TITLE_COLOR);
|
||||
drawScreenTemplate(title, icons[0], OPTION_MENU_TITLE_BAR);
|
||||
|
||||
drawTopmenuDatetime();
|
||||
|
||||
if (name) {
|
||||
// must be done at the end so that we can write something at the right of the menu title
|
||||
lcdDrawText(50, 3, name, MENU_TITLE_COLOR);
|
||||
if (menuVerticalPosition < 0) {
|
||||
lcdDrawBitmapPattern(58+menuPageIndex*MENU_ICONS_SPACING-10, 0, LBM_CURRENT_BG, TITLE_BGCOLOR);
|
||||
}
|
||||
else {
|
||||
lcdDrawSolidFilledRect(58+menuPageIndex*MENU_ICONS_SPACING-9, 0, 32, MENU_HEADER_HEIGHT, TITLE_BGCOLOR);
|
||||
lcdDrawBitmapPattern(58+menuPageIndex*MENU_ICONS_SPACING, MENU_TITLE_TOP-9, LBM_DOT, MENU_TITLE_COLOR);
|
||||
}
|
||||
|
||||
if (scrollbar_X && linesCount > NUM_BODY_LINES+1) {
|
||||
drawVerticalScrollbar(scrollbar_X, DEFAULT_SCROLLBAR_Y-FH, DEFAULT_SCROLLBAR_H+MENU_FOOTER_HEIGHT, menuVerticalOffset, linesCount, NUM_BODY_LINES+1);
|
||||
for (int i=0; i<menuPageCount; i++) {
|
||||
lcdDrawBitmapPattern(50+i*MENU_ICONS_SPACING, 7, icons[i+1], MENU_TITLE_COLOR);
|
||||
}
|
||||
|
||||
if (menuVerticalPosition < 0) {
|
||||
lcdDrawBitmapPattern(58+menuPageIndex*MENU_ICONS_SPACING-10, 0, LBM_CURRENT_SHADOW, TEXT_COLOR);
|
||||
lcdDrawBitmapPattern(58+menuPageIndex*MENU_ICONS_SPACING, MENU_TITLE_TOP-9, LBM_CURRENT_DOT, MENU_TITLE_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,7 +208,7 @@ select_menu_value_t selectMenuItem(coord_t x, coord_t y, const pm_char * values,
|
||||
return value;
|
||||
}
|
||||
|
||||
uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, LcdFlags attr, evt_t event )
|
||||
uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, LcdFlags attr, evt_t event)
|
||||
{
|
||||
drawCheckBox(x, y, value, attr);
|
||||
return selectMenuItem(x, y, NULL, value, 0, 1, attr, event);
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#define OPTION_MENU_NO_FOOTER 0x01
|
||||
//#define OPTION_MENU_NO_TITLE_BAR 0x02
|
||||
#define OPTION_MENU_TITLE_BAR 0x02
|
||||
#define OPTION_MENU_NO_SCROLLBAR 0x04
|
||||
|
||||
#define OPTION_SLIDER_INVERS INVERS
|
||||
#define OPTION_SLIDER_BLINK BLINK
|
||||
@@ -67,10 +68,15 @@ int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int
|
||||
#endif
|
||||
|
||||
// Screen templates
|
||||
void drawScreenTemplate(const char * title, const uint8_t * icon, uint32_t options=0);
|
||||
void drawMenuTemplate(const char * title, uint16_t scrollbar_X=0, uint32_t options=0);
|
||||
void drawSubmenuTemplate(const char * name, uint16_t scrollbar_X=0, uint32_t options=0);
|
||||
void drawSplash();
|
||||
void drawSleepBitmap();
|
||||
void drawShutdownBitmap(uint32_t index);
|
||||
|
||||
// Main view standard widgets
|
||||
void drawMainViewTopBar();
|
||||
void drawMainPots();
|
||||
void drawTrims(uint8_t flightMode);
|
||||
|
||||
#endif // _WIDGETS_H_
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* 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"
|
||||
|
||||
class GaugeWidget: public Widget
|
||||
{
|
||||
public:
|
||||
GaugeWidget(const WidgetFactory * factory, const Zone & zone, Widget::PersistentData * persistentData):
|
||||
Widget(factory, zone, persistentData)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void create()
|
||||
{
|
||||
persistentData->options[0].unsignedValue = 1;
|
||||
persistentData->options[1].signedValue = -RESX;
|
||||
persistentData->options[2].signedValue = RESX;
|
||||
persistentData->options[3].unsignedValue = RED;
|
||||
}
|
||||
|
||||
void refresh();
|
||||
|
||||
static const ZoneOption options[];
|
||||
};
|
||||
|
||||
const ZoneOption GaugeWidget::options[] = {
|
||||
{ "Source", ZoneOption::Source },
|
||||
{ "Min", ZoneOption::Integer },
|
||||
{ "Max", ZoneOption::Integer },
|
||||
{ "Color", ZoneOption::Color },
|
||||
{ NULL, ZoneOption::Bool }
|
||||
};
|
||||
|
||||
void GaugeWidget::refresh()
|
||||
{
|
||||
mixsrc_t index = persistentData->options[0].unsignedValue;
|
||||
int32_t min = persistentData->options[1].signedValue;
|
||||
int32_t max = persistentData->options[2].signedValue;
|
||||
uint16_t color = persistentData->options[3].unsignedValue;
|
||||
|
||||
getvalue_t value = getValue(index);
|
||||
getvalue_t value_in_range = value;
|
||||
if (value < min)
|
||||
value_in_range = min;
|
||||
else if (value > max)
|
||||
value_in_range;
|
||||
|
||||
int w = divRoundClosest(zone.w * (value_in_range - min), (max - min));
|
||||
int percent = divRoundClosest(100 * (value_in_range - min), (max - min));
|
||||
|
||||
// Gauge label
|
||||
putsMixerSource(zone.x, zone.y + 5, index, SMLSIZE | TEXT_INVERTED_COLOR);
|
||||
|
||||
// Gauge
|
||||
lcdSetColor(color);
|
||||
lcdDrawSolidFilledRect(zone.x, zone.y + 20, zone.w, 16, TEXT_INVERTED_COLOR);
|
||||
lcdDrawNumber(zone.x+zone.w/2+20, zone.y + 21, percent, SMLSIZE | CUSTOM_COLOR, 0, NULL, "%");
|
||||
lcdInvertRect(zone.x + w, zone.y + 20, zone.w - w, 16, CUSTOM_COLOR);
|
||||
}
|
||||
|
||||
BaseWidgetFactory<GaugeWidget> gaugeWidget("Gauge", "", GaugeWidget::options);
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* 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"
|
||||
|
||||
class ModelPanelWidget: public Widget
|
||||
{
|
||||
public:
|
||||
ModelPanelWidget(const WidgetFactory * factory, const Zone & zone, Widget::PersistentData * persistentData):
|
||||
Widget(factory, zone, persistentData)
|
||||
{
|
||||
}
|
||||
|
||||
void refresh();
|
||||
};
|
||||
|
||||
void ModelPanelWidget::refresh()
|
||||
{
|
||||
if (zone.h >= MODEL_BITMAP_HEIGHT) {
|
||||
lcdDrawFilledRect(zone.x, zone.y, zone.w, zone.h, SOLID, TEXT_BGCOLOR | OPACITY(5));
|
||||
lcdDrawBitmapPattern(zone.x + 6, zone.y + 4, LBM_MODEL_ICON, TITLE_BGCOLOR);
|
||||
lcdDrawSizedText(zone.x + 45, zone.y + 10, g_model.header.name, LEN_MODEL_NAME, ZCHAR | SMLSIZE);
|
||||
lcdDrawSolidHorizontalLine(zone.x + 39, zone.y + 27, zone.w - 48, TITLE_BGCOLOR);
|
||||
int scale = getBitmapScale(modelBitmap, zone.w, zone.h);
|
||||
int width = getBitmapScaledSize(getBitmapWidth(modelBitmap), scale);
|
||||
int height = getBitmapScaledSize(getBitmapHeight(modelBitmap), scale);
|
||||
lcdDrawBitmap(zone.x + (zone.w - width) / 2, zone.y + zone.h - MODEL_BITMAP_HEIGHT / 2 - height / 2, modelBitmap, 0, 0, scale);
|
||||
}
|
||||
else {
|
||||
int scale = getBitmapScale(modelBitmap, zone.w, zone.h);
|
||||
int width = getBitmapScaledSize(getBitmapWidth(modelBitmap), scale);
|
||||
int height = getBitmapScaledSize(getBitmapHeight(modelBitmap), scale);
|
||||
lcdDrawFilledRect(zone.x, zone.y, zone.w, height, SOLID, TEXT_BGCOLOR | OPACITY(5));
|
||||
lcdDrawSizedText(zone.x + 5, zone.y + 10, g_model.header.name, LEN_MODEL_NAME, ZCHAR | SMLSIZE);
|
||||
lcdDrawBitmap(zone.x + zone.w - width, zone.y, modelBitmap, 0, 0, scale);
|
||||
}
|
||||
}
|
||||
|
||||
BaseWidgetFactory<ModelPanelWidget> modelPanelWidget("ModelPanel", "", NULL);
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* 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"
|
||||
|
||||
class TextWidget: public Widget
|
||||
{
|
||||
public:
|
||||
TextWidget(const WidgetFactory * factory, const Zone & zone, Widget::PersistentData * persistentData):
|
||||
Widget(factory, zone, persistentData)
|
||||
{
|
||||
}
|
||||
|
||||
void create()
|
||||
{
|
||||
str2zchar(persistentData->options[0].stringValue, "Label", sizeof(persistentData->options[0].stringValue));
|
||||
persistentData->options[1].unsignedValue = RED;
|
||||
persistentData->options[2].unsignedValue = 0;
|
||||
}
|
||||
|
||||
void refresh();
|
||||
|
||||
static const ZoneOption options[];
|
||||
};
|
||||
|
||||
const ZoneOption TextWidget::options[] = {
|
||||
{ "Text", ZoneOption::String },
|
||||
{ "Color", ZoneOption::Color },
|
||||
{ "Size", ZoneOption::TextSize },
|
||||
{ NULL, ZoneOption::Bool }
|
||||
};
|
||||
|
||||
void TextWidget::refresh()
|
||||
{
|
||||
lcdSetColor(persistentData->options[1].unsignedValue);
|
||||
LcdFlags fontsize = FONTSIZE(persistentData->options[2].unsignedValue << 8);
|
||||
lcdDrawSizedText(zone.x, zone.y, persistentData->options[0].stringValue, sizeof(persistentData->options[0].stringValue), ZCHAR|fontsize|CUSTOM_COLOR);
|
||||
}
|
||||
|
||||
BaseWidgetFactory<TextWidget> textWidget("Text", "", TextWidget::options);
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* 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"
|
||||
|
||||
class TimerWidget: public Widget
|
||||
{
|
||||
public:
|
||||
TimerWidget(const WidgetFactory * factory, const Zone & zone, Widget::PersistentData * persistentData):
|
||||
Widget(factory, zone, persistentData)
|
||||
{
|
||||
}
|
||||
|
||||
void refresh();
|
||||
|
||||
static const ZoneOption options[];
|
||||
};
|
||||
|
||||
const ZoneOption TimerWidget::options[] = {
|
||||
{ "Timer source", ZoneOption::Timer },
|
||||
{ NULL, ZoneOption::Bool }
|
||||
};
|
||||
|
||||
void TimerWidget::refresh()
|
||||
{
|
||||
uint32_t index = persistentData->options[0].unsignedValue;
|
||||
|
||||
TimerData & timerData = g_model.timers[index];
|
||||
TimerState & timerState = timersStates[index];
|
||||
lcdDrawBitmapPattern(zone.x, zone.y, LBM_TIMER_BACKGROUND, TEXT_BGCOLOR);
|
||||
if (timerData.start) {
|
||||
lcdDrawBitmapPatternPie(zone.x+2, zone.y+3, LBM_RSCALE, TITLE_BGCOLOR, 0, timerState.val <= 0 ? 360 : 360*(timerData.start-timerState.val)/timerData.start);
|
||||
}
|
||||
else {
|
||||
lcdDrawBitmapPattern(zone.x+3, zone.y+4, LBM_TIMER, TITLE_BGCOLOR);
|
||||
}
|
||||
putsTimer(zone.x+76, zone.y+31, abs(timerState.val), TEXT_COLOR|DBLSIZE|LEFT);
|
||||
if (ZLEN(timerData.name) > 0) {
|
||||
lcdDrawSizedText(zone.x+78, zone.y+20, timerData.name, LEN_TIMER_NAME, ZCHAR|SMLSIZE|TEXT_COLOR);
|
||||
}
|
||||
drawStringWithIndex(zone.x+137, zone.y+17, "TMR", index+1, SMLSIZE|TEXT_COLOR);
|
||||
}
|
||||
|
||||
BaseWidgetFactory<TimerWidget> timerWidget("Timer", "", TimerWidget::options);
|
||||
+25
-13
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
@@ -27,7 +27,7 @@
|
||||
#define LUA_EXPORT(...) LEXP(__VA_ARGS__)
|
||||
#define LUA_EXPORT_MULTIPLE(...) LEXP_MULTIPLE(__VA_ARGS__)
|
||||
#define LUA_EXPORT_EXTRA(...) LEXP_EXTRA(__VA_ARGS__)
|
||||
#else
|
||||
#else
|
||||
#define LUA_EXPORT(...)
|
||||
#define LUA_EXPORT_MULTIPLE(...)
|
||||
#define LUA_EXPORT_EXTRA(...)
|
||||
@@ -105,6 +105,7 @@
|
||||
#define NUM_POTS 7
|
||||
#define NUM_XPOTS 3
|
||||
#define MAX_SENSORS 32
|
||||
#define MAX_CUSTOM_SCREENS 5
|
||||
#elif defined(PCBFLAMENCO)
|
||||
#define MAX_MODELS 60
|
||||
#define NUM_CHNOUT 32 // number of real output channels CH1-CH32
|
||||
@@ -566,7 +567,7 @@ enum PotsWarnMode {
|
||||
#define MODELDATA_EXTRA uint8_t spare:6; uint8_t potsWarnMode:2; ModuleData moduleData[NUM_MODULES+1]; uint8_t potsWarnEnabled; int8_t potsWarnPosition[NUM_POTS]; uint8_t rxBattAlarms[2];
|
||||
#else
|
||||
#define MODELDATA_BITMAP
|
||||
#define MODELDATA_EXTRA
|
||||
#define MODELDATA_EXTRA
|
||||
#endif
|
||||
|
||||
enum BacklightMode {
|
||||
@@ -1154,16 +1155,16 @@ PACK(union u_gvarint_t {
|
||||
uint8_t hi;
|
||||
} bytes_t;
|
||||
int16_t word;
|
||||
|
||||
|
||||
u_gvarint_t(int8_t l, uint8_t h) {bytes_t.lo=l; bytes_t.hi=h?255:0;} // hi bit is negativ sign
|
||||
|
||||
private:
|
||||
// prevent unwanted constructors, also saves program
|
||||
u_gvarint_t() {}
|
||||
u_gvarint_t(const u_gvarint_t&) {}
|
||||
});
|
||||
});
|
||||
#define MD_WEIGHT(md) (u_gvarint_t(md->weight,md->weightMode).word)
|
||||
|
||||
|
||||
PACK(union u_int8int16_t {
|
||||
struct {
|
||||
int8_t lo;
|
||||
@@ -1174,7 +1175,7 @@ PACK(union u_int8int16_t {
|
||||
|
||||
#define MD_WEIGHT_TO_UNION(md, var) var.bytes_t.lo=md->weight; var.bytes_t.hi=md->weightMode?255:0
|
||||
#define MD_UNION_TO_WEIGHT(var, md) md->weight=var.bytes_t.lo; if (var.word<0) md->weightMode=1; else md->weightMode=0
|
||||
// #define MD_SETWEIGHT(md, val) md->weight=val; if (val<0) md->weightMode=1; else md->weightMode=0
|
||||
// #define MD_SETWEIGHT(md, val) md->weight=val; if (val<0) md->weightMode=1; else md->weightMode=0
|
||||
|
||||
#define MD_OFFSET(md) (u_gvarint_t(md->offset,md->offsetMode).word)
|
||||
#define MD_OFFSET_TO_UNION(md, var) var.bytes_t.lo=md->offset; var.bytes_t.hi=md->offsetMode?255:0
|
||||
@@ -1220,7 +1221,7 @@ enum LogicalSwitchesFunctions {
|
||||
typedef int16_t ls_telemetry_value_t;
|
||||
PACK(typedef struct { // Logical Switches data
|
||||
uint8_t func;
|
||||
int32_t v1:10;
|
||||
int32_t v1:10;
|
||||
int32_t v3:10;
|
||||
int32_t andsw:9; // TODO rename to xswtch
|
||||
uint32_t andswtype:1; // TODO rename to xswtchType (AND / OR)
|
||||
@@ -1327,7 +1328,7 @@ PACK(typedef struct {
|
||||
uint8_t ratio; // 0.0 means not used, 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc.
|
||||
int16_t offset:12;
|
||||
uint16_t type:4; // channel unit (0=volts, ...)
|
||||
uint8_t alarms_value[2]; // 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc.
|
||||
uint8_t alarms_value[2]; // 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc.
|
||||
uint8_t alarms_level:4;
|
||||
uint8_t alarms_greater:2; // 0=LT(<), 1=GT(>)
|
||||
uint8_t multiplier:2; // 0=no multiplier, 1=*2 multiplier
|
||||
@@ -1662,7 +1663,7 @@ PACK(typedef struct {
|
||||
uint8_t invertELE:1;
|
||||
uint8_t invertAIL:1;
|
||||
uint8_t invertCOL:1;
|
||||
uint8_t type:5;
|
||||
uint8_t type:5;
|
||||
uint8_t collectiveSource;
|
||||
uint8_t value;
|
||||
}) SwashRingData;
|
||||
@@ -2287,12 +2288,20 @@ enum DisplayTrims
|
||||
};
|
||||
|
||||
#if defined(COLORLCD)
|
||||
#include "layout.h"
|
||||
#define SWITCHES_WARNING_DATA \
|
||||
swarnstate_t switchWarningState;
|
||||
PACK(typedef struct {
|
||||
char layoutName[10];
|
||||
Layout::PersistentData layoutData;
|
||||
}) CustomScreenData;
|
||||
#define CUSTOM_SCREENS_DATA \
|
||||
CustomScreenData screenData[MAX_CUSTOM_SCREENS];
|
||||
#else
|
||||
#define SWITCHES_WARNING_DATA \
|
||||
swarnstate_t switchWarningState; \
|
||||
swarnenable_t switchWarningEnable;
|
||||
#define CUSTOM_SCREENS_DATA
|
||||
#endif
|
||||
|
||||
PACK(typedef struct {
|
||||
@@ -2317,10 +2326,10 @@ PACK(typedef struct {
|
||||
MixData mixData[MAX_MIXERS];
|
||||
LimitData limitData[NUM_CHNOUT];
|
||||
ExpoData expoData[MAX_EXPOS];
|
||||
|
||||
|
||||
CurveData curves[MAX_CURVES];
|
||||
int8_t points[NUM_POINTS];
|
||||
|
||||
|
||||
LogicalSwitchData logicalSw[NUM_LOGICAL_SWITCH];
|
||||
CustomFunctionData customFn[NUM_CFN];
|
||||
SwashRingData swashR;
|
||||
@@ -2339,8 +2348,11 @@ PACK(typedef struct {
|
||||
MODELDATA_EXTRA
|
||||
|
||||
ARM_FIELD(TelemetrySensor telemetrySensors[MAX_SENSORS])
|
||||
|
||||
|
||||
TARANIS_REV9E_FIELD(uint8_t toplcdTimer)
|
||||
|
||||
CUSTOM_SCREENS_DATA
|
||||
|
||||
}) ModelData;
|
||||
|
||||
extern EEGeneral g_eeGeneral;
|
||||
|
||||
+31
-11
@@ -2,7 +2,7 @@
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
@@ -1524,7 +1524,7 @@ uint16_t anaIn(uint8_t chan)
|
||||
return temp;
|
||||
#else
|
||||
volatile uint16_t *p = &s_anaFilt[pgm_read_byte(crossAna+chan)];
|
||||
return *p;
|
||||
return *p;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
@@ -1587,7 +1587,7 @@ void getADC()
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
#endif
|
||||
{
|
||||
s_anaFilt[x] = v;
|
||||
@@ -1880,7 +1880,23 @@ void doMixerCalculations()
|
||||
s_mixer_first_run_done = true;
|
||||
}
|
||||
|
||||
#if defined(COLORLCD)
|
||||
void loadCustomScreens()
|
||||
{
|
||||
for (unsigned int i=0; i<MAX_CUSTOM_SCREENS; i++) {
|
||||
char name[sizeof(g_model.screenData[i].layoutName)+1];
|
||||
memset(name, 0, sizeof(name));
|
||||
strncpy(name, g_model.screenData[i].layoutName, sizeof(g_model.screenData[i].layoutName));
|
||||
customScreens[i] = loadLayout(name, &g_model.screenData[i].layoutData);
|
||||
}
|
||||
|
||||
if (customScreens[0] == NULL) {
|
||||
customScreens[0] = registeredLayouts[0]->create(&g_model.screenData[0].layoutData);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define loadCustomScreens()
|
||||
#endif
|
||||
|
||||
#if defined(NAVIGATION_STICKS)
|
||||
uint8_t StickScrollAllowed;
|
||||
@@ -1914,7 +1930,7 @@ void opentxStart()
|
||||
|
||||
#if defined(DEBUG_TRACE_BUFFER)
|
||||
trace_event(trace_start, 0x12345678);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(PCBSKY9X) && defined(SDCARD) && !defined(SIMU)
|
||||
for (int i=0; i<500 && !Card_initialized; i++) {
|
||||
@@ -1927,6 +1943,8 @@ void opentxStart()
|
||||
checkAll();
|
||||
#endif
|
||||
|
||||
loadCustomScreens();
|
||||
|
||||
#if defined(GUI)
|
||||
if (g_eeGeneral.chkSum != evalChkSum()) {
|
||||
chainMenu(menuFirstCalib);
|
||||
@@ -1994,7 +2012,7 @@ void opentxClose()
|
||||
#if !defined(PCBTARANIS) && !defined(COLORLCD)
|
||||
if (storageDirtyMsk & EE_MODEL) {
|
||||
displayPopup(STR_SAVEMODEL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
g_eeGeneral.unexpectedShutdown = 0;
|
||||
@@ -2017,7 +2035,7 @@ void opentxClose()
|
||||
#endif
|
||||
|
||||
#if defined(NAVIGATION_STICKS)
|
||||
uint8_t getSticksNavigationEvent()
|
||||
uint8_t getSticksNavigationEvent()
|
||||
{
|
||||
uint8_t evt = 0;
|
||||
if (StickScrollAllowed) {
|
||||
@@ -2198,10 +2216,10 @@ ISR(TIMER_AUDIO_VECT, ISR_NOBLOCK)
|
||||
#endif
|
||||
|
||||
// Clocks every 10ms
|
||||
ISR(TIMER_10MS_VECT, ISR_NOBLOCK)
|
||||
ISR(TIMER_10MS_VECT, ISR_NOBLOCK)
|
||||
{
|
||||
// without correction we are 0,16% too fast; that mean in one hour we are 5,76Sek too fast; we do not like that
|
||||
static uint8_t accuracyWarble; // because 16M / 1024 / 100 = 156.25. we need to correct the fault; no start value needed
|
||||
static uint8_t accuracyWarble; // because 16M / 1024 / 100 = 156.25. we need to correct the fault; no start value needed
|
||||
|
||||
#if defined(AUDIO)
|
||||
AUDIO_HEARTBEAT();
|
||||
@@ -2235,7 +2253,7 @@ ISR(TIMER3_CAPT_vect) // G: High frequency noise can cause stack overflo with IS
|
||||
sei(); // enable other interrupts
|
||||
|
||||
captureTrainerPulses(capture);
|
||||
|
||||
|
||||
cli(); // disable other interrupts for stack pops before this function's RETI
|
||||
RESUME_PPMIN_INTERRUPT();
|
||||
}
|
||||
@@ -2553,6 +2571,8 @@ void opentxInit(OPENTX_INIT_ARGS)
|
||||
startPulses();
|
||||
|
||||
wdt_enable(WDTO_500MS);
|
||||
|
||||
|
||||
}
|
||||
|
||||
#if !defined(SIMU)
|
||||
@@ -2571,11 +2591,11 @@ int main(void)
|
||||
#endif
|
||||
#if defined(PCBTARANIS)
|
||||
g_eeGeneral.contrast=30;
|
||||
#endif
|
||||
#endif
|
||||
wdt_disable();
|
||||
|
||||
boardInit();
|
||||
|
||||
|
||||
#if defined(GUI) && !defined(PCBTARANIS) && !defined(PCBFLAMENCO) && !defined(PCBHORUS)
|
||||
// TODO remove this
|
||||
lcdInit();
|
||||
|
||||
+2
-2
@@ -843,8 +843,8 @@ int getTrimValue(uint8_t phase, uint8_t idx);
|
||||
extern uint8_t gvarLastChanged;
|
||||
#endif
|
||||
#else
|
||||
#define GET_GVAR(x, ...) (x)
|
||||
#define GET_GVAR_PREC1(x, ...) (x*10)
|
||||
#define GET_GVAR(x, ...) (x)
|
||||
#define GET_GVAR_PREC1(x, ...) (x*10)
|
||||
#endif
|
||||
|
||||
#if defined(CPUARM)
|
||||
|
||||
@@ -575,6 +575,9 @@ const pm_char STR_MODEL_SELECT[] PROGMEM = TR_MODEL_SELECT;
|
||||
const pm_char STR_STOP_DISCOVER_SENSORS[] PROGMEM = TR_STOP_DISCOVER_SENSORS;
|
||||
const pm_char STR_DELETE_ALL_SENSORS[] PROGMEM = TR_DELETE_ALL_SENSORS;
|
||||
const pm_char STR_CONFIRMDELETE[] PROGMEM = TR_CONFIRMDELETE;
|
||||
const pm_char STR_SELECT_WIDGET[] PROGMEM = TR_SELECT_WIDGET;
|
||||
const pm_char STR_REMOVE_WIDGET[] PROGMEM = TR_REMOVE_WIDGET;
|
||||
const pm_char STR_WIDGET_SETTINGS[] PROGMEM = TR_WIDGET_SETTINGS;
|
||||
#endif
|
||||
|
||||
#if defined(PCBTARANIS) || defined(PCBFLAMENCO) || defined(PCBHORUS)
|
||||
|
||||
@@ -826,6 +826,9 @@ extern const pm_char STR_BLCOLOR[];
|
||||
extern const pm_char STR_STOP_DISCOVER_SENSORS[];
|
||||
extern const pm_char STR_DELETE_ALL_SENSORS[];
|
||||
extern const pm_char STR_CONFIRMDELETE[];
|
||||
extern const pm_char STR_SELECT_WIDGET[];
|
||||
extern const pm_char STR_REMOVE_WIDGET[];
|
||||
extern const pm_char STR_WIDGET_SETTINGS[];
|
||||
#endif
|
||||
|
||||
#if defined(PCBTARANIS) || defined(PCBFLAMENCO) || defined(PCBHORUS)
|
||||
@@ -834,9 +837,9 @@ extern const pm_char STR_BLCOLOR[];
|
||||
extern const pm_char STR_MODULE[];
|
||||
extern const pm_char STR_ENABLE_POPUP[];
|
||||
extern const pm_char STR_DISABLE_POPUP[];
|
||||
extern const pm_char STR_POPUP[];
|
||||
extern const pm_char STR_MIN[];
|
||||
extern const pm_char STR_MAX[];
|
||||
extern const pm_char STR_POPUP[];
|
||||
extern const pm_char STR_MIN[];
|
||||
extern const pm_char STR_MAX[];
|
||||
extern const pm_char STR_CURVE_PRESET[];
|
||||
extern const pm_char STR_PRESET[];
|
||||
extern const pm_char STR_MIRROR[];
|
||||
|
||||
@@ -1099,6 +1099,9 @@
|
||||
#define TR_STOP_DISCOVER_SENSORS INDENT "Zastavit autodetekci"
|
||||
#define TR_DELETE_ALL_SENSORS INDENT "Odstranit všechny senzory"
|
||||
#define TR_CONFIRMDELETE "Opravdu odstranit vše?"
|
||||
#define TR_SELECT_WIDGET "Select widget"
|
||||
#define TR_REMOVE_WIDGET "Remove widget"
|
||||
#define TR_WIDGET_SETTINGS "Widget settings"
|
||||
|
||||
#define TR_MENU_INPUTS "\314Vstupy"
|
||||
#define TR_MENU_LUA "\322Lua skripty"
|
||||
|
||||
@@ -1102,6 +1102,9 @@
|
||||
#define TR_STOP_DISCOVER_SENSORS INDENT "Stop Sensorsuche"
|
||||
#define TR_DELETE_ALL_SENSORS INDENT "Lösche alle Sensoren"
|
||||
#define TR_CONFIRMDELETE "Wirklich alle löschen?"
|
||||
#define TR_SELECT_WIDGET "Select widget"
|
||||
#define TR_REMOVE_WIDGET "Remove widget"
|
||||
#define TR_WIDGET_SETTINGS "Widget settings"
|
||||
// ----------------------------- Symbole für Auswahlliste----------
|
||||
#define TR_MENU_INPUTS "\314Inputs"
|
||||
#define TR_MENU_LUA "\322Lua Scripte"
|
||||
|
||||
@@ -1128,6 +1128,9 @@
|
||||
#define TR_STOP_DISCOVER_SENSORS INDENT "Stop discovery"
|
||||
#define TR_DELETE_ALL_SENSORS INDENT "Delete all sensors"
|
||||
#define TR_CONFIRMDELETE "Really delete all?"
|
||||
#define TR_SELECT_WIDGET "Select widget"
|
||||
#define TR_REMOVE_WIDGET "Remove widget"
|
||||
#define TR_WIDGET_SETTINGS "Widget settings"
|
||||
|
||||
#define TR_MENU_INPUTS "\314Inputs"
|
||||
#define TR_MENU_LUA "\322Lua scripts"
|
||||
|
||||
@@ -1054,6 +1054,9 @@
|
||||
#define TR_STOP_DISCOVER_SENSORS INDENT "Stop discovery"
|
||||
#define TR_DELETE_ALL_SENSORS INDENT "Delete all sensors"
|
||||
#define TR_CONFIRMDELETE "Really delete all?"
|
||||
#define TR_SELECT_WIDGET "Select widget"
|
||||
#define TR_REMOVE_WIDGET "Remove widget"
|
||||
#define TR_WIDGET_SETTINGS "Widget settings"
|
||||
|
||||
#define TR_MENU_INPUTS "\314Inputs"
|
||||
#define TR_MENU_LUA "\322Lua scripts"
|
||||
|
||||
@@ -1054,6 +1054,9 @@
|
||||
#define TR_STOP_DISCOVER_SENSORS INDENT "Stop discovery"
|
||||
#define TR_DELETE_ALL_SENSORS INDENT "Delete all sensors"
|
||||
#define TR_CONFIRMDELETE "Really delete all?"
|
||||
#define TR_SELECT_WIDGET "Select widget"
|
||||
#define TR_REMOVE_WIDGET "Remove widget"
|
||||
#define TR_WIDGET_SETTINGS "Widget settings"
|
||||
|
||||
#define TR_MENU_INPUTS "\314Inputs"
|
||||
#define TR_MENU_LUA "\322Lua scripts"
|
||||
|
||||
@@ -1089,6 +1089,9 @@
|
||||
#define TR_STOP_DISCOVER_SENSORS INDENT "Terminer découverte"
|
||||
#define TR_DELETE_ALL_SENSORS TR(INDENT "Suppr. tous capteurs",INDENT "Supprimer tous capteurs")
|
||||
#define TR_CONFIRMDELETE TR("Tout effacer?","Vraiment tout effacer?")
|
||||
#define TR_SELECT_WIDGET "Select widget"
|
||||
#define TR_REMOVE_WIDGET "Remove widget"
|
||||
#define TR_WIDGET_SETTINGS "Widget settings"
|
||||
|
||||
#define TR_MENU_INPUTS "\314Entrées"
|
||||
#define TR_MENU_LUA "\322Scripts Lua"
|
||||
|
||||
@@ -1101,6 +1101,9 @@
|
||||
#define TR_STOP_DISCOVER_SENSORS INDENT "Ferma ricerca.."
|
||||
#define TR_DELETE_ALL_SENSORS INDENT "Elimina tutti i sensori"
|
||||
#define TR_CONFIRMDELETE "Confermi eliminazione?"
|
||||
#define TR_SELECT_WIDGET "Select widget"
|
||||
#define TR_REMOVE_WIDGET "Remove widget"
|
||||
#define TR_WIDGET_SETTINGS "Widget settings"
|
||||
|
||||
#define TR_MENU_INPUTS "\314Ingressi"
|
||||
#define TR_MENU_LUA "\322Lua scripts"
|
||||
|
||||
@@ -1120,6 +1120,9 @@
|
||||
#define TR_STOP_DISCOVER_SENSORS INDENT "Stop ontdekking"
|
||||
#define TR_DELETE_ALL_SENSORS INDENT "Wis alle sensors"
|
||||
#define TR_CONFIRMDELETE "Echt alles wissen?"
|
||||
#define TR_SELECT_WIDGET "Select widget"
|
||||
#define TR_REMOVE_WIDGET "Remove widget"
|
||||
#define TR_WIDGET_SETTINGS "Widget settings"
|
||||
|
||||
|
||||
#define TR_MENU_INPUTS "\314Inputs"
|
||||
|
||||
@@ -1102,6 +1102,9 @@
|
||||
#define TR_STOP_DISCOVER_SENSORS INDENT "Szukanie STOP "
|
||||
#define TR_DELETE_ALL_SENSORS INDENT "Usuń czujniki "
|
||||
#define TR_CONFIRMDELETE "Usunąć wszystkie ?"
|
||||
#define TR_SELECT_WIDGET "Select widget"
|
||||
#define TR_REMOVE_WIDGET "Remove widget"
|
||||
#define TR_WIDGET_SETTINGS "Widget settings"
|
||||
|
||||
#define TR_MENU_INPUTS "\314Wejści"
|
||||
#define TR_MENU_LUA "\322SkryptyLUA"
|
||||
|
||||
@@ -1048,6 +1048,9 @@
|
||||
#define TR_STOP_DISCOVER_SENSORS INDENT "Stop discovery"
|
||||
#define TR_DELETE_ALL_SENSORS INDENT "Delete all sensors"
|
||||
#define TR_CONFIRMDELETE "Really delete all?"
|
||||
#define TR_SELECT_WIDGET "Select widget"
|
||||
#define TR_REMOVE_WIDGET "Remove widget"
|
||||
#define TR_WIDGET_SETTINGS "Widget settings"
|
||||
|
||||
#define TR_MENU_INPUTS "\314Inputs"
|
||||
#define TR_MENU_LUA "\322Lua scripts"
|
||||
|
||||
@@ -1125,6 +1125,9 @@
|
||||
#define TR_STOP_DISCOVER_SENSORS INDENT "Avbryt sökning"
|
||||
#define TR_DELETE_ALL_SENSORS INDENT "Ta bort alla sensorer"
|
||||
#define TR_CONFIRMDELETE "Ta bort alla?"
|
||||
#define TR_SELECT_WIDGET "Select widget"
|
||||
#define TR_REMOVE_WIDGET "Remove widget"
|
||||
#define TR_WIDGET_SETTINGS "Widget settings"
|
||||
|
||||
#define TR_MENU_INPUTS "\314Inputs"
|
||||
#define TR_MENU_LUA "\322Lua scripts"
|
||||
|
||||
@@ -91,10 +91,8 @@ def createFontBitmap(filename, fontname, fontsize, fontbold, foreground, backgro
|
||||
with open(filename + ".specs", "w") as f:
|
||||
f.write("{ ")
|
||||
f.write(",".join(str(tmp) for tmp in coords))
|
||||
if extraWidth:
|
||||
for i in range(1, 14):
|
||||
f.write(", %d" % (int(coords[-1]) + i * (extraWidth / 12)))
|
||||
# f.write(file("fonts/extra_%dpx.specs" % fontsize).read())
|
||||
for i in range(1, 14):
|
||||
f.write(", %d" % (int(coords[-1]) + i * (extraWidth / 12)))
|
||||
f.write(" }")
|
||||
return coords
|
||||
|
||||
|
||||
Reference in New Issue
Block a user