chore(bw): refactor and cleanup of code (#6481)
This commit is contained in:
@@ -244,6 +244,8 @@ inline void ALERT(const char *title, const char *msg, uint8_t sound)
|
||||
|
||||
#else // !COLORLCD && GUI
|
||||
|
||||
#include "popups.h"
|
||||
|
||||
inline void RAISE_ALERT(const char *title, const char *msg, const char *info,
|
||||
uint8_t sound)
|
||||
{
|
||||
|
||||
@@ -6,7 +6,6 @@ set(GUI_SRC
|
||||
widgets.cpp
|
||||
startup_shutdown.cpp
|
||||
model_select.cpp
|
||||
menu_model.cpp
|
||||
model_setup.cpp
|
||||
model_failsafe.cpp
|
||||
model_logical_switches.cpp
|
||||
@@ -14,7 +13,6 @@ set(GUI_SRC
|
||||
model_outputs.cpp
|
||||
model_telemetry.cpp
|
||||
model_telemetry_sensor.cpp
|
||||
menu_radio.cpp
|
||||
radio_setup.cpp
|
||||
radio_calibration.cpp
|
||||
view_main.cpp
|
||||
@@ -43,6 +41,7 @@ include(gui/common/stdlcd/CMakeLists.txt)
|
||||
|
||||
set(BOOTLOADER_SRC ${BOOTLOADER_SRC}
|
||||
${RADIO_SRC_DIR}/gui/128x64/lcd.cpp
|
||||
${RADIO_SRC_DIR}/gui/common/stdlcd/lcd_common.cpp
|
||||
${RADIO_SRC_DIR}/gui/common/stdlcd/fonts.cpp
|
||||
${RADIO_SRC_DIR}/gui/common/stdlcd/utf8.cpp
|
||||
)
|
||||
|
||||
+2
-155
@@ -23,174 +23,21 @@
|
||||
|
||||
#include "gui_common.h"
|
||||
#include "menus.h"
|
||||
#include "popups.h"
|
||||
#include "widgets_common.h"
|
||||
|
||||
#include "navigation/navigation.h"
|
||||
#include "common/stdlcd/draw_functions.h"
|
||||
#include "draw_functions.h"
|
||||
|
||||
#define MENUS_SCROLLBAR_WIDTH 0
|
||||
|
||||
#define NUM_BODY_LINES (LCD_LINES-1)
|
||||
#define TEXT_VIEWER_LINES NUM_BODY_LINES
|
||||
#define MENU_HEADER_HEIGHT FH
|
||||
|
||||
#define CURVE_SIDE_WIDTH (LCD_H/2-2)
|
||||
#define CURVE_CENTER_X (LCD_W-CURVE_SIDE_WIDTH-3)
|
||||
#define CURVE_CENTER_Y (LCD_H/2)
|
||||
|
||||
#define MIXES_2ND_COLUMN (10*FW)
|
||||
|
||||
// Temporary no highlight
|
||||
extern uint8_t noHighlightCounter;
|
||||
#define NO_HIGHLIGHT() (noHighlightCounter > 0)
|
||||
#define START_NO_HIGHLIGHT() do { noHighlightCounter = 25; } while(0)
|
||||
|
||||
void drawSlider(coord_t x, coord_t y, uint8_t width, uint8_t value, uint8_t max, uint8_t attr);
|
||||
void drawSlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr);
|
||||
|
||||
void title(const char * s);
|
||||
|
||||
typedef int choice_t;
|
||||
|
||||
choice_t editChoice(coord_t x, coord_t y, const char *label,
|
||||
const char *const *values, choice_t value, choice_t min,
|
||||
choice_t max, LcdFlags attr, event_t event);
|
||||
choice_t editChoice(coord_t x, coord_t y, const char *label,
|
||||
const char *const *values, choice_t value, choice_t min,
|
||||
choice_t max, LcdFlags attr, event_t event, coord_t lblX);
|
||||
choice_t editChoice(coord_t x, coord_t y, const char *label,
|
||||
const char *const *values, choice_t value, choice_t min,
|
||||
choice_t max, LcdFlags attr, event_t event, coord_t lblX,
|
||||
IsValueAvailable isValueAvailable);
|
||||
|
||||
uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label,
|
||||
LcdFlags attr, event_t event);
|
||||
uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label,
|
||||
LcdFlags attr, event_t event, coord_t lblX);
|
||||
|
||||
swsrc_t editSwitch(coord_t x, coord_t y, swsrc_t value, LcdFlags attr,
|
||||
event_t event);
|
||||
|
||||
uint16_t editSrcVarFieldValue(coord_t x, coord_t y, const char* title, uint16_t value,
|
||||
int16_t min, int16_t max, LcdFlags attr, event_t event,
|
||||
IsValueAvailable isValueAvailable, int16_t sourceMin, int16_t sourceMax);
|
||||
|
||||
#if defined(GVARS)
|
||||
|
||||
#define GVAR_MENU_ITEM(x, y, v, min, max, attr, editflags, event) \
|
||||
editGVarFieldValue(x, y, v, min, max, attr, editflags, event)
|
||||
|
||||
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min,
|
||||
int16_t max, LcdFlags attr, uint8_t editflags,
|
||||
event_t event);
|
||||
|
||||
void drawGVarValue(coord_t x, coord_t y, uint8_t gvar, gvar_t value,
|
||||
LcdFlags flags = 0);
|
||||
|
||||
void editGVarValue(coord_t x, coord_t y, event_t event, uint8_t gvar,
|
||||
uint8_t flightMode, LcdFlags flags);
|
||||
|
||||
#define displayGVar(x, y, v, min, max) \
|
||||
GVAR_MENU_ITEM(x, y, v, min, max, 0, 0, 0)
|
||||
|
||||
#else // GVARS
|
||||
|
||||
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min,
|
||||
int16_t max, LcdFlags attr, event_t event);
|
||||
|
||||
#define GVAR_MENU_ITEM(x, y, v, min, max, attr, editflags, event) \
|
||||
editGVarFieldValue(x, y, v, min, max, attr, event)
|
||||
|
||||
#define displayGVar(x, y, v, min, max) lcdDraw8bitsNumber(x, y, v)
|
||||
|
||||
#endif
|
||||
|
||||
void editName(coord_t x, coord_t y, char *name, uint8_t size, event_t event,
|
||||
uint8_t active, LcdFlags attr, uint8_t old_editMode);
|
||||
|
||||
void editSingleName(coord_t x, coord_t y, const char *label, char *name,
|
||||
uint8_t size, event_t event, uint8_t active,
|
||||
uint8_t old_editMode, coord_t lblX = 0);
|
||||
|
||||
uint8_t editDelay(coord_t y, event_t event, uint8_t attr, const char * str, uint8_t delay, uint8_t prec);
|
||||
|
||||
#define EDIT_DELAY(x, y, event, attr, str, delay, prec) editDelay(y, event, attr, str, delay, prec)
|
||||
|
||||
#define COPY_MODE 1
|
||||
#define MOVE_MODE 2
|
||||
|
||||
extern uint8_t s_copyMode;
|
||||
extern int8_t s_copySrcRow;
|
||||
extern int8_t s_copyTgtOfs;
|
||||
extern uint8_t s_currIdx;
|
||||
extern uint8_t s_currIdxSubMenu;
|
||||
extern mixsrc_t s_currSrcRaw;
|
||||
extern uint16_t s_currScale;
|
||||
extern uint8_t s_copySrcIdx;
|
||||
extern uint8_t s_copySrcCh;
|
||||
extern int8_t s_currCh;
|
||||
extern uint8_t s_maxLines;
|
||||
|
||||
#define STATUS_LINE_LENGTH 32
|
||||
extern char statusLineMsg[STATUS_LINE_LENGTH];
|
||||
void showStatusLine();
|
||||
void drawStatusLine();
|
||||
|
||||
void menuTextView(event_t event);
|
||||
void pushMenuTextView(const char *filename);
|
||||
void pushModelNotes();
|
||||
void readModelNotes();
|
||||
|
||||
void menuChannelsView(event_t event);
|
||||
void menuChannelsViewCommon(event_t event);
|
||||
|
||||
#define EDIT_MODE_INIT 0
|
||||
|
||||
extern uint8_t editNameCursorPos;
|
||||
|
||||
uint8_t getExposCount();
|
||||
void insertExpo(uint8_t idx);
|
||||
void deleteExpo(uint8_t idx);
|
||||
|
||||
void onSwitchLongEnterPress(const char *result);
|
||||
void onSourceLongEnterPress(const char *result);
|
||||
|
||||
uint8_t switchToMix(uint8_t source);
|
||||
|
||||
void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr);
|
||||
|
||||
extern const unsigned char sticks[] ;
|
||||
|
||||
void drawSplash();
|
||||
void drawScreenIndex(uint8_t index, uint8_t count, uint8_t attr);
|
||||
void drawStick(coord_t centrex, int16_t xval, int16_t yval);
|
||||
void drawWheel(coord_t centrex, int16_t wval);
|
||||
void drawThrottle(coord_t centrex, int16_t tval);
|
||||
void drawPotsBars();
|
||||
void doMainScreenGraphics();
|
||||
|
||||
void drawProgressScreen(const char * title, const char * message, int num, int den);
|
||||
void drawSleepBitmap();
|
||||
|
||||
void drawVerticalScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible);
|
||||
void drawGauge(coord_t x, coord_t y, coord_t w, coord_t h, int32_t val, int32_t max);
|
||||
|
||||
void drawAlertBox(const char * title, const char * text, const char * action);
|
||||
void showAlertBox(const char * title, const char * text, const char * action , uint8_t sound);
|
||||
|
||||
#define SET_SCROLLBAR_X(x)
|
||||
#define LOAD_MODEL_BITMAP()
|
||||
|
||||
#define IS_MAIN_VIEW_DISPLAYED() menuHandlers[0] == menuMainView
|
||||
#define IS_TELEMETRY_VIEW_DISPLAYED() menuHandlers[0] == menuViewTelemetry
|
||||
#define IS_OTHER_VIEW_DISPLAYED() menuHandlers[0] == menuChannelsView
|
||||
|
||||
void editCurveRef(coord_t x, coord_t y, CurveRef & curve, event_t event, LcdFlags flags,
|
||||
IsValueAvailable isValueAvailable, int16_t sourceMin, int16_t sourceMax);
|
||||
|
||||
#if defined(FLIGHT_MODES)
|
||||
void displayFlightModes(coord_t x, coord_t y, FlightModesType value);
|
||||
FlightModesType editFlightModes(coord_t x, coord_t y, event_t event, FlightModesType value, uint8_t attr);
|
||||
#else
|
||||
#define displayFlightModes(...)
|
||||
#endif
|
||||
|
||||
+35
-579
@@ -19,13 +19,9 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include "lcd.h"
|
||||
#include "bitfield.h"
|
||||
#include "gui/common/stdlcd/fonts.h"
|
||||
#include "gui/common/stdlcd/utf8.h"
|
||||
#include "utf8.h"
|
||||
|
||||
#if !defined(SIMU)
|
||||
#define assert(x)
|
||||
@@ -35,237 +31,9 @@
|
||||
|
||||
#if !defined(BOOT)
|
||||
#include "edgetx.h"
|
||||
#include "hal/switch_driver.h"
|
||||
#include "hal/adc_driver.h"
|
||||
#include "switches.h"
|
||||
#endif
|
||||
|
||||
pixel_t displayBuf[DISPLAY_BUFFER_SIZE] __DMA;
|
||||
|
||||
void lcdClear()
|
||||
{
|
||||
memset(displayBuf, 0, DISPLAY_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
coord_t lcdLastRightPos;
|
||||
coord_t lcdNextPos;
|
||||
coord_t lcdLastLeftPos;
|
||||
|
||||
void lcdPutPattern(coord_t x, coord_t y, const uint8_t * pattern, uint8_t width, uint8_t height, LcdFlags flags)
|
||||
{
|
||||
bool blink = false;
|
||||
bool inv = false;
|
||||
if (flags & BLINK) {
|
||||
if (BLINK_ON_PHASE) {
|
||||
if (flags & INVERS)
|
||||
inv = true;
|
||||
else {
|
||||
blink = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (flags & INVERS) {
|
||||
inv = true;
|
||||
}
|
||||
|
||||
uint8_t lines = (height+7)/8;
|
||||
assert(lines <= 5);
|
||||
|
||||
for (int8_t i=0; i<width+2; i++) {
|
||||
if (x >= 0 && x < LCD_W) {
|
||||
uint8_t b[5] = { 0 };
|
||||
if (i==0) {
|
||||
if (x==0 || !inv) {
|
||||
lcdNextPos++;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
// we need to work on the previous x when INVERS
|
||||
x--;
|
||||
}
|
||||
}
|
||||
else if (i<=width) {
|
||||
uint8_t skip = true;
|
||||
for (uint8_t j=0; j<lines; j++) {
|
||||
b[j] = *(pattern++); /*top byte*/
|
||||
if (b[j] != 0xff) {
|
||||
skip = false;
|
||||
}
|
||||
}
|
||||
if (skip) {
|
||||
if (flags & FIXEDWIDTH) {
|
||||
for (uint8_t j=0; j<lines; j++) {
|
||||
b[j] = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((flags & CONDENSED) && i==2) {
|
||||
/*condense the letter by skipping column 3 */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for (int8_t j=-1; j<=height; j++) {
|
||||
bool plot;
|
||||
if (j < 0 || ((j == height) && !(FONTSIZE(flags) == SMLSIZE))) {
|
||||
plot = false;
|
||||
if (height >= 12) continue;
|
||||
if (j<0 && !inv) continue;
|
||||
if (y+j < 0) continue;
|
||||
}
|
||||
else {
|
||||
uint8_t line = (j / 8);
|
||||
uint8_t pixel = (j % 8);
|
||||
plot = b[line] & (1 << pixel);
|
||||
}
|
||||
if (inv) plot = !plot;
|
||||
if (!blink) {
|
||||
if (flags & VERTICAL)
|
||||
lcdDrawPoint(y+j, LCD_H-x, plot ? FORCE : ERASE);
|
||||
else
|
||||
lcdDrawPoint(x, y+j, plot ? FORCE : ERASE);
|
||||
}
|
||||
}
|
||||
}
|
||||
x++;
|
||||
lcdNextPos++;
|
||||
}
|
||||
}
|
||||
|
||||
struct PatternData
|
||||
{
|
||||
uint8_t width;
|
||||
uint8_t height;
|
||||
const uint8_t * data;
|
||||
};
|
||||
|
||||
uint8_t getPatternWidth(const PatternData * pattern)
|
||||
{
|
||||
uint8_t result = 0;
|
||||
uint8_t lines = (pattern->height+7)/8;
|
||||
const uint8_t * data = pattern->data;
|
||||
for (int8_t i=0; i<pattern->width; i++) {
|
||||
for (uint8_t j=0; j<lines; j++) {
|
||||
if (data[j] != 0xff) {
|
||||
result += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
data += lines;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
LcdFlags getCharPattern(PatternData * pattern, unsigned char c, LcdFlags flags)
|
||||
{
|
||||
#if !defined(BOOT)
|
||||
static const uint8_t fontWidth[] = { 5, 3, 5, 8, 10, 22, 5 };
|
||||
static const uint8_t fontHeight[] = { 7, 5, 6, 12, 16, 38, 7 };
|
||||
|
||||
uint32_t fontsize = FONTSIZE(flags);
|
||||
unsigned char c_remapped = 0;
|
||||
|
||||
if (fontsize == DBLSIZE || (flags & BOLD)) {
|
||||
// To save space only some DBLSIZE and BOLD chars are available
|
||||
// c has to be remapped. All non existing chars mapped to 0 (space)
|
||||
if (c >= ',' && c <= ':')
|
||||
c_remapped = c - ',' + 1;
|
||||
else if (c >= 'A' && c <= 'Z')
|
||||
c_remapped = c - 'A' + 16;
|
||||
else if (c >= 'a' && c <= 'z')
|
||||
c_remapped = c - 'a' + 42;
|
||||
else if (c == '_')
|
||||
c_remapped = 4;
|
||||
else if (c != ' ')
|
||||
flags &= ~BOLD; // For BOLD use Standard font if character is not in BOLD
|
||||
}
|
||||
|
||||
uint8_t fontIdx = fontsize >> 8;
|
||||
if (fontIdx == 0 && flags & BOLD) fontIdx = 6;
|
||||
|
||||
pattern->width = fontWidth[fontIdx];
|
||||
pattern->height = fontHeight[fontIdx];
|
||||
int charSize = (pattern->height + 7) / 8 * pattern->width;
|
||||
|
||||
switch (fontIdx) {
|
||||
case 0: // Standard
|
||||
pattern->data = &font_5x7[(c - FONT_BASE_START) * charSize];
|
||||
break;
|
||||
case 1: // TINSIZE
|
||||
pattern->data = &font_3x5[(c - FONT_BASE_START) * charSize];
|
||||
break;
|
||||
case 2: // SMLSIZE
|
||||
// Adjust language special characters offset
|
||||
if (c >= FONT_LANG_START)
|
||||
c = c - (FONT_SYMS_CNT - FONT_SYMS_CNT_4x6);
|
||||
pattern->data = &font_4x6[(c - FONT_BASE_START) * charSize];
|
||||
break;
|
||||
case 3: // MDLSIZE
|
||||
// Adjust language special characters offset
|
||||
if (c >= FONT_LANG_START)
|
||||
c = c - FONT_SYMS_CNT;
|
||||
pattern->data = &font_8x10[(c - FONT_BASE_START) * charSize];
|
||||
break;
|
||||
case 4: // DBLSIZE
|
||||
// Adjust language special characters offset and symbols offset
|
||||
if (c >= FONT_LANG_START)
|
||||
c_remapped = c - (FONT_BASE_CNT - FONT_BASE_CNT_10x14) - (FONT_SYMS_CNT - FONT_SYMS_CNT_10x14) - FONT_BASE_START;
|
||||
else if (c >= FONT_SYMS_START)
|
||||
c_remapped = c - (FONT_BASE_CNT - FONT_BASE_CNT_10x14) - FONT_BASE_START;
|
||||
pattern->data = &font_10x14[(c_remapped) * charSize];
|
||||
break;
|
||||
case 5: // XXLSIZE
|
||||
pattern->data = &font_22x38_num[(c - '0' + 5) * charSize];
|
||||
break;
|
||||
case 6: // BOLD
|
||||
pattern->data = &font_5x7_B[c_remapped * charSize];
|
||||
break;
|
||||
};
|
||||
#else
|
||||
pattern->width = 5;
|
||||
pattern->height = 7;
|
||||
pattern->data = &font_5x7[(c - FONT_BASE_START) * 5];
|
||||
#endif
|
||||
return flags;
|
||||
}
|
||||
|
||||
uint8_t getCharWidth(char c, LcdFlags flags)
|
||||
{
|
||||
PatternData pattern;
|
||||
getCharPattern(&pattern, c, flags);
|
||||
return getPatternWidth(&pattern);
|
||||
}
|
||||
|
||||
void lcdDrawChar(coord_t x, coord_t y, uint8_t c, LcdFlags flags)
|
||||
{
|
||||
lcdNextPos = x - 1;
|
||||
PatternData pattern;
|
||||
flags = getCharPattern(&pattern, c, flags);
|
||||
lcdPutPattern(x, y, pattern.data, pattern.width, pattern.height, flags);
|
||||
}
|
||||
|
||||
void lcdDrawChar(coord_t x, coord_t y, uint8_t c)
|
||||
{
|
||||
lcdDrawChar(x, y, c, 0);
|
||||
}
|
||||
|
||||
uint8_t getTextWidth(const char * s, uint8_t len, LcdFlags flags)
|
||||
{
|
||||
uint8_t width = 0;
|
||||
if (len == 0) len = strlen(s);
|
||||
while (len--) {
|
||||
unsigned char c = map_utf8_char(s, len);
|
||||
if (!c) {
|
||||
break;
|
||||
}
|
||||
width += getCharWidth(c, flags) + 1;
|
||||
s++;
|
||||
}
|
||||
return width;
|
||||
}
|
||||
extern LcdFlags getCharPattern(PatternData * pattern, unsigned char c, LcdFlags flags);
|
||||
|
||||
void lcdDrawSizedText(coord_t x, coord_t y, const char * s, uint8_t len, LcdFlags flags)
|
||||
{
|
||||
@@ -345,43 +113,7 @@ void lcdDrawSizedText(coord_t x, coord_t y, const char * s, uint8_t len, LcdFlag
|
||||
#endif
|
||||
}
|
||||
|
||||
void lcdDrawSizedText(coord_t x, coord_t y, const char * s, uint8_t len)
|
||||
{
|
||||
lcdDrawSizedText(x, y, s, len, 0);
|
||||
}
|
||||
|
||||
void lcdDrawText(coord_t x, coord_t y, const char * s, LcdFlags flags)
|
||||
{
|
||||
lcdDrawSizedText(x, y, s, 255, flags);
|
||||
}
|
||||
|
||||
void lcdDrawCenteredText(coord_t y, const char * s, LcdFlags flags)
|
||||
{
|
||||
coord_t x = (LCD_W - getTextWidth(s, flags)) / 2;
|
||||
lcdDrawText(x, y, s, flags);
|
||||
}
|
||||
|
||||
void lcdDrawText(coord_t x, coord_t y, const char * s)
|
||||
{
|
||||
lcdDrawText(x, y, s, 0);
|
||||
}
|
||||
|
||||
void lcdDrawTextAlignedLeft(coord_t y, const char * s)
|
||||
{
|
||||
lcdDrawText(0, y, s);
|
||||
}
|
||||
|
||||
void lcdDrawTextIndented(coord_t y, const char * s)
|
||||
{
|
||||
lcdDrawText(INDENT_WIDTH, y, s);
|
||||
}
|
||||
|
||||
#if !defined(BOOT)
|
||||
void lcdDrawTextAtIndex(coord_t x, coord_t y, const char *const *s,uint8_t idx, LcdFlags flags)
|
||||
{
|
||||
lcdDrawSizedText(x, y, s[idx], UINT8_MAX, flags);
|
||||
}
|
||||
|
||||
void lcdDrawHexNumber(coord_t x, coord_t y, uint32_t val, LcdFlags flags)
|
||||
{
|
||||
x += FWNUM*4+1;
|
||||
@@ -393,184 +125,9 @@ void lcdDrawHexNumber(coord_t x, coord_t y, uint32_t val, LcdFlags flags)
|
||||
val >>= 4;
|
||||
}
|
||||
}
|
||||
|
||||
void lcdDrawHexChar(coord_t x, coord_t y, uint8_t val, LcdFlags flags)
|
||||
{
|
||||
x += FWNUM*2;
|
||||
for (int i=0; i<2; i++) {
|
||||
x -= FWNUM;
|
||||
char c = val & 0xf;
|
||||
c = c>9 ? c+'A'-10 : c+'0';
|
||||
lcdDrawChar(x, y, c, flags|(c>='A' ? CONDENSED : 0));
|
||||
val >>= 4;
|
||||
}
|
||||
}
|
||||
|
||||
void lcdDraw8bitsNumber(coord_t x, coord_t y, int8_t val)
|
||||
{
|
||||
lcdDrawNumber(x, y, val);
|
||||
}
|
||||
|
||||
void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags flags)
|
||||
{
|
||||
lcdDrawNumber(x, y, val, flags, 0);
|
||||
}
|
||||
|
||||
void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags flags, uint8_t len)
|
||||
{
|
||||
char str[16+1];
|
||||
char *s = str+16;
|
||||
*s = '\0';
|
||||
int idx = 0;
|
||||
int mode = MODE(flags);
|
||||
bool neg = false;
|
||||
|
||||
if (val == INT_MAX) {
|
||||
flags &= ~(LEADING0 | PREC1 | PREC2);
|
||||
lcdDrawText(x, y, "INT_MAX", flags);
|
||||
return;
|
||||
}
|
||||
|
||||
if (val < 0) {
|
||||
if (val == INT_MIN) {
|
||||
flags &= ~(LEADING0 | PREC1 | PREC2);
|
||||
lcdDrawText(x, y, "INT_MIN", flags);
|
||||
return;
|
||||
}
|
||||
val = -val;
|
||||
neg = true;
|
||||
}
|
||||
do {
|
||||
*--s = '0' + (val % 10);
|
||||
++idx;
|
||||
val /= 10;
|
||||
if (mode!=0 && idx==mode) {
|
||||
mode = 0;
|
||||
*--s = '.';
|
||||
if (val==0) {
|
||||
*--s = '0';
|
||||
}
|
||||
}
|
||||
} while (val!=0 || mode>0 || (mode==MODE(LEADING0) && idx<len));
|
||||
if (neg) {
|
||||
*--s = '-';
|
||||
}
|
||||
flags &= ~(LEADING0 | PREC1 | PREC2);
|
||||
lcdDrawText(x, y, s, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
void lcdDrawSolidHorizontalLine(coord_t x, coord_t y, coord_t w, LcdFlags att)
|
||||
{
|
||||
lcdDrawHorizontalLine(x, y, w, 0xff, att);
|
||||
}
|
||||
|
||||
#if !defined(BOOT)
|
||||
void lcdDrawLine(coord_t x1, coord_t y1, coord_t x2, coord_t y2, uint8_t pat, LcdFlags att)
|
||||
{
|
||||
int dx = x2-x1; /* the horizontal distance of the line */
|
||||
int dy = y2-y1; /* the vertical distance of the line */
|
||||
int dxabs = abs(dx);
|
||||
int dyabs = abs(dy);
|
||||
int sdx = sgn(dx);
|
||||
int sdy = sgn(dy);
|
||||
int x = dyabs>>1;
|
||||
int y = dxabs>>1;
|
||||
int px = x1;
|
||||
int py = y1;
|
||||
|
||||
if (dxabs >= dyabs) {
|
||||
/* the line is more horizontal than vertical */
|
||||
for (int i=0; i<=dxabs; i++) {
|
||||
if ((1<<(px%8)) & pat) {
|
||||
lcdDrawPoint(px, py, att);
|
||||
}
|
||||
y += dyabs;
|
||||
if (y>=dxabs) {
|
||||
y -= dxabs;
|
||||
py += sdy;
|
||||
}
|
||||
px += sdx;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* the line is more vertical than horizontal */
|
||||
for (int i=0; i<=dyabs; i++) {
|
||||
if ((1<<(py%8)) & pat) {
|
||||
lcdDrawPoint(px, py, att);
|
||||
}
|
||||
x += dxabs;
|
||||
if (x >= dyabs) {
|
||||
x -= dyabs;
|
||||
px += sdx;
|
||||
}
|
||||
py += sdy;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void lcdDrawVerticalLine(coord_t x, coord_t y, coord_t h, uint8_t pat, LcdFlags att)
|
||||
{
|
||||
if (x < 0 || x >= LCD_W || h == 0) return;
|
||||
if (h < 0) { y = y + h + 1; h = -h; }
|
||||
if (y + h <= 0 || y >= LCD_H) return;
|
||||
if (y < 0) { h += y; y = 0; }
|
||||
if (y + h > LCD_H) { h = LCD_H - y; }
|
||||
|
||||
if (pat==DOTTED && !(y%2))
|
||||
pat = ~pat;
|
||||
|
||||
uint8_t * p = &displayBuf[ y / 8 * LCD_W + x ];
|
||||
y = (y & 0x07);
|
||||
if (y) {
|
||||
ASSERT_IN_DISPLAY(p);
|
||||
uint8_t msk = ~(bfBitmask<uint8_t>(y));
|
||||
h -= 8-y;
|
||||
if (h < 0)
|
||||
msk -= ~(bfBitmask<uint8_t>(8 + h));
|
||||
lcdMaskPoint(p, msk & pat, att);
|
||||
p += LCD_W;
|
||||
}
|
||||
while (h >= 8) {
|
||||
ASSERT_IN_DISPLAY(p);
|
||||
lcdMaskPoint(p, pat, att);
|
||||
p += LCD_W;
|
||||
h -= 8;
|
||||
}
|
||||
if (h > 0) {
|
||||
ASSERT_IN_DISPLAY(p);
|
||||
lcdMaskPoint(p, (bfBitmask<uint8_t>(h)) & pat, att);
|
||||
}
|
||||
}
|
||||
|
||||
void lcdDrawSolidVerticalLine(coord_t x, coord_t y, coord_t h, LcdFlags att)
|
||||
{
|
||||
lcdDrawVerticalLine(x, y, h, SOLID, att);
|
||||
}
|
||||
|
||||
void lcdDrawRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat, LcdFlags att)
|
||||
{
|
||||
lcdDrawVerticalLine(x, y, h, pat, att);
|
||||
lcdDrawVerticalLine(x+w-1, y, h, pat, att);
|
||||
if (~att & ROUND) { x+=1; w-=2; }
|
||||
lcdDrawHorizontalLine(x, y+h-1, w, pat, att);
|
||||
lcdDrawHorizontalLine(x, y, w, pat, att);
|
||||
}
|
||||
|
||||
#if !defined(BOOT)
|
||||
void lcdDrawFilledRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat, LcdFlags att)
|
||||
{
|
||||
for (coord_t i=y; i<y+h; i++) { // cast to coord_t needed otherwise (y+h) is promoted to int (see #5055)
|
||||
if ((att&ROUND) && (i==y || i==y+h-1))
|
||||
lcdDrawHorizontalLine(x+1, i, w-2, pat, att);
|
||||
else
|
||||
lcdDrawHorizontalLine(x, i, w, pat, att);
|
||||
pat = (pat >> 1) + ((pat & 1) << 7);
|
||||
}
|
||||
}
|
||||
|
||||
void drawTelemetryTopBar()
|
||||
{
|
||||
if (g_model.timers[0].mode) {
|
||||
@@ -593,135 +150,6 @@ void drawTelemetryTopBar()
|
||||
lcdInvertLine(0);
|
||||
}
|
||||
|
||||
#if defined(RTCLOCK)
|
||||
void drawRtcTime(coord_t x, coord_t y, LcdFlags att)
|
||||
{
|
||||
drawTimer(x, y, getValue(MIXSRC_TX_TIME), att, att);
|
||||
}
|
||||
#endif
|
||||
|
||||
void drawTimer(coord_t x, coord_t y, int32_t tme, LcdFlags att, LcdFlags att2)
|
||||
{
|
||||
div_t qr;
|
||||
if (IS_RIGHT_ALIGNED(att)) {
|
||||
att -= RIGHT;
|
||||
if (att & DBLSIZE)
|
||||
x -= 5*(2*FWNUM)-4;
|
||||
else if (att & MIDSIZE)
|
||||
x -= 5*8-8;
|
||||
else
|
||||
x -= 5*FWNUM+1;
|
||||
}
|
||||
|
||||
if (tme < 0) {
|
||||
lcdDrawChar(x - ((att & DBLSIZE) ? FW+2 : ((att & MIDSIZE) ? FW+0 : FWNUM)), y, '-', att);
|
||||
tme = -tme;
|
||||
}
|
||||
|
||||
qr = div((int)tme, 60);
|
||||
|
||||
char separator = ':';
|
||||
if (att & TIMEHOUR) {
|
||||
div_t qr2 = div(qr.quot, 60);
|
||||
if (qr2.quot < 100) {
|
||||
lcdDrawNumber(x, y, qr2.quot, att|LEADING0|LEFT, 2);
|
||||
}
|
||||
else {
|
||||
lcdDrawNumber(x, y, qr2.quot, att|LEFT);
|
||||
}
|
||||
lcdDrawChar(lcdNextPos, y, separator, att);
|
||||
qr.quot = qr2.rem;
|
||||
x = lcdNextPos;
|
||||
}
|
||||
if (FONTSIZE(att) == MIDSIZE) {
|
||||
lcdLastRightPos--;
|
||||
}
|
||||
if (separator == CHR_HOUR)
|
||||
att &= ~DBLSIZE;
|
||||
lcdDrawNumber(x, y, qr.quot, att|LEADING0|LEFT, 2);
|
||||
#if defined(RTCLOCK)
|
||||
if (att & TIMEBLINK)
|
||||
lcdDrawChar(lcdLastRightPos, y, separator, BLINK);
|
||||
else
|
||||
#endif
|
||||
lcdDrawChar(lcdLastRightPos, y, separator, att&att2);
|
||||
lcdDrawNumber(lcdNextPos, y, qr.rem, (att2|LEADING0|LEFT) & (~RIGHT), 2);
|
||||
}
|
||||
|
||||
// TODO to be optimized with drawValueWithUnit
|
||||
void putsVolts(coord_t x, coord_t y, uint16_t volts, LcdFlags att)
|
||||
{
|
||||
lcdDrawNumber(x, y, (int16_t)volts, (~NO_UNIT) & (att | ((att&PREC2)==PREC2 ? 0 : PREC1)));
|
||||
if (~att & NO_UNIT) lcdDrawChar(lcdLastRightPos, y, 'V', att);
|
||||
}
|
||||
|
||||
void putsVBat(coord_t x, coord_t y, LcdFlags att)
|
||||
{
|
||||
putsVolts(x, y, g_vbat100mV, att);
|
||||
}
|
||||
|
||||
void putsChn(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
|
||||
{
|
||||
drawStringWithIndex(x, y, STR_CH, idx, att);
|
||||
}
|
||||
|
||||
void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
|
||||
{
|
||||
lcdDrawText(x, y, getAnalogShortLabel(idx), att);
|
||||
}
|
||||
|
||||
void drawModelName(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), att);
|
||||
}
|
||||
}
|
||||
|
||||
void drawSwitch(coord_t x, coord_t y, swsrc_t idx, LcdFlags flags, bool autoBold)
|
||||
{
|
||||
char s[8];
|
||||
getSwitchPositionName(s, idx);
|
||||
if (autoBold && idx != SWSRC_NONE && getSwitch(idx))
|
||||
flags |= BOLD;
|
||||
lcdDrawText(x, y, s, flags);
|
||||
}
|
||||
|
||||
void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att)
|
||||
{
|
||||
char s[8];
|
||||
getCurveString(s, idx);
|
||||
lcdDrawText(x, y, s, att);
|
||||
}
|
||||
|
||||
void drawTimerMode(coord_t x, coord_t y, swsrc_t mode, LcdFlags att)
|
||||
{
|
||||
if (mode >= 0) {
|
||||
if (mode < TMRMODE_COUNT)
|
||||
return lcdDrawTextAtIndex(x, y, STR_VTMRMODES, mode, att);
|
||||
else
|
||||
mode -= (TMRMODE_COUNT-1);
|
||||
}
|
||||
drawSwitch(x, y, mode, att);
|
||||
}
|
||||
|
||||
void drawShortTrimMode(coord_t x, coord_t y, uint8_t fm, uint8_t idx, LcdFlags att)
|
||||
{
|
||||
trim_t v = getRawTrimValue(fm, idx);
|
||||
uint8_t mode = v.mode;
|
||||
uint8_t p = v.mode >> 1;
|
||||
if (mode == TRIM_MODE_NONE) {
|
||||
putsChnLetter(x, y, idx, att);
|
||||
}
|
||||
else {
|
||||
lcdDrawChar(x, y, '0' + p, att);
|
||||
}
|
||||
}
|
||||
|
||||
void drawGPSCoord(coord_t x, coord_t y, int32_t value, const char * direction, LcdFlags att, bool seconds=true)
|
||||
{
|
||||
att &= ~RIGHT & ~BOLD;
|
||||
@@ -848,10 +276,6 @@ void drawGPSSensorValue(coord_t x, coord_t y, TelemetryItem & telemetryItem, Lcd
|
||||
drawGPSPosition(x, y, telemetryItem.gps.longitude, telemetryItem.gps.latitude, flags);
|
||||
}
|
||||
|
||||
|
||||
#define LCD_BYTE_FILTER(p, keep, add) *(p) = (*(p) & (keep)) | (add)
|
||||
|
||||
|
||||
void lcdDraw1bitBitmap(coord_t x, coord_t y, const uint8_t * img, uint8_t idx, LcdFlags att)
|
||||
{
|
||||
const uint8_t * q = img;
|
||||
@@ -958,4 +382,36 @@ void lcdDrawHorizontalLine(coord_t x, coord_t y, coord_t w, uint8_t pat, LcdFlag
|
||||
}
|
||||
}
|
||||
|
||||
void lcdFlushed() {}
|
||||
void lcdDrawVerticalLine(coord_t x, coord_t y, coord_t h, uint8_t pat, LcdFlags att)
|
||||
{
|
||||
if (x < 0 || x >= LCD_W || h == 0) return;
|
||||
if (h < 0) { y = y + h + 1; h = -h; }
|
||||
if (y + h <= 0 || y >= LCD_H) return;
|
||||
if (y < 0) { h += y; y = 0; }
|
||||
if (y + h > LCD_H) { h = LCD_H - y; }
|
||||
|
||||
if (pat==DOTTED && !(y%2))
|
||||
pat = ~pat;
|
||||
|
||||
uint8_t * p = &displayBuf[ y / 8 * LCD_W + x ];
|
||||
y = (y & 0x07);
|
||||
if (y) {
|
||||
ASSERT_IN_DISPLAY(p);
|
||||
uint8_t msk = ~(bfBitmask<uint8_t>(y));
|
||||
h -= 8-y;
|
||||
if (h < 0)
|
||||
msk -= ~(bfBitmask<uint8_t>(8 + h));
|
||||
lcdMaskPoint(p, msk & pat, att);
|
||||
p += LCD_W;
|
||||
}
|
||||
while (h >= 8) {
|
||||
ASSERT_IN_DISPLAY(p);
|
||||
lcdMaskPoint(p, pat, att);
|
||||
p += LCD_W;
|
||||
h -= 8;
|
||||
}
|
||||
if (h > 0) {
|
||||
ASSERT_IN_DISPLAY(p);
|
||||
lcdMaskPoint(p, (bfBitmask<uint8_t>(h)) & pat, att);
|
||||
}
|
||||
}
|
||||
|
||||
+7
-141
@@ -26,142 +26,18 @@
|
||||
#include "edgetx_types.h"
|
||||
#include "board.h"
|
||||
|
||||
#define BOX_WIDTH 23
|
||||
#define CENTER_OFS 0
|
||||
#define OFS_CHECKTRIMS CENTER_OFS+(9*FW)
|
||||
#define INDENT_WIDTH (FW/2)
|
||||
constexpr coord_t BOX_WIDTH = 23;
|
||||
constexpr coord_t BOX_CENTERY = LCD_H - BOX_WIDTH/2 - 9;
|
||||
constexpr coord_t MARKER_WIDTH = 5;
|
||||
#define CENTER_OFS 0
|
||||
|
||||
#define FW 6
|
||||
#define FWNUM 5
|
||||
#define FH 8
|
||||
#define BITMAP_BUFFER_SIZE(w, h) (2 + (w) * (((h)+7)/8))
|
||||
#define DISPLAY_BUFFER_SIZE (LCD_W*((LCD_H+7)/8))
|
||||
|
||||
#define LCD_LINES (LCD_H/FH)
|
||||
#define LCD_COLS (LCD_W/FW)
|
||||
#include "lcd_common.h"
|
||||
|
||||
#define BITMAP_BUFFER_SIZE(w, h) (2 + (w) * (((h)+7)/8))
|
||||
|
||||
/* lcdDrawText flags */
|
||||
#define BLINK 0x01
|
||||
#define INVERS 0x02
|
||||
#define BOLD 0x40
|
||||
#define LEFT 0x00 /* fake */
|
||||
#define RIGHT 0x04 /* align right */
|
||||
#define CENTERED 0x20
|
||||
#define CONDENSED 0x08
|
||||
#define FIXEDWIDTH 0x10
|
||||
/* no 0x80 here because of "GV"1 which is aligned LEFT */
|
||||
/* no 0x10 here because of "MODEL"01 which uses LEADING0 */
|
||||
|
||||
/* lcdDrawNumber additional flags */
|
||||
#define LEADING0 0x10
|
||||
#define PREC1 0x20
|
||||
#define PREC2 0x30
|
||||
#define MODE(flags) ((((int8_t)(flags) & 0x30) - 0x10) >> 4)
|
||||
|
||||
#define IS_LEFT_ALIGNED(att) !((att) & RIGHT)
|
||||
#define IS_RIGHT_ALIGNED(att) (!IS_LEFT_ALIGNED(att))
|
||||
|
||||
/* line, rect, square flags */
|
||||
#define FORCE 0x02
|
||||
#define ERASE 0x04
|
||||
#define ROUND 0x08
|
||||
|
||||
/* telemetry flags */
|
||||
#define NO_UNIT 0x40
|
||||
|
||||
#define FONTSIZE_MASK 0x0700
|
||||
#define FONTSIZE(x) ((x) & FONTSIZE_MASK)
|
||||
#define TINSIZE 0x0100
|
||||
#define SMLSIZE 0x0200
|
||||
#define MIDSIZE 0x0300
|
||||
#define DBLSIZE 0x0400
|
||||
#define XXLSIZE 0x0500
|
||||
#define ERASEBG 0x8000
|
||||
#define VERTICAL 0x0800
|
||||
|
||||
#define TIMEBLINK 0x1000
|
||||
#define TIMEHOUR 0x2000
|
||||
#define STREXPANDED 0x4000
|
||||
|
||||
#define DISPLAY_BUFFER_SIZE (LCD_W*((LCD_H+7)/8))
|
||||
|
||||
extern pixel_t displayBuf[DISPLAY_BUFFER_SIZE];
|
||||
extern coord_t lcdLastRightPos;
|
||||
extern coord_t lcdLastLeftPos;
|
||||
extern coord_t lcdNextPos;
|
||||
|
||||
#define DISPLAY_END (displayBuf + DISPLAY_BUFFER_SIZE)
|
||||
#define IS_IN_DISPLAY(p) ((p) >= displayBuf && (p) < DISPLAY_END)
|
||||
#define ASSERT_IN_DISPLAY(p) assert((p) >= displayBuf && (p) < DISPLAY_END)
|
||||
|
||||
void lcdDrawChar(coord_t x, coord_t y, uint8_t c);
|
||||
void lcdDrawChar(coord_t x, coord_t y, uint8_t c, LcdFlags flags);
|
||||
void lcdDrawCenteredText(coord_t y, const char * s, LcdFlags flags = 0);
|
||||
void lcdDrawText(coord_t x, coord_t y, const char * s, LcdFlags flags);
|
||||
void lcdDrawTextAtIndex(coord_t x, coord_t y, const char *const *s, uint8_t idx, LcdFlags flags);
|
||||
void lcdDrawSizedText(coord_t x, coord_t y, const char * s, unsigned char len, LcdFlags flags);
|
||||
void lcdDrawText(coord_t x, coord_t y, const char * s);
|
||||
void lcdDrawSizedText(coord_t x, coord_t y, const char * s, unsigned char len);
|
||||
void lcdDrawTextAlignedLeft(coord_t y, const char * s);
|
||||
void lcdDrawTextIndented(coord_t y, const char * s);
|
||||
void drawTimerWithMode(coord_t x, coord_t y, uint8_t index, LcdFlags att);
|
||||
|
||||
void lcdDrawHexNumber(coord_t x, coord_t y, uint32_t val, LcdFlags mode=0);
|
||||
void lcdDrawHexChar(coord_t x, coord_t y, uint8_t val, LcdFlags flags=0);
|
||||
|
||||
void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags mode, uint8_t len);
|
||||
void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags mode=0);
|
||||
void lcdDraw8bitsNumber(coord_t x, coord_t y, int8_t val);
|
||||
|
||||
void drawModelName(coord_t x, coord_t y, char * name, uint8_t id, LcdFlags att);
|
||||
#if !defined(BOOT) // TODO not here ...
|
||||
void drawSwitch(coord_t x, coord_t y, swsrc_t swtch, LcdFlags att=0, bool autoBold = true);
|
||||
#endif
|
||||
void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att=0);
|
||||
void drawTimerMode(coord_t x, coord_t y, swsrc_t mode, LcdFlags att=0);
|
||||
|
||||
void drawShortTrimMode(coord_t x, coord_t y, uint8_t mode, uint8_t idx, LcdFlags att);
|
||||
|
||||
void putsChn(coord_t x, coord_t y, uint8_t idx, LcdFlags attr);
|
||||
void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags attr);
|
||||
|
||||
void putsVolts(coord_t x, coord_t y, uint16_t volts, LcdFlags att);
|
||||
void putsVBat(coord_t x, coord_t y, LcdFlags att);
|
||||
|
||||
#define SOLID 0xff
|
||||
#define DOTTED 0x55
|
||||
|
||||
void lcdDrawPoint(coord_t x, coord_t y, LcdFlags att=0);
|
||||
void lcdMaskPoint(uint8_t *p, uint8_t mask, LcdFlags att=0);
|
||||
void lcdDrawSolidHorizontalLine(coord_t x, coord_t y, coord_t w, LcdFlags att=0);
|
||||
void lcdDrawHorizontalLine(coord_t x, coord_t y, coord_t w, uint8_t pat, LcdFlags att=0);
|
||||
void lcdDrawSolidVerticalLine(coord_t x, coord_t y, coord_t h, LcdFlags att=0);
|
||||
void lcdDrawVerticalLine(coord_t x, coord_t y, coord_t h, uint8_t pat, LcdFlags att=0);
|
||||
void lcdDrawLine(coord_t x1, coord_t y1, coord_t x2, coord_t y2, uint8_t pat=SOLID, LcdFlags att=0);
|
||||
void lcdDrawFilledRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat=SOLID, LcdFlags att=0);
|
||||
inline void lcdDrawSolidFilledRect(coord_t x, coord_t y, coord_t w, coord_t h, LcdFlags att=0)
|
||||
{
|
||||
lcdDrawFilledRect(x, y, w, h, SOLID, att);
|
||||
}
|
||||
void lcdDrawRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat=SOLID, LcdFlags att=0);
|
||||
|
||||
void lcdInvertLine(int8_t line);
|
||||
#define lcdInvertLastLine() lcdInvertLine(LCD_LINES-1)
|
||||
inline void lcdDrawSquare(coord_t x, coord_t y, coord_t w, LcdFlags att=0)
|
||||
{
|
||||
lcdDrawRect(x, y, w, w, SOLID, att);
|
||||
}
|
||||
|
||||
void drawTelemetryTopBar();
|
||||
|
||||
#define V_BAR(xx, yy, ll) \
|
||||
lcdDrawSolidVerticalLine(xx-1,yy-ll,ll); \
|
||||
lcdDrawSolidVerticalLine(xx ,yy-ll,ll); \
|
||||
lcdDrawSolidVerticalLine(xx+1,yy-ll,ll)
|
||||
|
||||
|
||||
void lcdClear();
|
||||
void lcdDraw1bitBitmap(coord_t x, coord_t y, const unsigned char * img, uint8_t idx, LcdFlags att=0);
|
||||
inline void lcdDrawBitmap(coord_t x, coord_t y, const uint8_t * bitmap)
|
||||
{
|
||||
lcdDraw1bitBitmap(x, y, bitmap, 0);
|
||||
@@ -169,14 +45,6 @@ inline void lcdDrawBitmap(coord_t x, coord_t y, const uint8_t * bitmap)
|
||||
|
||||
uint8_t * lcdLoadBitmap(uint8_t * dest, const char * filename, uint8_t width, uint8_t height);
|
||||
|
||||
#if defined(BOOT)
|
||||
#define BLINK_ON_PHASE (0)
|
||||
#else
|
||||
#define SLOW_BLINK_ON_PHASE (g_blinkTmr10ms & (1<<7))
|
||||
#define BLINK_ON_PHASE (g_blinkTmr10ms & (1<<6))
|
||||
#define FAST_BLINK_ON_PHASE (g_blinkTmr10ms & (1<<4))
|
||||
#endif
|
||||
|
||||
inline pixel_t getPixel(uint8_t x, uint8_t y)
|
||||
{
|
||||
if (x>=LCD_W || y>=LCD_H) {
|
||||
@@ -187,5 +55,3 @@ inline pixel_t getPixel(uint8_t x, uint8_t y)
|
||||
pixel_t mask = 1 << (y & 7);
|
||||
return ((pixel & mask) ? 0xf : 0);
|
||||
}
|
||||
|
||||
uint8_t getTextWidth(const char * s, uint8_t len=0, LcdFlags flags=0);
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 "edgetx.h"
|
||||
|
||||
const MenuHandler menuTabModel[MENU_MODEL_PAGES_COUNT] = {
|
||||
{ menuModelSelect, nullptr },
|
||||
{ menuModelSetup, nullptr },
|
||||
#if defined(HELI)
|
||||
{ menuModelHeli, modelHeliEnabled },
|
||||
#endif
|
||||
#if defined(FLIGHT_MODES)
|
||||
{ menuModelFlightModesAll, modelFMEnabled },
|
||||
#endif
|
||||
{ menuModelExposAll, nullptr },
|
||||
{ menuModelMixAll, nullptr },
|
||||
{ menuModelLimits, nullptr },
|
||||
{ menuModelCurvesAll, modelCurvesEnabled },
|
||||
{ menuModelLogicalSwitches, modelLSEnabled },
|
||||
{ menuModelSpecialFunctions, modelSFEnabled },
|
||||
#if defined(LUA_MODEL_SCRIPTS)
|
||||
{ menuModelCustomScripts, modelCustomScriptsEnabled },
|
||||
#endif
|
||||
{ menuModelTelemetry, modelTelemetryEnabled },
|
||||
{ menuModelDisplay, nullptr }
|
||||
};
|
||||
|
||||
uint8_t editDelay(coord_t y, event_t event, uint8_t attr, const char * str, uint8_t delay, uint8_t prec)
|
||||
{
|
||||
lcdDrawTextAlignedLeft(y, str);
|
||||
lcdDrawNumber(MIXES_2ND_COLUMN, y, delay, attr|prec|LEFT);
|
||||
if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, delay, DELAY_MAX);
|
||||
return delay;
|
||||
}
|
||||
|
||||
uint8_t s_copyMode = 0;
|
||||
int8_t s_copySrcRow;
|
||||
int8_t s_copyTgtOfs;
|
||||
uint8_t s_maxLines = 8;
|
||||
uint8_t s_copySrcIdx;
|
||||
uint8_t s_copySrcCh;
|
||||
|
||||
uint8_t editNameCursorPos = 0;
|
||||
|
||||
void editSingleName(coord_t x, coord_t y, const char* label, char* name,
|
||||
uint8_t size, event_t event, uint8_t active,
|
||||
uint8_t old_editMode, coord_t lblX)
|
||||
{
|
||||
lcdDrawText(lblX, y, label);
|
||||
editName(x, y, name, size, event, active, 0, old_editMode);
|
||||
}
|
||||
|
||||
uint8_t s_currIdx;
|
||||
uint8_t s_currIdxSubMenu;
|
||||
mixsrc_t s_currSrcRaw;
|
||||
uint16_t s_currScale;
|
||||
@@ -21,125 +21,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "keys.h"
|
||||
#include "common/stdlcd/menus.h"
|
||||
#include "common/stdlcd/features.h"
|
||||
#include "menus_common.h"
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
#define NAVIGATION_LINE_BY_LINE 0x40
|
||||
#define IS_LINE_SELECTED(sub, k) ((sub)==(k) && menuHorizontalPosition < 0)
|
||||
#else
|
||||
#define NAVIGATION_LINE_BY_LINE 0
|
||||
#define IS_LINE_SELECTED(sub, k) (false)
|
||||
#endif
|
||||
|
||||
inline bool isRadioMenuDisplayed()
|
||||
{
|
||||
return menuVerticalPositions[0] == 1;
|
||||
}
|
||||
|
||||
inline bool isModelMenuDisplayed()
|
||||
{
|
||||
return menuVerticalPositions[0] == 0;
|
||||
}
|
||||
|
||||
void onMainViewMenu(const char * result);
|
||||
void menuFirstCalib(event_t event);
|
||||
void menuMainView(event_t event);
|
||||
void menuViewTelemetry(event_t event);
|
||||
void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomFunctionsContext * functionsContext);
|
||||
|
||||
enum MenuRadioIndexes
|
||||
{
|
||||
#if defined(RADIO_TOOLS)
|
||||
MENU_RADIO_TOOLS,
|
||||
#endif
|
||||
MENU_RADIO_SD_MANAGER,
|
||||
MENU_RADIO_SETUP,
|
||||
MENU_RADIO_SPECIAL_FUNCTIONS,
|
||||
MENU_RADIO_TRAINER,
|
||||
MENU_RADIO_HARDWARE,
|
||||
MENU_RADIO_VERSION,
|
||||
MENU_RADIO_PAGES_COUNT
|
||||
};
|
||||
|
||||
void menuRadioSetup(event_t event);
|
||||
void menuRadioSdManager(event_t event);
|
||||
void menuRadioSpecialFunctions(event_t event);
|
||||
void menuRadioTrainer(event_t event);
|
||||
void menuRadioVersion(event_t event);
|
||||
void menuRadioDiagKeys(event_t event);
|
||||
void menuRadioDiagAnalogs(event_t event);
|
||||
void menuRadioDiagFS(event_t event);
|
||||
void menuRadioHardware(event_t event);
|
||||
void menuRadioTools(event_t event);
|
||||
void menuRadioSpectrumAnalyser(event_t event);
|
||||
void menuRadioPowerMeter(event_t event);
|
||||
void menuRadioCalibration(event_t event);
|
||||
void menuGhostModuleConfig(event_t event);
|
||||
|
||||
extern bool radioGFEnabled();
|
||||
extern bool radioTrainerEnabled();
|
||||
|
||||
extern const MenuHandler menuTabGeneral[MENU_RADIO_PAGES_COUNT];
|
||||
|
||||
enum MenuModelIndexes {
|
||||
MENU_MODEL_SELECT,
|
||||
MENU_MODEL_SETUP,
|
||||
CASE_HELI(MENU_MODEL_HELI)
|
||||
CASE_FLIGHT_MODES(MENU_MODEL_FLIGHT_MODES)
|
||||
MENU_MODEL_INPUTS,
|
||||
MENU_MODEL_MIXES,
|
||||
MENU_MODEL_OUTPUTS,
|
||||
MENU_MODEL_CURVES,
|
||||
MENU_MODEL_LOGICAL_SWITCHES,
|
||||
MENU_MODEL_SPECIAL_FUNCTIONS,
|
||||
#if defined(LUA_MODEL_SCRIPTS)
|
||||
MENU_MODEL_CUSTOM_SCRIPTS,
|
||||
#endif
|
||||
MENU_MODEL_TELEMETRY,
|
||||
MENU_MODEL_DISPLAY,
|
||||
MENU_MODEL_PAGES_COUNT
|
||||
};
|
||||
|
||||
void menuModelSelect(event_t event);
|
||||
void menuModelSetup(event_t event);
|
||||
void menuModelFailsafe(event_t event);
|
||||
void menuModelModuleOptions(event_t event);
|
||||
void menuModelReceiverOptions(event_t event);
|
||||
void menuModelHeli(event_t event);
|
||||
void menuModelFlightModesAll(event_t event);
|
||||
void menuModelExpoOne(event_t event);
|
||||
void menuModelExposAll(event_t event);
|
||||
void menuModelMixOne(event_t event);
|
||||
void menuModelMixAll(event_t event);
|
||||
void menuModelLimits(event_t event);
|
||||
void menuModelCurvesAll(event_t event);
|
||||
void menuModelCurveOne(event_t event);
|
||||
void menuModelGVars(event_t event);
|
||||
void menuModelLogicalSwitches(event_t event);
|
||||
void menuModelSpecialFunctions(event_t event);
|
||||
void menuModelCustomScripts(event_t event);
|
||||
void menuModelTelemetry(event_t event);
|
||||
void menuModelSensor(event_t event);
|
||||
void menuModelDisplay(event_t event);
|
||||
void menuModelTemplates(event_t event);
|
||||
void menuModelGVarOne(event_t event);
|
||||
#if defined(USBJ_EX)
|
||||
void menuModelUSBJoystick(event_t event);
|
||||
#endif
|
||||
|
||||
extern bool modelHeliEnabled();
|
||||
extern bool modelFMEnabled();
|
||||
extern bool modelCurvesEnabled();
|
||||
extern bool modelLSEnabled();
|
||||
extern bool modelSFEnabled();
|
||||
extern bool modelCustomScriptsEnabled();
|
||||
extern bool modelTelemetryEnabled();
|
||||
|
||||
extern const MenuHandler menuTabModel[MENU_MODEL_PAGES_COUNT];
|
||||
|
||||
void menuStatisticsView(event_t event);
|
||||
void menuStatisticsDebug(event_t event);
|
||||
void menuStatisticsDebug2(event_t event);
|
||||
void menuAboutView(event_t event);
|
||||
|
||||
@@ -21,36 +21,6 @@
|
||||
|
||||
#include "edgetx.h"
|
||||
|
||||
void editGVarValue(coord_t x, coord_t y, event_t event, uint8_t gvar, uint8_t flightMode, LcdFlags flags)
|
||||
{
|
||||
FlightModeData * fm = &g_model.flightModeData[flightMode];
|
||||
gvar_t * v = &fm->gvars[gvar];
|
||||
int16_t vmin, vmax;
|
||||
if (*v > GVAR_MAX) {
|
||||
uint8_t fm = *v - GVAR_MAX - 1;
|
||||
if (fm >= flightMode) fm++;
|
||||
drawFlightMode(x, y, fm + 1, flags&(~LEFT));
|
||||
vmin = GVAR_MAX + 1;
|
||||
vmax = GVAR_MAX + MAX_FLIGHT_MODES - 1;
|
||||
}
|
||||
else {
|
||||
drawGVarValue(x, y, gvar, *v, flags);
|
||||
vmin = GVAR_MIN + g_model.gvars[gvar].min;
|
||||
vmax = GVAR_MAX - g_model.gvars[gvar].max;
|
||||
}
|
||||
|
||||
if (flags & INVERS) {
|
||||
if (event == EVT_KEY_LONG(KEY_ENTER) && flightMode > 0) {
|
||||
killEvents(event);
|
||||
*v = (*v > GVAR_MAX ? 0 : GVAR_MAX+1);
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
else if (s_editMode > 0) {
|
||||
*v = checkIncDec(event, *v, vmin, vmax, EE_MODEL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum GVarFields {
|
||||
GVAR_FIELD_NAME,
|
||||
GVAR_FIELD_UNIT,
|
||||
|
||||
@@ -206,25 +206,11 @@ void menuModelLogicalSwitchOne(event_t event)
|
||||
break;
|
||||
|
||||
case LS_FIELD_DURATION:
|
||||
lcdDrawTextAlignedLeft(y, STR_DURATION);
|
||||
if (cs->duration > 0)
|
||||
lcdDrawNumber(CSWONE_2ND_COLUMN, y, cs->duration, attr|PREC1|LEFT);
|
||||
else
|
||||
lcdDrawMMM(CSWONE_2ND_COLUMN, y, attr);
|
||||
if (attr) {
|
||||
CHECK_INCDEC_MODELVAR_ZERO(event, cs->duration, MAX_LS_DURATION);
|
||||
}
|
||||
cs->duration = editNumberField(STR_DURATION, 0, CSWONE_2ND_COLUMN, y, cs->duration, 0, MAX_LS_DURATION, attr|PREC1, event, STR_MMMINV[0]);
|
||||
break;
|
||||
|
||||
case LS_FIELD_DELAY:
|
||||
lcdDrawTextAlignedLeft(y, STR_DELAY);
|
||||
if (cs->delay > 0)
|
||||
lcdDrawNumber(CSWONE_2ND_COLUMN, y, cs->delay, attr|PREC1|LEFT);
|
||||
else
|
||||
lcdDrawMMM(CSWONE_2ND_COLUMN, y, attr);
|
||||
if (attr) {
|
||||
CHECK_INCDEC_MODELVAR_ZERO(event, cs->delay, MAX_LS_DELAY);
|
||||
}
|
||||
cs->delay = editNumberField(STR_DELAY, 0, CSWONE_2ND_COLUMN, y, cs->delay, 0, MAX_LS_DELAY, attr|PREC1, event, STR_MMMINV[0]);
|
||||
break;
|
||||
|
||||
case LS_FIELD_PERSIST:
|
||||
|
||||
@@ -172,12 +172,7 @@ void menuModelMixOne(event_t event)
|
||||
break;
|
||||
|
||||
case MIX_FIELD_WARNING:
|
||||
lcdDrawTextAlignedLeft(y, STR_MIXWARNING);
|
||||
if (md2->mixWarn)
|
||||
lcdDrawNumber(MIXES_2ND_COLUMN, y, md2->mixWarn, attr|LEFT);
|
||||
else
|
||||
lcdDrawText(MIXES_2ND_COLUMN, y, STR_OFF, attr);
|
||||
if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, md2->mixWarn, 3);
|
||||
md2->mixWarn = editNumberField(STR_MIXWARNING, 0, MIXES_2ND_COLUMN, y, md2->mixWarn, 0, 3, attr, event, STR_OFF);
|
||||
break;
|
||||
|
||||
case MIX_FIELD_MLTPX:
|
||||
@@ -189,11 +184,11 @@ void menuModelMixOne(event_t event)
|
||||
break;
|
||||
|
||||
case MIX_FIELD_DELAY_UP:
|
||||
md2->delayUp = EDIT_DELAY(0, y, event, attr, STR_DELAYUP, md2->delayUp, (md2->delayPrec ? PREC2 : PREC1));
|
||||
md2->delayUp = editDelay(y, event, attr, STR_DELAYUP, md2->delayUp, (md2->delayPrec ? PREC2 : PREC1));
|
||||
break;
|
||||
|
||||
case MIX_FIELD_DELAY_DOWN:
|
||||
md2->delayDown = EDIT_DELAY(0, y, event, attr, STR_DELAYDOWN, md2->delayDown, (md2->delayPrec ? PREC2 : PREC1));
|
||||
md2->delayDown = editDelay(y, event, attr, STR_DELAYDOWN, md2->delayDown, (md2->delayPrec ? PREC2 : PREC1));
|
||||
break;
|
||||
|
||||
case MIX_FIELD_SLOW_PREC:
|
||||
@@ -201,11 +196,11 @@ void menuModelMixOne(event_t event)
|
||||
break;
|
||||
|
||||
case MIX_FIELD_SLOW_UP:
|
||||
md2->speedUp = EDIT_DELAY(0, y, event, attr, STR_SLOWUP, md2->speedUp, (md2->speedPrec ? PREC2 : PREC1));
|
||||
md2->speedUp = editDelay(y, event, attr, STR_SLOWUP, md2->speedUp, (md2->speedPrec ? PREC2 : PREC1));
|
||||
break;
|
||||
|
||||
case MIX_FIELD_SLOW_DOWN:
|
||||
md2->speedDown = EDIT_DELAY(0, y, event, attr, STR_SLOWDOWN, md2->speedDown, (md2->speedPrec ? PREC2 : PREC1));
|
||||
md2->speedDown = editDelay(y, event, attr, STR_SLOWDOWN, md2->speedDown, (md2->speedPrec ? PREC2 : PREC1));
|
||||
break;
|
||||
}
|
||||
y += FH;
|
||||
|
||||
@@ -164,11 +164,8 @@ void menuModelLimitsOne(event_t event)
|
||||
|
||||
#if defined(PPM_CENTER_ADJUSTABLE)
|
||||
case ITEM_OUTPUTONE_PPM_CENTER:
|
||||
lcdDrawTextAlignedLeft(y, STR_LIMITS_HEADERS_PPMCENTER);
|
||||
lcdDrawNumber(LIMITS_ONE_2ND_COLUMN, y, PPM_CENTER+ld->ppmCenter, attr);
|
||||
if (active) {
|
||||
CHECK_INCDEC_MODELVAR(event, ld->ppmCenter, -PPM_CENTER_MAX, +PPM_CENTER_MAX);
|
||||
}
|
||||
ld->ppmCenter = editNumberField(STR_LIMITS_HEADERS_PPMCENTER, 0, LIMITS_ONE_2ND_COLUMN, y, ld->ppmCenter,
|
||||
-PPM_CENTER_MAX, PPM_CENTER_MAX, attr, event, nullptr, PPM_CENTER);
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -492,13 +492,13 @@ void editTimerCountdown(int timerIdx, coord_t y, LcdFlags attr, event_t event)
|
||||
}
|
||||
}
|
||||
|
||||
#include "common/stdlcd/model_setup_pxx1.cpp"
|
||||
#include "model_setup_pxx1.cpp"
|
||||
|
||||
#if defined(PXX2)
|
||||
#include "common/stdlcd/model_setup_pxx2.cpp"
|
||||
#include "model_setup_pxx2.cpp"
|
||||
#endif
|
||||
#if defined(AFHDS3)
|
||||
#include "common/stdlcd/model_setup_afhds3.cpp"
|
||||
#include "model_setup_afhds3.cpp"
|
||||
#endif
|
||||
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
@@ -1217,13 +1217,8 @@ void menuModelSetup(event_t event)
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_CUSTOM_THROTTLE_WARNING_VALUE:
|
||||
{
|
||||
lcdDrawText(INDENT_WIDTH * 4, y, STR_CUSTOM_THROTTLE_WARNING_VAL);
|
||||
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.customThrottleWarningPosition, attr | LEFT, 2);
|
||||
if (attr) {
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.customThrottleWarningPosition, -100, 100);
|
||||
}
|
||||
}
|
||||
g_model.customThrottleWarningPosition = editNumberField(STR_CUSTOM_THROTTLE_WARNING_VAL, INDENT_WIDTH * 4, MODEL_SETUP_2ND_COLUMN, y,
|
||||
g_model.customThrottleWarningPosition, -100, 100, attr, event);
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_SWITCHES_WARNING2:
|
||||
@@ -1754,7 +1749,7 @@ void menuModelSetup(event_t event)
|
||||
}
|
||||
if (bluetooth.distantAddr[0]) {
|
||||
lcdDrawText(INDENT_WIDTH, y+1, bluetooth.distantAddr, TINSIZE);
|
||||
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_CLEAR, attr);
|
||||
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_CLEAR_BTN, attr);
|
||||
if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) {
|
||||
bluetooth.state = BLUETOOTH_STATE_CLEAR_REQUESTED;
|
||||
memclear(bluetooth.distantAddr, sizeof(bluetooth.distantAddr));
|
||||
@@ -1896,17 +1891,11 @@ void menuModelSetup(event_t event)
|
||||
#if defined(HARDWARE_EXTERNAL_MODULE)
|
||||
case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_MODEL_NUM:
|
||||
#endif
|
||||
{
|
||||
lcdDrawTextIndented(y, STR_RECEIVER_NUM);
|
||||
lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.header.modelId[moduleIdx], attr | LEADING0 | LEFT, 2);
|
||||
if (attr) {
|
||||
CHECK_INCDEC_MODELVAR_ZERO(event, g_model.header.modelId[moduleIdx], getMaxRxNum(moduleIdx));
|
||||
if (checkIncDec_Ret) {
|
||||
g_model.header.modelId[moduleIdx] = editNumberField(STR_RECEIVER_NUM, INDENT_WIDTH, MODEL_SETUP_2ND_COLUMN, y,
|
||||
g_model.header.modelId[moduleIdx], 0, getMaxRxNum(moduleIdx), attr|LEADING0, event);
|
||||
if (attr && checkIncDec_Ret)
|
||||
modelHeaders[g_eeGeneral.currModel].modelId[moduleIdx] = g_model.header.modelId[moduleIdx];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_REGISTER_RANGE:
|
||||
#if defined(HARDWARE_EXTERNAL_MODULE)
|
||||
|
||||
@@ -239,19 +239,12 @@ void menuModelTelemetry(event_t event)
|
||||
break;
|
||||
|
||||
case ITEM_TELEMETRY_RSSI_ALARM1:
|
||||
g_model.rfAlarms.warning = editNumberField(STR_LOWALARM, INDENT_WIDTH, TELEM_COL3, y, g_model.rfAlarms.warning, 0, 100, attr, event);
|
||||
break;
|
||||
|
||||
case ITEM_TELEMETRY_RSSI_ALARM2:
|
||||
{
|
||||
bool warning = (k==ITEM_TELEMETRY_RSSI_ALARM1);
|
||||
lcdDrawTextIndented(y, (warning ? STR_LOWALARM : STR_CRITICALALARM));
|
||||
lcdDrawNumber(TELEM_COL3, y, warning? g_model.rfAlarms.warning : g_model.rfAlarms.critical, attr, 3);
|
||||
if (attr && s_editMode>0) {
|
||||
if (warning)
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.rfAlarms.warning, 0, 100);
|
||||
else
|
||||
CHECK_INCDEC_MODELVAR(event, g_model.rfAlarms.critical, 0, 100);
|
||||
}
|
||||
g_model.rfAlarms.critical = editNumberField(STR_CRITICALALARM, INDENT_WIDTH, TELEM_COL3, y, g_model.rfAlarms.critical, 0, 100, attr, event);
|
||||
break;
|
||||
}
|
||||
|
||||
case ITEM_TELEMETRY_DISABLE_ALARMS:
|
||||
g_model.disableTelemetryWarning = editCheckBox(g_model.disableTelemetryWarning, TELEM_COL3, y, STR_DISABLE_ALARM, attr, event, INDENT_WIDTH);
|
||||
|
||||
@@ -212,9 +212,7 @@ void menuModelSensor(event_t event)
|
||||
}
|
||||
else {
|
||||
if (sensor->unit == UNIT_RPMS) {
|
||||
lcdDrawTextAlignedLeft(y, STR_BLADES);
|
||||
if (attr) CHECK_INCDEC_MODELVAR(event, sensor->custom.ratio, 1, 30000);
|
||||
lcdDrawNumber(SENSOR_2ND_COLUMN, y, sensor->custom.ratio, LEFT|attr);
|
||||
sensor->custom.ratio = editNumberField(STR_BLADES, 0, SENSOR_2ND_COLUMN, y, sensor->custom.ratio, 1, 30000, attr, event);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
@@ -288,10 +286,8 @@ void menuModelSensor(event_t event)
|
||||
break;
|
||||
}
|
||||
else {
|
||||
lcdDrawTextAlignedLeft(y, STR_OFFSET);
|
||||
if (attr) CHECK_INCDEC_MODELVAR(event, sensor->custom.offset, -30000, +30000);
|
||||
if (sensor->prec > 0) attr |= (sensor->prec == 2 ? PREC2 : PREC1);
|
||||
lcdDrawNumber(SENSOR_2ND_COLUMN, y, sensor->custom.offset, LEFT|attr);
|
||||
sensor->custom.offset = editNumberField(STR_OFFSET, 0, SENSOR_2ND_COLUMN, y, sensor->custom.offset, -30000, 30000, attr, event);
|
||||
break;
|
||||
}
|
||||
// no break
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 "edgetx.h"
|
||||
|
||||
void menuModelTemplates(event_t event)
|
||||
{
|
||||
SIMPLE_MENU(STR_MENUTEMPLATES, menuTabModel, MENU_MODEL_TEMPLATES, 1+TMPL_COUNT);
|
||||
|
||||
uint8_t sub = menuVerticalPosition - 1;
|
||||
|
||||
if (sub < TMPL_COUNT) {
|
||||
if (warningResult) {
|
||||
warningResult = 0;
|
||||
applyTemplate(sub);
|
||||
AUDIO_WARNING2();
|
||||
}
|
||||
if (event==EVT_KEY_BREAK(KEY_ENTER)) {
|
||||
POPUP_CONFIRMATION(STR_VTEMPLATES+1 + (sub * LEN2_VTEMPLATES), nullptr);
|
||||
s_editMode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
coord_t y = MENU_HEADER_HEIGHT + 1;
|
||||
uint8_t k = 0;
|
||||
for (uint8_t i=0; i<LCD_LINES-1 && k<TMPL_COUNT; i++) {
|
||||
k = i+menuVerticalOffset;
|
||||
lcdDrawNumber(3*FW, y, k, (sub==k ? INVERS : 0)|LEADING0, 2);
|
||||
lcdDrawTextAtIndex(4*FW, y, STR_VTEMPLATES, k, (sub==k ? INVERS : 0));
|
||||
y+=FH;
|
||||
}
|
||||
}
|
||||
@@ -33,13 +33,4 @@
|
||||
#define WARNING_LINE_X 12
|
||||
#define WARNING_LINE_Y MESSAGEBOX_Y + 2
|
||||
|
||||
#define POPUP_MENU_MAX_LINES 13
|
||||
#define MENU_MAX_DISPLAY_LINES 6
|
||||
#define MENU_LINE_LENGTH (LEN_MODEL_NAME+12)
|
||||
|
||||
enum {
|
||||
MENU_OFFSET_INTERNAL,
|
||||
MENU_OFFSET_EXTERNAL
|
||||
};
|
||||
|
||||
#include "common/stdlcd/popups_common.h"
|
||||
#include "popups_common.h"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "hal/adc_driver.h"
|
||||
#include "gui/common/stdlcd/calibration.h"
|
||||
#include "calibration.h"
|
||||
|
||||
void menuRadioCalibration(event_t event)
|
||||
{
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
#define MODELNAME_Y (0)
|
||||
#define PHASE_X (6*FW-2)
|
||||
#define PHASE_Y (2*FH)
|
||||
#define PHASE_FLAGS 0
|
||||
#define VBATT_X (6*FW-1)
|
||||
#define VBATT_Y (2*FH)
|
||||
#define VBATTUNIT_Y (3*FH)
|
||||
@@ -582,7 +581,7 @@ void menuMainView(event_t event)
|
||||
if (view_base != VIEW_CHAN_MONITOR) {
|
||||
// Flight Mode Name
|
||||
uint8_t mode = mixerCurrentFlightMode;
|
||||
lcdDrawSizedText(PHASE_X, PHASE_Y, g_model.flightModeData[mode].name, sizeof(g_model.flightModeData[mode].name), PHASE_FLAGS);
|
||||
lcdDrawSizedText(PHASE_X, PHASE_Y, g_model.flightModeData[mode].name, sizeof(g_model.flightModeData[mode].name));
|
||||
|
||||
// Model Name
|
||||
drawModelName(MODELNAME_X, MODELNAME_Y, g_model.header.name, g_eeGeneral.currModel, BIGSIZE);
|
||||
@@ -627,16 +626,10 @@ void menuMainView(event_t event)
|
||||
// Issue 98
|
||||
lcdDrawText(15 * FW, 0, "BIND", 0);
|
||||
}
|
||||
#if defined(RTCLOCK)
|
||||
else if (view_base != VIEW_CHAN_MONITOR && rtcIsValid()) {
|
||||
drawRtcTime(CLOCK_X, CLOCK_Y, LEFT|TIMEBLINK);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#if defined(RTCLOCK)
|
||||
if (view_base != VIEW_CHAN_MONITOR && rtcIsValid()) {
|
||||
drawRtcTime(CLOCK_X, CLOCK_Y, LEFT|TIMEBLINK);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
// For surface radio
|
||||
void drawWheel(coord_t centrex, int16_t tval)
|
||||
{
|
||||
constexpr coord_t BOX_CENTERY = (LCD_H - 9 - BOX_WIDTH / 2);
|
||||
constexpr coord_t MARKER_WIDTH = 5;
|
||||
lcdDrawSquare(centrex-BOX_WIDTH/2, BOX_CENTERY-BOX_WIDTH/2, BOX_WIDTH);
|
||||
lcdDrawSolidHorizontalLine(centrex - MARKER_WIDTH /2 , BOX_CENTERY, MARKER_WIDTH);
|
||||
coord_t x1 = centrex - MARKER_WIDTH - tval / 300;
|
||||
@@ -33,235 +31,14 @@ void drawWheel(coord_t centrex, int16_t tval)
|
||||
lcdDrawLine( x1, BOX_CENTERY+BOX_WIDTH / MARKER_WIDTH, x2, BOX_CENTERY-BOX_WIDTH / MARKER_WIDTH, SOLID, FORCE);
|
||||
lcdDrawLine( x1 + BOX_WIDTH/2, BOX_CENTERY+BOX_WIDTH / MARKER_WIDTH,
|
||||
x2 + BOX_WIDTH / 2, BOX_CENTERY-BOX_WIDTH / MARKER_WIDTH, SOLID, FORCE);
|
||||
#undef BOX_CENTERY
|
||||
#undef MARKER_WIDTH
|
||||
}
|
||||
|
||||
// For surface radio
|
||||
void drawThrottle(coord_t centrex, int16_t wval)
|
||||
{
|
||||
constexpr coord_t BOX_CENTERY = (LCD_H - 9 - BOX_WIDTH / 2);
|
||||
constexpr coord_t MARKER_WIDTH = 5;
|
||||
lcdDrawSquare(centrex-BOX_WIDTH/2, BOX_CENTERY-BOX_WIDTH/2, BOX_WIDTH);
|
||||
lcdDrawSolidHorizontalLine(centrex - MARKER_WIDTH, BOX_CENTERY, 2 * MARKER_WIDTH + 1);
|
||||
coord_t tsize = - wval / 150;
|
||||
lcdDrawLine( centrex - tsize, BOX_CENTERY, centrex, BOX_CENTERY + tsize, SOLID, FORCE);
|
||||
lcdDrawLine( centrex + tsize, BOX_CENTERY, centrex, BOX_CENTERY + tsize, SOLID, FORCE);
|
||||
}
|
||||
|
||||
void drawStick(coord_t centrex, int16_t xval, int16_t yval)
|
||||
{
|
||||
#define BOX_CENTERY (LCD_H-9-BOX_WIDTH/2)
|
||||
#define MARKER_WIDTH 5
|
||||
lcdDrawSquare(centrex-BOX_WIDTH/2, BOX_CENTERY-BOX_WIDTH/2, BOX_WIDTH);
|
||||
lcdDrawSolidVerticalLine(centrex, BOX_CENTERY-1, 3);
|
||||
lcdDrawSolidHorizontalLine(centrex-1, BOX_CENTERY, 3);
|
||||
lcdDrawSquare(centrex + (xval/((2*RESX)/(BOX_WIDTH-MARKER_WIDTH))) - MARKER_WIDTH/2, BOX_CENTERY - (yval/((2*RESX)/(BOX_WIDTH-MARKER_WIDTH))) - MARKER_WIDTH/2, MARKER_WIDTH, ROUND);
|
||||
#undef BOX_CENTERY
|
||||
#undef MARKER_WIDTH
|
||||
}
|
||||
|
||||
void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr)
|
||||
{
|
||||
if (value)
|
||||
lcdDrawChar(x+1, y, '#');
|
||||
if (attr)
|
||||
lcdDrawSolidFilledRect(x, y, 7, 7);
|
||||
else
|
||||
lcdDrawSquare(x, y, 7);
|
||||
}
|
||||
|
||||
void drawScreenIndex(uint8_t index, uint8_t count, uint8_t attr)
|
||||
{
|
||||
lcdDrawNumber(LCD_W, 0, count, RIGHT | attr);
|
||||
coord_t x = 1+LCD_W-FW*(count>9 ? 3 : 2);
|
||||
lcdDrawChar(x, 0, '/', attr);
|
||||
lcdDrawNumber(x, 0, index+1, RIGHT | attr);
|
||||
}
|
||||
|
||||
void drawVerticalScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible)
|
||||
{
|
||||
lcdDrawVerticalLine(x, y, h, DOTTED);
|
||||
coord_t yofs = (h * offset) / count;
|
||||
coord_t yhgt = (h * visible) / count;
|
||||
if (yhgt + yofs > h)
|
||||
yhgt = h - yofs;
|
||||
lcdDrawVerticalLine(x, y + yofs, yhgt, SOLID, FORCE);
|
||||
}
|
||||
|
||||
void drawGauge(coord_t x, coord_t y, coord_t w, coord_t h, int32_t val, int32_t max)
|
||||
{
|
||||
#if defined(PCBX7) || defined(PCBX9LITE) || defined(PCBX9LITES) // X7/X9 LCD doesn't like too many horizontal lines
|
||||
h++;
|
||||
#else
|
||||
lcdDrawRect(x, y, w+1, h);
|
||||
#endif
|
||||
lcdDrawFilledRect(x+1, y+1, w-1, 4, SOLID, ERASE);
|
||||
coord_t len = limit((uint8_t)1, uint8_t((abs(val) * w/2 + max/2) / max), uint8_t(w/2));
|
||||
coord_t x0 = (val>0) ? x+w/2 : x+1+w/2-len;
|
||||
for (coord_t i=h-2; i>0; i--) {
|
||||
lcdDrawSolidHorizontalLine(x0, y+i, len);
|
||||
}
|
||||
}
|
||||
|
||||
void title(const char * s)
|
||||
{
|
||||
lcdDrawText(0, 0, s, INVERS);
|
||||
}
|
||||
|
||||
choice_t editChoice(coord_t x, coord_t y, const char * label, const char *const *values, choice_t value, choice_t min, choice_t max, LcdFlags attr, event_t event, coord_t lblX, IsValueAvailable isValueAvailable)
|
||||
{
|
||||
if (label) {
|
||||
lcdDrawText(lblX, y, label);
|
||||
}
|
||||
if (values) lcdDrawTextAtIndex(x, y, values, value-min, attr);
|
||||
if (attr & (~RIGHT)) value = checkIncDec(event, value, min, max, (isModelMenuDisplayed()) ? EE_MODEL : EE_GENERAL, isValueAvailable);
|
||||
return value;
|
||||
}
|
||||
|
||||
choice_t editChoice(coord_t x, coord_t y, const char * label, const char *const *values, choice_t value, choice_t min, choice_t max, LcdFlags attr, event_t event, coord_t lblX)
|
||||
{
|
||||
return editChoice(x, y, label, values, value, min, max, attr, event, lblX, nullptr);
|
||||
}
|
||||
|
||||
choice_t editChoice(coord_t x, coord_t y, const char * label, const char *const *values, choice_t value, choice_t min, choice_t max, LcdFlags attr, event_t event)
|
||||
{
|
||||
return editChoice(x, y, label, values, value, min, max, attr, event, 0, nullptr);
|
||||
}
|
||||
|
||||
uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label, LcdFlags attr, event_t event, coord_t lblX)
|
||||
{
|
||||
drawCheckBox(x, y, value, attr);
|
||||
return editChoice(x, y, label, nullptr, value, 0, 1, attr, event, lblX);
|
||||
}
|
||||
|
||||
uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label, LcdFlags attr, event_t event)
|
||||
{
|
||||
return editCheckBox(value, x, y, label, attr, event, 0);
|
||||
}
|
||||
|
||||
swsrc_t editSwitch(coord_t x, coord_t y, swsrc_t value, LcdFlags attr, event_t event)
|
||||
{
|
||||
lcdDrawTextAlignedLeft(y, STR_SWITCH);
|
||||
drawSwitch(x, y, value, attr);
|
||||
if (attr & (~RIGHT)) CHECK_INCDEC_MODELSWITCH(event, value, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes);
|
||||
return value;
|
||||
}
|
||||
|
||||
void drawSlider(coord_t x, coord_t y, uint8_t width, uint8_t value, uint8_t max, uint8_t attr)
|
||||
{
|
||||
lcdDrawChar(x + (value * (width - FWNUM)) / max, y, '$');
|
||||
lcdDrawSolidHorizontalLine(x, y + 3, width, FORCE);
|
||||
if (attr && (!(attr & BLINK) || !BLINK_ON_PHASE)) {
|
||||
lcdDrawSolidFilledRect(x, y, width, FH - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void drawSlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr)
|
||||
{
|
||||
drawSlider(x, y, 5*FW - 1, value, max, attr);
|
||||
}
|
||||
|
||||
uint16_t editSrcVarFieldValue(coord_t x, coord_t y, const char* title, uint16_t value,
|
||||
int16_t min, int16_t max, LcdFlags attr, event_t event,
|
||||
IsValueAvailable isValueAvailable, int16_t sourceMin, int16_t sourceMax)
|
||||
{
|
||||
if (title)
|
||||
lcdDrawTextAlignedLeft(y, title);
|
||||
SourceNumVal v;
|
||||
v.rawValue = value;
|
||||
if (v.isSource) {
|
||||
drawSource(x, y, v.value, attr);
|
||||
if (attr & (~RIGHT)) {
|
||||
value = checkIncDec(event, value, sourceMin, sourceMax,
|
||||
EE_MODEL|INCDEC_SOURCE|INCDEC_SOURCE_VALUE|INCDEC_SOURCE_INVERT|NO_INCDEC_MARKS, isValueAvailable);
|
||||
}
|
||||
} else {
|
||||
lcdDrawNumber(x, y, v.value, attr);
|
||||
if (attr & (~RIGHT)) {
|
||||
value = checkIncDec(event, value, min, max, sourceMin, sourceMax,
|
||||
EE_MODEL|INCDEC_SOURCE_VALUE|NO_INCDEC_MARKS|INCDEC_SKIP_VAL_CHECK_FUNC,
|
||||
isValueAvailable);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
#if defined(GVARS)
|
||||
void drawGVarValue(coord_t x, coord_t y, uint8_t gvar, gvar_t value, LcdFlags flags)
|
||||
{
|
||||
uint8_t prec = g_model.gvars[gvar].prec;
|
||||
if (prec > 0) {
|
||||
flags |= (prec == 1 ? PREC1 : PREC2);
|
||||
}
|
||||
drawValueWithUnit(x, y, value, g_model.gvars[gvar].unit ? UNIT_PERCENT : UNIT_RAW, flags);
|
||||
}
|
||||
|
||||
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t editflags, event_t event)
|
||||
{
|
||||
bool invers = (attr & INVERS);
|
||||
|
||||
// TRACE("editGVarFieldValue(val=%d min=%d max=%d)", value, min, max);
|
||||
|
||||
if (modelGVEnabled() && invers && event == EVT_KEY_LONG(KEY_ENTER)) {
|
||||
killEvents(event);
|
||||
s_editMode = !s_editMode;
|
||||
if (attr & PREC1)
|
||||
value = (GV_IS_GV_VALUE(value) ? GET_GVAR(value, min, max, mixerCurrentFlightMode)*10 : GV_VALUE_FROM_INDEX(0));
|
||||
else
|
||||
value = (GV_IS_GV_VALUE(value) ? GET_GVAR(value, min, max, mixerCurrentFlightMode) : GV_VALUE_FROM_INDEX(0));
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
|
||||
if (GV_IS_GV_VALUE(value)) {
|
||||
attr &= ~PREC1;
|
||||
int8_t idx = (int16_t)GV_INDEX_FROM_VALUE(value);
|
||||
if (invers) {
|
||||
CHECK_INCDEC_MODELVAR(event, idx, -MAX_GVARS, MAX_GVARS-1);
|
||||
}
|
||||
value = (int16_t)GV_VALUE_FROM_INDEX(idx);
|
||||
drawGVarName(x, y, idx, attr);
|
||||
}
|
||||
else {
|
||||
lcdDrawNumber(x, y, value, attr);
|
||||
if (invers) value = checkIncDec(event, value, min, max, EE_MODEL | editflags);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
#else
|
||||
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, event_t event)
|
||||
{
|
||||
lcdDrawNumber(x, y, value, attr);
|
||||
if (attr&INVERS) value = checkIncDec(event, value, min, max, EE_MODEL);
|
||||
return value;
|
||||
}
|
||||
#endif
|
||||
|
||||
char statusLineMsg[STATUS_LINE_LENGTH];
|
||||
tmr10ms_t statusLineTime = 0;
|
||||
uint8_t statusLineHeight = 0;
|
||||
|
||||
void showStatusLine()
|
||||
{
|
||||
statusLineTime = get_tmr10ms();
|
||||
}
|
||||
|
||||
#define STATUS_LINE_DELAY (3 * 100) /* 3s */
|
||||
void drawStatusLine()
|
||||
{
|
||||
if (statusLineTime) {
|
||||
if ((tmr10ms_t)(get_tmr10ms() - statusLineTime) <= (tmr10ms_t)STATUS_LINE_DELAY) {
|
||||
if (statusLineHeight < FH) statusLineHeight++;
|
||||
}
|
||||
else if (statusLineHeight) {
|
||||
statusLineHeight--;
|
||||
}
|
||||
else {
|
||||
statusLineTime = 0;
|
||||
}
|
||||
|
||||
lcdDrawFilledRect(0, LCD_H-statusLineHeight, LCD_W, FH, SOLID, ERASE);
|
||||
lcdDrawText(5, LCD_H+1-statusLineHeight, statusLineMsg);
|
||||
lcdDrawFilledRect(0, LCD_H-statusLineHeight, LCD_W, FH, SOLID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ set(GUI_SRC
|
||||
popups.cpp
|
||||
widgets.cpp
|
||||
startup_shutdown.cpp
|
||||
menu_model.cpp
|
||||
model_select.cpp
|
||||
model_setup.cpp
|
||||
model_failsafe.cpp
|
||||
@@ -14,7 +13,6 @@ set(GUI_SRC
|
||||
model_outputs.cpp
|
||||
model_telemetry.cpp
|
||||
model_telemetry_sensor.cpp
|
||||
menu_radio.cpp
|
||||
radio_setup.cpp
|
||||
radio_calibration.cpp
|
||||
view_main.cpp
|
||||
@@ -45,6 +43,7 @@ include(gui/common/stdlcd/CMakeLists.txt)
|
||||
|
||||
set(BOOTLOADER_SRC ${BOOTLOADER_SRC}
|
||||
${RADIO_SRC_DIR}/gui/212x64/lcd.cpp
|
||||
${RADIO_SRC_DIR}/gui/common/stdlcd/lcd_common.cpp
|
||||
${RADIO_SRC_DIR}/gui/common/stdlcd/fonts.cpp
|
||||
${RADIO_SRC_DIR}/gui/common/stdlcd/utf8.cpp
|
||||
)
|
||||
|
||||
+2
-140
@@ -22,26 +22,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "gui_common.h"
|
||||
#include "lcd.h"
|
||||
#include "menus.h"
|
||||
#include "popups.h"
|
||||
#include "widgets_common.h"
|
||||
|
||||
#include "navigation/navigation.h"
|
||||
#include "common/stdlcd/draw_functions.h"
|
||||
|
||||
#define NUM_BODY_LINES (LCD_LINES-1)
|
||||
#define TEXT_VIEWER_LINES NUM_BODY_LINES
|
||||
#define MENU_HEADER_HEIGHT FH
|
||||
#include "draw_functions.h"
|
||||
|
||||
#define MODEL_BITMAP_WIDTH 64
|
||||
#define MODEL_BITMAP_HEIGHT 32
|
||||
#define MODEL_BITMAP_SIZE BITMAP_BUFFER_SIZE(MODEL_BITMAP_WIDTH, MODEL_BITMAP_HEIGHT)
|
||||
#define LOAD_MODEL_BITMAP() loadModelBitmap(g_model.header.bitmap, modelBitmap)
|
||||
|
||||
#define CURVE_SIDE_WIDTH (LCD_H/2-2)
|
||||
#define CURVE_CENTER_X (LCD_W-CURVE_SIDE_WIDTH-3)
|
||||
#define CURVE_CENTER_Y (LCD_H/2)
|
||||
|
||||
#define MIXES_2ND_COLUMN (18*FW)
|
||||
|
||||
#define MENUS_SCROLLBAR_WIDTH 2
|
||||
@@ -49,141 +41,11 @@
|
||||
extern uint8_t modelBitmap[MODEL_BITMAP_SIZE];
|
||||
bool loadModelBitmap(char * name, uint8_t * bitmap);
|
||||
|
||||
// Temporary no highlight
|
||||
extern uint8_t noHighlightCounter;
|
||||
#define NO_HIGHLIGHT() (noHighlightCounter > 0)
|
||||
#define START_NO_HIGHLIGHT() do { noHighlightCounter = 25; } while(0)
|
||||
|
||||
void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr);
|
||||
void drawSlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr);
|
||||
void drawSplash();
|
||||
void drawScreenIndex(uint8_t index, uint8_t count, uint8_t attr);
|
||||
void drawVerticalScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible);
|
||||
void drawGauge(coord_t x, coord_t y, coord_t w, coord_t h, int32_t val, int32_t max);
|
||||
void drawColumnHeader(const char * const * headers, uint8_t index);
|
||||
void drawStick(coord_t centrex, int16_t xval, int16_t yval);
|
||||
|
||||
void drawAlertBox(const char * title, const char * text, const char * action);
|
||||
void showAlertBox(const char * title, const char * text, const char * action, uint8_t sound);
|
||||
|
||||
void doMainScreenGraphics();
|
||||
|
||||
void title(const char * s);
|
||||
|
||||
typedef int choice_t;
|
||||
|
||||
choice_t editChoice(coord_t x, coord_t y, const char *label,
|
||||
const char *const *values, choice_t value, choice_t min,
|
||||
choice_t max, LcdFlags attr, event_t event, coord_t lblX = 0);
|
||||
choice_t editChoice(coord_t x, coord_t y, const char *label,
|
||||
const char *const *values, choice_t value, choice_t min,
|
||||
choice_t max, LcdFlags attr, event_t event, coord_t lblX,
|
||||
IsValueAvailable isValueAvailable);
|
||||
|
||||
uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label,
|
||||
LcdFlags attr, event_t event, coord_t lblX = 0);
|
||||
|
||||
swsrc_t editSwitch(coord_t x, coord_t y, swsrc_t value, LcdFlags attr,
|
||||
event_t event);
|
||||
|
||||
uint16_t editSrcVarFieldValue(coord_t x, coord_t y, const char* title, uint16_t value,
|
||||
int16_t min, int16_t max, LcdFlags attr, event_t event,
|
||||
IsValueAvailable isValueAvailable, int16_t sourceMin, int16_t sourceMax);
|
||||
|
||||
#if defined(GVARS)
|
||||
void drawGVarValue(coord_t x, coord_t y, uint8_t gvar, gvar_t value,
|
||||
LcdFlags flags = 0);
|
||||
|
||||
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min,
|
||||
int16_t max, LcdFlags attr, uint8_t editflags,
|
||||
event_t event);
|
||||
|
||||
#define GVAR_MENU_ITEM(x, y, v, min, max, lcdattr, editflags, event) \
|
||||
editGVarFieldValue(x, y, v, min, max, lcdattr, editflags, event)
|
||||
|
||||
#define displayGVar(x, y, v, min, max) \
|
||||
GVAR_MENU_ITEM(x, y, v, min, max, 0, 0, 0)
|
||||
|
||||
#else // GVARS
|
||||
|
||||
#define GVAR_MENU_ITEM(x, y, v, min, max, lcdattr, editflags, event) \
|
||||
editGVarFieldValue(x, y, v, min, max, lcdattr, event)
|
||||
|
||||
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min,
|
||||
int16_t max, LcdFlags attr, event_t event);
|
||||
|
||||
#define displayGVar(x, y, v, min, max) lcdDrawNumber(x, y, v)
|
||||
|
||||
#endif
|
||||
|
||||
void editCurveRef(coord_t x, coord_t y, CurveRef & curve, event_t event, LcdFlags flags,
|
||||
IsValueAvailable isValueAvailable, int16_t sourceMin, int16_t sourceMax);
|
||||
|
||||
extern uint8_t editNameCursorPos;
|
||||
|
||||
void editName(coord_t x, coord_t y, char *name, uint8_t size, event_t event,
|
||||
uint8_t active, LcdFlags attr, uint8_t old_editMode);
|
||||
|
||||
void editSingleName(coord_t x, coord_t y, const char *label, char *name,
|
||||
uint8_t size, event_t event, uint8_t active,
|
||||
uint8_t old_editMode, coord_t lblX = 0);
|
||||
|
||||
uint8_t editDelay(coord_t y, event_t event, uint8_t attr, const char * str, uint8_t delay, uint8_t prec);
|
||||
|
||||
#define EDIT_DELAY(y, event, attr, str, delay, prec) editDelay(y, event, attr, str, delay, prec)
|
||||
|
||||
void copySelection(char * dst, const char * src, uint8_t size);
|
||||
|
||||
#define COPY_MODE 1
|
||||
#define MOVE_MODE 2
|
||||
|
||||
extern uint8_t s_copyMode;
|
||||
extern int8_t s_copySrcRow;
|
||||
extern int8_t s_copyTgtOfs;
|
||||
extern uint8_t s_currIdx;
|
||||
extern uint8_t s_currIdxSubMenu;
|
||||
extern mixsrc_t s_currSrcRaw;
|
||||
extern uint16_t s_currScale;
|
||||
extern uint8_t s_copySrcIdx;
|
||||
extern uint8_t s_copySrcCh;
|
||||
extern int8_t s_currCh;
|
||||
extern uint8_t s_maxLines;
|
||||
|
||||
uint8_t getExposCount();
|
||||
void deleteExpo(uint8_t idx);
|
||||
void insertExpo(uint8_t idx);
|
||||
|
||||
#define STATUS_LINE_LENGTH 32
|
||||
extern char statusLineMsg[STATUS_LINE_LENGTH];
|
||||
void showStatusLine();
|
||||
void drawStatusLine();
|
||||
|
||||
void menuTextView(event_t event);
|
||||
void pushMenuTextView(const char *filename);
|
||||
void pushModelNotes();
|
||||
void readModelNotes();
|
||||
|
||||
void menuChannelsView(event_t event);
|
||||
|
||||
#define EDIT_MODE_INIT 0
|
||||
|
||||
void onSwitchLongEnterPress(const char *result);
|
||||
void onSourceLongEnterPress(const char *result);
|
||||
|
||||
uint8_t switchToMix(uint8_t source);
|
||||
|
||||
extern coord_t scrollbar_X;
|
||||
#define SET_SCROLLBAR_X(x) scrollbar_X = (x);
|
||||
|
||||
extern const unsigned char sticks[] ;
|
||||
|
||||
#if defined(FLIGHT_MODES)
|
||||
void displayFlightModes(coord_t x, coord_t y, FlightModesType value);
|
||||
FlightModesType editFlightModes(coord_t x, coord_t y, event_t event, FlightModesType value, uint8_t attr);
|
||||
#else
|
||||
#define displayFlightModes(...)
|
||||
#endif
|
||||
|
||||
#define IS_MAIN_VIEW_DISPLAYED() menuHandlers[0] == menuMainView
|
||||
#define IS_TELEMETRY_VIEW_DISPLAYED() menuHandlers[0] == menuViewTelemetry
|
||||
#define IS_OTHER_VIEW_DISPLAYED() (menuHandlers[0] == menuMainViewChannelsMonitor || menuHandlers[0] == menuChannelsView)
|
||||
|
||||
@@ -19,12 +19,8 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include "lcd.h"
|
||||
#include "common/stdlcd/fonts.h"
|
||||
#include "common/stdlcd/utf8.h"
|
||||
#include "utf8.h"
|
||||
|
||||
#if !defined(SIMU)
|
||||
#define assert(x)
|
||||
@@ -34,243 +30,15 @@
|
||||
|
||||
#if !defined(BOOT)
|
||||
#include "edgetx.h"
|
||||
#include "hal/switch_driver.h"
|
||||
#include "hal/adc_driver.h"
|
||||
#include "switches.h"
|
||||
#endif
|
||||
|
||||
pixel_t displayBuf[DISPLAY_BUFFER_SIZE] __DMA;
|
||||
extern LcdFlags getCharPattern(PatternData * pattern, unsigned char c, LcdFlags flags);
|
||||
|
||||
inline bool lcdIsPointOutside(coord_t x, coord_t y)
|
||||
{
|
||||
return (x<0 || x>=LCD_W || y<0 || y>=LCD_H);
|
||||
}
|
||||
|
||||
void lcdClear()
|
||||
{
|
||||
memset(displayBuf, 0, DISPLAY_BUFFER_SIZE * sizeof(pixel_t));
|
||||
}
|
||||
|
||||
coord_t lcdLastRightPos;
|
||||
coord_t lcdLastLeftPos;
|
||||
coord_t lcdNextPos;
|
||||
|
||||
struct PatternData
|
||||
{
|
||||
uint8_t width;
|
||||
uint8_t height;
|
||||
const uint8_t * data;
|
||||
};
|
||||
|
||||
uint8_t getPatternWidth(const PatternData * pattern)
|
||||
{
|
||||
uint8_t result = 0;
|
||||
uint8_t lines = (pattern->height+7)/8;
|
||||
const uint8_t * data = pattern->data;
|
||||
for (int8_t i=0; i<pattern->width; i++) {
|
||||
for (uint8_t j=0; j<lines; j++) {
|
||||
if (data[j] != 0xff) {
|
||||
result += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
data += lines;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void lcdPutPattern(coord_t x, coord_t y, const uint8_t * pattern, uint8_t width, uint8_t height, LcdFlags flags)
|
||||
{
|
||||
bool blink = false;
|
||||
bool inv = false;
|
||||
if (flags & BLINK) {
|
||||
if (BLINK_ON_PHASE) {
|
||||
if (flags & INVERS)
|
||||
inv = true;
|
||||
else {
|
||||
blink = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (flags & INVERS) {
|
||||
inv = true;
|
||||
}
|
||||
|
||||
uint8_t lines = (height+7)/8;
|
||||
assert(lines <= 5);
|
||||
|
||||
for (int8_t i = 0; i < int8_t(width + 2); i++) {
|
||||
if (x < LCD_W) {
|
||||
uint8_t b[5] = { 0 };
|
||||
if (i == 0) {
|
||||
if (x == 0 || !inv) {
|
||||
lcdNextPos++;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
// we need to work on the previous x when INVERS
|
||||
x--;
|
||||
}
|
||||
}
|
||||
else if (i <= width) {
|
||||
uint8_t skip = true;
|
||||
for (uint8_t j=0; j<lines; j++) {
|
||||
b[j] = *(pattern++); /*top byte*/
|
||||
if (b[j] != 0xFF) {
|
||||
skip = false;
|
||||
}
|
||||
}
|
||||
if (skip) {
|
||||
if (flags & FIXEDWIDTH) {
|
||||
for (uint8_t j=0; j<lines; j++) {
|
||||
b[j] = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int8_t j = -1; j <= int8_t(height); j++) {
|
||||
bool plot;
|
||||
if (j < 0 || (j == height && FONTSIZE(flags) != SMLSIZE)) {
|
||||
plot = false;
|
||||
if (height >= 12)
|
||||
continue;
|
||||
if (j < 0 && !inv)
|
||||
continue;
|
||||
if (y + j < 0)
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
uint8_t line = (j / 8);
|
||||
uint8_t pixel = (j % 8);
|
||||
plot = b[line] & (1 << pixel);
|
||||
}
|
||||
if (inv)
|
||||
plot = !plot;
|
||||
if (!blink) {
|
||||
if (flags & VERTICAL)
|
||||
lcdDrawPoint(y+j, LCD_H-x, plot ? FORCE : ERASE);
|
||||
else
|
||||
lcdDrawPoint(x, y+j, plot ? FORCE : ERASE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x++;
|
||||
lcdNextPos++;
|
||||
}
|
||||
}
|
||||
|
||||
LcdFlags getCharPattern(PatternData * pattern, unsigned char c, LcdFlags flags)
|
||||
{
|
||||
#if !defined(BOOT)
|
||||
static const uint8_t fontWidth[] = { 5, 3, 5, 8, 10, 22, 5 };
|
||||
static const uint8_t fontHeight[] = { 7, 5, 6, 12, 16, 38, 7 };
|
||||
|
||||
uint32_t fontsize = FONTSIZE(flags);
|
||||
unsigned char c_remapped = 0;
|
||||
|
||||
if (fontsize == DBLSIZE || (flags & BOLD)) {
|
||||
// To save space only some DBLSIZE and BOLD chars are available
|
||||
// c has to be remapped. All non existing chars mapped to 0 (space)
|
||||
if (c >= ',' && c <= ':')
|
||||
c_remapped = c - ',' + 1;
|
||||
else if (c >= 'A' && c <= 'Z')
|
||||
c_remapped = c - 'A' + 16;
|
||||
else if (c >= 'a' && c <= 'z')
|
||||
c_remapped = c - 'a' + 42;
|
||||
else if (c == '_')
|
||||
c_remapped = 4;
|
||||
else if (c != ' ')
|
||||
flags &= ~BOLD; // For BOLD use Standard font if character is not in BOLD
|
||||
}
|
||||
|
||||
uint8_t fontIdx = fontsize >> 8;
|
||||
if (fontIdx == 0 && flags & BOLD) fontIdx = 6;
|
||||
|
||||
pattern->width = fontWidth[fontIdx];
|
||||
pattern->height = fontHeight[fontIdx];
|
||||
int charSize = (pattern->height + 7) / 8 * pattern->width;
|
||||
|
||||
switch (fontIdx) {
|
||||
case 0: // Standard
|
||||
pattern->data = &font_5x7[(c - FONT_BASE_START) * charSize];
|
||||
break;
|
||||
case 1: // TINSIZE
|
||||
pattern->data = &font_3x5[(c - FONT_BASE_START) * charSize];
|
||||
break;
|
||||
case 2: // SMLSIZE
|
||||
// Adjust language special characters offset
|
||||
if (c >= FONT_LANG_START)
|
||||
c = c - (FONT_SYMS_CNT - FONT_SYMS_CNT_4x6);
|
||||
pattern->data = &font_4x6[(c - FONT_BASE_START) * charSize];
|
||||
break;
|
||||
case 3: // MDLSIZE
|
||||
// Adjust language special characters offset
|
||||
if (c >= FONT_LANG_START)
|
||||
c = c - FONT_SYMS_CNT;
|
||||
pattern->data = &font_8x10[(c - FONT_BASE_START) * charSize];
|
||||
break;
|
||||
case 4: // DBLSIZE
|
||||
// Adjust language special characters offset and symbols offset
|
||||
if (c >= FONT_LANG_START)
|
||||
c_remapped = c - (FONT_BASE_CNT - FONT_BASE_CNT_10x14) - (FONT_SYMS_CNT - FONT_SYMS_CNT_10x14) - FONT_BASE_START;
|
||||
else if (c >= FONT_SYMS_START)
|
||||
c_remapped = c - (FONT_BASE_CNT - FONT_BASE_CNT_10x14) - FONT_BASE_START;
|
||||
pattern->data = &font_10x14[(c_remapped) * charSize];
|
||||
break;
|
||||
case 5: // XXLSIZE
|
||||
pattern->data = &font_22x38_num[(c - '0' + 5) * charSize];
|
||||
break;
|
||||
case 6: // BOLD
|
||||
pattern->data = &font_5x7_B[c_remapped * charSize];
|
||||
break;
|
||||
};
|
||||
#else
|
||||
pattern->width = 5;
|
||||
pattern->height = 7;
|
||||
pattern->data = &font_5x7[(c - FONT_BASE_START) * 5];
|
||||
#endif
|
||||
return flags;
|
||||
}
|
||||
|
||||
uint8_t getCharWidth(char c, LcdFlags flags)
|
||||
{
|
||||
PatternData pattern;
|
||||
getCharPattern(&pattern, c, flags);
|
||||
return getPatternWidth(&pattern);
|
||||
}
|
||||
|
||||
void lcdDrawChar(coord_t x, coord_t y, uint8_t c, LcdFlags flags)
|
||||
{
|
||||
lcdNextPos = x - 1;
|
||||
PatternData pattern;
|
||||
flags = getCharPattern(&pattern, c, flags);
|
||||
lcdPutPattern(x, y, pattern.data, pattern.width, pattern.height, flags);
|
||||
}
|
||||
|
||||
void lcdDrawChar(coord_t x, coord_t y, uint8_t c)
|
||||
{
|
||||
lcdDrawChar(x, y, c, 0);
|
||||
}
|
||||
|
||||
uint8_t getTextWidth(const char * s, uint8_t len, LcdFlags flags)
|
||||
{
|
||||
uint8_t width = 0;
|
||||
for (int i = 0; len == 0 || i < len; ++i) {
|
||||
unsigned char c = map_utf8_char(s, len);
|
||||
if (!c) {
|
||||
break;
|
||||
}
|
||||
width += getCharWidth(c, flags) + 1;
|
||||
s++;
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
void lcdDrawSizedText(coord_t x, coord_t y, const char * s, uint8_t len, LcdFlags flags)
|
||||
{
|
||||
const coord_t orig_x = x;
|
||||
@@ -364,43 +132,7 @@ void lcdDrawSizedText(coord_t x, coord_t y, const char * s, uint8_t len, LcdFlag
|
||||
}
|
||||
}
|
||||
|
||||
void lcdDrawSizedText(coord_t x, coord_t y, const char * s, uint8_t len)
|
||||
{
|
||||
lcdDrawSizedText(x, y, s, len, 0);
|
||||
}
|
||||
|
||||
void lcdDrawCenteredText(coord_t y, const char * s, LcdFlags flags)
|
||||
{
|
||||
coord_t x = (LCD_W - getTextWidth(s, flags)) / 2;
|
||||
lcdDrawText(x, y, s, flags);
|
||||
}
|
||||
|
||||
void lcdDrawText(coord_t x, coord_t y, const char * s, LcdFlags flags)
|
||||
{
|
||||
lcdDrawSizedText(x, y, s, 255, flags);
|
||||
}
|
||||
|
||||
void lcdDrawText(coord_t x, coord_t y, const char * s)
|
||||
{
|
||||
lcdDrawText(x, y, s, 0);
|
||||
}
|
||||
|
||||
void lcdDrawTextAlignedLeft(coord_t y, const char * s)
|
||||
{
|
||||
lcdDrawText(0, y, s);
|
||||
}
|
||||
|
||||
void lcdDrawTextIndented(coord_t y, const char * s)
|
||||
{
|
||||
lcdDrawText(INDENT_WIDTH, y, s);
|
||||
}
|
||||
|
||||
#if !defined(BOOT)
|
||||
void lcdDrawTextAtIndex(coord_t x, coord_t y, const char *const *s,uint8_t idx, LcdFlags flags)
|
||||
{
|
||||
lcdDrawSizedText(x, y, s[idx], UINT8_MAX, flags);
|
||||
}
|
||||
|
||||
void lcdDrawHexNumber(coord_t x, coord_t y, uint32_t val, LcdFlags flags)
|
||||
{
|
||||
for (int i=12; i>=0; i-=4) {
|
||||
@@ -410,133 +142,9 @@ void lcdDrawHexNumber(coord_t x, coord_t y, uint32_t val, LcdFlags flags)
|
||||
x = lcdNextPos;
|
||||
}
|
||||
}
|
||||
|
||||
void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags flags)
|
||||
{
|
||||
lcdDrawNumber(x, y, val, flags, 0);
|
||||
}
|
||||
|
||||
void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags flags, uint8_t len)
|
||||
{
|
||||
char str[16+1];
|
||||
char *s = str+16;
|
||||
*s = '\0';
|
||||
int idx = 0;
|
||||
int mode = MODE(flags);
|
||||
bool neg = false;
|
||||
|
||||
if (val == INT_MAX) {
|
||||
flags &= ~(LEADING0 | PREC1 | PREC2);
|
||||
lcdDrawText(x, y, "INT_MAX", flags);
|
||||
return;
|
||||
}
|
||||
|
||||
if (val < 0) {
|
||||
if (val == INT_MIN) {
|
||||
flags &= ~(LEADING0 | PREC1 | PREC2);
|
||||
lcdDrawText(x, y, "INT_MIN", flags);
|
||||
return;
|
||||
}
|
||||
val = -val;
|
||||
neg = true;
|
||||
}
|
||||
do {
|
||||
*--s = '0' + (val % 10);
|
||||
++idx;
|
||||
val /= 10;
|
||||
if (mode!=0 && idx==mode) {
|
||||
mode = 0;
|
||||
*--s = '.';
|
||||
if (val==0) {
|
||||
*--s = '0';
|
||||
}
|
||||
}
|
||||
} while (val!=0 || mode>0 || (mode==MODE(LEADING0) && idx<len));
|
||||
if (neg) {
|
||||
*--s = '-';
|
||||
}
|
||||
flags &= ~(LEADING0 | PREC1 | PREC2);
|
||||
lcdDrawText(x, y, s, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
void lcdDrawSolidHorizontalLine(coord_t x, coord_t y, coord_t w, LcdFlags att)
|
||||
{
|
||||
if (w < 0) { x += w; w = -w; }
|
||||
lcdDrawHorizontalLine(x, y, w, 0xff, att);
|
||||
}
|
||||
|
||||
#if !defined(BOOT)
|
||||
void lcdDrawLine(coord_t x1, coord_t y1, coord_t x2, coord_t y2, uint8_t pat, LcdFlags att)
|
||||
{
|
||||
int dx = x2-x1; /* the horizontal distance of the line */
|
||||
int dy = y2-y1; /* the vertical distance of the line */
|
||||
int dxabs = abs(dx);
|
||||
int dyabs = abs(dy);
|
||||
int sdx = sgn(dx);
|
||||
int sdy = sgn(dy);
|
||||
int x = dyabs>>1;
|
||||
int y = dxabs>>1;
|
||||
int px = x1;
|
||||
int py = y1;
|
||||
|
||||
if (dxabs >= dyabs) {
|
||||
/* the line is more horizontal than vertical */
|
||||
for (int i=0; i<=dxabs; i++) {
|
||||
if ((1<<(px%8)) & pat) {
|
||||
lcdDrawPoint(px, py, att);
|
||||
}
|
||||
y += dyabs;
|
||||
if (y>=dxabs) {
|
||||
y -= dxabs;
|
||||
py += sdy;
|
||||
}
|
||||
px += sdx;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* the line is more vertical than horizontal */
|
||||
for (int i=0; i<=dyabs; i++) {
|
||||
if ((1<<(py%8)) & pat) {
|
||||
lcdDrawPoint(px, py, att);
|
||||
}
|
||||
x += dxabs;
|
||||
if (x >= dyabs) {
|
||||
x -= dyabs;
|
||||
px += sdx;
|
||||
}
|
||||
py += sdy;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void lcdDrawSolidVerticalLine(coord_t x, coord_t y, coord_t h, LcdFlags att)
|
||||
{
|
||||
lcdDrawVerticalLine(x, y, h, SOLID, att);
|
||||
}
|
||||
|
||||
void lcdDrawRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat, LcdFlags att)
|
||||
{
|
||||
lcdDrawVerticalLine(x, y, h, pat, att);
|
||||
lcdDrawVerticalLine(x+w-1, y, h, pat, att);
|
||||
if (~att & ROUND) { x+=1; w-=2; }
|
||||
lcdDrawHorizontalLine(x, y+h-1, w, pat, att);
|
||||
lcdDrawHorizontalLine(x, y, w, pat, att);
|
||||
}
|
||||
|
||||
#if !defined(BOOT)
|
||||
void lcdDrawFilledRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat, LcdFlags att)
|
||||
{
|
||||
for (coord_t i=y; i<y+h; i++) {
|
||||
if ((att&ROUND) && (i==y || i==y+h-1))
|
||||
lcdDrawHorizontalLine(x+1, i, w-2, pat, att);
|
||||
else
|
||||
lcdDrawHorizontalLine(x, i, w, pat, att);
|
||||
pat = (pat >> 1) + ((pat & 1) << 7);
|
||||
}
|
||||
}
|
||||
|
||||
void drawTelemetryTopBar()
|
||||
{
|
||||
drawModelName(0, 0, g_model.header.name, g_eeGeneral.currModel, 0);
|
||||
@@ -567,120 +175,11 @@ void drawTelemetryTopBar()
|
||||
lcdInvertLine(0);
|
||||
}
|
||||
|
||||
void drawRtcTime(coord_t x, coord_t y, LcdFlags att)
|
||||
{
|
||||
drawTimer(x, y, getValue(MIXSRC_TX_TIME), att, att);
|
||||
}
|
||||
|
||||
void drawTimer(coord_t x, coord_t y, int32_t tme, LcdFlags att, LcdFlags att2)
|
||||
{
|
||||
div_t qr;
|
||||
|
||||
if (att & RIGHT) {
|
||||
att -= RIGHT;
|
||||
if (att & DBLSIZE)
|
||||
x -= 5*(2*FWNUM)-4;
|
||||
else if (att & MIDSIZE)
|
||||
x -= 5*8-4;
|
||||
else
|
||||
x -= 5*FWNUM+1;
|
||||
}
|
||||
|
||||
if (tme < 0) {
|
||||
lcdDrawChar(x - ((att & DBLSIZE) ? FW+2 : ((att & MIDSIZE) ? FW+0 : FWNUM)), y, '-', att);
|
||||
tme = -tme;
|
||||
}
|
||||
|
||||
qr = div((int)tme, 60);
|
||||
|
||||
#define separator ':'
|
||||
if (att & TIMEHOUR) {
|
||||
div_t qr2 = div(qr.quot, 60);
|
||||
if (qr2.quot < 100) {
|
||||
lcdDrawNumber(x, y, qr2.quot, att|LEADING0|LEFT, 2);
|
||||
}
|
||||
else {
|
||||
lcdDrawNumber(x, y, qr2.quot, att|LEFT);
|
||||
}
|
||||
lcdDrawChar(lcdNextPos, y, separator, att);
|
||||
qr.quot = qr2.rem;
|
||||
x = lcdNextPos;
|
||||
}
|
||||
|
||||
lcdDrawNumber(x, y, qr.quot, att|LEADING0|LEFT, 2);
|
||||
if (att & TIMEBLINK)
|
||||
lcdDrawChar(lcdNextPos, y, separator, BLINK);
|
||||
else
|
||||
lcdDrawChar(lcdNextPos, y, separator, att&att2);
|
||||
lcdDrawNumber(lcdNextPos, y, qr.rem, (att2|LEADING0) & (~RIGHT), 2);
|
||||
}
|
||||
|
||||
// TODO to be optimized with drawValueWithUnit
|
||||
void putsVolts(coord_t x, coord_t y, uint16_t volts, LcdFlags att)
|
||||
{
|
||||
lcdDrawNumber(x, y, (int16_t)volts, (~NO_UNIT) & (att | ((att&PREC2)==PREC2 ? 0 : PREC1)));
|
||||
if (~att & NO_UNIT) lcdDrawChar(lcdLastRightPos, y, 'V', att);
|
||||
}
|
||||
|
||||
void putsVBat(coord_t x, coord_t y, LcdFlags att)
|
||||
{
|
||||
putsVolts(x, y, g_vbat100mV, att);
|
||||
}
|
||||
|
||||
void drawMainControlLabel(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
|
||||
{
|
||||
lcdDrawSizedText(x, y, getMainControlLabel(idx), UINT8_MAX, att);
|
||||
}
|
||||
|
||||
void putsChn(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
|
||||
{
|
||||
drawStringWithIndex(x, y, STR_CH, idx, att);
|
||||
}
|
||||
|
||||
void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
|
||||
{
|
||||
lcdDrawText(x, y, getAnalogShortLabel(idx), att);
|
||||
}
|
||||
|
||||
void drawModelName(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), att);
|
||||
}
|
||||
}
|
||||
|
||||
void drawSwitch(coord_t x, coord_t y, int32_t idx, LcdFlags flags, bool autoBold)
|
||||
{
|
||||
char s[8];
|
||||
getSwitchPositionName(s, idx);
|
||||
if (autoBold && idx != SWSRC_NONE && getSwitch(idx))
|
||||
flags |= BOLD;
|
||||
lcdDrawText(x, y, s, flags);
|
||||
}
|
||||
|
||||
void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags flags)
|
||||
{
|
||||
char s[8];
|
||||
getCurveString(s, idx);
|
||||
lcdDrawText(x, y, s, flags);
|
||||
}
|
||||
|
||||
void drawTimerMode(coord_t x, coord_t y, swsrc_t mode, LcdFlags att)
|
||||
{
|
||||
if (mode >= 0) {
|
||||
if (mode < TMRMODE_COUNT)
|
||||
return lcdDrawTextAtIndex(x, y, STR_VTMRMODES, mode, att);
|
||||
else
|
||||
mode -= (TMRMODE_COUNT-1);
|
||||
}
|
||||
drawSwitch(x, y, mode, att);
|
||||
}
|
||||
|
||||
void drawGPSCoord(coord_t x, coord_t y, int32_t value, const char * direction, LcdFlags att, bool seconds=true)
|
||||
{
|
||||
uint32_t absvalue = abs(value);
|
||||
@@ -976,5 +475,3 @@ void lcdDrawRleBitmap(coord_t x, coord_t y, const uint8_t * img, coord_t offset,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void lcdFlushed() {}
|
||||
|
||||
+11
-136
@@ -26,152 +26,29 @@
|
||||
#include "edgetx_types.h"
|
||||
#include "board.h"
|
||||
|
||||
#define BOX_WIDTH 31
|
||||
#define CENTER_OFS (7*FW-FW/2)
|
||||
#define OFS_CHECKTRIMS CENTER_OFS+(9*FW)
|
||||
#define INDENT_WIDTH (FW/2)
|
||||
constexpr coord_t BOX_WIDTH = 31;
|
||||
constexpr coord_t BOX_CENTERY = LCD_H - BOX_WIDTH / 2 - 10;
|
||||
constexpr coord_t MARKER_WIDTH = 5;
|
||||
#define CENTER_OFS (7 * FW - FW / 2)
|
||||
|
||||
#define FW 6
|
||||
#define FWNUM 5
|
||||
#define FH 8
|
||||
#define BITMAP_BUFFER_SIZE(w, h) (2 + (w) * (((h)+7)/8)*4)
|
||||
#define DISPLAY_BUFFER_SIZE (LCD_W*LCD_H*4/8)
|
||||
|
||||
#define LCD_LINES (LCD_H/FH)
|
||||
#define LCD_COLS (LCD_W/FW)
|
||||
#define GREY(x) ((x) * 0x010000)
|
||||
#define WHITE GREY(0xf)
|
||||
#define GREY_DEFAULT GREY(11)
|
||||
#define COLOUR_MASK(x) ((x) & 0x0F0000)
|
||||
|
||||
#define BITMAP_BUFFER_SIZE(w, h) (2 + (w) * (((h)+7)/8)*4)
|
||||
#include "lcd_common.h"
|
||||
|
||||
/* lcdDrawText flags */
|
||||
#define BLINK 0x01
|
||||
#define INVERS 0x02
|
||||
#define BOLD 0x04
|
||||
#define LEFT 0x00
|
||||
#define RIGHT 0x08
|
||||
#define CENTERED 0x20
|
||||
#define FIXEDWIDTH 0x10
|
||||
/* no 0x80 here because of "GV"1 which is aligned LEFT */
|
||||
/* no 0x10 here because of "MODEL"01 which uses LEADING0 */
|
||||
#define ZCHAR 0x80
|
||||
|
||||
/* lcdDrawNumber additional flags */
|
||||
#define LEADING0 0x10
|
||||
#define PREC1 0x20
|
||||
#define PREC2 0x30
|
||||
#define MODE(flags) ((((int8_t)(flags) & 0x30) - 0x10) >> 4)
|
||||
|
||||
/* line, rect, square flags */
|
||||
#define FORCE 0x02
|
||||
#define ERASE 0x04
|
||||
#define ROUND 0x08
|
||||
#define FILL_WHITE 0x10
|
||||
|
||||
/* telemetry flags */
|
||||
#define NO_UNIT 0x40
|
||||
|
||||
#define FONTSIZE_MASK 0x0700
|
||||
#define FONTSIZE(x) ((x) & FONTSIZE_MASK)
|
||||
#define TINSIZE 0x0100
|
||||
#define SMLSIZE 0x0200
|
||||
#define MIDSIZE 0x0300
|
||||
#define DBLSIZE 0x0400
|
||||
#define XXLSIZE 0x0500
|
||||
#define ERASEBG 0x8000
|
||||
#define VERTICAL 0x0800
|
||||
|
||||
#define TIMEBLINK 0x1000
|
||||
#define TIMEHOUR 0x2000
|
||||
#define STREXPANDED 0x4000
|
||||
|
||||
#define GREY(x) ((x) * 0x010000)
|
||||
#define WHITE GREY(0xf)
|
||||
#define GREY_DEFAULT GREY(11)
|
||||
#define COLOUR_MASK(x) ((x) & 0x0F0000)
|
||||
|
||||
#define DISPLAY_BUFFER_SIZE (LCD_W*LCD_H*4/8)
|
||||
|
||||
extern pixel_t displayBuf[DISPLAY_BUFFER_SIZE];
|
||||
extern coord_t lcdLastRightPos;
|
||||
extern coord_t lcdLastLeftPos;
|
||||
extern coord_t lcdNextPos;
|
||||
|
||||
#define DISPLAY_END (displayBuf + DISPLAY_BUFFER_SIZE)
|
||||
#define ASSERT_IN_DISPLAY(p) assert((p) >= displayBuf && (p) < DISPLAY_END)
|
||||
|
||||
void lcdDrawChar(coord_t x, coord_t y, uint8_t c);
|
||||
void lcdDrawChar(coord_t x, coord_t y, uint8_t c, LcdFlags mode);
|
||||
void lcdDrawCenteredText(coord_t y, const char * s, LcdFlags flags = 0);
|
||||
void lcdDrawText(coord_t x, coord_t y, const char * s, LcdFlags mode);
|
||||
void lcdDrawTextAtIndex(coord_t x, coord_t y, const char *const *s,uint8_t idx, LcdFlags mode);
|
||||
void lcdDrawSizedText(coord_t x, coord_t y, const char * s, unsigned char len, LcdFlags mode);
|
||||
void lcdDrawText(coord_t x, coord_t y, const char * s);
|
||||
void lcdDrawSizedText(coord_t x, coord_t y, const char * s, unsigned char len);
|
||||
void lcdDrawTextAlignedLeft(coord_t y, const char * s);
|
||||
void lcdDrawTextIndented(coord_t y, const char * s);
|
||||
|
||||
void lcdDrawHexNumber(coord_t x, coord_t y, uint32_t val, LcdFlags mode=0);
|
||||
void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags mode, uint8_t len);
|
||||
void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags mode=0);
|
||||
|
||||
void drawModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att);
|
||||
void drawSwitch(coord_t x, coord_t y, int32_t swtch, LcdFlags att=0, bool autoBold = true);
|
||||
void drawMainControlLabel(coord_t x, coord_t y, uint8_t idx, LcdFlags att=0);
|
||||
void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att=0);
|
||||
void drawTimerMode(coord_t x, coord_t y, swsrc_t mode, LcdFlags att=0);
|
||||
|
||||
void putsChn(coord_t x, coord_t y, uint8_t idx, LcdFlags attr);
|
||||
void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags attr);
|
||||
|
||||
void putsVolts(coord_t x, coord_t y, uint16_t volts, LcdFlags att);
|
||||
void putsVBat(coord_t x, coord_t y, LcdFlags att);
|
||||
|
||||
#define SOLID 0xff
|
||||
#define DOTTED 0x55
|
||||
|
||||
void lcdDrawPoint(coord_t x, coord_t y, LcdFlags att=0);
|
||||
void lcdMaskPoint(uint8_t *p, uint8_t mask, LcdFlags att=0);
|
||||
void lcdDrawSolidHorizontalLine(coord_t x, coord_t y, coord_t w, LcdFlags att=0);
|
||||
void lcdDrawHorizontalLine(coord_t x, coord_t y, coord_t w, uint8_t pat, LcdFlags att=0);
|
||||
void lcdDrawSolidVerticalLine(coord_t x, coord_t y, coord_t h, LcdFlags att=0);
|
||||
void lcdDrawVerticalLine(coord_t x, coord_t y, coord_t h, uint8_t pat, LcdFlags att=0);
|
||||
void lcdDrawLine(coord_t x1, coord_t y1, coord_t x2, coord_t y2, uint8_t pat=SOLID, LcdFlags att=0);
|
||||
void lcdDrawFilledRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat=SOLID, LcdFlags att=0);
|
||||
inline void lcdDrawSolidFilledRect(coord_t x, coord_t y, coord_t w, coord_t h, LcdFlags att=0)
|
||||
{
|
||||
lcdDrawFilledRect(x, y, w, h, SOLID, att);
|
||||
}
|
||||
void lcdDrawRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat=SOLID, LcdFlags att=0);
|
||||
inline void lcdDrawSquare(coord_t x, coord_t y, coord_t w, LcdFlags att=0)
|
||||
{
|
||||
lcdDrawRect(x, y, w, w, SOLID, att);
|
||||
}
|
||||
|
||||
void lcdInvertLine(int8_t line);
|
||||
#define lcdInvertLastLine() lcdInvertLine(LCD_LINES-1)
|
||||
|
||||
void drawTelemetryTopBar();
|
||||
|
||||
#define V_BAR(xx, yy, ll) \
|
||||
lcdDrawSolidVerticalLine(xx-1,yy-ll,ll); \
|
||||
lcdDrawSolidVerticalLine(xx ,yy-ll,ll); \
|
||||
lcdDrawSolidVerticalLine(xx+1,yy-ll,ll)
|
||||
|
||||
void lcdDraw1bitBitmap(coord_t x, coord_t y, const unsigned char * img, uint8_t idx, LcdFlags att=0);
|
||||
|
||||
void lcdDrawBitmap(coord_t x, coord_t y, const uint8_t * img, coord_t offset=0, coord_t width=0);
|
||||
void lcdDrawRleBitmap(coord_t x, coord_t y, const uint8_t * img, coord_t offset=0, coord_t width=0, bool overlay=false);
|
||||
#define LCD_ICON(x, y, icon) lcdDrawRleBitmap(x, y, icons, icon)
|
||||
|
||||
|
||||
void lcdClear();
|
||||
|
||||
uint8_t * lcdLoadBitmap(uint8_t * dest, const char * filename, uint16_t width, uint16_t height);
|
||||
|
||||
#if defined(BOOT)
|
||||
#define BLINK_ON_PHASE (0)
|
||||
#else
|
||||
#define BLINK_ON_PHASE (g_blinkTmr10ms & (1 << 6))
|
||||
#define SLOW_BLINK_ON_PHASE (g_blinkTmr10ms & (1 << 7))
|
||||
#endif
|
||||
|
||||
inline pixel_t getPixel(unsigned int x, unsigned int y)
|
||||
{
|
||||
if (x>=LCD_W || y>=LCD_H) {
|
||||
@@ -182,8 +59,6 @@ inline pixel_t getPixel(unsigned int x, unsigned int y)
|
||||
return (y & 1) ? (*p >> 4) : (*p & 0x0F);
|
||||
}
|
||||
|
||||
uint8_t getTextWidth(const char * s, uint8_t len=0, LcdFlags flags=0);
|
||||
|
||||
class RleBitmap
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 "edgetx.h"
|
||||
|
||||
const MenuHandler menuTabGeneral[MENU_RADIO_PAGES_COUNT] = {
|
||||
#if defined(RADIO_TOOLS)
|
||||
{ menuRadioTools, nullptr },
|
||||
#endif
|
||||
{ menuRadioSdManager, nullptr },
|
||||
{ menuRadioSetup, nullptr },
|
||||
{ menuRadioSpecialFunctions, radioGFEnabled },
|
||||
{ menuRadioTrainer, radioTrainerEnabled },
|
||||
{ menuRadioHardware, nullptr },
|
||||
{ menuRadioVersion, nullptr }
|
||||
};
|
||||
|
||||
void menuRadioSpecialFunctions(event_t event)
|
||||
{
|
||||
MENU(STR_MENUSPECIALFUNCS, menuTabGeneral, MENU_RADIO_SPECIAL_FUNCTIONS, MAX_SPECIAL_FUNCTIONS, { NAVIGATION_LINE_BY_LINE|5/*repeated*/ });
|
||||
return menuSpecialFunctions(event, g_eeGeneral.customFn, &globalFunctionsContext);
|
||||
}
|
||||
@@ -21,109 +21,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "keys.h"
|
||||
#include "common/stdlcd/menus.h"
|
||||
#include "common/stdlcd/features.h"
|
||||
#include "menus_common.h"
|
||||
|
||||
inline bool isRadioMenuDisplayed()
|
||||
{
|
||||
return menuVerticalPositions[0] == 1;
|
||||
}
|
||||
|
||||
inline bool isModelMenuDisplayed()
|
||||
{
|
||||
return menuVerticalPositions[0] == 0;
|
||||
}
|
||||
|
||||
void onMainViewMenu(const char * result);
|
||||
void menuFirstCalib(event_t event);
|
||||
void menuMainViewChannelsMonitor(event_t event);
|
||||
void menuChannelsView(event_t event);
|
||||
void menuMainView(event_t event);
|
||||
void menuViewTelemetry(event_t event);
|
||||
void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomFunctionsContext * functionsContext);
|
||||
void menuModelNotes(event_t event);
|
||||
void menuStatisticsView(event_t event);
|
||||
void menuStatisticsDebug(event_t event);
|
||||
void menuStatisticsDebug2(event_t event);
|
||||
void menuAboutView(event_t event);
|
||||
|
||||
#if defined(DEBUG_TRACE_BUFFER)
|
||||
void menuTraceBuffer(event_t event);
|
||||
#endif
|
||||
|
||||
enum MenuRadioIndexes {
|
||||
#if defined(LUA) || defined(PXX2) || defined(MULTIMODULE)
|
||||
MENU_RADIO_TOOLS,
|
||||
#endif
|
||||
MENU_RADIO_SD_MANAGER,
|
||||
MENU_RADIO_SETUP,
|
||||
MENU_RADIO_SPECIAL_FUNCTIONS,
|
||||
MENU_RADIO_TRAINER,
|
||||
MENU_RADIO_HARDWARE,
|
||||
MENU_RADIO_VERSION,
|
||||
MENU_RADIO_PAGES_COUNT
|
||||
};
|
||||
|
||||
void menuRadioSetup(event_t event);
|
||||
void menuRadioSdManager(event_t event);
|
||||
void menuRadioSpecialFunctions(event_t event);
|
||||
void menuRadioTrainer(event_t event);
|
||||
void menuRadioVersion(event_t event);
|
||||
void menuRadioDiagKeys(event_t event);
|
||||
void menuRadioDiagAnalogs(event_t event);
|
||||
void menuRadioHardware(event_t event);
|
||||
void menuRadioTools(event_t event);
|
||||
void menuRadioCalibration(event_t event);
|
||||
void menuRadioSpectrumAnalyser(event_t event);
|
||||
void menuRadioPowerMeter(event_t event);
|
||||
void menuGhostModuleConfig(event_t event);
|
||||
|
||||
extern const MenuHandler menuTabGeneral[MENU_RADIO_PAGES_COUNT];
|
||||
|
||||
enum MenuModelIndexes {
|
||||
MENU_MODEL_SELECT,
|
||||
MENU_MODEL_SETUP,
|
||||
CASE_HELI(MENU_MODEL_HELI)
|
||||
CASE_FLIGHT_MODES(MENU_MODEL_FLIGHT_MODES)
|
||||
MENU_MODEL_INPUTS,
|
||||
MENU_MODEL_MIXES,
|
||||
MENU_MODEL_OUTPUTS,
|
||||
MENU_MODEL_CURVES,
|
||||
CASE_GVARS(MENU_MODEL_GVARS)
|
||||
MENU_MODEL_LOGICAL_SWITCHES,
|
||||
MENU_MODEL_SPECIAL_FUNCTIONS,
|
||||
#if defined(LUA_MODEL_SCRIPTS)
|
||||
MENU_MODEL_CUSTOM_SCRIPTS,
|
||||
#endif
|
||||
MENU_MODEL_TELEMETRY,
|
||||
MENU_MODEL_DISPLAY,
|
||||
MENU_MODEL_PAGES_COUNT
|
||||
};
|
||||
|
||||
void menuModelSelect(event_t event);
|
||||
void menuModelSetup(event_t event);
|
||||
void menuModelFailsafe(event_t event);
|
||||
void menuModelModuleOptions(event_t event);
|
||||
void menuModelReceiverOptions(event_t event);
|
||||
void menuModelHeli(event_t event);
|
||||
void menuModelFlightModesAll(event_t event);
|
||||
void menuModelExpoOne(event_t event);
|
||||
void menuModelExposAll(event_t event);
|
||||
void menuModelMixOne(event_t event);
|
||||
void menuModelMixAll(event_t event);
|
||||
void menuModelLimits(event_t event);
|
||||
void menuModelCurvesAll(event_t event);
|
||||
void menuModelCurveOne(event_t event);
|
||||
void menuModelGVars(event_t event);
|
||||
void menuModelLogicalSwitches(event_t event);
|
||||
void menuModelSpecialFunctions(event_t event);
|
||||
void menuModelCustomScripts(event_t event);
|
||||
void menuModelTelemetry(event_t event);
|
||||
void menuModelSensor(event_t event);
|
||||
void menuModelDisplay(event_t event);
|
||||
#if defined(USBJ_EX)
|
||||
void menuModelUSBJoystick(event_t event);
|
||||
#endif
|
||||
|
||||
extern const MenuHandler menuTabModel[MENU_MODEL_PAGES_COUNT];
|
||||
|
||||
@@ -164,6 +164,6 @@ void menuModelCustomScripts(event_t event)
|
||||
}
|
||||
|
||||
// Script name
|
||||
lcdDrawSizedText(16*FW, y, sd.name, sizeof(sd.name), ZCHAR);
|
||||
lcdDrawSizedText(16*FW, y, sd.name, sizeof(sd.name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ void menuModelFailsafe(event_t event)
|
||||
if (lenLabel > 0) {
|
||||
if (lenLabel > reusableBuffer.modelFailsafe.maxNameLen)
|
||||
reusableBuffer.modelFailsafe.maxNameLen = lenLabel;
|
||||
lcdDrawSizedText(x - colW, y, g_model.limitData[ch+channelStart].name, sizeof(g_model.limitData[ch+channelStart].name), ZCHAR | SMLSIZE);
|
||||
lcdDrawSizedText(x - colW, y, g_model.limitData[ch+channelStart].name, sizeof(g_model.limitData[ch+channelStart].name), SMLSIZE);
|
||||
}
|
||||
else {
|
||||
putsChn(x - colW, y, ch+1, SMLSIZE);
|
||||
|
||||
@@ -23,36 +23,6 @@
|
||||
|
||||
static int numFlightModes() { return modelFMEnabled() ? MAX_FLIGHT_MODES : 1; }
|
||||
|
||||
void editGVarValue(coord_t x, coord_t y, event_t event, uint8_t gvar, uint8_t flightMode, LcdFlags flags)
|
||||
{
|
||||
FlightModeData * fm = &g_model.flightModeData[flightMode];
|
||||
gvar_t * v = &fm->gvars[gvar];
|
||||
int16_t vmin, vmax;
|
||||
if (*v > GVAR_MAX) {
|
||||
uint8_t fm = *v - GVAR_MAX - 1;
|
||||
if (fm >= flightMode) fm++;
|
||||
drawFlightMode(x, y, fm + 1, flags&(~LEFT));
|
||||
vmin = GVAR_MAX + 1;
|
||||
vmax = GVAR_MAX + MAX_FLIGHT_MODES - 1;
|
||||
}
|
||||
else {
|
||||
drawGVarValue(x, y, gvar, *v, flags);
|
||||
vmin = GVAR_MIN + g_model.gvars[gvar].min;
|
||||
vmax = GVAR_MAX - g_model.gvars[gvar].max;
|
||||
}
|
||||
|
||||
if (flags & INVERS) {
|
||||
if (event == EVT_KEY_LONG(KEY_ENTER) && flightMode > 0) {
|
||||
killEvents(event);
|
||||
*v = (*v > GVAR_MAX ? 0 : GVAR_MAX+1);
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
else if (s_editMode > 0) {
|
||||
*v = checkIncDec(event, *v, vmin, vmax, EE_MODEL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum GVarFields {
|
||||
GVAR_FIELD_NAME,
|
||||
GVAR_FIELD_UNIT,
|
||||
|
||||
@@ -190,11 +190,11 @@ void menuModelMixOne(event_t event)
|
||||
break;
|
||||
|
||||
case MIX_FIELD_DELAY_UP:
|
||||
md2->delayUp = EDIT_DELAY(y, event, attr, STR_DELAYUP, md2->delayUp, (md2->delayPrec ? PREC2 : PREC1));
|
||||
md2->delayUp = editDelay(y, event, attr, STR_DELAYUP, md2->delayUp, (md2->delayPrec ? PREC2 : PREC1));
|
||||
break;
|
||||
|
||||
case MIX_FIELD_DELAY_DOWN:
|
||||
md2->delayDown = EDIT_DELAY(y, event, attr, STR_DELAYDOWN, md2->delayDown, (md2->delayPrec ? PREC2 : PREC1));
|
||||
md2->delayDown = editDelay(y, event, attr, STR_DELAYDOWN, md2->delayDown, (md2->delayPrec ? PREC2 : PREC1));
|
||||
break;
|
||||
|
||||
case MIX_FIELD_SLOW_PREC:
|
||||
@@ -202,11 +202,11 @@ void menuModelMixOne(event_t event)
|
||||
break;
|
||||
|
||||
case MIX_FIELD_SLOW_UP:
|
||||
md2->speedUp = EDIT_DELAY(y, event, attr, STR_SLOWUP, md2->speedUp, (md2->speedPrec ? PREC2 : PREC1));
|
||||
md2->speedUp = editDelay(y, event, attr, STR_SLOWUP, md2->speedUp, (md2->speedPrec ? PREC2 : PREC1));
|
||||
break;
|
||||
|
||||
case MIX_FIELD_SLOW_DOWN:
|
||||
md2->speedDown = EDIT_DELAY(y, event, attr, STR_SLOWDOWN, md2->speedDown, (md2->speedPrec ? PREC2 : PREC1));
|
||||
md2->speedDown = editDelay(y, event, attr, STR_SLOWDOWN, md2->speedDown, (md2->speedPrec ? PREC2 : PREC1));
|
||||
break;
|
||||
}
|
||||
y += FH;
|
||||
|
||||
@@ -459,13 +459,13 @@ void onBluetoothConnectMenu(const char * result)
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "common/stdlcd/model_setup_pxx1.cpp"
|
||||
#include "model_setup_pxx1.cpp"
|
||||
|
||||
#if defined(PXX2)
|
||||
#include "common/stdlcd/model_setup_pxx2.cpp"
|
||||
#include "model_setup_pxx2.cpp"
|
||||
#endif
|
||||
#if defined(AFHDS3)
|
||||
#include "common/stdlcd/model_setup_afhds3.cpp"
|
||||
#include "model_setup_afhds3.cpp"
|
||||
#endif
|
||||
|
||||
#if defined(USBJ_EX)
|
||||
@@ -1358,7 +1358,7 @@ void menuModelSetup(event_t event)
|
||||
}
|
||||
if (bluetooth.distantAddr[0]) {
|
||||
lcdDrawText(INDENT_WIDTH, y+1, bluetooth.distantAddr, TINSIZE);
|
||||
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_CLEAR, attr);
|
||||
lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_CLEAR_BTN, attr);
|
||||
if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) {
|
||||
bluetooth.state = BLUETOOTH_STATE_CLEAR_REQUESTED;
|
||||
memclear(bluetooth.distantAddr, sizeof(bluetooth.distantAddr));
|
||||
|
||||
@@ -288,7 +288,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
|
||||
}
|
||||
else {
|
||||
TelemetrySensor * sensor = & g_model.telemetrySensors[param-FUNC_RESET_PARAM_FIRST_TELEM];
|
||||
lcdDrawSizedText(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, sensor->label, TELEM_LABEL_LEN, attr|ZCHAR);
|
||||
lcdDrawSizedText(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, sensor->label, TELEM_LABEL_LEN, attr);
|
||||
}
|
||||
if (active) INCDEC_ENABLE_CHECK(functionsContext == &globalFunctionsContext ? isSourceAvailableInGlobalResetSpecialFunction : isSourceAvailableInResetSpecialFunction);
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ void menuModelTelemetry(event_t event)
|
||||
int index = k - ITEM_TELEMETRY_SENSOR_FIRST;
|
||||
lcdDrawNumber(INDENT_WIDTH, y, index+1, LEFT|attr);
|
||||
lcdDrawChar(lcdLastRightPos, y, ':', attr);
|
||||
lcdDrawSizedText(3*FW, y, g_model.telemetrySensors[index].label, TELEM_LABEL_LEN, ZCHAR);
|
||||
lcdDrawSizedText(3*FW, y, g_model.telemetrySensors[index].label, TELEM_LABEL_LEN);
|
||||
if (telemetryItems[index].isFresh()) {
|
||||
lcdDrawChar(10*FW, y, '*');
|
||||
}
|
||||
|
||||
@@ -33,13 +33,4 @@
|
||||
#define WARNING_LINE_X 16
|
||||
#define WARNING_LINE_Y MESSAGEBOX_Y + 2
|
||||
|
||||
#define POPUP_MENU_MAX_LINES 13
|
||||
#define MENU_MAX_DISPLAY_LINES 6
|
||||
#define MENU_LINE_LENGTH (LEN_MODEL_NAME+12)
|
||||
|
||||
enum {
|
||||
MENU_OFFSET_INTERNAL,
|
||||
MENU_OFFSET_EXTERNAL
|
||||
};
|
||||
|
||||
#include "common/stdlcd/popups_common.h"
|
||||
#include "popups_common.h"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "edgetx.h"
|
||||
#include "hal/adc_driver.h"
|
||||
#include "gui/common/stdlcd/calibration.h"
|
||||
#include "calibration.h"
|
||||
|
||||
#define XPOT_DELTA 10
|
||||
#define XPOT_DELAY 10 /* cycles */
|
||||
|
||||
@@ -84,7 +84,7 @@ void menuChannelsView(event_t event)
|
||||
if (lenLabel > 0) {
|
||||
if (lenLabel > 4)
|
||||
viewChannels.longNames = true;
|
||||
lcdDrawSizedText(x+1-ofs, y, g_model.limitData[ch].name, sizeof(g_model.limitData[ch].name), ZCHAR | SMLSIZE);
|
||||
lcdDrawSizedText(x+1-ofs, y, g_model.limitData[ch].name, sizeof(g_model.limitData[ch].name), SMLSIZE);
|
||||
}
|
||||
else {
|
||||
putsChn(x+1-ofs, y, ch+1, SMLSIZE);
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#define BITMAP_Y (LCD_H/2)
|
||||
#define PHASE_X BITMAP_X
|
||||
#define PHASE_Y (3*FH)
|
||||
#define PHASE_FLAGS (0)
|
||||
#define TIMERS_X 145
|
||||
#define TIMERS_Y 20
|
||||
#define TIMERS_H 25
|
||||
@@ -54,7 +53,6 @@
|
||||
#define TRIM_RH_X (LCD_W-32-9)
|
||||
|
||||
#define TRIM_LEN 27
|
||||
#define MARKER_WIDTH 5
|
||||
|
||||
const unsigned char logo_taranis[] = {
|
||||
#include "logo.lbm"
|
||||
@@ -358,7 +356,7 @@ void displayTimers()
|
||||
TimerData & timerData = g_model.timers[i];
|
||||
uint8_t y = TIMERS_Y + i*TIMERS_H;
|
||||
if (ZLEN(timerData.name) > 0) {
|
||||
lcdDrawSizedText(TIMERS_X, y-7, timerData.name, LEN_TIMER_NAME, ZCHAR|SMLSIZE);
|
||||
lcdDrawSizedText(TIMERS_X, y-7, timerData.name, LEN_TIMER_NAME, SMLSIZE);
|
||||
}
|
||||
else {
|
||||
lcdDrawTextAtIndex(TIMERS_X, y-7, STR_VTMRMODES, timerData.mode, SMLSIZE);
|
||||
@@ -519,7 +517,7 @@ void menuMainView(event_t event)
|
||||
|
||||
// Flight Mode Name
|
||||
int mode = mixerCurrentFlightMode;
|
||||
lcdDrawSizedText(PHASE_X, PHASE_Y, g_model.flightModeData[mode].name, sizeof(g_model.flightModeData[mode].name), ZCHAR|PHASE_FLAGS);
|
||||
lcdDrawSizedText(PHASE_X, PHASE_Y, g_model.flightModeData[mode].name, sizeof(g_model.flightModeData[mode].name));
|
||||
|
||||
// Model Name
|
||||
drawModelName(MODELNAME_X, MODELNAME_Y, g_model.header.name, g_eeGeneral.currModel, BIGSIZE);
|
||||
@@ -621,7 +619,7 @@ void menuMainView(event_t event)
|
||||
lcdDrawFilledRect(BITMAP_X, BITMAP_Y, 64, 32, SOLID, ERASE);
|
||||
lcdDrawRect(BITMAP_X, BITMAP_Y, 64, 32);
|
||||
drawStringWithIndex(BITMAP_X+FW, BITMAP_Y+FH-1, STR_GV, gvarLastChanged+1);
|
||||
lcdDrawSizedText(BITMAP_X+4*FW+FW/2, BITMAP_Y+FH-1, g_model.gvars[gvarLastChanged].name, LEN_GVAR_NAME, ZCHAR);
|
||||
lcdDrawSizedText(BITMAP_X+4*FW+FW/2, BITMAP_Y+FH-1, g_model.gvars[gvarLastChanged].name, LEN_GVAR_NAME);
|
||||
lcdDrawText(BITMAP_X+FW, BITMAP_Y+2*FH+3, "[", BOLD);
|
||||
drawGVarValue(BITMAP_X+2*FW, BITMAP_Y+2*FH+3, gvarLastChanged, GVAR_VALUE(gvarLastChanged, getGVarFlightMode(mixerCurrentFlightMode, gvarLastChanged)), LEFT|BOLD);
|
||||
lcdDrawText(lcdLastRightPos, BITMAP_Y+2*FH+3, "]", BOLD);
|
||||
|
||||
@@ -21,207 +21,9 @@
|
||||
|
||||
#include "edgetx.h"
|
||||
|
||||
void drawStick(coord_t centrex, int16_t xval, int16_t yval)
|
||||
{
|
||||
#define BOX_CENTERY (LCD_H-BOX_WIDTH/2-10)
|
||||
#define MARKER_WIDTH 5
|
||||
lcdDrawSquare(centrex-BOX_WIDTH/2, BOX_CENTERY-BOX_WIDTH/2, BOX_WIDTH);
|
||||
lcdDrawSolidVerticalLine(centrex, BOX_CENTERY-1, 3);
|
||||
lcdDrawSolidHorizontalLine(centrex-1, BOX_CENTERY, 3);
|
||||
lcdDrawSquare(centrex + (xval/((2*RESX)/(BOX_WIDTH-MARKER_WIDTH))) - MARKER_WIDTH/2, BOX_CENTERY - (yval/((2*RESX)/(BOX_WIDTH-MARKER_WIDTH))) - MARKER_WIDTH/2, MARKER_WIDTH, ROUND);
|
||||
#undef BOX_CENTERY
|
||||
#undef MARKER_WIDTH
|
||||
}
|
||||
|
||||
void drawColumnHeader(const char * const *headers, uint8_t index)
|
||||
{
|
||||
lcdDrawText(16*FW+3, 0, " ", 0);
|
||||
lcdDrawText(17*FW, 0, headers[index], 0);
|
||||
lcdDrawText(lcdNextPos, 0, " ", 0);
|
||||
}
|
||||
|
||||
void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr)
|
||||
{
|
||||
if (value)
|
||||
lcdDrawChar(x+1, y, '#');
|
||||
if (attr)
|
||||
lcdDrawFilledRect(x, y, 7, 7);
|
||||
else
|
||||
lcdDrawSquare(x, y, 7);
|
||||
}
|
||||
|
||||
void drawScreenIndex(uint8_t index, uint8_t count, uint8_t attr)
|
||||
{
|
||||
lcdDrawNumber(LCD_W, 0, count, RIGHT | attr);
|
||||
coord_t x = 1+LCD_W-FW*(count>9 ? 3 : 2);
|
||||
lcdDrawChar(x, 0, '/', attr);
|
||||
lcdDrawNumber(x, 0, index+1, RIGHT | attr);
|
||||
}
|
||||
|
||||
void drawVerticalScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible)
|
||||
{
|
||||
lcdDrawVerticalLine(x, y, h, DOTTED);
|
||||
coord_t yofs = (h * offset) / count;
|
||||
coord_t yhgt = (h * visible) / count;
|
||||
if (yhgt + yofs > h)
|
||||
yhgt = h - yofs;
|
||||
lcdDrawVerticalLine(x, y + yofs, yhgt, SOLID, FORCE);
|
||||
}
|
||||
|
||||
void drawGauge(coord_t x, coord_t y, coord_t w, coord_t h, int32_t val, int32_t max)
|
||||
{
|
||||
lcdDrawRect(x, y, w+1, h);
|
||||
lcdDrawFilledRect(x+1, y+1, w-1, 4, SOLID, ERASE);
|
||||
coord_t len = limit((uint8_t)1, uint8_t((abs(val) * w/2 + max/2) / max), uint8_t(w/2));
|
||||
coord_t x0 = (val>0) ? x+w/2 : x+1+w/2-len;
|
||||
for (coord_t i=h-2; i>0; i--) {
|
||||
lcdDrawSolidHorizontalLine(x0, y+i, len);
|
||||
}
|
||||
}
|
||||
|
||||
void title(const char * s)
|
||||
{
|
||||
lcdDrawText(0, 0, s, INVERS);
|
||||
}
|
||||
|
||||
choice_t editChoice(coord_t x, coord_t y, const char * label, const char* const* values, choice_t value, choice_t min, choice_t max, LcdFlags attr, event_t event, coord_t lblX, IsValueAvailable isValueAvailable)
|
||||
{
|
||||
if (label) {
|
||||
lcdDrawText(lblX, y, label);
|
||||
}
|
||||
if (values) lcdDrawTextAtIndex(x, y, values, value-min, attr);
|
||||
if (attr & (~RIGHT)) value = checkIncDec(event, value, min, max, (isModelMenuDisplayed()) ? EE_MODEL : EE_GENERAL, isValueAvailable);
|
||||
return value;
|
||||
}
|
||||
|
||||
choice_t editChoice(coord_t x, coord_t y, const char * label, const char* const* values, choice_t value, choice_t min, choice_t max, LcdFlags attr, event_t event, coord_t lblX)
|
||||
{
|
||||
return editChoice(x, y, label, values, value, min, max, attr, event, lblX, nullptr);
|
||||
}
|
||||
|
||||
uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label, LcdFlags attr, event_t event, coord_t lblX)
|
||||
{
|
||||
drawCheckBox(x, y, value, attr);
|
||||
return editChoice(x, y, label, nullptr, value, 0, 1, attr, event, lblX);
|
||||
}
|
||||
|
||||
swsrc_t editSwitch(coord_t x, coord_t y, swsrc_t value, LcdFlags attr, event_t event)
|
||||
{
|
||||
lcdDrawTextAlignedLeft(y, STR_SWITCH);
|
||||
drawSwitch(x, y, value, attr);
|
||||
if (attr & (~RIGHT)) CHECK_INCDEC_MODELSWITCH(event, value, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes);
|
||||
return value;
|
||||
}
|
||||
|
||||
void drawSlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr)
|
||||
{
|
||||
lcdDrawChar(x+(value*4*FW)/max, y, '$');
|
||||
lcdDrawSolidHorizontalLine(x, y+3, 5*FW-1, FORCE);
|
||||
if (attr && (!(attr & BLINK) || !BLINK_ON_PHASE)) lcdDrawFilledRect(x, y, 5*FW-1, FH-1);
|
||||
}
|
||||
|
||||
uint16_t editSrcVarFieldValue(coord_t x, coord_t y, const char* title, uint16_t value,
|
||||
int16_t min, int16_t max, LcdFlags attr, event_t event,
|
||||
IsValueAvailable isValueAvailable, int16_t sourceMin, int16_t sourceMax)
|
||||
{
|
||||
if (title)
|
||||
lcdDrawTextAlignedLeft(y, title);
|
||||
SourceNumVal v;
|
||||
v.rawValue = value;
|
||||
if (v.isSource) {
|
||||
drawSource(x, y, v.value, attr);
|
||||
if (attr & (~RIGHT)) {
|
||||
value = checkIncDec(event, value, sourceMin, sourceMax,
|
||||
EE_MODEL|INCDEC_SOURCE|INCDEC_SOURCE_VALUE|INCDEC_SOURCE_INVERT|NO_INCDEC_MARKS, isValueAvailable);
|
||||
}
|
||||
} else {
|
||||
lcdDrawNumber(x, y, v.value, attr);
|
||||
if (attr & (~RIGHT)) {
|
||||
value = checkIncDec(event, value, min, max, sourceMin, sourceMax,
|
||||
EE_MODEL|INCDEC_SOURCE_VALUE|NO_INCDEC_MARKS|INCDEC_SKIP_VAL_CHECK_FUNC,
|
||||
isValueAvailable);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
#if defined(GVARS)
|
||||
void drawGVarValue(coord_t x, coord_t y, uint8_t gvar, gvar_t value, LcdFlags flags)
|
||||
{
|
||||
uint8_t prec = g_model.gvars[gvar].prec;
|
||||
if (prec > 0) {
|
||||
flags |= (prec == 1 ? PREC1 : PREC2);
|
||||
}
|
||||
drawValueWithUnit(x, y, value, g_model.gvars[gvar].unit ? UNIT_PERCENT : UNIT_RAW, flags);
|
||||
}
|
||||
|
||||
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t editflags, event_t event)
|
||||
{
|
||||
bool invers = (attr & INVERS);
|
||||
|
||||
// TRACE("editGVarFieldValue(val=%d min=%d max=%d)", value, min, max);
|
||||
|
||||
if (modelGVEnabled() && invers && event == EVT_KEY_LONG(KEY_ENTER)) {
|
||||
killEvents(event);
|
||||
s_editMode = !s_editMode;
|
||||
if (attr & PREC1) {
|
||||
value = (GV_IS_GV_VALUE(value) ? GET_GVAR(value, min, max, mixerCurrentFlightMode)*10 : GV_VALUE_FROM_INDEX(0));
|
||||
}
|
||||
else {
|
||||
value = (GV_IS_GV_VALUE(value) ? GET_GVAR(value, min, max, mixerCurrentFlightMode) : GV_VALUE_FROM_INDEX(0));
|
||||
}
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
|
||||
if (GV_IS_GV_VALUE(value)) {
|
||||
attr &= ~PREC1;
|
||||
int8_t idx = (int16_t)GV_INDEX_FROM_VALUE(value);
|
||||
if (invers) {
|
||||
CHECK_INCDEC_MODELVAR(event, idx, -MAX_GVARS, MAX_GVARS-1);
|
||||
}
|
||||
value = (int16_t)GV_VALUE_FROM_INDEX(idx);
|
||||
drawGVarName(x, y, idx, attr);
|
||||
}
|
||||
else {
|
||||
lcdDrawNumber(x, y, value, attr);
|
||||
if (invers) value = checkIncDec(event, value, min, max, EE_MODEL | editflags);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
#else
|
||||
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, event_t event)
|
||||
{
|
||||
lcdDrawNumber(x, y, value, attr);
|
||||
if (attr&INVERS) value = checkIncDec(event, value, min, max, EE_MODEL);
|
||||
return value;
|
||||
}
|
||||
#endif
|
||||
|
||||
char statusLineMsg[STATUS_LINE_LENGTH];
|
||||
tmr10ms_t statusLineTime = 0;
|
||||
uint8_t statusLineHeight = 0;
|
||||
|
||||
void showStatusLine()
|
||||
{
|
||||
statusLineTime = get_tmr10ms();
|
||||
}
|
||||
|
||||
#define STATUS_LINE_DELAY (3 * 100) /* 3s */
|
||||
void drawStatusLine()
|
||||
{
|
||||
if (statusLineTime) {
|
||||
if ((tmr10ms_t)(get_tmr10ms() - statusLineTime) <= (tmr10ms_t)STATUS_LINE_DELAY) {
|
||||
if (statusLineHeight < FH) statusLineHeight++;
|
||||
}
|
||||
else if (statusLineHeight) {
|
||||
statusLineHeight--;
|
||||
}
|
||||
else {
|
||||
statusLineTime = 0;
|
||||
}
|
||||
|
||||
lcdDrawFilledRect(0, LCD_H-statusLineHeight, LCD_W, FH, SOLID, ERASE);
|
||||
lcdDrawText(5, LCD_H+1-statusLineHeight, statusLineMsg, 0);
|
||||
lcdDrawFilledRect(0, LCD_H-statusLineHeight, LCD_W, FH, SOLID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ if(NOT GUI_DIR STREQUAL colorlcd)
|
||||
gui/navigation/common.cpp
|
||||
gui/navigation/navigation.cpp
|
||||
)
|
||||
include_directories(gui gui/common/stdlcd)
|
||||
endif()
|
||||
|
||||
set(SRC
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
set(GUI_SRC
|
||||
${GUI_SRC}
|
||||
../common/stdlcd/menus.cpp
|
||||
../common/stdlcd/menu_model.cpp
|
||||
../common/stdlcd/menu_radio.cpp
|
||||
../common/stdlcd/menus_common.cpp
|
||||
../common/stdlcd/draw_functions.cpp
|
||||
../common/stdlcd/fonts.cpp
|
||||
../common/stdlcd/utf8.cpp
|
||||
../common/stdlcd/popups.cpp
|
||||
../common/stdlcd/popups_common.cpp
|
||||
../common/stdlcd/model_inputs.cpp
|
||||
../common/stdlcd/model_mixes.cpp
|
||||
../common/stdlcd/view_text.cpp
|
||||
@@ -17,6 +19,8 @@ set(GUI_SRC
|
||||
../common/stdlcd/calibration.cpp
|
||||
../common/stdlcd/splash.cpp
|
||||
../common/stdlcd/radio_sdmanager.cpp
|
||||
../common/stdlcd/widgets_common.cpp
|
||||
../common/stdlcd/lcd_common.cpp
|
||||
model_curve_edit.cpp
|
||||
)
|
||||
|
||||
|
||||
@@ -173,6 +173,8 @@ static int nameCharIdx(char v)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t editNameCursorPos = 0;
|
||||
|
||||
void editName(coord_t x, coord_t y, char* name, uint8_t size, event_t event,
|
||||
uint8_t active, LcdFlags attr, uint8_t old_editMode)
|
||||
{
|
||||
@@ -603,3 +605,112 @@ void drawSource(coord_t x, coord_t y, mixsrc_t idx, LcdFlags att)
|
||||
lcdDrawText(x, y, s, att);
|
||||
}
|
||||
}
|
||||
|
||||
void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr)
|
||||
{
|
||||
if (value)
|
||||
lcdDrawChar(x+1, y, '#');
|
||||
if (attr)
|
||||
lcdDrawSolidFilledRect(x, y, 7, 7);
|
||||
else
|
||||
lcdDrawSquare(x, y, 7);
|
||||
}
|
||||
|
||||
void drawScreenIndex(uint8_t index, uint8_t count, uint8_t attr)
|
||||
{
|
||||
lcdDrawNumber(LCD_W, 0, count, RIGHT | attr);
|
||||
coord_t x = 1+LCD_W-FW*(count>9 ? 3 : 2);
|
||||
lcdDrawChar(x, 0, '/', attr);
|
||||
lcdDrawNumber(x, 0, index+1, RIGHT | attr);
|
||||
}
|
||||
|
||||
void drawVerticalScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible)
|
||||
{
|
||||
lcdDrawVerticalLine(x, y, h, DOTTED);
|
||||
coord_t yofs = (h * offset) / count;
|
||||
coord_t yhgt = (h * visible) / count;
|
||||
if (yhgt + yofs > h)
|
||||
yhgt = h - yofs;
|
||||
lcdDrawVerticalLine(x, y + yofs, yhgt, SOLID, FORCE);
|
||||
}
|
||||
|
||||
void title(const char * s)
|
||||
{
|
||||
lcdDrawText(0, 0, s, INVERS);
|
||||
}
|
||||
|
||||
#if defined(GVARS)
|
||||
void drawGVarValue(coord_t x, coord_t y, uint8_t gvar, gvar_t value, LcdFlags flags)
|
||||
{
|
||||
uint8_t prec = g_model.gvars[gvar].prec;
|
||||
if (prec > 0) {
|
||||
flags |= (prec == 1 ? PREC1 : PREC2);
|
||||
}
|
||||
drawValueWithUnit(x, y, value, g_model.gvars[gvar].unit ? UNIT_PERCENT : UNIT_RAW, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
char statusLineMsg[STATUS_LINE_LENGTH];
|
||||
static tmr10ms_t statusLineTime = 0;
|
||||
static uint8_t statusLineHeight = 0;
|
||||
|
||||
void showStatusLine()
|
||||
{
|
||||
statusLineTime = get_tmr10ms();
|
||||
}
|
||||
|
||||
#define STATUS_LINE_DELAY (3 * 100) /* 3s */
|
||||
void drawStatusLine()
|
||||
{
|
||||
if (statusLineTime) {
|
||||
if ((tmr10ms_t)(get_tmr10ms() - statusLineTime) <= (tmr10ms_t)STATUS_LINE_DELAY) {
|
||||
if (statusLineHeight < FH) statusLineHeight++;
|
||||
}
|
||||
else if (statusLineHeight) {
|
||||
statusLineHeight--;
|
||||
}
|
||||
else {
|
||||
statusLineTime = 0;
|
||||
}
|
||||
|
||||
lcdDrawFilledRect(0, LCD_H-statusLineHeight, LCD_W, FH, SOLID, ERASE);
|
||||
lcdDrawText(5, LCD_H+1-statusLineHeight, statusLineMsg);
|
||||
lcdDrawFilledRect(0, LCD_H-statusLineHeight, LCD_W, FH, SOLID);
|
||||
}
|
||||
}
|
||||
|
||||
void drawGauge(coord_t x, coord_t y, coord_t w, coord_t h, int32_t val, int32_t max)
|
||||
{
|
||||
#if defined(PCBX7) || defined(PCBX9LITE) || defined(PCBX9LITES) // X7/X9 LCD doesn't like too many horizontal lines
|
||||
h++;
|
||||
#else
|
||||
lcdDrawRect(x, y, w+1, h);
|
||||
#endif
|
||||
lcdDrawFilledRect(x+1, y+1, w-1, 4, SOLID, ERASE);
|
||||
coord_t len = limit((uint8_t)1, uint8_t((abs(val) * w/2 + max/2) / max), uint8_t(w/2));
|
||||
coord_t x0 = (val>0) ? x+w/2 : x+1+w/2-len;
|
||||
for (coord_t i=h-2; i>0; i--)
|
||||
lcdDrawSolidHorizontalLine(x0, y+i, len);
|
||||
}
|
||||
|
||||
void drawSlider(coord_t x, coord_t y, uint8_t width, uint8_t value, uint8_t max, uint8_t attr)
|
||||
{
|
||||
lcdDrawChar(x + (value * (width - FWNUM)) / max, y, '$');
|
||||
lcdDrawSolidHorizontalLine(x, y + 3, width, FORCE);
|
||||
if (attr && (!(attr & BLINK) || !BLINK_ON_PHASE)) {
|
||||
lcdDrawSolidFilledRect(x, y, width, FH - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void drawSlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr)
|
||||
{
|
||||
drawSlider(x, y, 5*FW - 1, value, max, attr);
|
||||
}
|
||||
|
||||
void drawStick(coord_t centrex, int16_t xval, int16_t yval)
|
||||
{
|
||||
lcdDrawSquare(centrex-BOX_WIDTH/2, BOX_CENTERY-BOX_WIDTH/2, BOX_WIDTH);
|
||||
lcdDrawSolidVerticalLine(centrex, BOX_CENTERY-1, 3);
|
||||
lcdDrawSolidHorizontalLine(centrex-1, BOX_CENTERY, 3);
|
||||
lcdDrawSquare(centrex + (xval/((2*RESX)/(BOX_WIDTH-MARKER_WIDTH))) - MARKER_WIDTH/2, BOX_CENTERY - (yval/((2*RESX)/(BOX_WIDTH-MARKER_WIDTH))) - MARKER_WIDTH/2, MARKER_WIDTH, ROUND);
|
||||
}
|
||||
|
||||
@@ -55,3 +55,22 @@ void drawCursor(FnFuncP fn, uint8_t offset = 0);
|
||||
void drawCurve(coord_t offset = 0);
|
||||
|
||||
void drawSource(coord_t x, coord_t y, mixsrc_t idx, LcdFlags att=0);
|
||||
|
||||
void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr);
|
||||
void drawScreenIndex(uint8_t index, uint8_t count, uint8_t attr);
|
||||
void drawVerticalScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible);
|
||||
void drawGauge(coord_t x, coord_t y, coord_t w, coord_t h, int32_t val, int32_t max);
|
||||
#if defined(GVARS)
|
||||
void drawGVarValue(coord_t x, coord_t y, uint8_t gvar, gvar_t value, LcdFlags flags = 0);
|
||||
#endif
|
||||
|
||||
void drawStick(coord_t centrex, int16_t xval, int16_t yval);
|
||||
void drawSlider(coord_t x, coord_t y, uint8_t width, uint8_t value, uint8_t max, uint8_t attr);
|
||||
void drawSlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr);
|
||||
|
||||
void title(const char * s);
|
||||
|
||||
#define STATUS_LINE_LENGTH 32
|
||||
extern char statusLineMsg[STATUS_LINE_LENGTH];
|
||||
void showStatusLine();
|
||||
void drawStatusLine();
|
||||
|
||||
@@ -0,0 +1,533 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 <memory.h>
|
||||
|
||||
#include "lcd.h"
|
||||
#include "fonts.h"
|
||||
#include "utf8.h"
|
||||
|
||||
#if !defined(SIMU)
|
||||
#define assert(x)
|
||||
#else
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#if !defined(BOOT)
|
||||
#include "edgetx.h"
|
||||
#endif
|
||||
|
||||
pixel_t displayBuf[DISPLAY_BUFFER_SIZE] __DMA;
|
||||
|
||||
coord_t lcdLastRightPos;
|
||||
coord_t lcdLastLeftPos;
|
||||
coord_t lcdNextPos;
|
||||
|
||||
void lcdFlushed() {}
|
||||
|
||||
void lcdClear()
|
||||
{
|
||||
memset(displayBuf, 0, DISPLAY_BUFFER_SIZE * sizeof(pixel_t));
|
||||
}
|
||||
|
||||
LcdFlags getCharPattern(PatternData * pattern, unsigned char c, LcdFlags flags)
|
||||
{
|
||||
#if !defined(BOOT)
|
||||
static const uint8_t fontWidth[] = { 5, 3, 5, 8, 10, 22, 5 };
|
||||
static const uint8_t fontHeight[] = { 7, 5, 6, 12, 16, 38, 7 };
|
||||
|
||||
uint32_t fontsize = FONTSIZE(flags);
|
||||
unsigned char c_remapped = 0;
|
||||
|
||||
if (fontsize == DBLSIZE || (flags & BOLD)) {
|
||||
// To save space only some DBLSIZE and BOLD chars are available
|
||||
// c has to be remapped. All non existing chars mapped to 0 (space)
|
||||
if (c >= ',' && c <= ':')
|
||||
c_remapped = c - ',' + 1;
|
||||
else if (c >= 'A' && c <= 'Z')
|
||||
c_remapped = c - 'A' + 16;
|
||||
else if (c >= 'a' && c <= 'z')
|
||||
c_remapped = c - 'a' + 42;
|
||||
else if (c == '_')
|
||||
c_remapped = 4;
|
||||
else if (c != ' ')
|
||||
flags &= ~BOLD; // For BOLD use Standard font if character is not in BOLD
|
||||
}
|
||||
|
||||
uint8_t fontIdx = fontsize >> 8;
|
||||
if (fontIdx == 0 && flags & BOLD) fontIdx = 6;
|
||||
|
||||
pattern->width = fontWidth[fontIdx];
|
||||
pattern->height = fontHeight[fontIdx];
|
||||
int charSize = (pattern->height + 7) / 8 * pattern->width;
|
||||
|
||||
switch (fontIdx) {
|
||||
case 0: // Standard
|
||||
pattern->data = &font_5x7[(c - FONT_BASE_START) * charSize];
|
||||
break;
|
||||
case 1: // TINSIZE
|
||||
pattern->data = &font_3x5[(c - FONT_BASE_START) * charSize];
|
||||
break;
|
||||
case 2: // SMLSIZE
|
||||
// Adjust language special characters offset
|
||||
if (c >= FONT_LANG_START)
|
||||
c = c - (FONT_SYMS_CNT - FONT_SYMS_CNT_4x6);
|
||||
pattern->data = &font_4x6[(c - FONT_BASE_START) * charSize];
|
||||
break;
|
||||
case 3: // MDLSIZE
|
||||
// Adjust language special characters offset
|
||||
if (c >= FONT_LANG_START)
|
||||
c = c - FONT_SYMS_CNT;
|
||||
pattern->data = &font_8x10[(c - FONT_BASE_START) * charSize];
|
||||
break;
|
||||
case 4: // DBLSIZE
|
||||
// Adjust language special characters offset and symbols offset
|
||||
if (c >= FONT_LANG_START)
|
||||
c_remapped = c - (FONT_BASE_CNT - FONT_BASE_CNT_10x14) - (FONT_SYMS_CNT - FONT_SYMS_CNT_10x14) - FONT_BASE_START;
|
||||
else if (c >= FONT_SYMS_START)
|
||||
c_remapped = c - (FONT_BASE_CNT - FONT_BASE_CNT_10x14) - FONT_BASE_START;
|
||||
pattern->data = &font_10x14[(c_remapped) * charSize];
|
||||
break;
|
||||
case 5: // XXLSIZE
|
||||
pattern->data = &font_22x38_num[(c - '0' + 5) * charSize];
|
||||
break;
|
||||
case 6: // BOLD
|
||||
pattern->data = &font_5x7_B[c_remapped * charSize];
|
||||
break;
|
||||
};
|
||||
#else
|
||||
pattern->width = 5;
|
||||
pattern->height = 7;
|
||||
pattern->data = &font_5x7[(c - FONT_BASE_START) * 5];
|
||||
#endif
|
||||
return flags;
|
||||
}
|
||||
|
||||
static uint8_t getPatternWidth(const PatternData * pattern)
|
||||
{
|
||||
uint8_t result = 0;
|
||||
uint8_t lines = (pattern->height+7)/8;
|
||||
const uint8_t * data = pattern->data;
|
||||
for (int8_t i=0; i<pattern->width; i++) {
|
||||
for (uint8_t j=0; j<lines; j++) {
|
||||
if (data[j] != 0xff) {
|
||||
result += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
data += lines;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t getCharWidth(char c, LcdFlags flags)
|
||||
{
|
||||
PatternData pattern;
|
||||
getCharPattern(&pattern, c, flags);
|
||||
return getPatternWidth(&pattern);
|
||||
}
|
||||
|
||||
uint8_t getTextWidth(const char * s, uint8_t len, LcdFlags flags)
|
||||
{
|
||||
uint8_t width = 0;
|
||||
for (int i = 0; len == 0 || i < len; ++i) {
|
||||
unsigned char c = map_utf8_char(s, len);
|
||||
if (!c) {
|
||||
break;
|
||||
}
|
||||
width += getCharWidth(c, flags) + 1;
|
||||
s++;
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
void lcdPutPattern(coord_t x, coord_t y, const uint8_t * pattern, uint8_t width, uint8_t height, LcdFlags flags)
|
||||
{
|
||||
bool blink = false;
|
||||
bool inv = false;
|
||||
if (flags & BLINK) {
|
||||
if (BLINK_ON_PHASE) {
|
||||
if (flags & INVERS)
|
||||
inv = true;
|
||||
else {
|
||||
blink = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (flags & INVERS) {
|
||||
inv = true;
|
||||
}
|
||||
|
||||
uint8_t lines = (height+7)/8;
|
||||
assert(lines <= 5);
|
||||
|
||||
for (int8_t i=0; i<width+2; i++) {
|
||||
if (x >= 0 && x < LCD_W) {
|
||||
uint8_t b[5] = { 0 };
|
||||
if (i==0) {
|
||||
if (x==0 || !inv) {
|
||||
lcdNextPos++;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
// we need to work on the previous x when INVERS
|
||||
x--;
|
||||
}
|
||||
}
|
||||
else if (i<=width) {
|
||||
uint8_t skip = true;
|
||||
for (uint8_t j=0; j<lines; j++) {
|
||||
b[j] = *(pattern++); /*top byte*/
|
||||
if (b[j] != 0xff) {
|
||||
skip = false;
|
||||
}
|
||||
}
|
||||
if (skip) {
|
||||
if (flags & FIXEDWIDTH) {
|
||||
for (uint8_t j=0; j<lines; j++) {
|
||||
b[j] = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((flags & CONDENSED) && i==2) {
|
||||
/*condense the letter by skipping column 3 */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for (int8_t j=-1; j<=height; j++) {
|
||||
bool plot;
|
||||
if (j < 0 || ((j == height) && !(FONTSIZE(flags) == SMLSIZE))) {
|
||||
plot = false;
|
||||
if (height >= 12) continue;
|
||||
if (j<0 && !inv) continue;
|
||||
if (y+j < 0) continue;
|
||||
}
|
||||
else {
|
||||
uint8_t line = (j / 8);
|
||||
uint8_t pixel = (j % 8);
|
||||
plot = b[line] & (1 << pixel);
|
||||
}
|
||||
if (inv) plot = !plot;
|
||||
if (!blink) {
|
||||
if (flags & VERTICAL)
|
||||
lcdDrawPoint(y+j, LCD_H-x, plot ? FORCE : ERASE);
|
||||
else
|
||||
lcdDrawPoint(x, y+j, plot ? FORCE : ERASE);
|
||||
}
|
||||
}
|
||||
}
|
||||
x++;
|
||||
lcdNextPos++;
|
||||
}
|
||||
}
|
||||
|
||||
void lcdDrawChar(coord_t x, coord_t y, uint8_t c, LcdFlags flags)
|
||||
{
|
||||
lcdNextPos = x - 1;
|
||||
PatternData pattern;
|
||||
flags = getCharPattern(&pattern, c, flags);
|
||||
lcdPutPattern(x, y, pattern.data, pattern.width, pattern.height, flags);
|
||||
}
|
||||
|
||||
void lcdDrawChar(coord_t x, coord_t y, uint8_t c)
|
||||
{
|
||||
lcdDrawChar(x, y, c, 0);
|
||||
}
|
||||
|
||||
void lcdDrawSizedText(coord_t x, coord_t y, const char * s, uint8_t len)
|
||||
{
|
||||
lcdDrawSizedText(x, y, s, len, 0);
|
||||
}
|
||||
|
||||
void lcdDrawText(coord_t x, coord_t y, const char * s, LcdFlags flags)
|
||||
{
|
||||
lcdDrawSizedText(x, y, s, 255, flags);
|
||||
}
|
||||
|
||||
void lcdDrawCenteredText(coord_t y, const char * s, LcdFlags flags)
|
||||
{
|
||||
coord_t x = (LCD_W - getTextWidth(s, flags)) / 2;
|
||||
lcdDrawText(x, y, s, flags);
|
||||
}
|
||||
|
||||
void lcdDrawText(coord_t x, coord_t y, const char * s)
|
||||
{
|
||||
lcdDrawText(x, y, s, 0);
|
||||
}
|
||||
|
||||
void lcdDrawTextAlignedLeft(coord_t y, const char * s)
|
||||
{
|
||||
lcdDrawText(0, y, s);
|
||||
}
|
||||
|
||||
void lcdDrawTextIndented(coord_t y, const char * s)
|
||||
{
|
||||
lcdDrawText(INDENT_WIDTH, y, s);
|
||||
}
|
||||
|
||||
#if !defined(BOOT)
|
||||
void lcdDrawTextAtIndex(coord_t x, coord_t y, const char *const *s,uint8_t idx, LcdFlags flags)
|
||||
{
|
||||
lcdDrawSizedText(x, y, s[idx], UINT8_MAX, flags);
|
||||
}
|
||||
|
||||
void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags flags)
|
||||
{
|
||||
lcdDrawNumber(x, y, val, flags, 0);
|
||||
}
|
||||
|
||||
void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags flags, uint8_t len)
|
||||
{
|
||||
char str[16+1];
|
||||
char *s = str+16;
|
||||
*s = '\0';
|
||||
int idx = 0;
|
||||
int mode = MODE(flags);
|
||||
bool neg = false;
|
||||
|
||||
if (val == INT_MAX) {
|
||||
flags &= ~(LEADING0 | PREC1 | PREC2);
|
||||
lcdDrawText(x, y, "INT_MAX", flags);
|
||||
return;
|
||||
}
|
||||
|
||||
if (val < 0) {
|
||||
if (val == INT_MIN) {
|
||||
flags &= ~(LEADING0 | PREC1 | PREC2);
|
||||
lcdDrawText(x, y, "INT_MIN", flags);
|
||||
return;
|
||||
}
|
||||
val = -val;
|
||||
neg = true;
|
||||
}
|
||||
do {
|
||||
*--s = '0' + (val % 10);
|
||||
++idx;
|
||||
val /= 10;
|
||||
if (mode!=0 && idx==mode) {
|
||||
mode = 0;
|
||||
*--s = '.';
|
||||
if (val==0) {
|
||||
*--s = '0';
|
||||
}
|
||||
}
|
||||
} while (val!=0 || mode>0 || (mode==MODE(LEADING0) && idx<len));
|
||||
if (neg) {
|
||||
*--s = '-';
|
||||
}
|
||||
flags &= ~(LEADING0 | PREC1 | PREC2);
|
||||
lcdDrawText(x, y, s, flags);
|
||||
}
|
||||
|
||||
void drawTimer(coord_t x, coord_t y, int32_t tme, LcdFlags att, LcdFlags att2)
|
||||
{
|
||||
div_t qr;
|
||||
if (IS_RIGHT_ALIGNED(att)) {
|
||||
att -= RIGHT;
|
||||
if (att & DBLSIZE)
|
||||
x -= 5*(2*FWNUM)-4;
|
||||
else if (att & MIDSIZE)
|
||||
x -= 5*8-8;
|
||||
else
|
||||
x -= 5*FWNUM+1;
|
||||
}
|
||||
|
||||
if (tme < 0) {
|
||||
lcdDrawChar(x - ((att & DBLSIZE) ? FW+2 : ((att & MIDSIZE) ? FW+0 : FWNUM)), y, '-', att);
|
||||
tme = -tme;
|
||||
}
|
||||
|
||||
qr = div((int)tme, 60);
|
||||
|
||||
constexpr char separator = ':';
|
||||
if (att & TIMEHOUR) {
|
||||
div_t qr2 = div(qr.quot, 60);
|
||||
if (qr2.quot < 100) {
|
||||
lcdDrawNumber(x, y, qr2.quot, att|LEADING0|LEFT, 2);
|
||||
}
|
||||
else {
|
||||
lcdDrawNumber(x, y, qr2.quot, att|LEFT);
|
||||
}
|
||||
lcdDrawChar(lcdNextPos, y, separator, att);
|
||||
qr.quot = qr2.rem;
|
||||
x = lcdNextPos;
|
||||
}
|
||||
|
||||
#if LCD_W < 212
|
||||
if (FONTSIZE(att) == MIDSIZE) {
|
||||
lcdLastRightPos--;
|
||||
}
|
||||
#endif
|
||||
|
||||
lcdDrawNumber(x, y, qr.quot, att|LEADING0|LEFT, 2);
|
||||
if (att & TIMEBLINK)
|
||||
lcdDrawChar(lcdLastRightPos, y, separator, BLINK);
|
||||
else
|
||||
lcdDrawChar(lcdLastRightPos, y, separator, att&att2);
|
||||
lcdDrawNumber(lcdNextPos, y, qr.rem, (att2|LEADING0|LEFT) & (~RIGHT), 2);
|
||||
}
|
||||
|
||||
// TODO to be optimized with drawValueWithUnit
|
||||
void putsVolts(coord_t x, coord_t y, uint16_t volts, LcdFlags att)
|
||||
{
|
||||
lcdDrawNumber(x, y, (int16_t)volts, (~NO_UNIT) & (att | ((att&PREC2)==PREC2 ? 0 : PREC1)));
|
||||
if (~att & NO_UNIT) lcdDrawChar(lcdLastRightPos, y, 'V', att);
|
||||
}
|
||||
|
||||
void putsVBat(coord_t x, coord_t y, LcdFlags att)
|
||||
{
|
||||
putsVolts(x, y, g_vbat100mV, att);
|
||||
}
|
||||
|
||||
void putsChn(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
|
||||
{
|
||||
drawStringWithIndex(x, y, STR_CH, idx, att);
|
||||
}
|
||||
|
||||
void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags att)
|
||||
{
|
||||
lcdDrawText(x, y, getAnalogShortLabel(idx), att);
|
||||
}
|
||||
|
||||
void drawModelName(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), att);
|
||||
}
|
||||
}
|
||||
|
||||
void drawSwitch(coord_t x, coord_t y, swsrc_t idx, LcdFlags flags, bool autoBold)
|
||||
{
|
||||
char s[8];
|
||||
getSwitchPositionName(s, idx);
|
||||
if (autoBold && idx != SWSRC_NONE && getSwitch(idx))
|
||||
flags |= BOLD;
|
||||
lcdDrawText(x, y, s, flags);
|
||||
}
|
||||
|
||||
void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att)
|
||||
{
|
||||
char s[8];
|
||||
getCurveString(s, idx);
|
||||
lcdDrawText(x, y, s, att);
|
||||
}
|
||||
|
||||
void drawTimerMode(coord_t x, coord_t y, swsrc_t mode, LcdFlags att)
|
||||
{
|
||||
if (mode >= 0) {
|
||||
if (mode < TMRMODE_COUNT)
|
||||
return lcdDrawTextAtIndex(x, y, STR_VTMRMODES, mode, att);
|
||||
else
|
||||
mode -= (TMRMODE_COUNT-1);
|
||||
}
|
||||
drawSwitch(x, y, mode, att);
|
||||
}
|
||||
|
||||
#if defined(RTCLOCK)
|
||||
void drawRtcTime(coord_t x, coord_t y, LcdFlags att)
|
||||
{
|
||||
drawTimer(x, y, getValue(MIXSRC_TX_TIME), att, att);
|
||||
}
|
||||
#endif
|
||||
|
||||
void lcdDrawFilledRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat, LcdFlags att)
|
||||
{
|
||||
for (coord_t i=y; i<y+h; i++) { // cast to coord_t needed otherwise (y+h) is promoted to int (see #5055)
|
||||
if ((att&ROUND) && (i==y || i==y+h-1))
|
||||
lcdDrawHorizontalLine(x+1, i, w-2, pat, att);
|
||||
else
|
||||
lcdDrawHorizontalLine(x, i, w, pat, att);
|
||||
pat = (pat >> 1) + ((pat & 1) << 7);
|
||||
}
|
||||
}
|
||||
|
||||
void lcdDrawLine(coord_t x1, coord_t y1, coord_t x2, coord_t y2, uint8_t pat, LcdFlags att)
|
||||
{
|
||||
int dx = x2-x1; /* the horizontal distance of the line */
|
||||
int dy = y2-y1; /* the vertical distance of the line */
|
||||
int dxabs = abs(dx);
|
||||
int dyabs = abs(dy);
|
||||
int sdx = sgn(dx);
|
||||
int sdy = sgn(dy);
|
||||
int x = dyabs>>1;
|
||||
int y = dxabs>>1;
|
||||
int px = x1;
|
||||
int py = y1;
|
||||
|
||||
if (dxabs >= dyabs) {
|
||||
/* the line is more horizontal than vertical */
|
||||
for (int i=0; i<=dxabs; i++) {
|
||||
if ((1<<(px%8)) & pat) {
|
||||
lcdDrawPoint(px, py, att);
|
||||
}
|
||||
y += dyabs;
|
||||
if (y>=dxabs) {
|
||||
y -= dxabs;
|
||||
py += sdy;
|
||||
}
|
||||
px += sdx;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* the line is more vertical than horizontal */
|
||||
for (int i=0; i<=dyabs; i++) {
|
||||
if ((1<<(py%8)) & pat) {
|
||||
lcdDrawPoint(px, py, att);
|
||||
}
|
||||
x += dxabs;
|
||||
if (x >= dyabs) {
|
||||
x -= dyabs;
|
||||
px += sdx;
|
||||
}
|
||||
py += sdy;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // !BOOT
|
||||
|
||||
void lcdDrawSolidVerticalLine(coord_t x, coord_t y, coord_t h, LcdFlags att)
|
||||
{
|
||||
lcdDrawVerticalLine(x, y, h, SOLID, att);
|
||||
}
|
||||
|
||||
void lcdDrawRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat, LcdFlags att)
|
||||
{
|
||||
lcdDrawVerticalLine(x, y, h, pat, att);
|
||||
lcdDrawVerticalLine(x+w-1, y, h, pat, att);
|
||||
if (~att & ROUND) { x+=1; w-=2; }
|
||||
lcdDrawHorizontalLine(x, y+h-1, w, pat, att);
|
||||
lcdDrawHorizontalLine(x, y, w, pat, att);
|
||||
}
|
||||
|
||||
void lcdDrawSolidHorizontalLine(coord_t x, coord_t y, coord_t w, LcdFlags att)
|
||||
{
|
||||
if (w < 0) { x += w; w = -w; }
|
||||
lcdDrawHorizontalLine(x, y, w, 0xff, att);
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define OFS_CHECKTRIMS CENTER_OFS+(9*FW)
|
||||
#define INDENT_WIDTH (FW/2)
|
||||
|
||||
#define FW 6
|
||||
#define FWNUM 5
|
||||
#define FH 8
|
||||
|
||||
#define LCD_LINES (LCD_H/FH)
|
||||
#define LCD_COLS (LCD_W/FW)
|
||||
|
||||
#define NUM_BODY_LINES (LCD_LINES-1)
|
||||
#define TEXT_VIEWER_LINES NUM_BODY_LINES
|
||||
#define MENU_HEADER_HEIGHT FH
|
||||
|
||||
#define CURVE_SIDE_WIDTH (LCD_H/2-2)
|
||||
#define CURVE_CENTER_X (LCD_W-CURVE_SIDE_WIDTH-3)
|
||||
#define CURVE_CENTER_Y (LCD_H/2)
|
||||
|
||||
/* lcdDrawText flags */
|
||||
#define BLINK 0x01
|
||||
#define INVERS 0x02
|
||||
#define BOLD 0x40
|
||||
#define LEFT 0x00
|
||||
#define RIGHT 0x04
|
||||
#define CENTERED 0x20
|
||||
#define CONDENSED 0x08
|
||||
#define FIXEDWIDTH 0x10
|
||||
/* no 0x80 here because of "GV"1 which is aligned LEFT */
|
||||
/* no 0x10 here because of "MODEL"01 which uses LEADING0 */
|
||||
|
||||
/* lcdDrawNumber additional flags */
|
||||
#define LEADING0 0x10
|
||||
#define PREC1 0x20
|
||||
#define PREC2 0x30
|
||||
#define MODE(flags) ((((int8_t)(flags) & 0x30) - 0x10) >> 4)
|
||||
|
||||
#define IS_LEFT_ALIGNED(att) !((att) & RIGHT)
|
||||
#define IS_RIGHT_ALIGNED(att) (!IS_LEFT_ALIGNED(att))
|
||||
|
||||
/* line, rect, square flags */
|
||||
#define FORCE 0x02
|
||||
#define ERASE 0x04
|
||||
#define ROUND 0x08
|
||||
#define FILL_WHITE 0x10
|
||||
|
||||
/* telemetry flags */
|
||||
#define NO_UNIT 0x40
|
||||
|
||||
#define FONTSIZE_MASK 0x0700
|
||||
#define FONTSIZE(x) ((x) & FONTSIZE_MASK)
|
||||
#define TINSIZE 0x0100
|
||||
#define SMLSIZE 0x0200
|
||||
#define MIDSIZE 0x0300
|
||||
#define DBLSIZE 0x0400
|
||||
#define XXLSIZE 0x0500
|
||||
#define ERASEBG 0x8000
|
||||
#define VERTICAL 0x0800
|
||||
|
||||
#define TIMEBLINK 0x1000
|
||||
#define TIMEHOUR 0x2000
|
||||
#define STREXPANDED 0x4000
|
||||
|
||||
extern pixel_t displayBuf[DISPLAY_BUFFER_SIZE];
|
||||
extern coord_t lcdLastRightPos;
|
||||
extern coord_t lcdLastLeftPos;
|
||||
extern coord_t lcdNextPos;
|
||||
|
||||
#define DISPLAY_END (displayBuf + DISPLAY_BUFFER_SIZE)
|
||||
#define IS_IN_DISPLAY(p) ((p) >= displayBuf && (p) < DISPLAY_END)
|
||||
#define ASSERT_IN_DISPLAY(p) assert((p) >= displayBuf && (p) < DISPLAY_END)
|
||||
|
||||
#define SOLID 0xff
|
||||
#define DOTTED 0x55
|
||||
|
||||
#if defined(BOOT)
|
||||
#define BLINK_ON_PHASE (0)
|
||||
#else
|
||||
#define SLOW_BLINK_ON_PHASE (g_blinkTmr10ms & (1<<7))
|
||||
#define BLINK_ON_PHASE (g_blinkTmr10ms & (1<<6))
|
||||
#define FAST_BLINK_ON_PHASE (g_blinkTmr10ms & (1<<4))
|
||||
#endif
|
||||
|
||||
struct PatternData
|
||||
{
|
||||
uint8_t width;
|
||||
uint8_t height;
|
||||
const uint8_t * data;
|
||||
};
|
||||
|
||||
void lcdClear();
|
||||
|
||||
void lcdDrawChar(coord_t x, coord_t y, uint8_t c);
|
||||
void lcdDrawChar(coord_t x, coord_t y, uint8_t c, LcdFlags flags);
|
||||
void lcdDrawCenteredText(coord_t y, const char * s, LcdFlags flags = 0);
|
||||
void lcdDrawText(coord_t x, coord_t y, const char * s, LcdFlags flags);
|
||||
void lcdDrawTextAtIndex(coord_t x, coord_t y, const char *const *s, uint8_t idx, LcdFlags flags);
|
||||
void lcdDrawSizedText(coord_t x, coord_t y, const char * s, unsigned char len, LcdFlags flags);
|
||||
void lcdDrawText(coord_t x, coord_t y, const char * s);
|
||||
void lcdDrawSizedText(coord_t x, coord_t y, const char * s, unsigned char len);
|
||||
void lcdDrawTextAlignedLeft(coord_t y, const char * s);
|
||||
void lcdDrawTextIndented(coord_t y, const char * s);
|
||||
|
||||
void lcdDrawHexNumber(coord_t x, coord_t y, uint32_t val, LcdFlags mode=0);
|
||||
|
||||
void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags mode, uint8_t len);
|
||||
void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags mode=0);
|
||||
|
||||
void drawModelName(coord_t x, coord_t y, char * name, uint8_t id, LcdFlags att);
|
||||
void drawSwitch(coord_t x, coord_t y, swsrc_t swtch, LcdFlags att=0, bool autoBold = true);
|
||||
void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att=0);
|
||||
void drawTimerMode(coord_t x, coord_t y, swsrc_t mode, LcdFlags att=0);
|
||||
|
||||
void putsChn(coord_t x, coord_t y, uint8_t idx, LcdFlags attr);
|
||||
void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags attr);
|
||||
|
||||
void putsVolts(coord_t x, coord_t y, uint16_t volts, LcdFlags att);
|
||||
void putsVBat(coord_t x, coord_t y, LcdFlags att);
|
||||
|
||||
void lcdDrawPoint(coord_t x, coord_t y, LcdFlags att=0);
|
||||
void lcdMaskPoint(uint8_t *p, uint8_t mask, LcdFlags att=0);
|
||||
void lcdDrawSolidHorizontalLine(coord_t x, coord_t y, coord_t w, LcdFlags att=0);
|
||||
void lcdDrawHorizontalLine(coord_t x, coord_t y, coord_t w, uint8_t pat, LcdFlags att=0);
|
||||
void lcdDrawSolidVerticalLine(coord_t x, coord_t y, coord_t h, LcdFlags att=0);
|
||||
void lcdDrawVerticalLine(coord_t x, coord_t y, coord_t h, uint8_t pat, LcdFlags att=0);
|
||||
void lcdDrawLine(coord_t x1, coord_t y1, coord_t x2, coord_t y2, uint8_t pat=SOLID, LcdFlags att=0);
|
||||
|
||||
void lcdDrawFilledRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat=SOLID, LcdFlags att=0);
|
||||
void lcdDrawRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat=SOLID, LcdFlags att=0);
|
||||
|
||||
inline void lcdDrawSolidFilledRect(coord_t x, coord_t y, coord_t w, coord_t h, LcdFlags att=0)
|
||||
{
|
||||
lcdDrawFilledRect(x, y, w, h, SOLID, att);
|
||||
}
|
||||
|
||||
inline void lcdDrawSquare(coord_t x, coord_t y, coord_t w, LcdFlags att=0)
|
||||
{
|
||||
lcdDrawRect(x, y, w, w, SOLID, att);
|
||||
}
|
||||
|
||||
void lcdInvertLine(int8_t line);
|
||||
#define lcdInvertLastLine() lcdInvertLine(LCD_LINES-1)
|
||||
|
||||
void drawTelemetryTopBar();
|
||||
|
||||
#define V_BAR(xx, yy, ll) \
|
||||
lcdDrawSolidVerticalLine(xx-1,yy-ll,ll); \
|
||||
lcdDrawSolidVerticalLine(xx ,yy-ll,ll); \
|
||||
lcdDrawSolidVerticalLine(xx+1,yy-ll,ll)
|
||||
|
||||
void lcdDraw1bitBitmap(coord_t x, coord_t y, const unsigned char * img, uint8_t idx, LcdFlags att=0);
|
||||
|
||||
uint8_t getTextWidth(const char * s, uint8_t len=0, LcdFlags flags=0);
|
||||
@@ -34,7 +34,7 @@ const MenuHandler menuTabModel[] = {
|
||||
{ menuModelMixAll, nullptr },
|
||||
{ menuModelLimits, nullptr },
|
||||
{ menuModelCurvesAll, modelCurvesEnabled },
|
||||
#if defined(GVARS) && defined(FLIGHT_MODES)
|
||||
#if defined(GVARS) && defined(FLIGHT_MODES) && (LCD_W >= 212)
|
||||
{ menuModelGVars, modelGVEnabled },
|
||||
#endif
|
||||
{ menuModelLogicalSwitches, modelLSEnabled },
|
||||
@@ -46,16 +46,6 @@ const MenuHandler menuTabModel[] = {
|
||||
{ menuModelDisplay, nullptr }
|
||||
};
|
||||
|
||||
uint8_t editDelay(coord_t y, event_t event, uint8_t attr, const char * str, uint8_t delay, uint8_t prec)
|
||||
{
|
||||
lcdDrawTextAlignedLeft(y, str);
|
||||
lcdDrawNumber(MIXES_2ND_COLUMN, y, delay, attr|prec|LEFT);
|
||||
if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, delay, DELAY_MAX);
|
||||
return delay;
|
||||
}
|
||||
|
||||
#define COPY_MODE 1
|
||||
#define MOVE_MODE 2
|
||||
uint8_t s_copyMode = 0;
|
||||
int8_t s_copySrcRow;
|
||||
int8_t s_copyTgtOfs;
|
||||
@@ -63,15 +53,6 @@ uint8_t s_maxLines = 8;
|
||||
uint8_t s_copySrcIdx;
|
||||
uint8_t s_copySrcCh;
|
||||
|
||||
uint8_t editNameCursorPos = 0;
|
||||
|
||||
void editSingleName(coord_t x, coord_t y, const char * label, char *name, uint8_t size, event_t event, uint8_t active, uint8_t old_editMode, coord_t lblX)
|
||||
{
|
||||
lcdDrawText(lblX, y, label);
|
||||
TRACE("EDIT SINGLE NAME %s", name);
|
||||
editName(x, y, name, size, event, active, 0, old_editMode);
|
||||
}
|
||||
|
||||
uint8_t s_currIdx;
|
||||
uint8_t s_currIdxSubMenu;
|
||||
mixsrc_t s_currSrcRaw;
|
||||
@@ -42,8 +42,8 @@ void menuRadioSpecialFunctions(event_t event)
|
||||
}
|
||||
#endif
|
||||
|
||||
MENU(STR_MENUSPECIALFUNCS, menuTabGeneral, MENU_RADIO_SPECIAL_FUNCTIONS, HEADER_LINE+MAX_SPECIAL_FUNCTIONS, { HEADER_LINE_COLUMNS NAVIGATION_LINE_BY_LINE|5/*repeated*/ });
|
||||
|
||||
MENU(STR_MENUSPECIALFUNCS, menuTabGeneral, MENU_RADIO_SPECIAL_FUNCTIONS,
|
||||
HEADER_LINE+MAX_SPECIAL_FUNCTIONS, { HEADER_LINE_COLUMNS NAVIGATION_LINE_BY_LINE|5/*repeated*/ });
|
||||
menuSpecialFunctions(event, g_eeGeneral.customFn, &globalFunctionsContext);
|
||||
|
||||
#if defined(NAVIGATION_X7)
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "edgetx_types.h"
|
||||
|
||||
typedef int8_t horzpos_t;
|
||||
typedef uint16_t vertpos_t;
|
||||
|
||||
typedef void (* MenuHandlerFunc)(event_t event);
|
||||
typedef bool (* MenuEnabledFunc)();
|
||||
|
||||
typedef struct _MenuHandler {
|
||||
MenuHandlerFunc menuFunc;
|
||||
MenuEnabledFunc enabledFunc;
|
||||
|
||||
bool isEnabled() const
|
||||
{
|
||||
if (enabledFunc)
|
||||
return enabledFunc();
|
||||
return true;
|
||||
}
|
||||
} MenuHandler;
|
||||
|
||||
extern tmr10ms_t menuEntryTime;
|
||||
extern vertpos_t menuVerticalPosition;
|
||||
extern horzpos_t menuHorizontalPosition;
|
||||
extern vertpos_t menuVerticalOffset;
|
||||
extern uint8_t menuCalibrationState;
|
||||
extern MenuHandlerFunc menuHandlers[5];
|
||||
extern uint8_t menuVerticalPositions[4];
|
||||
extern uint8_t menuVerticalOffsets[4];
|
||||
extern uint8_t menuLevel;
|
||||
extern event_t menuEvent;
|
||||
|
||||
void chainMenu(MenuHandlerFunc newMenu);
|
||||
void pushMenu(MenuHandlerFunc newMenu);
|
||||
void popMenu();
|
||||
void abortPopMenu();
|
||||
|
||||
inline MenuHandlerFunc lastPopMenu()
|
||||
{
|
||||
return menuHandlers[menuLevel + 1];
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "edgetx_types.h"
|
||||
#include "keys.h"
|
||||
#include "feature_control.h"
|
||||
|
||||
#define COPY_MODE 1
|
||||
#define MOVE_MODE 2
|
||||
#define EDIT_MODE_INIT 0
|
||||
|
||||
typedef int8_t horzpos_t;
|
||||
typedef uint16_t vertpos_t;
|
||||
|
||||
typedef void (* MenuHandlerFunc)(event_t event);
|
||||
typedef bool (* MenuEnabledFunc)();
|
||||
|
||||
typedef struct _MenuHandler {
|
||||
MenuHandlerFunc menuFunc;
|
||||
MenuEnabledFunc enabledFunc;
|
||||
|
||||
bool isEnabled() const
|
||||
{
|
||||
if (enabledFunc)
|
||||
return enabledFunc();
|
||||
return true;
|
||||
}
|
||||
} MenuHandler;
|
||||
|
||||
extern tmr10ms_t menuEntryTime;
|
||||
extern vertpos_t menuVerticalPosition;
|
||||
extern horzpos_t menuHorizontalPosition;
|
||||
extern vertpos_t menuVerticalOffset;
|
||||
extern uint8_t menuCalibrationState;
|
||||
extern MenuHandlerFunc menuHandlers[5];
|
||||
extern uint8_t menuVerticalPositions[4];
|
||||
extern uint8_t menuVerticalOffsets[4];
|
||||
extern uint8_t menuLevel;
|
||||
extern event_t menuEvent;
|
||||
|
||||
void chainMenu(MenuHandlerFunc newMenu);
|
||||
void pushMenu(MenuHandlerFunc newMenu);
|
||||
void popMenu();
|
||||
void abortPopMenu();
|
||||
|
||||
inline MenuHandlerFunc lastPopMenu()
|
||||
{
|
||||
return menuHandlers[menuLevel + 1];
|
||||
}
|
||||
|
||||
inline bool isRadioMenuDisplayed()
|
||||
{
|
||||
return menuVerticalPositions[0] == 1;
|
||||
}
|
||||
|
||||
inline bool isModelMenuDisplayed()
|
||||
{
|
||||
return menuVerticalPositions[0] == 0;
|
||||
}
|
||||
|
||||
void onMainViewMenu(const char * result);
|
||||
void menuFirstCalib(event_t event);
|
||||
void menuChannelsViewCommon(event_t event);
|
||||
void menuChannelsView(event_t event);
|
||||
void menuMainView(event_t event);
|
||||
void menuViewTelemetry(event_t event);
|
||||
void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomFunctionsContext * functionsContext);
|
||||
void menuStatisticsView(event_t event);
|
||||
void menuStatisticsDebug(event_t event);
|
||||
void menuStatisticsDebug2(event_t event);
|
||||
void menuAboutView(event_t event);
|
||||
|
||||
enum MenuRadioIndexes
|
||||
{
|
||||
#if defined(RADIO_TOOLS)
|
||||
MENU_RADIO_TOOLS,
|
||||
#endif
|
||||
MENU_RADIO_SD_MANAGER,
|
||||
MENU_RADIO_SETUP,
|
||||
MENU_RADIO_SPECIAL_FUNCTIONS,
|
||||
MENU_RADIO_TRAINER,
|
||||
MENU_RADIO_HARDWARE,
|
||||
MENU_RADIO_VERSION,
|
||||
MENU_RADIO_PAGES_COUNT
|
||||
};
|
||||
|
||||
enum MenuModelIndexes {
|
||||
MENU_MODEL_SELECT,
|
||||
MENU_MODEL_SETUP,
|
||||
CASE_HELI(MENU_MODEL_HELI)
|
||||
CASE_FLIGHT_MODES(MENU_MODEL_FLIGHT_MODES)
|
||||
MENU_MODEL_INPUTS,
|
||||
MENU_MODEL_MIXES,
|
||||
MENU_MODEL_OUTPUTS,
|
||||
MENU_MODEL_CURVES,
|
||||
#if LCD_W >= 212
|
||||
CASE_GVARS(MENU_MODEL_GVARS)
|
||||
#endif
|
||||
MENU_MODEL_LOGICAL_SWITCHES,
|
||||
MENU_MODEL_SPECIAL_FUNCTIONS,
|
||||
#if defined(LUA_MODEL_SCRIPTS)
|
||||
MENU_MODEL_CUSTOM_SCRIPTS,
|
||||
#endif
|
||||
MENU_MODEL_TELEMETRY,
|
||||
MENU_MODEL_DISPLAY,
|
||||
MENU_MODEL_PAGES_COUNT
|
||||
};
|
||||
|
||||
void menuRadioSetup(event_t event);
|
||||
void menuRadioSdManager(event_t event);
|
||||
void menuRadioSpecialFunctions(event_t event);
|
||||
void menuRadioTrainer(event_t event);
|
||||
void menuRadioVersion(event_t event);
|
||||
void menuRadioDiagKeys(event_t event);
|
||||
void menuRadioDiagAnalogs(event_t event);
|
||||
void menuRadioDiagFS(event_t event);
|
||||
void menuRadioHardware(event_t event);
|
||||
void menuRadioTools(event_t event);
|
||||
void menuRadioSpectrumAnalyser(event_t event);
|
||||
void menuRadioPowerMeter(event_t event);
|
||||
void menuRadioCalibration(event_t event);
|
||||
void menuGhostModuleConfig(event_t event);
|
||||
|
||||
void menuModelSelect(event_t event);
|
||||
void menuModelSetup(event_t event);
|
||||
void menuModelFailsafe(event_t event);
|
||||
void menuModelModuleOptions(event_t event);
|
||||
void menuModelReceiverOptions(event_t event);
|
||||
void menuModelHeli(event_t event);
|
||||
void menuModelFlightModesAll(event_t event);
|
||||
void menuModelExpoOne(event_t event);
|
||||
void menuModelExposAll(event_t event);
|
||||
void menuModelMixOne(event_t event);
|
||||
void menuModelMixAll(event_t event);
|
||||
void menuModelLimits(event_t event);
|
||||
void menuModelCurvesAll(event_t event);
|
||||
void menuModelCurveOne(event_t event);
|
||||
void menuModelLogicalSwitches(event_t event);
|
||||
void menuModelSpecialFunctions(event_t event);
|
||||
void menuModelCustomScripts(event_t event);
|
||||
void menuModelTelemetry(event_t event);
|
||||
void menuModelSensor(event_t event);
|
||||
void menuModelDisplay(event_t event);
|
||||
#if defined(USBJ_EX)
|
||||
void menuModelUSBJoystick(event_t event);
|
||||
#endif
|
||||
|
||||
extern const MenuHandler menuTabGeneral[MENU_RADIO_PAGES_COUNT];
|
||||
extern const MenuHandler menuTabModel[MENU_MODEL_PAGES_COUNT];
|
||||
|
||||
extern const unsigned char sticks[];
|
||||
|
||||
extern uint8_t s_copyMode;
|
||||
extern int8_t s_copySrcRow;
|
||||
extern int8_t s_copyTgtOfs;
|
||||
extern uint8_t s_currIdx;
|
||||
extern uint8_t s_currIdxSubMenu;
|
||||
extern mixsrc_t s_currSrcRaw;
|
||||
extern uint16_t s_currScale;
|
||||
extern uint8_t s_copySrcIdx;
|
||||
extern uint8_t s_copySrcCh;
|
||||
extern int8_t s_currCh;
|
||||
extern uint8_t s_maxLines;
|
||||
|
||||
// Temporary no highlight
|
||||
extern uint8_t noHighlightCounter;
|
||||
#define NO_HIGHLIGHT() (noHighlightCounter > 0)
|
||||
#define START_NO_HIGHLIGHT() do { noHighlightCounter = 25; } while(0)
|
||||
|
||||
void menuTextView(event_t event);
|
||||
void pushMenuTextView(const char *filename);
|
||||
void pushModelNotes();
|
||||
void readModelNotes();
|
||||
|
||||
uint8_t getExposCount();
|
||||
void insertExpo(uint8_t idx);
|
||||
void deleteExpo(uint8_t idx);
|
||||
|
||||
uint8_t switchToMix(uint8_t source);
|
||||
|
||||
void drawSplash();
|
||||
void doMainScreenGraphics();
|
||||
void drawAlertBox(const char * title, const char * text, const char * action);
|
||||
|
||||
#if defined(FLIGHT_MODES)
|
||||
void displayFlightModes(coord_t x, coord_t y, FlightModesType value);
|
||||
FlightModesType editFlightModes(coord_t x, coord_t y, event_t event, FlightModesType value, uint8_t attr);
|
||||
#else
|
||||
#define displayFlightModes(...)
|
||||
#endif
|
||||
|
||||
#define IS_MAIN_VIEW_DISPLAYED() menuHandlers[0] == menuMainView
|
||||
#define IS_TELEMETRY_VIEW_DISPLAYED() menuHandlers[0] == menuViewTelemetry
|
||||
@@ -39,14 +39,28 @@ enum MenuModelHeliItems {
|
||||
#define MODEL_HELI_2ND_COLUMN (14*FW)
|
||||
#endif
|
||||
|
||||
static int numberField(const char* name, coord_t y, int val, int min, LcdFlags attr, event_t event)
|
||||
{
|
||||
return editNumberField(name, INDENT_WIDTH, MODEL_HELI_2ND_COLUMN, y, val, min, 100, attr, event);
|
||||
}
|
||||
|
||||
static uint8_t sourceField(const char* name, coord_t y, uint8_t val, LcdFlags attr, event_t event)
|
||||
{
|
||||
lcdDrawTextAlignedLeft(y, name);
|
||||
drawSource(MODEL_HELI_2ND_COLUMN, y, val, attr);
|
||||
if (attr) CHECK_INCDEC_MODELSOURCE(event, val, 0, MIXSRC_LAST_CH);
|
||||
return val;
|
||||
}
|
||||
|
||||
void menuModelHeli(event_t event)
|
||||
{
|
||||
SIMPLE_MENU(STR_MENUHELISETUP, menuTabModel, MENU_MODEL_HELI, HEADER_LINE+ITEM_HELI_MAX);
|
||||
|
||||
uint8_t sub = menuVerticalPosition - HEADER_LINE;
|
||||
|
||||
coord_t y = MENU_HEADER_HEIGHT + 1;
|
||||
|
||||
for (uint8_t i=0; i<NUM_BODY_LINES; i++) {
|
||||
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;
|
||||
uint8_t k = i + menuVerticalOffset;
|
||||
LcdFlags blink = (s_editMode > 0 ? BLINK|INVERS : INVERS);
|
||||
LcdFlags attr = (sub == k ? blink : 0);
|
||||
@@ -57,46 +71,34 @@ void menuModelHeli(event_t event)
|
||||
break;
|
||||
|
||||
case ITEM_HELI_SWASHRING:
|
||||
lcdDrawTextAlignedLeft(y, STR_SWASHRING);
|
||||
lcdDrawNumber(MODEL_HELI_2ND_COLUMN, y, g_model.swashR.value, LEFT|attr);
|
||||
if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, g_model.swashR.value, 100);
|
||||
g_model.swashR.value = numberField(STR_SWASHRING, y, g_model.swashR.value, 0, attr, event);
|
||||
break;
|
||||
|
||||
case ITEM_HELI_ELE:
|
||||
lcdDrawTextAlignedLeft(y, STR_ELEVATOR);
|
||||
drawSource(MODEL_HELI_2ND_COLUMN, y, g_model.swashR.elevatorSource, attr);
|
||||
if (attr) CHECK_INCDEC_MODELSOURCE(event, g_model.swashR.elevatorSource, 0, MIXSRC_LAST_CH);
|
||||
g_model.swashR.elevatorSource = sourceField(STR_ELEVATOR, y, g_model.swashR.elevatorSource, attr, event);
|
||||
break;
|
||||
|
||||
case ITEM_HELI_ELE_WEIGHT:
|
||||
lcdDrawTextIndented(y, STR_WEIGHT);
|
||||
lcdDrawNumber(MODEL_HELI_2ND_COLUMN, y, g_model.swashR.elevatorWeight, LEFT|attr);
|
||||
if (attr) CHECK_INCDEC_MODELVAR(event, g_model.swashR.elevatorWeight, -100, 100);
|
||||
g_model.swashR.elevatorWeight = numberField(STR_WEIGHT, y, g_model.swashR.elevatorWeight, -100, attr, event);
|
||||
break;
|
||||
|
||||
case ITEM_HELI_AIL:
|
||||
lcdDrawTextAlignedLeft(y, STR_AILERON);
|
||||
drawSource(MODEL_HELI_2ND_COLUMN, y, g_model.swashR.aileronSource, attr);
|
||||
if (attr) CHECK_INCDEC_MODELSOURCE(event, g_model.swashR.aileronSource, 0, MIXSRC_LAST_CH);
|
||||
g_model.swashR.aileronSource = sourceField(STR_AILERON, y, g_model.swashR.aileronSource, attr, event);
|
||||
break;
|
||||
|
||||
case ITEM_HELI_AIL_WEIGHT:
|
||||
lcdDrawTextIndented(y, STR_WEIGHT);
|
||||
lcdDrawNumber(MODEL_HELI_2ND_COLUMN, y, g_model.swashR.aileronWeight, LEFT|attr);
|
||||
if (attr) CHECK_INCDEC_MODELVAR(event, g_model.swashR.aileronWeight, -100, 100);
|
||||
g_model.swashR.aileronWeight = numberField(STR_WEIGHT, y, g_model.swashR.aileronWeight, -100, attr, event);
|
||||
break;
|
||||
|
||||
case ITEM_HELI_COL:
|
||||
lcdDrawTextAlignedLeft(y, STR_COLLECTIVE);
|
||||
drawSource(MODEL_HELI_2ND_COLUMN, y, g_model.swashR.collectiveSource, attr);
|
||||
if (attr) CHECK_INCDEC_MODELSOURCE(event, g_model.swashR.collectiveSource, 0, MIXSRC_LAST_CH);
|
||||
g_model.swashR.collectiveSource = sourceField(STR_COLLECTIVE, y, g_model.swashR.collectiveSource, attr, event);
|
||||
break;
|
||||
|
||||
case ITEM_HELI_COL_WEIGHT:
|
||||
lcdDrawTextIndented(y, STR_WEIGHT);
|
||||
lcdDrawNumber(MODEL_HELI_2ND_COLUMN, y, g_model.swashR.collectiveWeight, LEFT|attr);
|
||||
if (attr) CHECK_INCDEC_MODELVAR(event, g_model.swashR.collectiveWeight, -100, 100);
|
||||
g_model.swashR.collectiveWeight = numberField(STR_WEIGHT, y, g_model.swashR.collectiveWeight, -100, attr, event);
|
||||
break;
|
||||
}
|
||||
|
||||
y += FH;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "edgetx.h"
|
||||
|
||||
void menuModelNotes(event_t event)
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include "edgetx.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
const char * warningText = nullptr;
|
||||
const char * warningInfoText;
|
||||
@@ -26,6 +26,25 @@
|
||||
#include "lcd.h"
|
||||
#include "keys.h"
|
||||
|
||||
#define POPUP_MENU_MAX_LINES 13
|
||||
#define MENU_MAX_DISPLAY_LINES 6
|
||||
#define MENU_LINE_LENGTH (LEN_MODEL_NAME+12)
|
||||
|
||||
enum {
|
||||
MENU_OFFSET_INTERNAL,
|
||||
MENU_OFFSET_EXTERNAL
|
||||
};
|
||||
|
||||
enum WarningType
|
||||
{
|
||||
WARNING_TYPE_WAIT,
|
||||
WARNING_TYPE_INFO,
|
||||
WARNING_TYPE_ASTERISK,
|
||||
WARNING_TYPE_CONFIRM,
|
||||
WARNING_TYPE_INPUT,
|
||||
WARNING_TYPE_ALERT
|
||||
};
|
||||
|
||||
extern const char * warningText;
|
||||
extern const char * warningInfoText;
|
||||
extern uint8_t warningInfoLength;
|
||||
@@ -61,16 +80,6 @@ void showAlertBox(const char * title, const char * text, const char * action , u
|
||||
void drawProgressScreen(const char * title, const char * message, int num, int den);
|
||||
typedef void (* ProgressHandler)(const char *, const char *, int, int);
|
||||
|
||||
enum WarningType
|
||||
{
|
||||
WARNING_TYPE_WAIT,
|
||||
WARNING_TYPE_INFO,
|
||||
WARNING_TYPE_ASTERISK,
|
||||
WARNING_TYPE_CONFIRM,
|
||||
WARNING_TYPE_INPUT,
|
||||
WARNING_TYPE_ALERT
|
||||
};
|
||||
|
||||
#if !defined(GUI)
|
||||
#define DISPLAY_WARNING(...)
|
||||
inline void POPUP_WAIT(const char * s) { }
|
||||
|
||||
@@ -367,6 +367,13 @@ static void _init_menu_tab_array(uint8_t* tab, size_t len)
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool editInversion(bool state, event_t event, coord_t y, LcdFlags flags)
|
||||
{
|
||||
lcdDrawChar(LCD_W - 8, y, state ? 127 : 126, flags);
|
||||
if (flags & (~RIGHT)) state = checkIncDec(event, state, 0, 1, EE_GENERAL);
|
||||
return state;
|
||||
}
|
||||
|
||||
void menuRadioHardware(event_t event)
|
||||
{
|
||||
uint8_t old_editMode = s_editMode;
|
||||
@@ -634,15 +641,10 @@ void menuRadioHardware(event_t event)
|
||||
// Sticks
|
||||
int idx = k - ITEM_RADIO_HARDWARE_STICK;
|
||||
|
||||
LcdFlags flags = menuHorizontalPosition == 0 ? attr : 0;
|
||||
editStickHardwareSettings(HW_SETTINGS_COLUMN1, y,
|
||||
idx, event, flags, old_editMode);
|
||||
editStickHardwareSettings(HW_SETTINGS_COLUMN1, y, idx, event,
|
||||
menuHorizontalPosition == 0 ? attr : 0, old_editMode);
|
||||
// ADC inversion
|
||||
flags = menuHorizontalPosition == 1 ? attr : 0;
|
||||
bool stickinversion = getStickInversion(idx);
|
||||
lcdDrawChar(LCD_W - 8, y, stickinversion ? 127 : 126, flags);
|
||||
if (flags & (~RIGHT)) stickinversion = checkIncDec(event, stickinversion, 0, 1, EE_GENERAL);
|
||||
setStickInversion(idx, stickinversion);
|
||||
setStickInversion(idx, editInversion(getStickInversion(idx), event, y, menuHorizontalPosition == 1 ? attr : 0));
|
||||
|
||||
} else if (k <= ITEM_RADIO_HARDWARE_POT_END) {
|
||||
// Pots & sliders
|
||||
@@ -673,11 +675,7 @@ void menuRadioHardware(event_t event)
|
||||
|
||||
if (!IS_POT_MULTIPOS(idx)) {
|
||||
// ADC inversion
|
||||
flags = menuHorizontalPosition == 2 ? attr : 0;
|
||||
bool potinversion = getPotInversion(idx);
|
||||
lcdDrawChar(LCD_W - 8, y, potinversion ? 127 : 126, flags);
|
||||
if (flags & (~RIGHT)) potinversion = checkIncDec(event, potinversion, 0, 1, EE_GENERAL);
|
||||
setPotInversion(idx, potinversion);
|
||||
setPotInversion(idx, editInversion(getPotInversion(idx), event, y, menuHorizontalPosition == 2 ? attr : 0));
|
||||
} else if (getPotInversion(idx)) {
|
||||
setPotInversion(idx, 0);
|
||||
storageDirty(EE_GENERAL);
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 "edgetx.h"
|
||||
|
||||
choice_t editChoice(coord_t x, coord_t y, const char * label, const char *const *values, choice_t value, choice_t min, choice_t max, LcdFlags attr, event_t event, coord_t lblX, IsValueAvailable isValueAvailable)
|
||||
{
|
||||
if (label) {
|
||||
lcdDrawText(lblX, y, label);
|
||||
}
|
||||
if (values) lcdDrawTextAtIndex(x, y, values, value-min, attr);
|
||||
if (attr & (~RIGHT)) value = checkIncDec(event, value, min, max, (isModelMenuDisplayed()) ? EE_MODEL : EE_GENERAL, isValueAvailable);
|
||||
return value;
|
||||
}
|
||||
|
||||
choice_t editChoice(coord_t x, coord_t y, const char * label, const char *const *values, choice_t value, choice_t min, choice_t max, LcdFlags attr, event_t event, coord_t lblX)
|
||||
{
|
||||
return editChoice(x, y, label, values, value, min, max, attr, event, lblX, nullptr);
|
||||
}
|
||||
|
||||
choice_t editChoice(coord_t x, coord_t y, const char * label, const char *const *values, choice_t value, choice_t min, choice_t max, LcdFlags attr, event_t event)
|
||||
{
|
||||
return editChoice(x, y, label, values, value, min, max, attr, event, 0, nullptr);
|
||||
}
|
||||
|
||||
uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label, LcdFlags attr, event_t event, coord_t lblX)
|
||||
{
|
||||
drawCheckBox(x, y, value, attr);
|
||||
return editChoice(x, y, label, nullptr, value, 0, 1, attr, event, lblX);
|
||||
}
|
||||
|
||||
uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label, LcdFlags attr, event_t event)
|
||||
{
|
||||
return editCheckBox(value, x, y, label, attr, event, 0);
|
||||
}
|
||||
|
||||
swsrc_t editSwitch(coord_t x, coord_t y, swsrc_t value, LcdFlags attr, event_t event)
|
||||
{
|
||||
lcdDrawTextAlignedLeft(y, STR_SWITCH);
|
||||
drawSwitch(x, y, value, attr);
|
||||
if (attr & (~RIGHT)) CHECK_INCDEC_MODELSWITCH(event, value, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes);
|
||||
return value;
|
||||
}
|
||||
|
||||
uint16_t editSrcVarFieldValue(coord_t x, coord_t y, const char* title, uint16_t value,
|
||||
int16_t min, int16_t max, LcdFlags attr, event_t event,
|
||||
IsValueAvailable isValueAvailable, int16_t sourceMin, int16_t sourceMax)
|
||||
{
|
||||
if (title)
|
||||
lcdDrawTextAlignedLeft(y, title);
|
||||
SourceNumVal v;
|
||||
v.rawValue = value;
|
||||
if (v.isSource) {
|
||||
drawSource(x, y, v.value, attr);
|
||||
if (attr & (~RIGHT)) {
|
||||
value = checkIncDec(event, value, sourceMin, sourceMax,
|
||||
EE_MODEL|INCDEC_SOURCE|INCDEC_SOURCE_VALUE|INCDEC_SOURCE_INVERT|NO_INCDEC_MARKS, isValueAvailable);
|
||||
}
|
||||
} else {
|
||||
lcdDrawNumber(x, y, v.value, attr);
|
||||
if (attr & (~RIGHT)) {
|
||||
value = checkIncDec(event, value, min, max, sourceMin, sourceMax,
|
||||
EE_MODEL|INCDEC_SOURCE_VALUE|NO_INCDEC_MARKS|INCDEC_SKIP_VAL_CHECK_FUNC,
|
||||
isValueAvailable);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t editflags, event_t event)
|
||||
{
|
||||
#if defined(GVARS)
|
||||
bool invers = (attr & INVERS);
|
||||
|
||||
// TRACE("editGVarFieldValue(val=%d min=%d max=%d)", value, min, max);
|
||||
|
||||
if (modelGVEnabled() && invers && event == EVT_KEY_LONG(KEY_ENTER)) {
|
||||
killEvents(event);
|
||||
s_editMode = !s_editMode;
|
||||
if (attr & PREC1)
|
||||
value = (GV_IS_GV_VALUE(value) ? GET_GVAR(value, min, max, mixerCurrentFlightMode)*10 : GV_VALUE_FROM_INDEX(0));
|
||||
else
|
||||
value = (GV_IS_GV_VALUE(value) ? GET_GVAR(value, min, max, mixerCurrentFlightMode) : GV_VALUE_FROM_INDEX(0));
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
|
||||
if (GV_IS_GV_VALUE(value)) {
|
||||
attr &= ~PREC1;
|
||||
int8_t idx = (int16_t)GV_INDEX_FROM_VALUE(value);
|
||||
if (invers) {
|
||||
CHECK_INCDEC_MODELVAR(event, idx, -MAX_GVARS, MAX_GVARS-1);
|
||||
}
|
||||
value = (int16_t)GV_VALUE_FROM_INDEX(idx);
|
||||
drawGVarName(x, y, idx, attr);
|
||||
}
|
||||
else {
|
||||
lcdDrawNumber(x, y, value, attr);
|
||||
if (invers) value = checkIncDec(event, value, min, max, EE_MODEL | editflags);
|
||||
}
|
||||
#else
|
||||
lcdDrawNumber(x, y, value, attr);
|
||||
if (attr&INVERS) value = checkIncDec(event, value, min, max, EE_MODEL);
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
|
||||
#if defined(GVARS)
|
||||
void editGVarValue(coord_t x, coord_t y, event_t event, uint8_t gvar, uint8_t flightMode, LcdFlags flags)
|
||||
{
|
||||
FlightModeData * fm = &g_model.flightModeData[flightMode];
|
||||
gvar_t * v = &fm->gvars[gvar];
|
||||
int16_t vmin, vmax;
|
||||
if (*v > GVAR_MAX) {
|
||||
uint8_t fm = *v - GVAR_MAX - 1;
|
||||
if (fm >= flightMode) fm++;
|
||||
drawFlightMode(x, y, fm + 1, flags&(~LEFT));
|
||||
vmin = GVAR_MAX + 1;
|
||||
vmax = GVAR_MAX + MAX_FLIGHT_MODES - 1;
|
||||
}
|
||||
else {
|
||||
drawGVarValue(x, y, gvar, *v, flags);
|
||||
vmin = GVAR_MIN + g_model.gvars[gvar].min;
|
||||
vmax = GVAR_MAX - g_model.gvars[gvar].max;
|
||||
}
|
||||
|
||||
if (flags & INVERS) {
|
||||
if (event == EVT_KEY_LONG(KEY_ENTER) && flightMode > 0) {
|
||||
killEvents(event);
|
||||
*v = (*v > GVAR_MAX ? 0 : GVAR_MAX+1);
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
else if (s_editMode > 0) {
|
||||
*v = checkIncDec(event, *v, vmin, vmax, EE_MODEL);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void editSingleName(coord_t x, coord_t y, const char * label, char *name, uint8_t size, event_t event, uint8_t active, uint8_t old_editMode, coord_t lblX)
|
||||
{
|
||||
lcdDrawText(lblX, y, label);
|
||||
editName(x, y, name, size, event, active, 0, old_editMode);
|
||||
}
|
||||
|
||||
uint8_t editDelay(coord_t y, event_t event, uint8_t attr, const char * str, uint8_t delay, uint8_t prec)
|
||||
{
|
||||
lcdDrawTextAlignedLeft(y, str);
|
||||
lcdDrawNumber(MIXES_2ND_COLUMN, y, delay, attr|prec|LEFT);
|
||||
if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, delay, DELAY_MAX);
|
||||
return delay;
|
||||
}
|
||||
|
||||
int editNumberField(const char* name, coord_t lx, coord_t vx, coord_t y, int val,
|
||||
int min, int max, LcdFlags attr, event_t event, const char* zeroStr, int ofst)
|
||||
{
|
||||
lcdDrawText(lx, y, name);
|
||||
if (zeroStr && val == 0)
|
||||
lcdDrawText(vx, y, zeroStr, attr & (~PREC1));
|
||||
else
|
||||
lcdDrawNumber(vx, y, val + ofst, LEFT|attr);
|
||||
if (attr & INVERS) CHECK_INCDEC_MODELVAR(event, val, min, max);
|
||||
return val;
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef int choice_t;
|
||||
|
||||
choice_t editChoice(coord_t x, coord_t y, const char *label,
|
||||
const char *const *values, choice_t value, choice_t min,
|
||||
choice_t max, LcdFlags attr, event_t event);
|
||||
choice_t editChoice(coord_t x, coord_t y, const char *label,
|
||||
const char *const *values, choice_t value, choice_t min,
|
||||
choice_t max, LcdFlags attr, event_t event, coord_t lblX);
|
||||
choice_t editChoice(coord_t x, coord_t y, const char *label,
|
||||
const char *const *values, choice_t value, choice_t min,
|
||||
choice_t max, LcdFlags attr, event_t event, coord_t lblX,
|
||||
IsValueAvailable isValueAvailable);
|
||||
|
||||
uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label,
|
||||
LcdFlags attr, event_t event);
|
||||
uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label,
|
||||
LcdFlags attr, event_t event, coord_t lblX);
|
||||
|
||||
swsrc_t editSwitch(coord_t x, coord_t y, swsrc_t value, LcdFlags attr,
|
||||
event_t event);
|
||||
|
||||
uint16_t editSrcVarFieldValue(coord_t x, coord_t y, const char* title, uint16_t value,
|
||||
int16_t min, int16_t max, LcdFlags attr, event_t event,
|
||||
IsValueAvailable isValueAvailable, int16_t sourceMin, int16_t sourceMax);
|
||||
|
||||
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min,
|
||||
int16_t max, LcdFlags attr, uint8_t editflags,
|
||||
event_t event);
|
||||
|
||||
#define GVAR_MENU_ITEM(x, y, v, min, max, attr, editflags, event) \
|
||||
editGVarFieldValue(x, y, v, min, max, attr, editflags, event)
|
||||
|
||||
#if defined(GVARS)
|
||||
void editGVarValue(coord_t x, coord_t y, event_t event, uint8_t gvar,
|
||||
uint8_t flightMode, LcdFlags flags);
|
||||
#endif
|
||||
|
||||
void editCurveRef(coord_t x, coord_t y, CurveRef & curve, event_t event, LcdFlags flags,
|
||||
IsValueAvailable isValueAvailable, int16_t sourceMin, int16_t sourceMax);
|
||||
|
||||
extern uint8_t editNameCursorPos;
|
||||
|
||||
void editName(coord_t x, coord_t y, char *name, uint8_t size, event_t event,
|
||||
uint8_t active, LcdFlags attr, uint8_t old_editMode);
|
||||
|
||||
void editSingleName(coord_t x, coord_t y, const char *label, char *name,
|
||||
uint8_t size, event_t event, uint8_t active,
|
||||
uint8_t old_editMode, coord_t lblX = 0);
|
||||
|
||||
uint8_t editDelay(coord_t y, event_t event, uint8_t attr, const char * str, uint8_t delay, uint8_t prec);
|
||||
|
||||
int editNumberField(const char* name, coord_t lx, coord_t vx, coord_t y, int val,
|
||||
int min, int max, LcdFlags attr, event_t event, const char* zeroStr = nullptr, int ofst = 0);
|
||||
@@ -1078,7 +1078,8 @@
|
||||
#define TR_CURVE_PRESET "预设..."
|
||||
#define TR_PRESET "预设"
|
||||
#define TR_MIRROR "镜像"
|
||||
#define TR_CLEAR BUTTON("清除")
|
||||
#define TR_CLEAR "清除"
|
||||
#define TR_CLEAR_BTN BUTTON("清除")
|
||||
#define TR_RESET "复位"
|
||||
#define TR_RESET_SUBMENU "复位..."
|
||||
#define TR_COUNT "点数"
|
||||
|
||||
@@ -1081,7 +1081,8 @@
|
||||
#define TR_CURVE_PRESET "Šablona"
|
||||
#define TR_PRESET "Šablona"
|
||||
#define TR_MIRROR "Zrcadlit"
|
||||
#define TR_CLEAR BUTTON("Smazat")
|
||||
#define TR_CLEAR "Smazat"
|
||||
#define TR_CLEAR_BTN BUTTON("Smazat")
|
||||
#define TR_RESET "Reset"
|
||||
#define TR_RESET_SUBMENU "Inicializovat ..."
|
||||
#define TR_COUNT "Velikost"
|
||||
|
||||
@@ -1083,7 +1083,8 @@
|
||||
#define TR_CURVE_PRESET TR ("Forudindstil", "Forudind.")
|
||||
#define TR_PRESET "Forudindstil"
|
||||
#define TR_MIRROR "Spejle"
|
||||
#define TR_CLEAR BUTTON("Slet")
|
||||
#define TR_CLEAR "Slet"
|
||||
#define TR_CLEAR_BTN BUTTON("Slet")
|
||||
#define TR_RESET "Nulstil"
|
||||
#define TR_RESET_SUBMENU "Nulstil..."
|
||||
#define TR_COUNT "Tæller"
|
||||
|
||||
@@ -1078,7 +1078,8 @@
|
||||
#define TR_CURVE_PRESET "Gerade 0 11 22 33 45"
|
||||
#define TR_PRESET "Preset"
|
||||
#define TR_MIRROR "Spiegeln"
|
||||
#define TR_CLEAR BUTTON("Löschen")
|
||||
#define TR_CLEAR "Löschen"
|
||||
#define TR_CLEAR_BTN BUTTON("Löschen")
|
||||
#define TR_RESET TR("Servowert reset","Servowerte zurücksetzen")
|
||||
#define TR_RESET_SUBMENU TR("Reset Werte ==>", "Reset=>Timer Flug Telem")
|
||||
#define TR_COUNT "Punkte"
|
||||
|
||||
@@ -1079,7 +1079,8 @@
|
||||
#define TR_CURVE_PRESET "Preset..."
|
||||
#define TR_PRESET "Preset"
|
||||
#define TR_MIRROR "Mirror"
|
||||
#define TR_CLEAR BUTTON("Clear")
|
||||
#define TR_CLEAR "Clear"
|
||||
#define TR_CLEAR_BTN BUTTON("Clear")
|
||||
#define TR_RESET "Reset"
|
||||
#define TR_RESET_SUBMENU "Reset..."
|
||||
#define TR_COUNT "Count"
|
||||
|
||||
@@ -1079,7 +1079,8 @@
|
||||
#define TR_CURVE_PRESET "Preset..."
|
||||
#define TR_PRESET "Preset"
|
||||
#define TR_MIRROR "Mirror"
|
||||
#define TR_CLEAR BUTTON("Borrar")
|
||||
#define TR_CLEAR "Borrar"
|
||||
#define TR_CLEAR_BTN BUTTON("Borrar")
|
||||
#define TR_RESET "Reset"
|
||||
#define TR_RESET_SUBMENU "Reset..."
|
||||
#define TR_COUNT "Puntos"
|
||||
|
||||
@@ -1078,7 +1078,8 @@
|
||||
#define TR_CURVE_PRESET "Preset..."
|
||||
#define TR_PRESET "Preset"
|
||||
#define TR_MIRROR "Mirror"
|
||||
#define TR_CLEAR BUTTON("Clear")
|
||||
#define TR_CLEAR "Clear"
|
||||
#define TR_CLEAR_BTN BUTTON("Clear")
|
||||
#define TR_RESET "Reset"
|
||||
#define TR_RESET_SUBMENU "Reset..."
|
||||
#define TR_COUNT "Count"
|
||||
|
||||
@@ -1081,7 +1081,8 @@
|
||||
#define TR_CURVE_PRESET "Courbe standard..."
|
||||
#define TR_PRESET "Pente"
|
||||
#define TR_MIRROR "Miroir"
|
||||
#define TR_CLEAR BUTTON("Effacer")
|
||||
#define TR_CLEAR "Effacer"
|
||||
#define TR_CLEAR_BTN BUTTON("Effacer")
|
||||
#define TR_RESET "Réinit."
|
||||
#define TR_RESET_SUBMENU "Réinit..."
|
||||
#define TR_COUNT "Nb points"
|
||||
|
||||
@@ -1081,7 +1081,8 @@
|
||||
#define TR_CURVE_PRESET "Preset..."
|
||||
#define TR_PRESET "Preset"
|
||||
#define TR_MIRROR "היפוך"
|
||||
#define TR_CLEAR BUTTON("ניקוי")
|
||||
#define TR_CLEAR "ניקוי"
|
||||
#define TR_CLEAR_BTN BUTTON("ניקוי")
|
||||
#define TR_RESET "איפוס"
|
||||
#define TR_RESET_SUBMENU "...איפוס"
|
||||
#define TR_COUNT "ספירה"
|
||||
|
||||
@@ -1078,7 +1078,8 @@
|
||||
#define TR_CURVE_PRESET "Preimpostate..."
|
||||
#define TR_PRESET "Preimpostate"
|
||||
#define TR_MIRROR "Mirror"
|
||||
#define TR_CLEAR BUTTON("Cancella")
|
||||
#define TR_CLEAR "Cancella"
|
||||
#define TR_CLEAR_BTN BUTTON("Cancella")
|
||||
#define TR_RESET "Azzera"
|
||||
#define TR_RESET_SUBMENU "Azzera..."
|
||||
#define TR_COUNT "Punti"
|
||||
|
||||
@@ -1077,7 +1077,8 @@
|
||||
#define TR_CURVE_PRESET "プリセット..."
|
||||
#define TR_PRESET "プリセット"
|
||||
#define TR_MIRROR "ミラー"
|
||||
#define TR_CLEAR BUTTON("消去")
|
||||
#define TR_CLEAR "消去"
|
||||
#define TR_CLEAR_BTN BUTTON("消去")
|
||||
#define TR_RESET "リセット"
|
||||
#define TR_RESET_SUBMENU "リセット..."
|
||||
#define TR_COUNT "カウント"
|
||||
|
||||
@@ -1127,7 +1127,8 @@
|
||||
#define TR_CURVE_PRESET "프리셋..."
|
||||
#define TR_PRESET "프리셋"
|
||||
#define TR_MIRROR "미러"
|
||||
#define TR_CLEAR BUTTON("지우기")
|
||||
#define TR_CLEAR "지우기"
|
||||
#define TR_CLEAR_BTN BUTTON("지우기")
|
||||
#define TR_RESET "초기화"
|
||||
#define TR_RESET_SUBMENU "초기화..."
|
||||
#define TR_COUNT "카운트"
|
||||
|
||||
@@ -1079,7 +1079,8 @@
|
||||
#define TR_CURVE_PRESET "Preset..."
|
||||
#define TR_PRESET "Preset"
|
||||
#define TR_MIRROR "Spiegelen"
|
||||
#define TR_CLEAR BUTTON("Wissen")
|
||||
#define TR_CLEAR "Wissen"
|
||||
#define TR_CLEAR_BTN BUTTON("Wissen")
|
||||
#define TR_RESET "Reset Servowaardes"
|
||||
#define TR_RESET_SUBMENU "Reset..."
|
||||
#define TR_COUNT "Punten"
|
||||
|
||||
@@ -1076,7 +1076,8 @@
|
||||
#define TR_CURVE_PRESET "Predef..."
|
||||
#define TR_PRESET "Predef."
|
||||
#define TR_MIRROR "Lustro"
|
||||
#define TR_CLEAR BUTTON("Wyczyść")
|
||||
#define TR_CLEAR "Wyczyść"
|
||||
#define TR_CLEAR_BTN BUTTON("Wyczyść")
|
||||
#define TR_RESET "Resetuj"
|
||||
#define TR_RESET_SUBMENU "Reset..."
|
||||
#define TR_COUNT "Punkty"
|
||||
|
||||
@@ -1079,7 +1079,8 @@
|
||||
#define TR_CURVE_PRESET "Preset..."
|
||||
#define TR_PRESET "Preset"
|
||||
#define TR_MIRROR "Espelhar"
|
||||
#define TR_CLEAR BUTTON("Clear")
|
||||
#define TR_CLEAR "Clear"
|
||||
#define TR_CLEAR_BTN BUTTON("Clear")
|
||||
#define TR_RESET "Reset"
|
||||
#define TR_RESET_SUBMENU "Reset..."
|
||||
#define TR_COUNT "Quantidade"
|
||||
|
||||
@@ -1080,7 +1080,8 @@
|
||||
#define TR_CURVE_PRESET "Предустановка..."
|
||||
#define TR_PRESET "Предустановка"
|
||||
#define TR_MIRROR "Зеркало"
|
||||
#define TR_CLEAR BUTTON("Очистить")
|
||||
#define TR_CLEAR "Очистить"
|
||||
#define TR_CLEAR_BTN BUTTON("Очистить")
|
||||
#define TR_RESET "Сброс"
|
||||
#define TR_RESET_SUBMENU "Сброс..."
|
||||
#define TR_COUNT "Колличество"
|
||||
|
||||
@@ -1086,7 +1086,8 @@
|
||||
#define TR_CURVE_PRESET "Förinställd..."
|
||||
#define TR_PRESET "Lutning"
|
||||
#define TR_MIRROR "Spegla"
|
||||
#define TR_CLEAR BUTTON("Rensa")
|
||||
#define TR_CLEAR "Rensa"
|
||||
#define TR_CLEAR_BTN BUTTON("Rensa")
|
||||
#define TR_RESET "Återställ"
|
||||
#define TR_RESET_SUBMENU "Återställ..."
|
||||
#define TR_COUNT "Antal"
|
||||
|
||||
@@ -1076,7 +1076,8 @@
|
||||
#define TR_CURVE_PRESET "預設..."
|
||||
#define TR_PRESET "預設"
|
||||
#define TR_MIRROR "鏡像"
|
||||
#define TR_CLEAR BUTTON("清除")
|
||||
#define TR_CLEAR "清除"
|
||||
#define TR_CLEAR_BTN BUTTON("清除")
|
||||
#define TR_RESET "重啟"
|
||||
#define TR_RESET_SUBMENU "重啟..."
|
||||
#define TR_COUNT "點數"
|
||||
|
||||
@@ -1079,7 +1079,8 @@
|
||||
#define TR_CURVE_PRESET "Передвстановлення..."
|
||||
#define TR_PRESET "Передвстановлення"
|
||||
#define TR_MIRROR "Дзеркало"
|
||||
#define TR_CLEAR BUTTON("Очистити")
|
||||
#define TR_CLEAR "Очистити"
|
||||
#define TR_CLEAR_BTN BUTTON("Очистити")
|
||||
#define TR_RESET "Скидання"
|
||||
#define TR_RESET_SUBMENU "Скидання..."
|
||||
#define TR_COUNT "Кількість"
|
||||
|
||||
@@ -743,6 +743,7 @@ STR(INVERTED)
|
||||
STR(CURVE_PRESET)
|
||||
STR(PRESET)
|
||||
STR(CLEAR)
|
||||
STR(CLEAR_BTN)
|
||||
STR(RESET)
|
||||
STR(ADD_ALL_TRIMS_TO_SUBTRIMS)
|
||||
STR(COUNT)
|
||||
|
||||
Reference in New Issue
Block a user