void CTFSlider::paintBackground( void ) { int wide,tall,nobx,noby; getPaintSize(wide,tall); getNobPos(nobx,noby); // Border drawSetColor( Scheme::sc_secondary1 ); drawOutlinedRect( 0,0,wide,tall ); if( isVertical() ) { // Nob Fill drawSetColor( Scheme::sc_primary2 ); drawFilledRect( 0,nobx,wide,noby ); // Nob Outline drawSetColor( Scheme::sc_primary1 ); drawOutlinedRect( 0,nobx,wide,noby ); } else { // Nob Fill drawSetColor( Scheme::sc_primary2 ); drawFilledRect( nobx,0,noby,tall ); // Nob Outline drawSetColor( Scheme::sc_primary1 ); drawOutlinedRect( nobx,0,noby,tall ); } }
void CEngineSurface :: drawOutlinedRect( int x0, int y0, int x1, int y1 ) { if( _drawColor[3] >= 255 ) return; drawFilledRect( x0, y0, x1, y0 + 1 ); // top drawFilledRect( x0, y1 - 1, x1, y1 ); // bottom drawFilledRect( x0, y0 + 1, x0 + 1, y1 - 1 ); // left drawFilledRect( x1 - 1, y0 + 1, x1, y1 - 1 ); // right }
void displayMenuBar(const MenuItem *menu, int index) { drawFilledRect(0, 0, LCD_W, 32, SOLID, ERASE); drawFilledRect(0, 24, LCD_W, 7, SOLID, GREY_DEFAULT); lcd_bmp(1, 0, MAINMENU_LBM); lcd_putsAtt(0, 24, menu[index].name, INVERS); lcd_rect(index*24, 0, 26, 24, SOLID, FORCE); lcd_hlineStip(0, 31, LCD_W, SOLID, FORCE); }
void Drawing::drawBar(int x, int y, int w, int h, Color color, float value) { x -= w / 2; y -= h / 2; drawFilledRect(x, y, w, h + 1, Color(0, 0, 0)); UINT height = (UINT)(((h + 1) * value) / 100); drawFilledRect(x + 1, y + 1, w - 2, height - 2, color); }
void CommandButton::paintBackground() { if ( m_bFlat ) { if ( isArmed() ) { // Orange Border drawSetColor( Scheme::sc_secondary1 ); drawOutlinedRect(0,0,_size[0],_size[1]); } } else { if ( isArmed() ) { // Orange highlight background drawSetColor( Scheme::sc_primary2 ); drawFilledRect(0,0,_size[0],_size[1]); } // Orange Border drawSetColor( Scheme::sc_secondary1 ); drawOutlinedRect(0,0,_size[0],_size[1]); } }
void menuGeneralVersion(uint8_t event) { if (s_warning_result) { s_warning_result = 0; displayPopup(STR_EEPROMFORMATTING); eeErase(false); #if !defined(SIMU) NVIC_SystemReset(); #else exit(0); #endif } SIMPLE_MENU(STR_MENUVERSION, menuTabGeneral, e_Vers, 1); lcd_putsLeft(MENU_HEADER_HEIGHT+1, vers_stamp); lcd_putsLeft(MENU_HEADER_HEIGHT+5*FH+1, STR_EEBACKUP); lcd_putsLeft(MENU_HEADER_HEIGHT+6*FH+1, STR_FACTORYRESET); drawFilledRect(0, MENU_HEADER_HEIGHT+5*FH, LCD_W, 2*FH+1, SOLID); if (event == EVT_KEY_LONG(KEY_ENTER)) { backupEeprom(); } else if (event == EVT_KEY_LONG(KEY_MENU)) { POPUP_CONFIRMATION(STR_CONFIRMRESET); } }
void displayBattVoltage() { #if defined(BATTGRAPH) putsVBat(VBATT_X-8, VBATT_Y+1, 0); drawFilledRect(VBATT_X-25, VBATT_Y+9, 22, 5); lcd_vline(VBATT_X-3, VBATT_Y+10, 3); uint8_t count = GET_TXBATT_BARS(); for (uint8_t i=0; i<count; i+=2) lcd_vline(VBATT_X-24+i, VBATT_Y+10, 3); if (!IS_TXBATT_WARNING() || BLINK_ON_PHASE) drawFilledRect(VBATT_X-26, VBATT_Y, 25, 15); #else LcdFlags att = (IS_TXBATT_WARNING() ? BLINK|INVERS : 0) | BIGSIZE; putsVBat(VBATT_X-1, VBATT_Y, att|NO_UNIT); lcd_putc(VBATT_X, VBATTUNIT_Y, 'V'); #endif }
void menu_lcd_onoff(coord_t x, coord_t y, uint8_t value, LcdFlags attr) { if (value) lcd_putc(x+1, y, '#'); if (attr) drawFilledRect(x, y, 7, 7); else lcd_square(x, y, 7); }
// ###################################################################### void Button::show(Image<PixRGB<byte> > &buttonImg) { drawFilledRect(buttonImg, itsRectangle, itsBgColor); writeText(buttonImg,itsCenterPoint,itsLabel.c_str(),itsLabelColor, itsBgColor,SimpleFont::FIXED(itsFontSize),false,ANCHOR_CENTER); drawRect(buttonImg, itsRectangle, itsBorderColor,itsBorderThickness); }
/* * Authors (alphabetical order) * - Andre Bernet <*****@*****.**> * - Andreas Weitl * - Bertrand Songis <*****@*****.**> * - Bryan J. Rentoul (Gruvin) <*****@*****.**> * - Cameron Weeks <*****@*****.**> * - Erez Raviv * - Gabriel Birkus * - Jean-Pierre Parisy * - Karl Szmutny * - Michael Blandford * - Michal Hlavinka * - Pat Mackenzie * - Philip Moss * - Rob Thomson * - Romolo Manfredini <*****@*****.**> * - Thomas Husterer * * opentx is based on code named * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, * er9x by Erez Raviv: http://code.google.com/p/er9x/, * and the original (and ongoing) project by * Thomas Husterer, th9x: http://code.google.com/p/th9x/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #include "../../opentx.h" const pm_uchar bmp_sleep[] PROGMEM = { #include "../../bitmaps/Taranis/sleep.lbm" }; void displaySleepBitmap() { lcd_clear(); lcd_bmp(76, 2, bmp_sleep, 0, 60); lcdRefresh(); } void drawStick(coord_t centrex, int16_t xval, int16_t yval) { #define BOX_CENTERY (LCD_H-BOX_WIDTH/2-10) #define MARKER_WIDTH 5 lcd_square(centrex-BOX_WIDTH/2, BOX_CENTERY-BOX_WIDTH/2, BOX_WIDTH); lcd_vline(centrex, BOX_CENTERY-1, 3); lcd_hline(centrex-1, BOX_CENTERY, 3); lcd_square(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 displayColumnHeader(const char * const *headers, uint8_t index) { lcd_putsAtt(17*FW, 0, headers[index], 0); } void menu_lcd_onoff(coord_t x, coord_t y, uint8_t value, LcdFlags attr) { if (value) lcd_putc(x+1, y, '#'); if (attr) drawFilledRect(x, y, 7, 7); else lcd_square(x, y, 7); } void displayScreenIndex(uint8_t index, uint8_t count, uint8_t attr) { lcd_outdezAtt(LCD_W, 0, count, attr); coord_t x = 1+LCD_W-FW*(count>9 ? 3 : 2); lcd_putcAtt(x, 0, '/', attr); lcd_outdezAtt(x, 0, index+1, attr); } void displayScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible) { lcd_vlineStip(x, y, h, DOTTED); coord_t yofs = (h * offset) / count; coord_t yhgt = (h * visible) / count; if (yhgt + yofs > h) yhgt = h - yofs; lcd_vlineStip(x, y + yofs, yhgt, SOLID, FORCE); } const pm_uchar MAINMENU_LBM[] PROGMEM = { #include "bitmaps/Taranis/mainmenu.lbm" }; void displayMenuBar(const MenuItem *menu, int index) { drawFilledRect(0, 0, LCD_W, 32, SOLID, ERASE); drawFilledRect(0, 24, LCD_W, 7, SOLID, GREY_DEFAULT); lcd_bmp(1, 0, MAINMENU_LBM); lcd_putsAtt(0, 24, menu[index].name, INVERS); lcd_rect(index*24, 0, 26, 24, SOLID, FORCE); lcd_hlineStip(0, 31, LCD_W, SOLID, FORCE); } void displayProgressBar(const char *label) { lcd_putsLeft(4*FH, label); lcd_rect(3, 6*FH+4, 204, 7); lcdRefresh(); } void updateProgressBar(int num, int den) { if (num > 0 && den > 0) { int width = (200*num)/den; lcd_hline(5, 6*FH+6, width, FORCE); lcd_hline(5, 6*FH+7, width, FORCE); lcd_hline(5, 6*FH+8, width, FORCE); lcdRefresh(); } } void drawGauge(coord_t x, coord_t y, coord_t w, coord_t h, int32_t val, int32_t max) { lcd_rect(x, y, w+1, h); drawFilledRect(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--) { lcd_hline(x0, y+i, len); } } void title(const pm_char * s) { lcd_putsAtt(0, 0, s, INVERS); } select_menu_value_t selectMenuItem(coord_t x, coord_t y, const pm_char *label, const pm_char *values, select_menu_value_t value, select_menu_value_t min, select_menu_value_t max, LcdFlags attr, uint8_t event) { lcd_putsColumnLeft(x, y, label); if (values) lcd_putsiAtt(x, y, values, value-min, attr); if (attr) value = checkIncDec(event, value, min, max, (menuVerticalPositions[0] == 0) ? EE_MODEL : EE_GENERAL); return value; } uint8_t onoffMenuItem(uint8_t value, coord_t x, coord_t y, const pm_char *label, LcdFlags attr, uint8_t event ) { menu_lcd_onoff(x, y, value, attr); return selectMenuItem(x, y, label, NULL, value, 0, 1, attr, event); } int8_t switchMenuItem(coord_t x, coord_t y, int8_t value, LcdFlags attr, uint8_t event) { lcd_putsColumnLeft(x, y, STR_SWITCH); putsSwitches(x, y, value, attr); if (attr) CHECK_INCDEC_MODELSWITCH(event, value, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes); return value; } void displaySlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr) { lcd_putc(x+(value*4*FW)/max, y, '$'); lcd_hline(x, y+3, 5*FW-1, FORCE); if (attr && (!(attr & BLINK) || !BLINK_ON_PHASE)) drawFilledRect(x, y, 5*FW-1, FH-1); } #if defined(GVARS) bool noZero(int val) { return val != 0; } int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t editflags, uint8_t event) { uint16_t delta = GV_GET_GV1_VALUE(max); bool invers = (attr & INVERS); // TRACE("gvarMenuItem(val=%d min=%d max=%d)", value, min, max); if (invers && event == EVT_KEY_LONG(KEY_ENTER)) { s_editMode = !s_editMode; if (attr & PREC1) value = (GV_IS_GV_VALUE(value, min, max) ? GET_GVAR(value, min, max, mixerCurrentFlightMode)*10 : delta); else value = (GV_IS_GV_VALUE(value, min, max) ? GET_GVAR(value, min, max, mixerCurrentFlightMode) : delta); eeDirty(EE_MODEL); } if (GV_IS_GV_VALUE(value, min, max)) { if (attr & LEFT) attr -= LEFT; /* because of ZCHAR */ else x -= 2*FW+FWNUM; attr &= ~PREC1; int8_t idx = (int16_t) GV_INDEX_CALC_DELTA(value, delta); if (idx >= 0) ++idx; // transform form idx=0=GV1 to idx=1=GV1 in order to handle double keys invert if (invers) { CHECK_INCDEC_MODELVAR_CHECK(event, idx, -MAX_GVARS, MAX_GVARS, noZero); if (idx == 0) idx = 1; // handle reset to zero, map to GV1 } if (idx < 0) { value = (int16_t) GV_CALC_VALUE_IDX_NEG(idx, delta); idx = -idx; lcd_putcAtt(x-6, y, '-', attr); } else { value = (int16_t) GV_CALC_VALUE_IDX_POS(idx-1, delta); } putsStrIdx(x, y, STR_GV, idx, attr); } else { lcd_outdezAtt(x, y, value, attr); if (invers) value = checkIncDec(event, value, min, max, EE_MODEL | editflags); } return value; } #else int16_t gvarMenuItem(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event) { lcd_outdezAtt(x, y, value, attr); if (attr&INVERS) value = checkIncDec(event, value, min, max, EE_MODEL); return value; } #endif #if defined(SDCARD) 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; } drawFilledRect(0, LCD_H-statusLineHeight, LCD_W, FH, SOLID, ERASE); lcd_putsAtt(5, LCD_H+1-statusLineHeight, statusLineMsg, 0); drawFilledRect(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) { lcd_rect(x, y, w+1, h); drawFilledRect(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--) { lcd_hline(x0, y+i, len); } }
/*luadoc @function lcd.drawFilledRectangle(x, y, w, h [, flags]) Draws a solid rectangle from top left corner (x,y) of specified width and height @param x,y (positive numbers) top left corner position @param w (number) width in pixels @param h (number) height in pixels @param flags (unsigned number) drawing flags @status current Introduced in 2.0.0 */ static int luaLcdDrawFilledRectangle(lua_State *L) { if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int w = luaL_checkinteger(L, 3); int h = luaL_checkinteger(L, 4); unsigned int flags = luaL_optunsigned(L, 5, 0); drawFilledRect(x, y, w, h, SOLID, flags); return 0; }
//=========================================================== // Various overloaded paint functions for Custom VGUI objects void CCommandMenu::paintBackground() { // Transparent black background if ( m_iSpectCmdMenu ) drawSetColor( 0, 0, 0, 64 ); else drawSetColor(Scheme::sc_primary3); drawFilledRect(0,0,_size[0],_size[1]); }
/*luadoc @function lcd.drawScreenTitle(title, page, pages) Draws a title bar @param title (string) text for the title @param page (number) page number @param pages (number) total number of pages. Only used as indicator on the right side of title bar. (i.e. idx=2, cnt=5, display `2/5`) @status current Introduced in 2.0.0 */ static int luaLcdDrawScreenTitle(lua_State *L) { if (!luaLcdAllowed) return 0; const char * str = luaL_checkstring(L, 1); int idx = luaL_checkinteger(L, 2); int cnt = luaL_checkinteger(L, 3); if (cnt) displayScreenIndex(idx-1, cnt, 0); drawFilledRect(0, 0, LCD_W, FH, SOLID, FILL_WHITE|GREY_DEFAULT); title(str); return 0; }
void displayRssiLine() { if (TELEMETRY_STREAMING()) { lcd_hline(0, 55, 212, 0); // separator uint8_t rssi = min((uint8_t)99, TELEMETRY_RSSI()); lcd_putsn(0, STATUS_BAR_Y, STR_RX, 2); lcd_outdezNAtt(4*FW, STATUS_BAR_Y, rssi, LEADING0, 2); lcd_rect(BAR_LEFT, 57, 78, 7); drawFilledRect(BAR_LEFT+1, 58, 19*rssi/25, 5, (rssi < getRssiAlarmValue(0)) ? DOTTED : SOLID); } else { lcd_putsAtt(7*FW, STATUS_BAR_Y, STR_NODATA, BLINK); lcd_status_line(); } }
/*luadoc @function lcd.drawCombobox(x, y, w, list, idx [, flags]) Draws a combo box @param x,y (positive numbers) top left corner position @param w (number) width of combo box in pixels @param list (table) combo box elements, each element is a string @param idx (integer) index of entry to highlight @param page (number) page number @param flags (unsigned number) drawing flags, the flags can not be combined: * `BLINK` combo box is expanded * `INVERS` combo box collapsed, text inversed * `0 or not present` combo box collapsed, text normal @status current Introduced in 2.0.0 */ static int luaLcdDrawCombobox(lua_State *L) { if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int w = luaL_checkinteger(L, 3); luaL_checktype(L, 4, LUA_TTABLE); int count = luaL_len(L, 4); /* get size of table */ int idx = luaL_checkinteger(L, 5); unsigned int flags = luaL_optunsigned(L, 6, 0); if (idx >= count) { // TODO error } if (flags & BLINK) { drawFilledRect(x, y, w-9, count*9+2, SOLID, ERASE); lcd_rect(x, y, w-9, count*9+2); for (int i=0; i<count; i++) { lua_rawgeti(L, 4, i+1); const char * item = luaL_checkstring(L, -1); lcd_putsAtt(x+2, y+2+9*i, item, 0); } drawFilledRect(x+1, y+1+9*idx, w-11, 9); drawFilledRect(x+w-10, y, 10, 11, SOLID, ERASE); lcd_rect(x+w-10, y, 10, 11); } else if (flags & INVERS) { drawFilledRect(x, y, w, 11); drawFilledRect(x+w-9, y+1, 8, 9, SOLID, ERASE); lua_rawgeti(L, 4, idx+1); const char * item = luaL_checkstring(L, -1); lcd_putsAtt(x+2, y+2, item, INVERS); } else { drawFilledRect(x, y, w, 11, SOLID, ERASE); lcd_rect(x, y, w, 11); drawFilledRect(x+w-10, y+1, 9, 9, SOLID); lua_rawgeti(L, 4, idx+1); const char * item = luaL_checkstring(L, -1); lcd_putsAtt(x+2, y+2, item, 0); } lcd_hline(x+w-8, y+3, 6); lcd_hline(x+w-8, y+5, 6); lcd_hline(x+w-8, y+7, 6); return 0; }
void editTimerMode(int timerIdx, coord_t y, LcdFlags attr, uint8_t event) { TimerData * timer = &g_model.timers[timerIdx]; putsStrIdx(0*FW, y, STR_TIMER, timerIdx+1); putsTimerMode(MODEL_SETUP_2ND_COLUMN, y, timer->mode, menuHorizontalPosition==0 ? attr : 0); putsTimer(MODEL_SETUP_2ND_COLUMN+5*FW-2+5*FWNUM+1, y, timer->start, menuHorizontalPosition==1 ? attr|TIMEHOUR : TIMEHOUR, menuHorizontalPosition==2 ? attr|TIMEHOUR : TIMEHOUR); if (attr && menuHorizontalPosition < 0) drawFilledRect(MODEL_SETUP_2ND_COLUMN-1, y-1, 11*FW, FH+1); if (attr && s_editMode>0) { div_t qr = div(timer->start, 60); switch (menuHorizontalPosition) { case 0: { swsrc_t timerMode = timer->mode; if (timerMode < 0) timerMode -= TMRMODE_COUNT-1; CHECK_INCDEC_MODELVAR_CHECK(event, timerMode, -TMRMODE_COUNT-SWSRC_LAST+1, TMRMODE_COUNT+SWSRC_LAST-1, isSwitchAvailableInTimers); if (timerMode < 0) timerMode += TMRMODE_COUNT-1; timer->mode = timerMode; #if defined(AUTOSWITCH) if (s_editMode>0) { swsrc_t val = timer->mode - (TMRMODE_COUNT-1); swsrc_t switchVal = checkIncDecMovedSwitch(val); if (val != switchVal) { timer->mode = switchVal + (TMRMODE_COUNT-1); eeDirty(EE_MODEL); } } #endif break; } case 1: qr.quot = checkIncDec(event, qr.quot, 0, 1439, EE_MODEL | NO_INCDEC_MARKS); // 23h59 timer->start = qr.rem + qr.quot*60; break; case 2: qr.rem -= checkIncDecModel(event, qr.rem+2, 1, 62)-2; timer->start -= qr.rem ; if ((int16_t)timer->start < 0) timer->start=0; if ((int32_t)timer->start > 86399) timer->start=86399; // 23h59:59 break; } } }
void drawOffsetBar(uint8_t x, uint8_t y, MixData * md) { int offset = GET_GVAR(MD_OFFSET(md), GV_RANGELARGE_NEG, GV_RANGELARGE, mixerCurrentFlightMode); int weight = GET_GVAR(MD_WEIGHT(md), GV_RANGELARGE_NEG, GV_RANGELARGE, mixerCurrentFlightMode); int barMin = offset - weight; int barMax = offset + weight; if (y > 15) { lcd_outdezAtt(x-((barMin >= 0) ? 2 : 3), y-6, barMin, TINSIZE|LEFT); lcd_outdezAtt(x+GAUGE_WIDTH+1, y-6, barMax, TINSIZE); } if (weight < 0) { barMin = -barMin; barMax = -barMax; } if (barMin < -101) barMin = -101; if (barMax > 101) barMax = 101; lcd_hlineStip(x-2, y, GAUGE_WIDTH+2, DOTTED); lcd_hlineStip(x-2, y+GAUGE_HEIGHT, GAUGE_WIDTH+2, DOTTED); lcd_vline(x-2, y+1, GAUGE_HEIGHT-1); lcd_vline(x+GAUGE_WIDTH-1, y+1, GAUGE_HEIGHT-1); if (barMin <= barMax) { int8_t right = (barMax * GAUGE_WIDTH) / 200; int8_t left = ((barMin * GAUGE_WIDTH) / 200)-1; drawFilledRect(x+GAUGE_WIDTH/2+left, y+2, right-left, GAUGE_HEIGHT-3); } lcd_vline(x+GAUGE_WIDTH/2-1, y, GAUGE_HEIGHT+1); if (barMin == -101) { for (uint8_t i=0; i<3; ++i) { lcd_plot(x+i, y+4-i); lcd_plot(x+3+i, y+4-i); } } if (barMax == 101) { for (uint8_t i=0; i<3; ++i) { lcd_plot(x+GAUGE_WIDTH-8+i, y+4-i); lcd_plot(x+GAUGE_WIDTH-5+i, y+4-i); } } }
void editTimerMode(int timerIdx, coord_t y, LcdFlags attr, uint8_t event) { TimerData * timer = &g_model.timers[timerIdx]; putsStrIdx(0*FW, y, STR_TIMER, timerIdx+1); putsTimerMode(MODEL_SETUP_2ND_COLUMN, y, timer->mode, m_posHorz==0 ? attr : 0); putsTimer(MODEL_SETUP_2ND_COLUMN+5*FW-2+5*FWNUM+1, y, timer->start, m_posHorz==1 ? attr : 0, m_posHorz==2 ? attr : 0); if (attr && m_posHorz < 0) drawFilledRect(MODEL_SETUP_2ND_COLUMN-1, y-1, LCD_W-MODEL_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH+1, FH+1); if (attr && s_editMode>0) { div_t qr = div(timer->start, 60); switch (m_posHorz) { case 0: { swsrc_t timerMode = timer->mode; if (timerMode < 0) timerMode -= TMRMODE_COUNT-1; CHECK_INCDEC_MODELVAR_CHECK(event, timerMode, -TMRMODE_COUNT-SWSRC_LAST+1, TMRMODE_COUNT+SWSRC_LAST-1, isSwitchAvailableInTimers); if (timerMode < 0) timerMode += TMRMODE_COUNT-1; timer->mode = timerMode; #if defined(AUTOSWITCH) if (s_editMode>0) { swsrc_t val = timer->mode - (TMRMODE_COUNT-1); swsrc_t switchVal = checkIncDecMovedSwitch(val); if (val != switchVal) { timer->mode = switchVal + (TMRMODE_COUNT-1); eeDirty(EE_MODEL); } } #endif break; } case 1: CHECK_INCDEC_MODELVAR_ZERO(event, qr.quot, 59); timer->start = qr.rem + qr.quot*60; break; case 2: qr.rem -= checkIncDecModel(event, qr.rem+2, 1, 62)-2; timer->start -= qr.rem ; if ((int16_t)timer->start < 0) timer->start=0; break; } } }
// ###################################################################### Image<float> CenterSurroundHistogramSegmenter::getSalientRegion (Point2D<int> pt) { Image<float> mask(itsImage.getDims(), ZEROS); Point2D<int> gpt(pt.i/GRID_SIZE, pt.j/GRID_SIZE); Point2D<int> cpt = gpt * GRID_SIZE; LINFO("pt: %3d %3d --> %3d %3d gpt: %3d %3d", pt.i, pt.j, cpt.i, cpt.j, gpt.i, gpt.j); // compute the center surround region ptsSalientRegion(pt); csTemplateSalientRegion(pt); // grow from the center surround region map itsCSrectangle = growCSregion(pt); drawCurrentCSbelief(pt); // display computed mask drawFilledRect(mask, itsCSrectangle*GRID_SIZE, 1.0F); return mask; }
void displayGaugesTelemetryScreen(FrSkyScreenData & screen) { // Custom Screen with gauges int barHeight = 5; for (int i=3; i>=0; i--) { FrSkyBarData & bar = screen.bars[i]; source_t source = bar.source; getvalue_t barMin = bar.barMin; getvalue_t barMax = bar.barMax; if (source <= MIXSRC_LAST_CH) { barMin = calc100toRESX(barMin); barMax = calc100toRESX(barMax); } if (source && barMax > barMin) { int y = barHeight+6+i*(barHeight+6); putsMixerSource(0, y+barHeight-5, source, 0); lcd_rect(BAR_LEFT, y, BAR_WIDTH+1, barHeight+2); getvalue_t value = getValue(source); putsChannel(BAR_LEFT+2+BAR_WIDTH, y+barHeight-5, source, LEFT); uint8_t thresholdX = 0; int width = barCoord(value, barMin, barMax); uint8_t barShade = SOLID; drawFilledRect(BAR_LEFT+1, y+1, width, barHeight, barShade); for (uint8_t j=24; j<99; j+=25) { if (j>thresholdX || j>width) { lcd_vline(j*BAR_WIDTH/100+BAR_LEFT+1, y+1, barHeight); } } if (thresholdX) { lcd_vlineStip(BAR_LEFT+1+thresholdX, y-2, barHeight+3, DOTTED); lcd_hline(BAR_LEFT+thresholdX, y-2, 3); } } else { barHeight += 2; } } displayRssiLine(); }
void displayTrims(uint8_t phase) { for (uint8_t i=0; i<4; i++) { static coord_t x[4] = {TRIM_LH_X, TRIM_LV_X, TRIM_RV_X, TRIM_RH_X}; static uint8_t vert[4] = {0,1,1,0}; coord_t xm, ym; uint8_t stickIndex = CONVERT_MODE(i); xm = x[stickIndex]; uint8_t att = ROUND; int16_t val = getTrimValue(phase, i); #if !defined(CPUM64) || !defined(FRSKY) int16_t dir = val; bool exttrim = false; if (val < TRIM_MIN || val > TRIM_MAX) { exttrim = true; } #endif if (val < -(TRIM_LEN+1)*4) { val = -(TRIM_LEN+1); } else if (val > (TRIM_LEN+1)*4) { val = TRIM_LEN+1; } else { val /= 4; } if (vert[i]) { ym = 31; lcd_vline(xm, ym-TRIM_LEN, TRIM_LEN*2); if (i!=2 || !g_model.thrTrim) { lcd_vline(xm-1, ym-1, 3); lcd_vline(xm+1, ym-1, 3); } ym -= val; #if !defined(CPUM64) || !defined(FRSKY) drawFilledRect(xm-3, ym-3, 7, 7, SOLID, att|ERASE); if (dir >= 0) { lcd_hline(xm-1, ym-1, 3); } if (dir <= 0) { lcd_hline(xm-1, ym+1, 3); } if (exttrim) { lcd_hline(xm-1, ym, 3); } #endif #if defined(CPUARM) if (g_model.displayTrims != DISPLAY_TRIMS_NEVER && dir != 0) { if (g_model.displayTrims == DISPLAY_TRIMS_ALWAYS || (trimsDisplayTimer > 0 && (trimsDisplayMask & (1<<i)))) { lcd_outdezAtt(dir>0 ? 22 : 54, xm-2, -abs(dir/5), TINSIZE|VERTICAL); } } #endif } else { ym = 60; lcd_hline(xm-TRIM_LEN, ym, TRIM_LEN*2); lcd_hline(xm-1, ym-1, 3); lcd_hline(xm-1, ym+1, 3); xm += val; #if !defined(CPUM64) || !defined(FRSKY) drawFilledRect(xm-3, ym-3, 7, 7, SOLID, att|ERASE); if (dir >= 0) { lcd_vline(xm+1, ym-1, 3); } if (dir <= 0) { lcd_vline(xm-1, ym-1, 3); } if (exttrim) { lcd_vline(xm, ym-1, 3); } #endif #if defined(CPUARM) if (g_model.displayTrims != DISPLAY_TRIMS_NEVER && dir != 0) { if (g_model.displayTrims == DISPLAY_TRIMS_ALWAYS || (trimsDisplayTimer > 0 && (trimsDisplayMask & (1<<i)))) { lcd_outdezAtt((stickIndex==0 ? TRIM_LH_X : TRIM_RH_X)+(dir>0 ? -11 : 20), ym-2, -abs(dir/5), TINSIZE); } } #endif } lcd_square(xm-3, ym-3, 7, att); } }
void drawRacket (int y, color_t color) { if (y > HEIGHT - RACKET_HEIGHT) { y = HEIGHT - RACKET_HEIGHT; } drawFilledRect(0,y,RACKET_WIDTH, y + RACKET_HEIGHT,color); }
void menuGeneralSetup(uint8_t event) { #if defined(RTCLOCK) struct gtm t; gettime(&t); if ((menuVerticalPosition==ITEM_SETUP_DATE || menuVerticalPosition==ITEM_SETUP_TIME) && (s_editMode>0) && (event==EVT_KEY_FIRST(KEY_ENTER) || event==EVT_KEY_FIRST(KEY_EXIT) || IS_ROTARY_BREAK(event) || IS_ROTARY_LONG(event))) { // set the date and time into RTC chip rtcSetTime(&t); } #endif #if defined(FAI_CHOICE) if (warningResult) { warningResult = 0; g_eeGeneral.fai = true; eeDirty(EE_GENERAL); } #endif MENU(STR_MENURADIOSETUP, menuTabGeneral, e_Setup, ITEM_SETUP_MAX, { 2, 2, 1, LABEL(SOUND), 0, 0, 0, 0, 0, 0, 0, CASE_VARIO_CPUARM(LABEL(VARIO)) CASE_VARIO_CPUARM(0) CASE_VARIO_CPUARM(0) CASE_VARIO_CPUARM(0) CASE_VARIO_CPUARM(0) CASE_HAPTIC(LABEL(HAPTIC)) CASE_HAPTIC(0) CASE_HAPTIC(0) CASE_HAPTIC(0) 0, LABEL(ALARMS), 0, 0, 0, 0, IF_ROTARY_ENCODERS(0) LABEL(BACKLIGHT), 0, 0, 0, CASE_REVPLUS(0) CASE_PWM_BACKLIGHT(0) CASE_PWM_BACKLIGHT(0) 0, CASE_SPLASH_PARAM(0) CASE_GPS(LABEL(GPS)) CASE_GPS(0) CASE_GPS(0) CASE_GPS(0) CASE_PXX(0) 0, 0, IF_FAI_CHOICE(0) CASE_MAVLINK(0) 0, 0, LABEL(TX_MODE), 0, 1/*to force edit mode*/ }); int sub = menuVerticalPosition; for (unsigned int i=0; i<NUM_BODY_LINES; i++) { coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH; uint8_t k = i+menuVerticalOffset; uint8_t blink = ((s_editMode>0) ? BLINK|INVERS : INVERS); uint8_t attr = (sub == k ? blink : 0); switch(k) { case ITEM_SETUP_DATE: lcd_putsLeft(y, STR_DATE); lcd_putc(RADIO_SETUP_DATE_COLUMN, y, '-'); lcd_putc(RADIO_SETUP_DATE_COLUMN+3*FW-2, y, '-'); for (uint8_t j=0; j<3; j++) { uint8_t rowattr = (menuHorizontalPosition==j ? attr : 0); switch (j) { case 0: lcd_outdezAtt(RADIO_SETUP_DATE_COLUMN, y, t.tm_year+1900, rowattr); if (rowattr && s_editMode>0) t.tm_year = checkIncDec(event, t.tm_year, 112, 200, 0); break; case 1: lcd_outdezNAtt(RADIO_SETUP_DATE_COLUMN+3*FW-2, y, t.tm_mon+1, rowattr|LEADING0, 2); if (rowattr && s_editMode>0) t.tm_mon = checkIncDec(event, t.tm_mon, 0, 11, 0); break; case 2: { int16_t year = 1900 + t.tm_year; int8_t dlim = (((((year%4==0) && (year%100!=0)) || (year%400==0)) && (t.tm_mon==1)) ? 1 : 0); static const pm_uint8_t dmon[] PROGMEM = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; dlim += pgm_read_byte(&dmon[t.tm_mon]); lcd_outdezNAtt(RADIO_SETUP_DATE_COLUMN+6*FW-4, y, t.tm_mday, rowattr|LEADING0, 2); if (rowattr && s_editMode>0) t.tm_mday = checkIncDec(event, t.tm_mday, 1, dlim, 0); break; } } } if (attr && menuHorizontalPosition < 0) drawFilledRect(RADIO_SETUP_2ND_COLUMN, y, LCD_W-RADIO_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8); if (attr && checkIncDec_Ret) { g_rtcTime = gmktime(&t); // update local timestamp and get wday calculated } break; case ITEM_SETUP_TIME: lcd_putsLeft(y, STR_TIME); lcd_putc(RADIO_SETUP_TIME_COLUMN+1, y, ':'); lcd_putc(RADIO_SETUP_TIME_COLUMN+3*FW-2, y, ':'); for (uint8_t j=0; j<3; j++) { uint8_t rowattr = (menuHorizontalPosition==j ? attr : 0); switch (j) { case 0: lcd_outdezNAtt(RADIO_SETUP_TIME_COLUMN, y, t.tm_hour, rowattr|LEADING0, 2); if (rowattr && s_editMode>0) t.tm_hour = checkIncDec(event, t.tm_hour, 0, 23, 0); break; case 1: lcd_outdezNAtt(RADIO_SETUP_TIME_COLUMN+3*FWNUM, y, t.tm_min, rowattr|LEADING0, 2); if (rowattr && s_editMode>0) t.tm_min = checkIncDec(event, t.tm_min, 0, 59, 0); break; case 2: lcd_outdezNAtt(RADIO_SETUP_TIME_COLUMN+6*FWNUM, y, t.tm_sec, rowattr|LEADING0, 2); if (rowattr && s_editMode>0) t.tm_sec = checkIncDec(event, t.tm_sec, 0, 59, 0); break; } } if (attr && menuHorizontalPosition < 0) drawFilledRect(RADIO_SETUP_2ND_COLUMN, y, LCD_W-RADIO_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8); if (attr && checkIncDec_Ret) g_rtcTime = gmktime(&t); // update local timestamp and get wday calculated break; case ITEM_SETUP_BATT_RANGE: lcd_putsLeft(y, STR_BATTERY_RANGE); putsVolts(RADIO_SETUP_2ND_COLUMN, y, 90+g_eeGeneral.vBatMin, (menuHorizontalPosition==0 ? attr : 0)|LEFT|NO_UNIT); lcd_putc(lcdLastPos, y, '-'); putsVolts(lcdLastPos+FW, y, 120+g_eeGeneral.vBatMax, (menuHorizontalPosition>0 ? attr : 0)|LEFT|NO_UNIT); if (attr && menuHorizontalPosition < 0) drawFilledRect(RADIO_SETUP_2ND_COLUMN, y, LCD_W-RADIO_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8); if (attr && s_editMode>0) { if (menuHorizontalPosition==0) CHECK_INCDEC_GENVAR(event, g_eeGeneral.vBatMin, -50, g_eeGeneral.vBatMax+29); // min=4.0V else CHECK_INCDEC_GENVAR(event, g_eeGeneral.vBatMax, g_eeGeneral.vBatMin-29, +40); // max=16.0V } break; case ITEM_SETUP_SOUND_LABEL: lcd_putsLeft(y, STR_SOUND_LABEL); break; case ITEM_SETUP_BEEP_MODE: g_eeGeneral.beepMode = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_SPEAKER, STR_VBEEPMODE, g_eeGeneral.beepMode, -2, 1, attr, event); #if defined(FRSKY) if (attr && checkIncDec_Ret) frskySendAlarms(); #endif break; case ITEM_SETUP_SPEAKER_VOLUME: { lcd_putsLeft(y, STR_SPEAKER_VOLUME); uint8_t b = g_eeGeneral.speakerVolume+VOLUME_LEVEL_DEF; displaySlider(RADIO_SETUP_2ND_COLUMN, y, b, VOLUME_LEVEL_MAX, attr); if (attr) { CHECK_INCDEC_GENVAR(event, b, 0, VOLUME_LEVEL_MAX); if (checkIncDec_Ret) { g_eeGeneral.speakerVolume = (int8_t)b-VOLUME_LEVEL_DEF; } } break; } case ITEM_SETUP_BEEP_VOLUME: SLIDER_5POS(y, g_eeGeneral.beepVolume, STR_BEEP_VOLUME, event, attr); break; case ITEM_SETUP_WAV_VOLUME: SLIDER_5POS(y, g_eeGeneral.wavVolume, STR_WAV_VOLUME, event, attr); break; case ITEM_SETUP_BACKGROUND_VOLUME: SLIDER_5POS(y, g_eeGeneral.backgroundVolume, STR_BG_VOLUME, event, attr); break; case ITEM_SETUP_BEEP_LENGTH: SLIDER_5POS(y, g_eeGeneral.beepLength, STR_BEEP_LENGTH, event, attr); break; case ITEM_SETUP_SPEAKER_PITCH: lcd_putsLeft( y, STR_SPKRPITCH); lcd_putcAtt(RADIO_SETUP_2ND_COLUMN, y, '+', attr); lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN+FW, y, g_eeGeneral.speakerPitch*15, attr|LEFT); lcd_putsAtt(lcdLastPos, y, "Hz", attr); if (attr) { CHECK_INCDEC_GENVAR(event, g_eeGeneral.speakerPitch, 0, 20); } break; #if defined(VARIO) case ITEM_SETUP_VARIO_LABEL: lcd_putsLeft(y, STR_VARIO); break; case ITEM_SETUP_VARIO_VOLUME: SLIDER_5POS(y, g_eeGeneral.varioVolume, TR_SPEAKER_VOLUME, event, attr); break; case ITEM_SETUP_VARIO_PITCH: lcd_putsLeft(y, STR_PITCH_AT_ZERO); lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, VARIO_FREQUENCY_ZERO+(g_eeGeneral.varioPitch*10), attr|LEFT); lcd_putsAtt(lcdLastPos, y, "Hz", attr); if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.varioPitch, -40, 40); break; case ITEM_SETUP_VARIO_RANGE: lcd_putsLeft(y, STR_PITCH_AT_MAX); lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, VARIO_FREQUENCY_ZERO+(g_eeGeneral.varioPitch*10)+VARIO_FREQUENCY_RANGE+(g_eeGeneral.varioRange*10), attr|LEFT); lcd_putsAtt(lcdLastPos, y, "Hz", attr); if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.varioRange, -80, 80); break; case ITEM_SETUP_VARIO_REPEAT: lcd_putsLeft(y, STR_REPEAT_AT_ZERO); lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, VARIO_REPEAT_ZERO+(g_eeGeneral.varioRepeat*10), attr|LEFT); lcd_putsAtt(lcdLastPos, y, STR_MS, attr); if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.varioRepeat, -30, 50); break; #endif #if defined(HAPTIC) case ITEM_SETUP_HAPTIC_LABEL: lcd_putsLeft(y, STR_HAPTIC_LABEL); break; case ITEM_SETUP_HAPTIC_MODE: g_eeGeneral.hapticMode = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_MODE, STR_VBEEPMODE, g_eeGeneral.hapticMode, -2, 1, attr, event); break; case ITEM_SETUP_HAPTIC_LENGTH: SLIDER_5POS(y, g_eeGeneral.hapticLength, STR_LENGTH, event, attr); break; case ITEM_SETUP_HAPTIC_STRENGTH: SLIDER_5POS(y, g_eeGeneral.hapticStrength, STR_HAPTICSTRENGTH, event, attr); break; #endif case ITEM_SETUP_CONTRAST: lcd_putsLeft(y, STR_CONTRAST); lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.contrast, attr|LEFT); if (attr) { CHECK_INCDEC_GENVAR(event, g_eeGeneral.contrast, CONTRAST_MIN, CONTRAST_MAX); lcdSetContrast(); } break; case ITEM_SETUP_ALARMS_LABEL: lcd_putsLeft(y, STR_ALARMS_LABEL); break; case ITEM_SETUP_BATTERY_WARNING: lcd_putsLeft(y, STR_BATTERYWARNING); putsVolts(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.vBatWarn, attr|LEFT); if(attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.vBatWarn, 40, 120); //4-12V break; case ITEM_SETUP_MEMORY_WARNING: { uint8_t b = 1-g_eeGeneral.disableMemoryWarning; g_eeGeneral.disableMemoryWarning = 1 - onoffMenuItem(b, RADIO_SETUP_2ND_COLUMN, y, STR_MEMORYWARNING, attr, event); break; } case ITEM_SETUP_ALARM_WARNING: { uint8_t b = 1-g_eeGeneral.disableAlarmWarning; g_eeGeneral.disableAlarmWarning = 1 - onoffMenuItem(b, RADIO_SETUP_2ND_COLUMN, y, STR_ALARMWARNING, attr, event); break; } case ITEM_SETUP_INACTIVITY_ALARM: lcd_putsLeft(y, STR_INACTIVITYALARM); lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.inactivityTimer, attr|LEFT); lcd_putc(lcdLastPos, y, 'm'); if(attr) g_eeGeneral.inactivityTimer = checkIncDec(event, g_eeGeneral.inactivityTimer, 0, 250, EE_GENERAL); //0..250minutes break; case ITEM_SETUP_BACKLIGHT_LABEL: lcd_putsLeft(y, STR_BACKLIGHT_LABEL); break; case ITEM_SETUP_BACKLIGHT_MODE: g_eeGeneral.backlightMode = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_MODE, STR_VBLMODE, g_eeGeneral.backlightMode, e_backlight_mode_off, e_backlight_mode_on, attr, event); break; case ITEM_SETUP_FLASH_BEEP: g_eeGeneral.alarmsFlash = onoffMenuItem(g_eeGeneral.alarmsFlash, RADIO_SETUP_2ND_COLUMN, y, STR_ALARM, attr, event ) ; break; case ITEM_SETUP_BACKLIGHT_DELAY: lcd_putsLeft(y, STR_BLDELAY); lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.lightAutoOff*5, attr|LEFT); lcd_putc(lcdLastPos, y, 's'); if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.lightAutoOff, 0, 600/5); break; case ITEM_SETUP_BRIGHTNESS: lcd_putsLeft(y, STR_BRIGHTNESS); lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, 100-g_eeGeneral.backlightBright, attr|LEFT) ; if (attr) { uint8_t b = 100 - g_eeGeneral.backlightBright; CHECK_INCDEC_GENVAR(event, b, 0, 100); g_eeGeneral.backlightBright = 100 - b; } break; #if defined(REVPLUS) case ITEM_SETUP_BACKLIGHT_COLOR: lcd_putsLeft(y, STR_BLCOLOR); displaySlider(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.backlightColor, 20, attr); if (attr) g_eeGeneral.backlightColor = checkIncDec(event, g_eeGeneral.backlightColor, 0, 20, EE_GENERAL | NO_INCDEC_MARKS); break; #endif #if defined(SPLASH) && !defined(FSPLASH) case ITEM_SETUP_DISABLE_SPLASH: { lcd_putsLeft(y, STR_SPLASHSCREEN); if (SPLASH_NEEDED()) { lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, SPLASH_TIMEOUT/100, attr|LEFT); lcd_putc(lcdLastPos, y, 's'); } else { lcd_putsiAtt(RADIO_SETUP_2ND_COLUMN, y, STR_MMMINV, 0, attr); // TODO define } if (attr) g_eeGeneral.splashMode = -checkIncDecGen(event, -g_eeGeneral.splashMode, -3, 4); break; } #endif #if defined(FRSKY) && defined(FRSKY_HUB) && defined(GPS) case ITEM_SETUP_LABEL_GPS: lcd_putsLeft(y, STR_GPS); break; case ITEM_SETUP_TIMEZONE: lcd_putsLeft(y, STR_TIMEZONE); lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.timezone, attr|LEFT); if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.timezone, -12, 12); break; case ITEM_SETUP_ADJUST_RTC: g_eeGeneral.adjustRTC = onoffMenuItem(g_eeGeneral.adjustRTC, RADIO_SETUP_2ND_COLUMN, y, STR_ADJUST_RTC, attr, event); break; case ITEM_SETUP_GPSFORMAT: g_eeGeneral.gpsFormat = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_GPSCOORD, STR_GPSFORMAT, g_eeGeneral.gpsFormat, 0, 1, attr, event); break; #endif #if defined(PXX) case ITEM_SETUP_COUNTRYCODE: g_eeGeneral.countryCode = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_COUNTRYCODE, STR_COUNTRYCODES, g_eeGeneral.countryCode, 0, 2, attr, event); break; #endif case ITEM_SETUP_LANGUAGE: lcd_putsLeft(y, STR_VOICELANG); lcd_putsAtt(RADIO_SETUP_2ND_COLUMN, y, currentLanguagePack->name, attr); if (attr) { currentLanguagePackIdx = checkIncDec(event, currentLanguagePackIdx, 0, DIM(languagePacks)-2, EE_GENERAL); if (checkIncDec_Ret) { currentLanguagePack = languagePacks[currentLanguagePackIdx]; strncpy(g_eeGeneral.ttsLanguage, currentLanguagePack->id, 2); } } break; case ITEM_SETUP_IMPERIAL: g_eeGeneral.imperial = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_UNITSSYSTEM, STR_VUNITSSYSTEM, g_eeGeneral.imperial, 0, 1, attr, event); break; #if defined(FAI_CHOICE) case ITEM_SETUP_FAI: onoffMenuItem(g_eeGeneral.fai, RADIO_SETUP_2ND_COLUMN, y, PSTR("FAI Mode"), attr, event); if (attr && checkIncDec_Ret) { if (g_eeGeneral.fai) POPUP_WARNING(PSTR("FAI\001mode blocked!")); else POPUP_CONFIRMATION(PSTR("FAI mode?")); } break; #endif #if defined(MAVLINK) case ITEM_MAVLINK_BAUD: g_eeGeneral.mavbaud = selectMenuItem(RADIO_SETUP_2ND_COLUMN, y, STR_MAVLINK_BAUD_LABEL, STR_MAVLINK_BAUDS, g_eeGeneral.mavbaud, 0, 7, attr, event); break; #endif case ITEM_SETUP_SWITCHES_DELAY: lcd_putsLeft(y, STR_SWITCHES_DELAY); lcd_outdezAtt(RADIO_SETUP_2ND_COLUMN, y, 10*SWITCHES_DELAY(), attr|LEFT); lcd_putsAtt(lcdLastPos, y, STR_MS, attr); if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.switchesDelay, -15, 100-15); break; case ITEM_SETUP_RX_CHANNEL_ORD: lcd_putsLeft(y, STR_RXCHANNELORD); // RAET->AETR for (uint8_t i=1; i<=4; i++) { putsChnLetter(RADIO_SETUP_2ND_COLUMN - FW + i*FW, y, channel_order(i), attr); } if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.templateSetup, 0, 23); break; case ITEM_SETUP_STICK_MODE_LABELS: lcd_putsLeft(y, NO_INDENT(STR_MODE)); for (uint8_t i=0; i<4; i++) { lcd_img((6+4*i)*FW, y, sticks, i, 0); #if defined(FRSKY_STICKS) if (g_eeGeneral.stickReverse & (1<<i)) { drawFilledRect((6+4*i)*FW, y, 3*FW, FH-1); } #endif } #if defined(FRSKY_STICKS) if (attr) { s_editMode = 0; CHECK_INCDEC_GENVAR(event, g_eeGeneral.stickReverse, 0, 15); lcd_rect(6*FW-1, y-1, 15*FW+2, 9); } #endif break; case ITEM_SETUP_STICK_MODE: lcd_putcAtt(2*FW, y, '1'+g_eeGeneral.stickMode, attr); for (uint8_t i=0; i<4; i++) { putsStickName((6+4*i)*FW, y, pgm_read_byte(modn12x3 + 4*g_eeGeneral.stickMode + i), 0); } if (attr && s_editMode>0) { CHECK_INCDEC_GENVAR(event, g_eeGeneral.stickMode, 0, 3); } else if (stickMode != g_eeGeneral.stickMode) { pausePulses(); stickMode = g_eeGeneral.stickMode; checkTHR(); resumePulses(); clearKeyEvents(); } break; } } }
void menuModelSelect(uint8_t event) { if (s_warning_result) { s_warning_result = 0; eeDeleteModel(m_posVert); // delete file s_copyMode = 0; event = EVT_ENTRY_UP; } uint8_t _event_ = (IS_ROTARY_BREAK(event) || IS_ROTARY_LONG(event) ? 0 : event); if ((s_copyMode && EVT_KEY_MASK(event) == KEY_EXIT) || event == EVT_KEY_BREAK(KEY_EXIT)) { _event_ -= KEY_EXIT; } int8_t oldSub = m_posVert; check_submenu_simple(_event_, MAX_MODELS-1); #if defined(NAVIGATION_POT2) if (event==0 && p2valdiff<0) { event = EVT_KEY_FIRST(KEY_RIGHT); } #endif if (s_editMode > 0) s_editMode = 0; #if !defined(CPUARM) if (event) { eeFlush(); // flush eeprom write } #endif int8_t sub = m_posVert; switch (event) { case EVT_ENTRY: m_posVert = sub = g_eeGeneral.currModel; if (sub >= LCD_LINES-1) s_pgOfs = sub-LCD_LINES+2; s_copyMode = 0; s_editMode = EDIT_MODE_INIT; eeCheck(true); break; case EVT_KEY_LONG(KEY_EXIT): killEvents(event); if (s_copyMode && s_copyTgtOfs == 0 && g_eeGeneral.currModel != sub && eeModelExists(sub)) { POPUP_CONFIRMATION(STR_DELETEMODEL); #if defined(CPUARM) SET_WARNING_INFO(modelHeaders[sub].name, sizeof(g_model.header.name), ZCHAR); #else char * name = reusableBuffer.modelsel.mainname; eeLoadModelName(sub, name); SET_WARNING_INFO(name, sizeof(g_model.header.name), ZCHAR); #endif } else { s_copyMode = 0; m_posVert = g_eeGeneral.currModel; } break; #if defined(ROTARY_ENCODER_NAVIGATION) case EVT_ROTARY_LONG: killEvents(event); if (s_editMode < 0) { popMenu(); break; } else if (!s_copyMode) { m_posVert = sub = g_eeGeneral.currModel; s_copyMode = 0; s_editMode = EDIT_MODE_INIT; } // no break #endif case EVT_KEY_BREAK(KEY_EXIT): if (s_copyMode) { sub = m_posVert = (s_copyMode == MOVE_MODE || s_copySrcRow<0) ? (MAX_MODELS+sub+s_copyTgtOfs) % MAX_MODELS : s_copySrcRow; s_copyMode = 0; } else if (m_posVert != g_eeGeneral.currModel) { m_posVert = g_eeGeneral.currModel; } else { popMenu(); } break; #if defined(ROTARY_ENCODER_NAVIGATION) case EVT_ROTARY_BREAK: if (s_editMode == -1) { s_editMode = 0; break; } // no break; #endif case EVT_KEY_LONG(KEY_ENTER): case EVT_KEY_BREAK(KEY_ENTER): s_editMode = 0; if (READ_ONLY()) { if (g_eeGeneral.currModel != sub && eeModelExists(sub)) { selectModel(sub); } } else if (s_copyMode && (s_copyTgtOfs || s_copySrcRow>=0)) { displayPopup(s_copyMode==COPY_MODE ? STR_COPYINGMODEL : STR_MOVINGMODEL); eeCheck(true); // force writing of current model data before this is changed uint8_t cur = (MAX_MODELS + sub + s_copyTgtOfs) % MAX_MODELS; if (s_copyMode == COPY_MODE) { if (!eeCopyModel(cur, s_copySrcRow)) { cur = sub; } } s_copySrcRow = g_eeGeneral.currModel; // to update the currModel value while (sub != cur) { uint8_t src = cur; cur = (s_copyTgtOfs > 0 ? cur+MAX_MODELS-1 : cur+1) % MAX_MODELS; eeSwapModels(src, cur); if (src == s_copySrcRow) s_copySrcRow = cur; else if (cur == s_copySrcRow) s_copySrcRow = src; } if (s_copySrcRow != g_eeGeneral.currModel) { g_eeGeneral.currModel = s_copySrcRow; eeDirty(EE_GENERAL); } s_copyMode = 0; event = EVT_ENTRY_UP; } else if (event == EVT_KEY_LONG(KEY_ENTER) || IS_ROTARY_BREAK(event)) { s_copyMode = 0; killEvents(event); #if defined(NAVIGATION_MENUS) if (g_eeGeneral.currModel != sub) { if (eeModelExists(sub)) { MENU_ADD_ITEM(STR_SELECT_MODEL); MENU_ADD_SD_ITEM(STR_BACKUP_MODEL); MENU_ADD_ITEM(STR_COPY_MODEL); MENU_ADD_ITEM(STR_MOVE_MODEL); MENU_ADD_ITEM(STR_DELETE_MODEL); } else { #if defined(SDCARD) MENU_ADD_ITEM(STR_CREATE_MODEL); MENU_ADD_ITEM(STR_RESTORE_MODEL); #else selectModel(sub); #endif } } else { MENU_ADD_SD_ITEM(STR_BACKUP_MODEL); MENU_ADD_ITEM(STR_COPY_MODEL); MENU_ADD_ITEM(STR_MOVE_MODEL); } menuHandler = onModelSelectMenu; #else if (g_eeGeneral.currModel != sub) { selectModel(sub); } #endif } else if (eeModelExists(sub)) { s_copyMode = (s_copyMode == COPY_MODE ? MOVE_MODE : COPY_MODE); s_copyTgtOfs = 0; s_copySrcRow = -1; } break; #if defined(ROTARY_ENCODER_NAVIGATION) case EVT_ROTARY_LEFT: case EVT_ROTARY_RIGHT: #endif case EVT_KEY_FIRST(KEY_LEFT): case EVT_KEY_FIRST(KEY_RIGHT): #if defined(ROTARY_ENCODER_NAVIGATION) if ((!IS_ROTARY_RIGHT(event) && !IS_ROTARY_LEFT(event)) || s_editMode < 0) { #endif if (sub == g_eeGeneral.currModel) { chainMenu((IS_ROTARY_RIGHT(event) || event == EVT_KEY_FIRST(KEY_RIGHT)) ? menuModelSetup : menuTabModel[DIM(menuTabModel)-1]); } else { AUDIO_WARNING2(); } break; #if defined(ROTARY_ENCODER_NAVIGATION) } // no break #endif case EVT_KEY_FIRST(KEY_MOVE_UP): case EVT_KEY_REPT(KEY_MOVE_UP): case EVT_KEY_FIRST(KEY_MOVE_DOWN): case EVT_KEY_REPT(KEY_MOVE_DOWN): if (s_copyMode) { int8_t next_ofs = s_copyTgtOfs + oldSub - m_posVert; if (next_ofs == MAX_MODELS || next_ofs == -MAX_MODELS) next_ofs = 0; if (s_copySrcRow < 0 && s_copyMode==COPY_MODE) { s_copySrcRow = oldSub; // find a hole (in the first empty slot above / below) sub = eeFindEmptyModel(s_copySrcRow, IS_ROTARY_DOWN(event) || event==EVT_KEY_FIRST(KEY_MOVE_DOWN)); if (sub < 0) { // no free room for duplicating the model AUDIO_ERROR(); sub = oldSub; s_copyMode = 0; } next_ofs = 0; m_posVert = sub; } s_copyTgtOfs = next_ofs; } break; } #if !defined(PCBSKY9X) lcd_puts(9*FW-(LEN_FREE-4)*FW, 0, STR_FREE); if (event) reusableBuffer.modelsel.eepromfree = EeFsGetFree(); lcd_outdezAtt(17*FW, 0, reusableBuffer.modelsel.eepromfree, 0); #endif #if defined(ROTARY_ENCODER_NAVIGATION) displayScreenIndex(e_ModelSelect, DIM(menuTabModel), (sub == g_eeGeneral.currModel) ? ((IS_RE_NAVIGATION_ENABLE() && s_editMode < 0) ? INVERS|BLINK : INVERS) : 0); #else displayScreenIndex(e_ModelSelect, DIM(menuTabModel), (sub == g_eeGeneral.currModel) ? INVERS : 0); #endif TITLE(STR_MENUMODELSEL); for (uint8_t i=0; i<LCD_LINES-1; i++) { coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH; uint8_t k = i+s_pgOfs; lcd_outdezNAtt(3*FW+2, y, k+1, LEADING0+((!s_copyMode && sub==k) ? INVERS : 0), 2); if (s_copyMode == MOVE_MODE || (s_copyMode == COPY_MODE && s_copySrcRow >= 0)) { if (k == sub) { if (s_copyMode == COPY_MODE) { k = s_copySrcRow; lcd_putc(MODELSEL_W-FW, y, '+'); } else { k = sub + s_copyTgtOfs; } } else if (s_copyTgtOfs < 0 && ((k < sub && k >= sub+s_copyTgtOfs) || (k-MAX_MODELS < sub && k-MAX_MODELS >= sub+s_copyTgtOfs))) k += 1; else if (s_copyTgtOfs > 0 && ((k > sub && k <= sub+s_copyTgtOfs) || (k+MAX_MODELS > sub && k+MAX_MODELS <= sub+s_copyTgtOfs))) k += MAX_MODELS-1; } k %= MAX_MODELS; if (eeModelExists(k)) { #if defined(PCBSKY9X) putsModelName(4*FW, y, modelHeaders[k].name, k, 0); #else char * name = reusableBuffer.modelsel.listnames[i]; if (event) eeLoadModelName(k, name); putsModelName(4*FW, y, name, k, 0); lcd_outdezAtt(20*FW, y, eeModelSize(k), 0); #endif if (k==g_eeGeneral.currModel && (s_copyMode!=COPY_MODE || s_copySrcRow<0 || i+s_pgOfs!=(vertpos_t)sub)) lcd_putc(1, y, '*'); } if (s_copyMode && (vertpos_t)sub==i+s_pgOfs) { drawFilledRect(9, y, MODELSEL_W-1-9, 7); lcd_rect(8, y-1, MODELSEL_W-1-7, 9, s_copyMode == COPY_MODE ? SOLID : DOTTED); } } }
void menuModelExpoMix(uint8_t expo, uint8_t event) { uint8_t sub = m_posVert; if (s_editMode > 0) s_editMode = 0; uint8_t chn = (expo ? expoAddress(s_currIdx)->chn+1 : mixAddress(s_currIdx)->destCh+1); switch (event) { case EVT_ENTRY: case EVT_ENTRY_UP: s_copyMode = 0; s_copyTgtOfs = 0; break; case EVT_KEY_LONG(KEY_EXIT): if (s_copyMode && s_copyTgtOfs == 0) { deleteExpoMix(expo, s_currIdx); killEvents(event); event = 0; } // no break case EVT_KEY_BREAK(KEY_EXIT): if (s_copyMode) { if (s_copyTgtOfs) { // cancel the current copy / move operation if (s_copyMode == COPY_MODE) { deleteExpoMix(expo, s_currIdx); } else { do { swapExpoMix(expo, s_currIdx, s_copyTgtOfs > 0); s_copyTgtOfs += (s_copyTgtOfs < 0 ? +1 : -1); } while (s_copyTgtOfs != 0); eeDirty(EE_MODEL); } m_posVert = s_copySrcRow; s_copyTgtOfs = 0; } s_copyMode = 0; event = 0; } break; case EVT_KEY_BREAK(KEY_ENTER): if ((!s_currCh || (s_copyMode && !s_copyTgtOfs)) && !READ_ONLY()) { s_copyMode = (s_copyMode == COPY_MODE ? MOVE_MODE : COPY_MODE); s_copySrcIdx = s_currIdx; s_copySrcCh = chn; s_copySrcRow = sub; break; } // no break case EVT_KEY_LONG(KEY_ENTER): killEvents(event); if (s_copyTgtOfs) { s_copyMode = 0; s_copyTgtOfs = 0; } else { if (READ_ONLY()) { if (!s_currCh) { pushMenu(expo ? menuModelExpoOne : menuModelMixOne); } } else { if (s_copyMode) s_currCh = 0; if (s_currCh) { if (reachExpoMixCountLimit(expo)) break; insertExpoMix(expo, s_currIdx); pushMenu(expo ? menuModelExpoOne : menuModelMixOne); s_copyMode = 0; } else { event = 0; s_copyMode = 0; MENU_ADD_ITEM(STR_EDIT); MENU_ADD_ITEM(STR_INSERT_BEFORE); MENU_ADD_ITEM(STR_INSERT_AFTER); MENU_ADD_ITEM(STR_COPY); MENU_ADD_ITEM(STR_MOVE); MENU_ADD_ITEM(STR_DELETE); menuHandler = onExpoMixMenu; } } } break; case EVT_KEY_LONG(KEY_LEFT): case EVT_KEY_LONG(KEY_RIGHT): if (s_copyMode && !s_copyTgtOfs) { if (reachExpoMixCountLimit(expo)) break; s_currCh = chn; if (event == EVT_KEY_LONG(KEY_RIGHT)) { s_currIdx++; m_posVert++; } insertExpoMix(expo, s_currIdx); pushMenu(expo ? menuModelExpoOne : menuModelMixOne); s_copyMode = 0; killEvents(event); } break; case EVT_KEY_FIRST(KEY_MOVE_UP): case EVT_KEY_REPT(KEY_MOVE_UP): case EVT_KEY_FIRST(KEY_MOVE_DOWN): case EVT_KEY_REPT(KEY_MOVE_DOWN): if (s_copyMode) { uint8_t key = (event & 0x1f); uint8_t next_ofs = (key==KEY_MOVE_UP ? s_copyTgtOfs - 1 : s_copyTgtOfs + 1); if (s_copyTgtOfs==0 && s_copyMode==COPY_MODE) { // insert a mix on the same channel (just above / just below) if (reachExpoMixCountLimit(expo)) break; copyExpoMix(expo, s_currIdx); if (key==KEY_MOVE_DOWN) s_currIdx++; else if (sub-s_pgOfs >= 6) s_pgOfs++; } else if (next_ofs==0 && s_copyMode==COPY_MODE) { // delete the mix deleteExpoMix(expo, s_currIdx); if (key==KEY_MOVE_UP) s_currIdx--; } else { // only swap the mix with its neighbor if (!swapExpoMix(expo, s_currIdx, key==KEY_MOVE_UP)) break; eeDirty(EE_MODEL); } s_copyTgtOfs = next_ofs; } break; } if (expo) { lcd_outdezAtt(FW*sizeof(TR_MENUINPUTS)+FW+FW/2, 0, getExpoMixCount(true)); lcd_puts(FW*sizeof(TR_MENUINPUTS)+FW+FW/2, 0, STR_MAX(MAX_EXPOS)); // Value uint8_t index = expoAddress(s_currIdx)->chn; if (!s_currCh) { lcd_outdezAtt(127, 2, calcRESXto1000(anas[index]), PREC1|TINSIZE); } SIMPLE_MENU(STR_MENUINPUTS, menuTabModel, e_InputsAll, s_maxLines); // Gauge if (!s_currCh) { drawGauge(127, 1, 58, 6, anas[index], 1024); } } else { lcd_outdezAtt(FW*sizeof(TR_MIXER)+FW+FW/2, 0, getExpoMixCount(false)); lcd_puts(FW*sizeof(TR_MIXER)+FW+FW/2, 0, STR_MAX(MAX_MIXERS)); // Value uint8_t index = mixAddress(s_currIdx)->destCh; if (!s_currCh) { displayHeaderChannelName(index); lcd_outdezAtt(127, 2, calcRESXto1000(ex_chans[index]), PREC1|TINSIZE); } SIMPLE_MENU(STR_MIXER, menuTabModel, e_MixAll, s_maxLines); // Gauge if (!s_currCh) { drawGauge(127, 1, 58, 6, ex_chans[index], 1024); } } sub = m_posVert; s_currCh = 0; int cur = 0; int i = 0; for (int ch=1; ch<=(expo ? NUM_INPUTS : NUM_CHNOUT); ch++) { void *pointer = NULL; MixData * &md = (MixData * &)pointer; ExpoData * &ed = (ExpoData * &)pointer; coord_t y = MENU_HEADER_HEIGHT+1+(cur-s_pgOfs)*FH; if (expo ? (i<MAX_EXPOS && (ed=expoAddress(i))->chn+1 == ch && EXPO_VALID(ed)) : (i<MAX_MIXERS && (md=mixAddress(i))->srcRaw && md->destCh+1 == ch)) { if (cur-s_pgOfs >= 0 && cur-s_pgOfs < NUM_BODY_LINES) { if (expo) { putsMixerSource(0, y, ch, 0); } else { putsChn(0, y, ch, 0); // show CHx } } uint8_t mixCnt = 0; do { if (s_copyMode) { if (s_copyMode == MOVE_MODE && cur-s_pgOfs >= 0 && cur-s_pgOfs < NUM_BODY_LINES && s_copySrcCh == ch && s_copyTgtOfs != 0 && i == (s_copySrcIdx + (s_copyTgtOfs<0))) { lcd_rect(expo ? 18 : 22, y-1, expo ? LCD_W-18 : LCD_W-22, 9, DOTTED); cur++; y+=FH; } if (s_currIdx == i) { sub = m_posVert = cur; s_currCh = ch; } } else if (sub == cur) { s_currIdx = i; } if (cur-s_pgOfs >= 0 && cur-s_pgOfs < NUM_BODY_LINES) { uint8_t attr = ((s_copyMode || sub != cur) ? 0 : INVERS); if (expo) { GVAR_MENU_ITEM(EXPO_LINE_WEIGHT_POS, y, ed->weight, MIN_EXPO_WEIGHT, 100, attr | (isExpoActive(i) ? BOLD : 0), 0, 0); displayExpoLine(y, ed); if (ed->mode!=3) { lcd_putc(EXPO_LINE_SIDE_POS, y, ed->mode == 2 ? 126 : 127); } } else { if (mixCnt > 0) lcd_putsiAtt(FW, y, STR_VMLTPX2, md->mltpx, 0); putsMixerSource(MIX_LINE_SRC_POS, y, md->srcRaw, 0); gvarWeightItem(MIX_LINE_WEIGHT_POS, y, md, attr | (isMixActive(i) ? BOLD : 0), 0); displayMixLine(y, md); char cs = ' '; if (md->speedDown || md->speedUp) cs = 'S'; if (md->delayUp || md->delayDown) cs = (cs =='S' ? '*' : 'D'); lcd_putc(MIX_LINE_DELAY_POS, y, cs); } if (s_copyMode) { if ((s_copyMode==COPY_MODE || s_copyTgtOfs == 0) && s_copySrcCh == ch && i == (s_copySrcIdx + (s_copyTgtOfs<0))) { /* draw a border around the raw on selection mode (copy/move) */ lcd_rect(expo ? EXPO_LINE_SELECT_POS : 22, y-1, expo ? (LCD_W-EXPO_LINE_SELECT_POS) : (LCD_W-22), 9, s_copyMode == COPY_MODE ? SOLID : DOTTED); } if (cur == sub) { /* invert the raw when it's the current one */ drawFilledRect(expo ? EXPO_LINE_SELECT_POS+1 : 23, y, expo ? (LCD_W-EXPO_LINE_SELECT_POS-2) : (LCD_W-24), 7); } } } cur++; y+=FH; mixCnt++; i++; if (expo) ed++; else md++; } while (expo ? (i<MAX_EXPOS && ed->chn+1 == ch && EXPO_VALID(ed)) : (i<MAX_MIXERS && md->srcRaw && md->destCh+1 == ch)); if (s_copyMode == MOVE_MODE && cur-s_pgOfs >= 0 && cur-s_pgOfs < NUM_BODY_LINES && s_copySrcCh == ch && i == (s_copySrcIdx + (s_copyTgtOfs<0))) { lcd_rect(expo ? EXPO_LINE_SELECT_POS : 22, y-1, expo ? LCD_W-EXPO_LINE_SELECT_POS : LCD_W-22, 9, DOTTED); cur++; y+=FH; } } else { uint8_t attr = 0; if (sub == cur) { s_currIdx = i; s_currCh = ch; if (!s_copyMode) { attr = INVERS; } } if (cur-s_pgOfs >= 0 && cur-s_pgOfs < NUM_BODY_LINES) { if (expo) { putsMixerSource(0, y, ch, attr); } else { putsChn(0, y, ch, attr); // show CHx } if (s_copyMode == MOVE_MODE && s_copySrcCh == ch) { lcd_rect(expo ? EXPO_LINE_SELECT_POS : 22, y-1, expo ? (LCD_W-EXPO_LINE_SELECT_POS) : (LCD_W-22), 9, DOTTED); } } cur++; y+=FH; } } s_maxLines = cur; if (sub >= s_maxLines-1) m_posVert = s_maxLines-1; }
void displaySlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr) { lcd_putc(x+(value*4*FW)/max, y, '$'); lcd_hline(x, y+3, 5*FW-1, FORCE); if (attr && (!(attr & BLINK) || !BLINK_ON_PHASE)) drawFilledRect(x, y, 5*FW-1, FH-1); }
void check(const char *name, check_event_t event, uint8_t curr, const menuHandlerFunc *menuTab, uint8_t menuTabSize, const pm_uint8_t *horTab, uint8_t horTabMax, vertpos_t rowcount, uint8_t flags) { vertpos_t l_posVert = menuVerticalPosition; horzpos_t l_posHorz = menuHorizontalPosition; uint8_t maxcol = MAXCOL(l_posVert); if (menuTab) { int cc = curr; switch (event) { case EVT_KEY_LONG(KEY_MENU): if (menuTab == menuTabModel) { killEvents(event); if (modelHasNotes()) { POPUP_MENU_ADD_SD_ITEM(STR_VIEW_CHANNELS); POPUP_MENU_ADD_ITEM(STR_VIEW_NOTES); popupMenuHandler = onLongMenuPress; } else { pushMenu(menuChannelsView); } } break; case EVT_KEY_LONG(KEY_PAGE): if (curr > 0) cc = curr - 1; else cc = menuTabSize-1; killEvents(event); break; case EVT_KEY_BREAK(KEY_PAGE): if (curr < (menuTabSize-1)) cc = curr + 1; else cc = 0; break; } if (!calibrationState && cc != curr) { chainMenu((menuHandlerFunc)pgm_read_adr(&menuTab[cc])); } if (!(flags&CHECK_FLAG_NO_SCREEN_INDEX)) { displayScreenIndex(curr, menuTabSize, 0); } drawFilledRect(0, 0, LCD_W, MENU_HEADER_HEIGHT, SOLID, FILL_WHITE|GREY_DEFAULT); } DISPLAY_PROGRESS_BAR(menuTab ? lcdLastPos-2*FW-((curr+1)/10*FWNUM)-2 : 20*FW+1); switch(event) { case EVT_ENTRY: menuEntryTime = get_tmr10ms(); l_posVert = POS_VERT_INIT; l_posHorz = POS_HORZ_INIT(l_posVert); SET_SCROLLBAR_X(LCD_W-1); s_editMode = EDIT_MODE_INIT; break; case EVT_ENTRY_UP: menuEntryTime = get_tmr10ms(); s_editMode = 0; l_posHorz = POS_HORZ_INIT(l_posVert); SET_SCROLLBAR_X(LCD_W-1); break; case EVT_ROTARY_BREAK: if (s_editMode > 1) break; if (menuHorizontalPosition < 0 && maxcol > 0 && READ_ONLY_UNLOCKED()) { l_posHorz = 0; break; } if (READ_ONLY_UNLOCKED()) { s_editMode = (s_editMode<=0); } break; case EVT_KEY_LONG(KEY_EXIT): s_editMode = 0; // TODO needed? we call ENTRY_UP after which does the same popMenu(); break; case EVT_KEY_BREAK(KEY_EXIT): if (s_editMode>0) { s_editMode = 0; break; } if (l_posHorz >= 0 && (COLATTR(l_posVert) & NAVIGATION_LINE_BY_LINE)) { l_posHorz = -1; } else { uint8_t posVertInit = POS_VERT_INIT; if (menuVerticalOffset != 0 || l_posVert != posVertInit) { menuVerticalOffset = 0; l_posVert = posVertInit; l_posHorz = POS_HORZ_INIT(l_posVert); } else { popMenu(); } } break; CASE_EVT_ROTARY_MOVE_RIGHT if (s_editMode != 0) break; if ((COLATTR(l_posVert) & NAVIGATION_LINE_BY_LINE)) { if (l_posHorz >= 0) { INC(l_posHorz, 0, maxcol); break; } } else { if (l_posHorz < maxcol) { l_posHorz++; break; } else { l_posHorz = 0; if (!IS_ROTARY_MOVE_RIGHT(event)) break; } } do { INC(l_posVert, POS_VERT_INIT, rowcount-1); } while (CURSOR_NOT_ALLOWED_IN_ROW(l_posVert)); s_editMode = 0; // if we go down, we must be in this mode l_posHorz = POS_HORZ_INIT(l_posVert); break; CASE_EVT_ROTARY_MOVE_LEFT if (s_editMode != 0) break; if ((COLATTR(l_posVert) & NAVIGATION_LINE_BY_LINE)) { if (l_posHorz >= 0) { DEC(l_posHorz, 0, maxcol); break; } } else { if (l_posHorz > 0) { l_posHorz--; break; } else if (IS_ROTARY_MOVE_LEFT(event) && s_editMode == 0) { l_posHorz = 0xff; } else { l_posHorz = maxcol; break; } } do { DEC(l_posVert, POS_VERT_INIT, rowcount-1); } while (CURSOR_NOT_ALLOWED_IN_ROW(l_posVert)); s_editMode = 0; // if we go up, we must be in this mode if ((COLATTR(l_posVert) & NAVIGATION_LINE_BY_LINE)) l_posHorz = -1; else l_posHorz = min((uint8_t)l_posHorz, MAXCOL(l_posVert)); break; } int linesCount = rowcount; if (l_posVert == 0 || (l_posVert==1 && MAXCOL(vertpos_t(0)) >= HIDDEN_ROW) || (l_posVert==2 && MAXCOL(vertpos_t(0)) >= HIDDEN_ROW && MAXCOL(vertpos_t(1)) >= HIDDEN_ROW)) { menuVerticalOffset = 0; if (horTab) { linesCount = 0; for (int i=0; i<rowcount; i++) { if (i>horTabMax || horTab[i] != HIDDEN_ROW) { linesCount++; } } } } else if (horTab) { if (rowcount > NUM_BODY_LINES) { while (1) { vertpos_t firstLine = 0; for (int numLines=0; firstLine<rowcount && numLines<menuVerticalOffset; firstLine++) { if (firstLine>=horTabMax || horTab[firstLine] != HIDDEN_ROW) { numLines++; } } if (l_posVert < firstLine) { menuVerticalOffset--; } else { vertpos_t lastLine = firstLine; for (int numLines=0; lastLine<rowcount && numLines<NUM_BODY_LINES; lastLine++) { if (lastLine>=horTabMax || horTab[lastLine] != HIDDEN_ROW) { numLines++; } } if (l_posVert >= lastLine) { menuVerticalOffset++; } else { linesCount = menuVerticalOffset + NUM_BODY_LINES; for (int i=lastLine; i<rowcount; i++) { if (i>horTabMax || horTab[i] != HIDDEN_ROW) { linesCount++; } } break; } } } } } else { if (l_posVert>=NUM_BODY_LINES+menuVerticalOffset) { menuVerticalOffset = l_posVert-NUM_BODY_LINES+1; } else if (l_posVert<menuVerticalOffset) { menuVerticalOffset = l_posVert; } } if (scrollbar_X && linesCount > NUM_BODY_LINES) { displayScrollbar(scrollbar_X, MENU_HEADER_HEIGHT, LCD_H-MENU_HEADER_HEIGHT, menuVerticalOffset, linesCount, NUM_BODY_LINES); } if (name) { title(name); } menuVerticalPosition = l_posVert; menuHorizontalPosition = l_posHorz; }
void menuModelSetup(uint8_t event) { horzpos_t l_posHorz = menuHorizontalPosition; bool CURSOR_ON_CELL = (menuHorizontalPosition >= 0); #if defined(TARANIS_INTERNAL_PPM) MENU_TAB({ 0, 0, TIMERS_ROWS, TOPLCD_ROWS 0, 1, 0, 0, LABEL(Throttle), 0, 0, 0, LABEL(PreflightCheck), 0, 0, SW_WARN_ITEMS(), POT_WARN_ITEMS(), NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1), 0, LABEL(InternalModule), INTERNAL_MODULE_MODE_ROWS, INTERNAL_MODULE_CHANNELS_ROWS, IF_INTERNAL_MODULE_ON(IS_MODULE_XJT(INTERNAL_MODULE) ? (HAS_RF_PROTOCOL_MODELINDEX(g_model.moduleData[INTERNAL_MODULE].rfProtocol) ? (uint8_t)2 : (uint8_t)1) : (IS_MODULE_PPM(INTERNAL_MODULE) ? (uint8_t)1 : HIDDEN_ROW)), IF_INTERNAL_MODULE_ON((IS_MODULE_XJT(INTERNAL_MODULE)) ? FAILSAFE_ROWS(INTERNAL_MODULE) : HIDDEN_ROW), LABEL(ExternalModule), (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0, EXTERNAL_MODULE_CHANNELS_ROWS, (IS_MODULE_XJT(EXTERNAL_MODULE) && !HAS_RF_PROTOCOL_MODELINDEX(g_model.moduleData[EXTERNAL_MODULE].rfProtocol)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW, IF_EXTERNAL_MODULE_XJT(FAILSAFE_ROWS(EXTERNAL_MODULE)), LABEL(Trainer), 0, TRAINER_CHANNELS_ROWS(), IF_TRAINER_ON(2)}); #else MENU_TAB({ 0, 0, TIMERS_ROWS, TOPLCD_ROWS 0, 1, 0, 0, LABEL(Throttle), 0, 0, 0, LABEL(PreflightCheck), 0, 0, SW_WARN_ITEMS(), POT_WARN_ITEMS(), NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1), 0, LABEL(InternalModule), INTERNAL_MODULE_MODE_ROWS, INTERNAL_MODULE_CHANNELS_ROWS, IF_INTERNAL_MODULE_ON(HAS_RF_PROTOCOL_MODELINDEX(g_model.moduleData[INTERNAL_MODULE].rfProtocol) ? (uint8_t)2 : (uint8_t)1), IF_INTERNAL_MODULE_ON(FAILSAFE_ROWS(INTERNAL_MODULE)), LABEL(ExternalModule), EXTERNAL_MODULE_MODE_ROWS, EXTERNAL_MODULE_CHANNELS_ROWS, (IS_MODULE_XJT(EXTERNAL_MODULE) && !HAS_RF_PROTOCOL_MODELINDEX(g_model.moduleData[EXTERNAL_MODULE].rfProtocol)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW, IF_EXTERNAL_MODULE_XJT(FAILSAFE_ROWS(EXTERNAL_MODULE)), LABEL(Trainer), 0, TRAINER_CHANNELS_ROWS(), IF_TRAINER_ON(2)}); #endif MENU_CHECK(STR_MENUSETUP, menuTabModel, e_ModelSetup, ITEM_MODEL_SETUP_MAX); #if (defined(DSM2) || defined(PXX)) if (menuEvent) { moduleFlag[0] = 0; moduleFlag[1] = 0; } #endif int sub = menuVerticalPosition; for (int i=0; i<NUM_BODY_LINES; ++i) { coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH; uint8_t k = i+menuVerticalOffset; for (int j=0; j<=k; j++) { if (mstate_tab[j] == HIDDEN_ROW) k++; } LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS); LcdFlags attr = (sub == k ? blink : 0); switch(k) { case ITEM_MODEL_NAME: editSingleName(MODEL_SETUP_2ND_COLUMN, y, STR_MODELNAME, g_model.header.name, sizeof(g_model.header.name), event, attr); memcpy(modelHeaders[g_eeGeneral.currModel].name, g_model.header.name, sizeof(g_model.header.name)); break; case ITEM_MODEL_BITMAP: lcd_putsLeft(y, STR_BITMAP); if (ZEXIST(g_model.header.bitmap)) lcd_putsnAtt(MODEL_SETUP_2ND_COLUMN, y, g_model.header.bitmap, sizeof(g_model.header.bitmap), attr); else lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN, y, STR_VCSWFUNC, 0, attr); if (attr && event==EVT_KEY_BREAK(KEY_ENTER) && READ_ONLY_UNLOCKED()) { s_editMode = 0; if (listSdFiles(BITMAPS_PATH, BITMAPS_EXT, sizeof(g_model.header.bitmap), g_model.header.bitmap, LIST_NONE_SD_FILE)) { popupMenuHandler = onModelSetupBitmapMenu; } else { POPUP_WARNING(STR_NO_BITMAPS_ON_SD); } } break; case ITEM_MODEL_TIMER1: editTimerMode(0, y, attr, event); break; case ITEM_MODEL_TIMER1_NAME: editSingleName(MODEL_SETUP_2ND_COLUMN, y, STR_TIMER_NAME, g_model.timers[0].name, LEN_TIMER_NAME, event, attr); break; case ITEM_MODEL_TIMER1_MINUTE_BEEP: g_model.timers[0].minuteBeep = onoffMenuItem(g_model.timers[0].minuteBeep, MODEL_SETUP_2ND_COLUMN, y, STR_MINUTEBEEP, attr, event); break; case ITEM_MODEL_TIMER1_COUNTDOWN_BEEP: g_model.timers[0].countdownBeep = selectMenuItem(MODEL_SETUP_2ND_COLUMN, y, STR_BEEPCOUNTDOWN, STR_VBEEPCOUNTDOWN, g_model.timers[0].countdownBeep, COUNTDOWN_SILENT, COUNTDOWN_COUNT-1, attr, event); break; case ITEM_MODEL_TIMER1_PERSISTENT: g_model.timers[0].persistent = selectMenuItem(MODEL_SETUP_2ND_COLUMN, y, STR_PERSISTENT, STR_VPERSISTENT, g_model.timers[0].persistent, 0, 2, attr, event); break; #if TIMERS > 1 case ITEM_MODEL_TIMER2: editTimerMode(1, y, attr, event); break; case ITEM_MODEL_TIMER2_NAME: editSingleName(MODEL_SETUP_2ND_COLUMN, y, STR_TIMER_NAME, g_model.timers[1].name, LEN_TIMER_NAME, event, attr); break; case ITEM_MODEL_TIMER2_MINUTE_BEEP: g_model.timers[1].minuteBeep = onoffMenuItem(g_model.timers[1].minuteBeep, MODEL_SETUP_2ND_COLUMN, y, STR_MINUTEBEEP, attr, event); break; case ITEM_MODEL_TIMER2_COUNTDOWN_BEEP: g_model.timers[1].countdownBeep = selectMenuItem(MODEL_SETUP_2ND_COLUMN, y, STR_BEEPCOUNTDOWN, STR_VBEEPCOUNTDOWN, g_model.timers[1].countdownBeep, COUNTDOWN_SILENT, COUNTDOWN_COUNT-1, attr, event); break; case ITEM_MODEL_TIMER2_PERSISTENT: g_model.timers[1].persistent = selectMenuItem(MODEL_SETUP_2ND_COLUMN, y, STR_PERSISTENT, STR_VPERSISTENT, g_model.timers[1].persistent, 0, 2, attr, event); break; #endif #if TIMERS > 2 case ITEM_MODEL_TIMER3: editTimerMode(2, y, attr, event); break; case ITEM_MODEL_TIMER3_NAME: editSingleName(MODEL_SETUP_2ND_COLUMN, y, STR_TIMER_NAME, g_model.timers[2].name, LEN_TIMER_NAME, event, attr); break; case ITEM_MODEL_TIMER3_MINUTE_BEEP: g_model.timers[2].minuteBeep = onoffMenuItem(g_model.timers[2].minuteBeep, MODEL_SETUP_2ND_COLUMN, y, STR_MINUTEBEEP, attr, event); break; case ITEM_MODEL_TIMER3_COUNTDOWN_BEEP: g_model.timers[2].countdownBeep = selectMenuItem(MODEL_SETUP_2ND_COLUMN, y, STR_BEEPCOUNTDOWN, STR_VBEEPCOUNTDOWN, g_model.timers[2].countdownBeep, COUNTDOWN_SILENT, COUNTDOWN_COUNT-1, attr, event); break; case ITEM_MODEL_TIMER3_PERSISTENT: g_model.timers[2].persistent = selectMenuItem(MODEL_SETUP_2ND_COLUMN, y, STR_PERSISTENT, STR_VPERSISTENT, g_model.timers[2].persistent, 0, 2, attr, event); break; #endif #if defined(REV9E) case ITEM_MODEL_TOP_LCD_TIMER: lcd_putsLeft(y, STR_TOPLCDTIMER); putsStrIdx(MODEL_SETUP_2ND_COLUMN, y, STR_TIMER, g_model.topLcdTimer+1, attr); if (attr) { g_model.topLcdTimer = checkIncDec(event, g_model.topLcdTimer, 0, TIMERS-1, EE_MODEL); } break; #endif case ITEM_MODEL_EXTENDED_LIMITS: ON_OFF_MENU_ITEM(g_model.extendedLimits, MODEL_SETUP_2ND_COLUMN, y, STR_ELIMITS, attr, event); break; case ITEM_MODEL_EXTENDED_TRIMS: ON_OFF_MENU_ITEM(g_model.extendedTrims, MODEL_SETUP_2ND_COLUMN, y, STR_ETRIMS, menuHorizontalPosition<=0 ? attr : 0, event==EVT_KEY_BREAK(KEY_ENTER) ? event : 0); lcd_putsAtt(MODEL_SETUP_2ND_COLUMN+3*FW, y, STR_RESET_BTN, (menuHorizontalPosition>0 && !NO_HIGHLIGHT()) ? attr : 0); if (attr && menuHorizontalPosition>0) { s_editMode = 0; if (event==EVT_KEY_LONG(KEY_ENTER)) { START_NO_HIGHLIGHT(); for (uint8_t i=0; i<MAX_FLIGHT_MODES; i++) { memclear(&g_model.flightModeData[i], TRIMS_ARRAY_SIZE); } eeDirty(EE_MODEL); AUDIO_WARNING1(); } } break; case ITEM_MODEL_DISPLAY_TRIMS: g_model.displayTrims = selectMenuItem(MODEL_SETUP_2ND_COLUMN, y, STR_DISPLAY_TRIMS, STR_VDISPLAYTRIMS, g_model.displayTrims, 0, 2, attr, event); break; case ITEM_MODEL_TRIM_INC: g_model.trimInc = selectMenuItem(MODEL_SETUP_2ND_COLUMN, y, STR_TRIMINC, STR_VTRIMINC, g_model.trimInc, -2, 2, attr, event); break; case ITEM_MODEL_THROTTLE_LABEL: lcd_putsLeft(y, STR_THROTTLE_LABEL); break; case ITEM_MODEL_THROTTLE_REVERSED: ON_OFF_MENU_ITEM(g_model.throttleReversed, MODEL_SETUP_2ND_COLUMN, y, STR_THROTTLEREVERSE, attr, event ) ; break; case ITEM_MODEL_THROTTLE_TRACE: { lcd_putsLeft(y, STR_TTRACE); if (attr) CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, g_model.thrTraceSrc, NUM_POTS+NUM_CHNOUT, isThrottleSourceAvailable); uint8_t idx = g_model.thrTraceSrc + MIXSRC_Thr; if (idx > MIXSRC_Thr) idx += 1; if (idx >= MIXSRC_FIRST_POT+NUM_POTS) idx += MIXSRC_CH1 - MIXSRC_FIRST_POT - NUM_POTS; putsMixerSource(MODEL_SETUP_2ND_COLUMN, y, idx, attr); break; } case ITEM_MODEL_THROTTLE_TRIM: ON_OFF_MENU_ITEM(g_model.thrTrim, MODEL_SETUP_2ND_COLUMN, y, STR_TTRIM, attr, event); break; case ITEM_MODEL_PREFLIGHT_LABEL: lcd_putsLeft(y, STR_PREFLIGHT); break; case ITEM_MODEL_CHECKLIST_DISPLAY: ON_OFF_MENU_ITEM(g_model.displayChecklist, MODEL_SETUP_2ND_COLUMN, y, STR_CHECKLIST, attr, event); break; case ITEM_MODEL_THROTTLE_WARNING: g_model.disableThrottleWarning = !onoffMenuItem(!g_model.disableThrottleWarning, MODEL_SETUP_2ND_COLUMN, y, STR_THROTTLEWARNING, attr, event); break; #if defined(REV9E) case ITEM_MODEL_SWITCHES_WARNING2: case ITEM_MODEL_SWITCHES_WARNING3: case ITEM_MODEL_POTS_WARNING2: if (i==0) { if (CURSOR_MOVED_LEFT(event)) menuVerticalOffset--; else menuVerticalOffset++; } break; #endif case ITEM_MODEL_SWITCHES_WARNING: { #if defined(REV9E) if (i>=NUM_BODY_LINES-2 && getSwitchWarningsCount() > 8*(NUM_BODY_LINES-i)) { if (CURSOR_MOVED_LEFT(event)) menuVerticalOffset--; else menuVerticalOffset++; break; } #endif lcd_putsLeft(y, STR_SWITCHWARNING); swarnstate_t states = g_model.switchWarningState; char c; if (attr) { s_editMode = 0; if (!READ_ONLY()) { switch (event) { CASE_EVT_ROTARY_BREAK case EVT_KEY_BREAK(KEY_ENTER): break; case EVT_KEY_LONG(KEY_ENTER): if (menuHorizontalPosition < 0) { START_NO_HIGHLIGHT(); getMovedSwitch(); g_model.switchWarningState = switches_states; AUDIO_WARNING1(); eeDirty(EE_MODEL); } killEvents(event); break; } } } LcdFlags line = attr; int current = 0; for (int i=0; i<NUM_SWITCHES; i++) { if (SWITCH_WARNING_ALLOWED(i)) { div_t qr = div(current, 8); if (!READ_ONLY() && event==EVT_KEY_BREAK(KEY_ENTER) && line && l_posHorz==current) { g_model.switchWarningEnable ^= (1 << i); eeDirty(EE_MODEL); } uint8_t swactive = !(g_model.switchWarningEnable & (1<<i)); c = "\300-\301"[states & 0x03]; lcd_putcAtt(MODEL_SETUP_2ND_COLUMN+qr.rem*(2*FW+1), y+FH*qr.quot, 'A'+i, line && (menuHorizontalPosition==current) ? INVERS : 0); if (swactive) lcd_putc(lcdNextPos, y+FH*qr.quot, c); ++current; } states >>= 2; } if (attr && menuHorizontalPosition < 0) { #if defined(REV9E) drawFilledRect(MODEL_SETUP_2ND_COLUMN-1, y-1, 8*(2*FW+1), 1+FH*((current+7)/8)); #else drawFilledRect(MODEL_SETUP_2ND_COLUMN-1, y-1, current*(2*FW+1), FH+1); #endif } break; } case ITEM_MODEL_POTS_WARNING: #if defined(REV9E) if (i==NUM_BODY_LINES-1 && g_model.potsWarnMode) { if (CURSOR_MOVED_LEFT(event)) menuVerticalOffset--; else menuVerticalOffset++; break; } #endif lcd_putsLeft(y, STR_POTWARNING); lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN, y, PSTR("\004""OFF\0""Man\0""Auto"), g_model.potsWarnMode, (menuHorizontalPosition == 0) ? attr : 0); if (attr && (menuHorizontalPosition == 0)) { CHECK_INCDEC_MODELVAR(event, g_model.potsWarnMode, POTS_WARN_OFF, POTS_WARN_AUTO); eeDirty(EE_MODEL); } if (attr) { if (menuHorizontalPosition > 0) s_editMode = 0; if (!READ_ONLY() && menuHorizontalPosition > 0) { switch (event) { case EVT_KEY_LONG(KEY_ENTER): killEvents(event); if (g_model.potsWarnMode == POTS_WARN_MANUAL) { SAVE_POT_POSITION(menuHorizontalPosition-1); AUDIO_WARNING1(); eeDirty(EE_MODEL); } break; case EVT_KEY_BREAK(KEY_ENTER): g_model.potsWarnEnabled ^= (1 << (menuHorizontalPosition-1)); eeDirty(EE_MODEL); break; } } } if (g_model.potsWarnMode) { coord_t x = MODEL_SETUP_2ND_COLUMN+28; for (int i=0; i<NUM_POTS; ++i) { if (i<NUM_XPOTS && !IS_POT_AVAILABLE(POT1+i)) { if (attr && (menuHorizontalPosition==i+1)) REPEAT_LAST_CURSOR_MOVE(); } else { #if defined(REV9E) if (i == NUM_XPOTS) { y += FH; x = MODEL_SETUP_2ND_COLUMN; } #endif LcdFlags flags = ((menuHorizontalPosition==i+1) && attr) ? BLINK : 0; if ((!attr || menuHorizontalPosition >= 0) && !(g_model.potsWarnEnabled & (1 << i))) { flags |= INVERS; } // TODO add a new function lcd_putsnAtt(x, y, STR_VSRCRAW+2+STR_VSRCRAW[0]*(NUM_STICKS+1+i), STR_VSRCRAW[0]-1, flags & ~ZCHAR); x = lcdNextPos+3; } } } if (attr && menuHorizontalPosition < 0) { #if defined(REV9E) drawFilledRect(MODEL_SETUP_2ND_COLUMN-1, y-FH-1, LCD_W-MODEL_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH+1, 2*FH+1); #else drawFilledRect(MODEL_SETUP_2ND_COLUMN-1, y-1, LCD_W-MODEL_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH+1, FH+1); #endif } break; case ITEM_MODEL_BEEP_CENTER: { lcd_putsLeft(y, STR_BEEPCTR); coord_t x = MODEL_SETUP_2ND_COLUMN; for (int i=0; i<NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS; i++) { if (i>=POT1 && i<POT1+NUM_XPOTS && !IS_POT_AVAILABLE(i)) { if (attr && menuHorizontalPosition == i) REPEAT_LAST_CURSOR_MOVE(); continue; } lcd_putsiAtt(x, y, STR_RETA123, i, ((menuHorizontalPosition==i) && attr) ? BLINK|INVERS : (((g_model.beepANACenter & ((BeepANACenter)1<<i)) || (attr && CURSOR_ON_LINE())) ? INVERS : 0 ) ); x += FW; } if (attr && CURSOR_ON_CELL) { if (event==EVT_KEY_BREAK(KEY_ENTER)) { if (READ_ONLY_UNLOCKED()) { s_editMode = 0; g_model.beepANACenter ^= ((BeepANACenter)1<<menuHorizontalPosition); eeDirty(EE_MODEL); } } } break; } case ITEM_MODEL_USE_GLOBAL_FUNCTIONS: lcd_putsLeft(y, STR_USE_GLOBAL_FUNCS); menu_lcd_onoff(MODEL_SETUP_2ND_COLUMN, y, !g_model.noGlobalFunctions, attr); if (attr) g_model.noGlobalFunctions = !checkIncDecModel(event, !g_model.noGlobalFunctions, 0, 1); break; case ITEM_MODEL_INTERNAL_MODULE_LABEL: lcd_putsLeft(y, TR_INTERNALRF); break; #if defined(TARANIS_INTERNAL_PPM) case ITEM_MODEL_INTERNAL_MODULE_MODE: lcd_putsLeft(y, STR_MODE); lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN, y, STR_TARANIS_PROTOCOLS, g_model.moduleData[INTERNAL_MODULE].type, menuHorizontalPosition==0 ? attr : 0); if (IS_MODULE_XJT(INTERNAL_MODULE)) lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_XJT_PROTOCOLS, 1+g_model.moduleData[INTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0); if (attr && s_editMode>0) { switch (menuHorizontalPosition) { case 0: g_model.moduleData[INTERNAL_MODULE].type = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_COUNT-2, EE_MODEL, isModuleAvailable); if (checkIncDec_Ret) { g_model.moduleData[INTERNAL_MODULE].rfProtocol = 0; g_model.moduleData[INTERNAL_MODULE].channelsStart = 0; g_model.moduleData[INTERNAL_MODULE].channelsCount = 0; } break; case 1: g_model.moduleData[INTERNAL_MODULE].rfProtocol = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].rfProtocol, RF_PROTO_X16, RF_PROTO_LAST, EE_MODEL, isRfProtocolAvailable); if (checkIncDec_Ret) { g_model.moduleData[INTERNAL_MODULE].channelsStart = 0; g_model.moduleData[INTERNAL_MODULE].channelsCount = 0; } } } break; #else case ITEM_MODEL_INTERNAL_MODULE_MODE: lcd_putsLeft(y, STR_MODE); lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN, y, STR_XJT_PROTOCOLS, 1+g_model.moduleData[0].rfProtocol, attr); if (attr) { g_model.moduleData[INTERNAL_MODULE].rfProtocol = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].rfProtocol, RF_PROTO_OFF, RF_PROTO_LAST, EE_MODEL, isRfProtocolAvailable); if (checkIncDec_Ret) { g_model.moduleData[0].type = MODULE_TYPE_XJT; g_model.moduleData[0].channelsStart = 0; g_model.moduleData[0].channelsCount = 0; } } break; #endif case ITEM_MODEL_TRAINER_MODE: g_model.trainerMode = selectMenuItem(MODEL_SETUP_2ND_COLUMN, y, STR_MODE, STR_VTRAINERMODES, g_model.trainerMode, 0, HAS_WIRELESS_TRAINER_HARDWARE() ? TRAINER_MODE_MASTER_BATTERY_COMPARTMENT : TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE, attr, event); break; case ITEM_MODEL_EXTERNAL_MODULE_LABEL: lcd_putsLeft(y, TR_EXTERNALRF); break; case ITEM_MODEL_EXTERNAL_MODULE_MODE: lcd_putsLeft(y, STR_MODE); lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN, y, STR_TARANIS_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].type, menuHorizontalPosition==0 ? attr : 0); if (IS_MODULE_XJT(EXTERNAL_MODULE)) lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_XJT_PROTOCOLS, 1+g_model.moduleData[EXTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0); else if (IS_MODULE_DSM2(EXTERNAL_MODULE)) lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_DSM_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0); if (attr && s_editMode>0) { switch (menuHorizontalPosition) { case 0: g_model.moduleData[EXTERNAL_MODULE].type = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_COUNT-1, EE_MODEL, isModuleAvailable); if (checkIncDec_Ret) { g_model.moduleData[EXTERNAL_MODULE].rfProtocol = 0; g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0; g_model.moduleData[EXTERNAL_MODULE].channelsCount = 0; } break; case 1: if (IS_MODULE_DSM2(EXTERNAL_MODULE)) CHECK_INCDEC_MODELVAR(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, DSM2_PROTO_LP45, DSM2_PROTO_DSMX); else g_model.moduleData[EXTERNAL_MODULE].rfProtocol = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, RF_PROTO_X16, RF_PROTO_LAST, EE_MODEL, isRfProtocolAvailable); if (checkIncDec_Ret) { g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0; g_model.moduleData[EXTERNAL_MODULE].channelsCount = 0; } } } break; case ITEM_MODEL_TRAINER_LABEL: lcd_putsLeft(y, STR_TRAINER); break; case ITEM_MODEL_INTERNAL_MODULE_CHANNELS: case ITEM_MODEL_EXTERNAL_MODULE_CHANNELS: case ITEM_MODEL_TRAINER_CHANNELS: { uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); ModuleData & moduleData = g_model.moduleData[moduleIdx]; lcd_putsLeft(y, STR_CHANNELRANGE); if ((int8_t)PORT_CHANNELS_ROWS(moduleIdx) >= 0) { lcd_putsAtt(MODEL_SETUP_2ND_COLUMN, y, STR_CH, menuHorizontalPosition==0 ? attr : 0); lcd_outdezAtt(lcdLastPos, y, moduleData.channelsStart+1, LEFT | (menuHorizontalPosition==0 ? attr : 0)); lcd_putc(lcdLastPos, y, '-'); lcd_outdezAtt(lcdLastPos + FW+1, y, moduleData.channelsStart+NUM_CHANNELS(moduleIdx), LEFT | (menuHorizontalPosition==1 ? attr : 0)); if (attr && s_editMode>0) { switch (menuHorizontalPosition) { case 0: CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.channelsStart, 32-8-moduleData.channelsCount); break; case 1: CHECK_INCDEC_MODELVAR(event, moduleData.channelsCount, -4, min<int8_t>(MAX_CHANNELS(moduleIdx), 32-8-moduleData.channelsStart)); #if defined(TARANIS_INTERNAL_PPM) if ((k == ITEM_MODEL_EXTERNAL_MODULE_CHANNELS && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) || (k == ITEM_MODEL_INTERNAL_MODULE_CHANNELS && g_model.moduleData[INTERNAL_MODULE].type == MODULE_TYPE_PPM) || (k == ITEM_MODEL_TRAINER_CHANNELS)) { SET_DEFAULT_PPM_FRAME_LENGTH(moduleIdx); } #else if ((k == ITEM_MODEL_EXTERNAL_MODULE_CHANNELS && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) || (k == ITEM_MODEL_TRAINER_CHANNELS)) { SET_DEFAULT_PPM_FRAME_LENGTH(moduleIdx); } #endif break; } } } break; } case ITEM_MODEL_INTERNAL_MODULE_BIND: case ITEM_MODEL_EXTERNAL_MODULE_BIND: case ITEM_MODEL_TRAINER_SETTINGS: { uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); ModuleData & moduleData = g_model.moduleData[moduleIdx]; if (IS_MODULE_PPM(moduleIdx)) { lcd_putsLeft(y, STR_PPMFRAME); lcd_puts(MODEL_SETUP_2ND_COLUMN+3*FW, y, STR_MS); lcd_outdezAtt(MODEL_SETUP_2ND_COLUMN, y, (int16_t)moduleData.ppmFrameLength*5 + 225, (menuHorizontalPosition<=0 ? attr : 0) | PREC1|LEFT); lcd_putc(MODEL_SETUP_2ND_COLUMN+8*FW+2, y, 'u'); lcd_outdezAtt(MODEL_SETUP_2ND_COLUMN+8*FW+2, y, (moduleData.ppmDelay*50)+300, (CURSOR_ON_LINE() || menuHorizontalPosition==1) ? attr : 0); lcd_putcAtt(MODEL_SETUP_2ND_COLUMN+10*FW, y, moduleData.ppmPulsePol ? '+' : '-', (CURSOR_ON_LINE() || menuHorizontalPosition==2) ? attr : 0); if (attr && s_editMode>0) { switch (menuHorizontalPosition) { case 0: CHECK_INCDEC_MODELVAR(event, moduleData.ppmFrameLength, -20, 35); break; case 1: CHECK_INCDEC_MODELVAR(event, moduleData.ppmDelay, -4, 10); break; case 2: CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.ppmPulsePol, 1); break; } } } else { horzpos_t l_posHorz = menuHorizontalPosition; coord_t xOffsetBind = MODEL_SETUP_BIND_OFS; if (IS_MODULE_XJT(moduleIdx) && g_model.moduleData[moduleIdx].rfProtocol == RF_PROTO_D8) { xOffsetBind = 0; lcd_putsLeft(y, INDENT "Receiver"); if (attr) l_posHorz += 1; } else { lcd_putsLeft(y, STR_RXNUM); } if (IS_MODULE_XJT(moduleIdx) || IS_MODULE_DSM2(moduleIdx)) { if (xOffsetBind) lcd_outdezNAtt(MODEL_SETUP_2ND_COLUMN, y, g_model.header.modelId[moduleIdx], (l_posHorz==0 ? attr : 0) | LEADING0|LEFT, 2); if (attr && l_posHorz==0) { if (s_editMode>0) { CHECK_INCDEC_MODELVAR_ZERO(event, g_model.header.modelId[moduleIdx], IS_MODULE_DSM2(moduleIdx) ? 20 : 63); if (checkIncDec_Ret) { modelHeaders[g_eeGeneral.currModel].modelId[moduleIdx] = g_model.header.modelId[moduleIdx]; } } if (s_editMode==0 && event==EVT_KEY_BREAK(KEY_ENTER)) { checkModelIdUnique(g_eeGeneral.currModel, moduleIdx); } } lcd_putsAtt(MODEL_SETUP_2ND_COLUMN+xOffsetBind, y, STR_MODULE_BIND, l_posHorz==1 ? attr : 0); lcd_putsAtt(MODEL_SETUP_2ND_COLUMN+MODEL_SETUP_RANGE_OFS+xOffsetBind, y, STR_MODULE_RANGE, l_posHorz==2 ? attr : 0); uint8_t newFlag = 0; if (attr && l_posHorz>0 && s_editMode>0) { if (l_posHorz == 1) newFlag = MODULE_BIND; else if (l_posHorz == 2) { newFlag = MODULE_RANGECHECK; } } moduleFlag[moduleIdx] = newFlag; } } break; } case ITEM_MODEL_INTERNAL_MODULE_FAILSAFE: case ITEM_MODEL_EXTERNAL_MODULE_FAILSAFE: { uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); ModuleData & moduleData = g_model.moduleData[moduleIdx]; lcd_putsLeft(y, TR_FAILSAFE); if (IS_MODULE_XJT(moduleIdx)) { lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN, y, STR_VFAILSAFE, moduleData.failsafeMode, menuHorizontalPosition==0 ? attr : 0); if (moduleData.failsafeMode == FAILSAFE_CUSTOM) lcd_putsAtt(MODEL_SETUP_2ND_COLUMN + MODEL_SETUP_SET_FAILSAFE_OFS, y, STR_SET, menuHorizontalPosition==1 ? attr : 0); if (attr) { if (moduleData.failsafeMode != FAILSAFE_CUSTOM) { menuHorizontalPosition = 0; } if (menuHorizontalPosition == 0) { if (s_editMode > 0) { CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.failsafeMode, FAILSAFE_LAST); if (checkIncDec_Ret) SEND_FAILSAFE_NOW(moduleIdx); } } else if (menuHorizontalPosition == 1) { s_editMode = 0; if (moduleData.failsafeMode==FAILSAFE_CUSTOM && event==EVT_KEY_FIRST(KEY_ENTER)) { g_moduleIdx = moduleIdx; pushMenu(menuModelFailsafe); } } else { drawFilledRect(MODEL_SETUP_2ND_COLUMN, y, LCD_W-MODEL_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8); } } } break; } } } #if defined(PXX) if (IS_RANGECHECK_ENABLE()) { displayPopup("RSSI: "); lcd_outdezAtt(16+4*FW, 5*FH, TELEMETRY_RSSI(), BOLD); } #endif }
void po::drawFilledRect(poRect rect) { drawFilledRect(rect.x, rect.y, rect.width, rect.height); }