void check(check_event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t menuTabSize, const pm_uint8_t *horTab, uint8_t horTabMax, vertpos_t maxrow) { vertpos_t l_posVert = menuVerticalPosition; horzpos_t l_posHorz = menuHorizontalPosition; uint8_t maxcol = MAXCOL(l_posVert); #if defined(NAVIGATION_POT1) // check pot 1 - if changed -> scroll values static int16_t p1val; static int16_t p1valprev; p1valdiff = (p1val-calibratedStick[6]) / SCROLL_POT1_TH; if (p1valdiff) { p1valdiff = (p1valprev-calibratedStick[6]) / 2; p1val = calibratedStick[6]; } p1valprev = calibratedStick[6]; #endif #if defined(NAVIGATION_POT2) // check pot 2 - if changed -> scroll menu static int16_t p2valprev; p2valdiff = (p2valprev-calibratedStick[4]) / SCROLL_TH; if (p2valdiff) p2valprev = calibratedStick[4]; #endif #if defined(NAVIGATION_POT3) // check pot 3 if changed -> cursor down/up static int16_t p3valprev; int8_t scrollUD = (p3valprev-calibratedStick[5]) / SCROLL_TH; if (scrollUD) p3valprev = calibratedStick[5]; #else #define scrollUD 0 #endif if (p2valdiff || scrollUD || p1valdiff) backlightOn(); // on keypress turn the light on if (menuTab) { uint8_t attr = 0; if (l_posVert==0 && !calibrationState) { attr = INVERS; int8_t cc = curr; if (p2valdiff) { cc = limit((int8_t)0, (int8_t)(cc - p2valdiff), (int8_t)(menuTabSize-1)); } switch(event) { #if defined(ROTARY_ENCODER_NAVIGATION) case EVT_ROTARY_BREAK: if (s_editMode < 0 && maxrow > 0) { s_editMode = 0; // TODO ? l_posVert = (horTab && horTab[1]==0xff) ? 2 : 1; l_posHorz = 0; } else { s_editMode = -1; } event = 0; break; #endif #if defined(ROTARY_ENCODER_NAVIGATION) case EVT_ROTARY_LEFT: if (s_editMode >= 0) break; #endif case EVT_KEY_FIRST(KEY_LEFT): if (curr > 0) cc = curr - 1; else cc = menuTabSize-1; break; #if defined(ROTARY_ENCODER_NAVIGATION) case EVT_ROTARY_RIGHT: if (s_editMode >= 0) break; #endif case EVT_KEY_FIRST(KEY_RIGHT): if (curr < (menuTabSize-1)) cc = curr + 1; else cc = 0; break; } if (cc != curr) { chainMenu((MenuHandlerFunc)pgm_read_adr(&menuTab[cc])); } #if defined(ROTARY_ENCODER_NAVIGATION) if (IS_RE_NAVIGATION_ENABLE() && s_editMode < 0) attr = INVERS|BLINK; #endif } calibrationState = 0; displayScreenIndex(curr, menuTabSize, attr); } DISPLAY_PROGRESS_BAR(menuTab ? lcdLastPos-2*FW-((curr+1)/10*FWNUM)-2 : 20*FW+1); if (s_editMode<=0) { if (scrollUD) { l_posVert = limit((int8_t)0, (int8_t)(l_posVert - scrollUD), (int8_t)maxrow); l_posHorz = min((uint8_t)l_posHorz, MAXCOL(l_posVert)); } if (p2valdiff && l_posVert>0) { l_posHorz = limit((int8_t)0, (int8_t)((uint8_t)l_posHorz - p2valdiff), (int8_t)maxcol); } } switch(event) { case EVT_ENTRY: l_posVert = POS_VERT_INIT; l_posHorz = POS_HORZ_INIT(l_posVert); SET_SCROLLBAR_X(LCD_W-1); #if defined(ROTARY_ENCODER_NAVIGATION) if (menuTab) { s_editMode = EDIT_MODE_INIT; break; } // no break #else s_editMode = EDIT_MODE_INIT; break; #endif #if defined(ROTARY_ENCODER_NAVIGATION) case EVT_ENTRY_UP: s_editMode = 0; SET_SCROLLBAR_X(LCD_W-1); break; case EVT_ROTARY_BREAK: if (s_editMode > 1) break; #endif case EVT_KEY_FIRST(KEY_ENTER): if (!menuTab || l_posVert>0) { if (READ_ONLY_UNLOCKED()) { s_editMode = (s_editMode<=0); } } break; #if defined(ROTARY_ENCODER_NAVIGATION) case EVT_ROTARY_LONG: if (s_editMode > 1) break; killEvents(event); if (l_posVert != POS_VERT_INIT) { l_posVert = POS_VERT_INIT; s_editMode = EDIT_MODE_INIT; break; } // no break #endif 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 defined(ROTARY_ENCODER_NAVIGATION) if (s_editMode == 0) s_editMode = EDIT_MODE_INIT; else #endif if (s_editMode>0) { s_editMode = 0; break; } if (l_posVert==0 || !menuTab) { popMenu(); // beeps itself } else { AUDIO_MENUS(); l_posVert = 0; l_posHorz = 0; } break; case EVT_KEY_REPT(KEY_RIGHT): //inc if (l_posHorz==maxcol) break; // no break case EVT_KEY_FIRST(KEY_RIGHT)://inc if (!horTab || s_editMode>0) break; #if defined(ROTARY_ENCODER_NAVIGATION) CASE_EVT_ROTARY_MOVE_RIGHT if (s_editMode != 0) break; if (l_posHorz < maxcol) { l_posHorz++; break; } else { l_posHorz = 0; if (!IS_ROTARY_MOVE_RIGHT(event)) break; } #else INC(l_posHorz, 0, maxcol); break; #endif case EVT_KEY_REPT(KEY_DOWN): //inc if (!IS_ROTARY_RIGHT(event) && l_posVert==maxrow) break; // no break case EVT_KEY_FIRST(KEY_DOWN): //inc if (s_editMode>0) break; do { INC(l_posVert, POS_VERT_INIT, maxrow); } while (CURSOR_NOT_ALLOWED_IN_ROW(l_posVert)); #if defined(ROTARY_ENCODER_NAVIGATION) s_editMode = 0; // if we go down, we must be in this mode #endif l_posHorz = min(l_posHorz, MAXCOL(l_posVert)); break; case EVT_KEY_REPT(KEY_LEFT): //dec if (l_posHorz==0) break; // no break case EVT_KEY_FIRST(KEY_LEFT)://dec if (!horTab || s_editMode>0) break; #if defined(ROTARY_ENCODER_NAVIGATION) CASE_EVT_ROTARY_MOVE_LEFT if (s_editMode != 0) break; 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; } #else DEC(l_posHorz, 0, maxcol); break; #endif case EVT_KEY_REPT(KEY_UP): //dec if (!IS_ROTARY_LEFT(event) && l_posVert==0) break; // no break case EVT_KEY_FIRST(KEY_UP): //dec if (s_editMode>0) break; do { DEC(l_posVert, POS_VERT_INIT, maxrow); } while (CURSOR_NOT_ALLOWED_IN_ROW(l_posVert)); #if defined(ROTARY_ENCODER_NAVIGATION) s_editMode = 0; // if we go up, we must be in this mode #endif l_posHorz = min((uint8_t)l_posHorz, MAXCOL(l_posVert)); break; } uint8_t maxLines = menuTab ? LCD_LINES-1 : LCD_LINES-2; if (l_posVert<1) { menuVerticalOffset=0; } else { if (l_posVert>maxLines+menuVerticalOffset) { menuVerticalOffset = l_posVert-maxLines; } else if (l_posVert<=menuVerticalOffset) { menuVerticalOffset = l_posVert-1; } } menuVerticalPosition = l_posVert; menuHorizontalPosition = l_posHorz; #if !defined(CPUM64) // cosmetics on 9x if (menuVerticalOffset > 0) { l_posVert--; if (l_posVert == menuVerticalOffset && CURSOR_NOT_ALLOWED_IN_ROW(l_posVert)) { menuVerticalOffset = l_posVert-1; } } #endif }
void menuModelFailsafe(uint8_t event) { static bool longNames = false; bool newLongNames = false; uint8_t ch = 0; uint8_t channelStart = g_model.moduleData[g_moduleIdx].channelsStart; if (event == EVT_KEY_LONG(KEY_ENTER)) { killEvents(event); event = 0; if (s_editMode) { g_model.moduleData[g_moduleIdx].failsafeChannels[menuVerticalPosition] = channelOutputs[menuVerticalPosition+channelStart]; eeDirty(EE_MODEL); AUDIO_WARNING1(); s_editMode = 0; SEND_FAILSAFE_NOW(g_moduleIdx); } else { int16_t & failsafe = g_model.moduleData[g_moduleIdx].failsafeChannels[menuVerticalPosition]; if (failsafe < FAILSAFE_CHANNEL_HOLD) failsafe = FAILSAFE_CHANNEL_HOLD; else if (failsafe == FAILSAFE_CHANNEL_HOLD) failsafe = FAILSAFE_CHANNEL_NOPULSE; else failsafe = 0; eeDirty(EE_MODEL); AUDIO_WARNING1(); SEND_FAILSAFE_NOW(g_moduleIdx); } } SIMPLE_SUBMENU_NOTITLE(NUM_CHANNELS(g_moduleIdx)); SET_SCROLLBAR_X(0); #define COL_W (LCD_W/2) const uint8_t SLIDER_W = 64; // Column separator lcd_vline(LCD_W/2, FH, LCD_H-FH); lcd_putsCenter(0*FH, FAILSAFESET); lcd_invert_line(0); unsigned int lim = g_model.extendedLimits ? 640*2 : 512*2; for (uint8_t col=0; col<2; col++) { coord_t x = col*COL_W+1; // Channels for (uint8_t line=0; line<8; line++) { coord_t y = 9+line*7; int32_t channelValue = channelOutputs[ch+channelStart]; int32_t failsafeValue = 0; bool failsafeEditable = false; uint8_t ofs = (col ? 0 : 1); if (ch < NUM_CHANNELS(g_moduleIdx)) { failsafeValue = g_model.moduleData[g_moduleIdx].failsafeChannels[8*col+line]; failsafeEditable = true; } if (failsafeEditable) { // Channel name if present, number if not uint8_t lenLabel = ZLEN(g_model.limitData[ch+channelStart].name); if (lenLabel > 4) { newLongNames = longNames = true; } if (lenLabel > 0) lcd_putsnAtt(x+1-ofs, y, g_model.limitData[ch+channelStart].name, sizeof(g_model.limitData[ch+channelStart].name), ZCHAR | SMLSIZE); else putsChn(x+1-ofs, y, ch+1, SMLSIZE); // Value LcdFlags flags = TINSIZE; if (menuVerticalPosition == ch) { flags |= INVERS; if (s_editMode) { if (failsafeValue == FAILSAFE_CHANNEL_HOLD || failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { s_editMode = 0; } else { flags |= BLINK; CHECK_INCDEC_MODELVAR(event, g_model.moduleData[g_moduleIdx].failsafeChannels[8*col+line], -lim, +lim); } } } #if defined(PPM_UNIT_PERCENT_PREC1) uint8_t wbar = (longNames ? SLIDER_W-16 : SLIDER_W-6); #else uint8_t wbar = (longNames ? SLIDER_W-10 : SLIDER_W); #endif if (failsafeValue == FAILSAFE_CHANNEL_HOLD) { lcd_putsAtt(x+COL_W-4-wbar-ofs-16, y, "HOLD", flags); failsafeValue = 0; } else if (failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { lcd_putsAtt(x+COL_W-4-wbar-ofs-16, y, "NONE", flags); failsafeValue = 0; } else { #if defined(PPM_UNIT_US) lcd_outdezAtt(x+COL_W-4-wbar-ofs, y, PPM_CH_CENTER(ch)+failsafeValue/2, flags); #elif defined(PPM_UNIT_PERCENT_PREC1) lcd_outdezAtt(x+COL_W-4-wbar-ofs, y, calcRESXto1000(failsafeValue), PREC1|flags); #else lcd_outdezAtt(x+COL_W-4-wbar-ofs, y, calcRESXto1000(failsafeValue)/10, flags); #endif } // Gauge lcd_rect(x+COL_W-3-wbar-ofs, y, wbar+1, 6); unsigned int lenChannel = limit((uint8_t)1, uint8_t((abs(channelValue) * wbar/2 + lim/2) / lim), uint8_t(wbar/2)); unsigned int lenFailsafe = limit((uint8_t)1, uint8_t((abs(failsafeValue) * wbar/2 + lim/2) / lim), uint8_t(wbar/2)); coord_t xChannel = (channelValue>0) ? x+COL_W-ofs-3-wbar/2 : x+COL_W-ofs-2-wbar/2-lenChannel; coord_t xFailsafe = (failsafeValue>0) ? x+COL_W-ofs-3-wbar/2 : x+COL_W-ofs-2-wbar/2-lenFailsafe; lcd_hlineStip(xChannel, y+1, lenChannel, DOTTED, 0); lcd_hlineStip(xChannel, y+2, lenChannel, DOTTED, 0); lcd_hline(xFailsafe, y+3, lenFailsafe); lcd_hline(xFailsafe, y+4, lenFailsafe); } ch++; } } longNames = newLongNames; }
bool check(check_event_t event, uint8_t curr, const MenuFuncP *menuTab, uint8_t menuTabSize, const pm_uint8_t *horTab, uint8_t horTabMax, vertpos_t maxrow, uint8_t flags) { vertpos_t l_posVert = m_posVert; horzpos_t l_posHorz = m_posHorz; uint8_t maxcol = MAXCOL(l_posVert); #define scrollUD 0 if (p2valdiff || scrollUD || p1valdiff) backlightOn(); // on keypress turn the light on if (menuTab) { uint8_t attr = 0; int8_t cc = curr; switch (event) { case EVT_KEY_LONG(KEY_MENU): if (menuTab == menuTabModel) { killEvents(event); if (modelHasNotes()) { MENU_ADD_SD_ITEM(STR_VIEW_CHANNELS); MENU_ADD_ITEM(STR_VIEW_NOTES); menuHandler = onLongMenuPress; } else { pushMenu(menuChannelsView); return false; } } 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((MenuFuncP)pgm_read_adr(&menuTab[cc])); return false; } if (!(flags&CHECK_FLAG_NO_SCREEN_INDEX)) { displayScreenIndex(curr, menuTabSize, attr); } lcd_filled_rect(0, 0, LCD_W, FH, SOLID, FILL_WHITE|GREY_DEFAULT); } DISPLAY_PROGRESS_BAR(menuTab ? lcdLastPos-2*FW-((curr+1)/10*FWNUM)-2 : 20*FW+1); if (s_editMode<=0) { if (scrollUD) { l_posVert = limit((int8_t)0, (int8_t)(l_posVert - scrollUD), (int8_t)maxrow); l_posHorz = min((uint8_t)l_posHorz, MAXCOL(l_posVert)); } if (p2valdiff && l_posVert>0) { l_posHorz = limit((int8_t)0, (int8_t)((uint8_t)l_posHorz - p2valdiff), (int8_t)maxcol); } } 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); #if defined(ROTARY_ENCODER_NAVIGATION) if (menuTab) { s_editMode = EDIT_MODE_INIT; break; } // no break #else s_editMode = EDIT_MODE_INIT; break; #endif 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 (m_posHorz < 0 && maxcol > 0 && READ_ONLY_UNLOCKED()) { l_posHorz = 0; break; } if (!menuTab || l_posVert>0) { if (READ_ONLY_UNLOCKED()) { s_editMode = (s_editMode<=0); } } break; #if defined(ROTARY_ENCODER_NAVIGATION) case EVT_ROTARY_LONG: if (s_editMode > 1) break; killEvents(event); if (l_posVert != POS_VERT_INIT) { l_posVert = POS_VERT_INIT; s_editMode = EDIT_MODE_INIT; break; } // no break #endif case EVT_KEY_LONG(KEY_EXIT): s_editMode = 0; // TODO needed? we call ENTRY_UP after which does the same popMenu(); return false; case EVT_KEY_BREAK(KEY_EXIT): #if defined(ROTARY_ENCODER_NAVIGATION) if (s_editMode == 0) s_editMode = EDIT_MODE_INIT; else #endif 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 (s_pgOfs != 0 || l_posVert != posVertInit) { s_pgOfs = 0; l_posVert = posVertInit; l_posHorz = POS_HORZ_INIT(l_posVert); } else { popMenu(); return false; } } 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, maxrow); } 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, maxrow); } 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; } #if defined(CPUARM) if (l_posVert<1) { s_pgOfs=0; } else if (menuTab && horTab) { if (maxrow > LCD_LINES-1) { while (1) { vertpos_t line = s_pgOfs+1; for (int numLines=0; line<=maxrow && numLines<LCD_LINES-1; line++) { if (MAXCOL(line) != HIDDEN_ROW) { numLines++; } } int max = line - s_pgOfs - 1; if (l_posVert > max+s_pgOfs) { s_pgOfs++; } else if (l_posVert < 1+s_pgOfs) { s_pgOfs--; } else { break; } } } } else { uint8_t max = menuTab ? LCD_LINES-1 : LCD_LINES-2; if (l_posVert>max+s_pgOfs) { s_pgOfs = l_posVert-max; } else if (l_posVert<1+s_pgOfs) { s_pgOfs = l_posVert-1; } } #if LCD_W >= 212 if (maxrow > LCD_LINES-1 && scrollbar_X) displayScrollbar(scrollbar_X, FH, LCD_H-FH, s_pgOfs, menuTab ? maxrow : maxrow+1, LCD_LINES-1); #endif #else uint8_t max = menuTab ? LCD_LINES-1 : LCD_LINES-2; if (l_posVert<1) s_pgOfs=0; else if (l_posVert>max+s_pgOfs) s_pgOfs = l_posVert-max; else if (l_posVert<1+s_pgOfs) s_pgOfs = l_posVert-1; #endif m_posVert = l_posVert; m_posHorz = l_posHorz; if (s_pgOfs > 0) { l_posVert--; if (l_posVert == s_pgOfs && CURSOR_NOT_ALLOWED_IN_ROW(l_posVert)) { s_pgOfs = l_posVert-1; } } return true; }
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 menuModelMixOne(uint8_t event) { if (event == EVT_KEY_LONG(KEY_MENU)) { pushMenu(menuChannelsView); killEvents(event); } TITLE(s_currCh ? STR_INSERTMIX : STR_EDITMIX); MixData *md2 = mixAddress(s_currIdx) ; putsChn(lcdLastPos+1*FW, 0, md2->destCh+1,0); SUBMENU_NOTITLE(MIX_FIELD_COUNT, {0, 0, 0, 0, 0, CASE_CURVES(1) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0, 0 /*, ...*/}); #if MENU_COLUMNS > 1 lcd_vline(MENU_COLUMN2_X-4, FH+1, LCD_H-FH-1); SET_SCROLLBAR_X(0); #endif int8_t sub = m_posVert; int8_t editMode = s_editMode; for (int k=0; k<MENU_COLUMNS*(LCD_LINES-1); k++) { coord_t y; coord_t COLUMN_X; if (k >= LCD_LINES-1) { y = 1 + (k-LCD_LINES+2)*FH; COLUMN_X = MENU_COLUMN2_X; } else { y = 1 + (k+1)*FH; COLUMN_X = 0; } int8_t i = k; #if MENU_COLUMNS < 2 i = i + s_pgOfs; #endif LcdFlags attr = (sub==i ? (editMode>0 ? BLINK|INVERS : INVERS) : 0); switch(i) { case MIX_FIELD_NAME: editSingleName(COLUMN_X+MIXES_2ND_COLUMN, y, STR_MIXNAME, md2->name, sizeof(md2->name), event, attr); break; case MIX_FIELD_SOURCE: lcd_putsColumnLeft(COLUMN_X, y, NO_INDENT(STR_SOURCE)); putsMixerSource(COLUMN_X+MIXES_2ND_COLUMN, y, md2->srcRaw, STREXPANDED|attr); if (attr) CHECK_INCDEC_MODELSOURCE(event, md2->srcRaw, 1, MIXSRC_LAST); break; case MIX_FIELD_WEIGHT: lcd_putsColumnLeft(COLUMN_X, y, STR_WEIGHT); gvarWeightItem(COLUMN_X+MIXES_2ND_COLUMN, y, md2, attr|LEFT, event); break; case MIX_FIELD_OFFSET: { lcd_putsColumnLeft(COLUMN_X, y, NO_INDENT(STR_OFFSET)); u_int8int16_t offset; MD_OFFSET_TO_UNION(md2, offset); offset.word = GVAR_MENU_ITEM(COLUMN_X+MIXES_2ND_COLUMN, y, offset.word, GV_RANGELARGE_OFFSET_NEG, GV_RANGELARGE_OFFSET, attr|LEFT, 0, event); MD_UNION_TO_OFFSET(offset, md2); drawOffsetBar(COLUMN_X+MIXES_2ND_COLUMN+22, y, md2); break; } case MIX_FIELD_TRIM: lcd_putsColumnLeft(COLUMN_X, y, STR_TRIM); menu_lcd_onoff(COLUMN_X+MIXES_2ND_COLUMN, y, !md2->carryTrim, attr); if (attr) md2->carryTrim = !checkIncDecModel(event, !md2->carryTrim, 0, 1); break; #if defined(CURVES) case MIX_FIELD_CURVE: { lcd_putsColumnLeft(COLUMN_X, y, STR_CURVE); editCurveRef(COLUMN_X+MIXES_2ND_COLUMN, y, md2->curve, event, attr); break; } #endif #if defined(FLIGHT_MODES) case MIX_FIELD_FLIGHT_PHASE: md2->flightModes = editFlightModes(COLUMN_X+MIXES_2ND_COLUMN, y, event, md2->flightModes, attr); break; #endif case MIX_FIELD_SWITCH: md2->swtch = switchMenuItem(COLUMN_X+MIXES_2ND_COLUMN, y, md2->swtch, attr, event); break; case MIX_FIELD_WARNING: lcd_putsColumnLeft(COLUMN_X+MIXES_2ND_COLUMN, y, STR_MIXWARNING); if (md2->mixWarn) lcd_outdezAtt(COLUMN_X+MIXES_2ND_COLUMN, y, md2->mixWarn, attr|LEFT); else lcd_putsAtt(COLUMN_X+MIXES_2ND_COLUMN, y, STR_OFF, attr); if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, md2->mixWarn, 3); break; case MIX_FIELD_MLTPX: md2->mltpx = selectMenuItem(COLUMN_X+MIXES_2ND_COLUMN, y, STR_MULTPX, STR_VMLTPX, md2->mltpx, 0, 2, attr, event); break; case MIX_FIELD_DELAY_UP: md2->delayUp = EDIT_DELAY(COLUMN_X, y, event, attr, STR_DELAYUP, md2->delayUp); break; case MIX_FIELD_DELAY_DOWN: md2->delayDown = EDIT_DELAY(COLUMN_X, y, event, attr, STR_DELAYDOWN, md2->delayDown); break; case MIX_FIELD_SLOW_UP: md2->speedUp = EDIT_DELAY(COLUMN_X, y, event, attr, STR_SLOWUP, md2->speedUp); break; case MIX_FIELD_SLOW_DOWN: md2->speedDown = EDIT_DELAY(COLUMN_X, y, event, attr, STR_SLOWDOWN, md2->speedDown); break; } } }
void menuModelExpoOne(uint8_t event) { if (event == EVT_KEY_LONG(KEY_MENU)) { pushMenu(menuChannelsView); killEvents(event); } ExpoData *ed = expoAddress(s_currIdx); putsMixerSource(7*FW+FW/2, 0, MIXSRC_FIRST_INPUT+ed->chn, 0); SUBMENU(STR_MENUINPUTS, EXPO_FIELD_MAX, {0, 0, 0, ed->srcRaw >= MIXSRC_FIRST_TELEM ? (uint8_t)0 : (uint8_t)HIDDEN_ROW, 0, 0, CASE_CURVES(CURVE_ROWS) CASE_FLIGHT_MODES((MAX_FLIGHT_MODES-1) | NAVIGATION_LINE_BY_LINE) 0 /*, ...*/}); SET_SCROLLBAR_X(EXPO_ONE_2ND_COLUMN+10*FW); int8_t sub = m_posVert; coord_t y = MENU_HEADER_HEIGHT + 1; for (unsigned int k=0; k<NUM_BODY_LINES; k++) { int i = k + s_pgOfs; for (int j=0; j<=i; ++j) { if (j<(int)DIM(mstate_tab) && mstate_tab[j] == HIDDEN_ROW) { ++i; } } LcdFlags attr = (sub==i ? (s_editMode>0 ? BLINK|INVERS : INVERS) : 0); switch(i) { case EXPO_FIELD_INPUT_NAME: editSingleName(EXPO_ONE_2ND_COLUMN, y, STR_INPUTNAME, g_model.inputNames[ed->chn], sizeof(g_model.inputNames[ed->chn]), event, attr); break; case EXPO_FIELD_NAME: editSingleName(EXPO_ONE_2ND_COLUMN, y, STR_EXPONAME, ed->name, sizeof(ed->name), event, attr); break; case EXPO_FIELD_SOURCE: lcd_putsLeft(y, NO_INDENT(STR_SOURCE)); putsMixerSource(EXPO_ONE_2ND_COLUMN, y, ed->srcRaw, STREXPANDED|attr); if (attr) ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isInputSourceAvailable); break; case EXPO_FIELD_SCALE: lcd_putsLeft(y, STR_SCALE); putsTelemetryChannelValue(EXPO_ONE_2ND_COLUMN, y, (ed->srcRaw - MIXSRC_FIRST_TELEM)/3, convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale), LEFT|attr); if (attr) ed->scale = checkIncDec(event, ed->scale, 0, maxTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1), EE_MODEL); break; case EXPO_FIELD_WEIGHT: lcd_putsLeft(y, STR_WEIGHT); ed->weight = GVAR_MENU_ITEM(EXPO_ONE_2ND_COLUMN, y, ed->weight, MIN_EXPO_WEIGHT, 100, LEFT|attr, 0, event); break; case EXPO_FIELD_OFFSET: lcd_putsLeft(y, NO_INDENT(STR_OFFSET)); ed->offset = GVAR_MENU_ITEM(EXPO_ONE_2ND_COLUMN, y, ed->offset, -100, 100, LEFT|attr, 0, event); break; #if defined(CURVES) case EXPO_FIELD_CURVE: lcd_putsLeft(y, STR_CURVE); editCurveRef(EXPO_ONE_2ND_COLUMN, y, ed->curve, event, attr); break; #endif #if defined(FLIGHT_MODES) case EXPO_FIELD_FLIGHT_MODES: ed->flightModes = editFlightModes(EXPO_ONE_2ND_COLUMN, y, event, ed->flightModes, attr); break; #endif case EXPO_FIELD_SWITCH: ed->swtch = switchMenuItem(EXPO_ONE_2ND_COLUMN, y, ed->swtch, attr, event); break; case EXPO_FIELD_SIDE: ed->mode = 4 - selectMenuItem(EXPO_ONE_2ND_COLUMN, y, STR_SIDE, STR_VSIDE, 4-ed->mode, 1, 3, attr, event); break; case EXPO_FIELD_TRIM: uint8_t not_stick = (ed->srcRaw > MIXSRC_Ail); int8_t carryTrim = -ed->carryTrim; lcd_putsLeft(y, STR_TRIM); lcd_putsiAtt(EXPO_ONE_2ND_COLUMN, y, STR_VMIXTRIMS, (not_stick && carryTrim == 0) ? 0 : carryTrim+1, m_posHorz==0 ? attr : 0); if (attr) ed->carryTrim = -checkIncDecModel(event, carryTrim, not_stick ? TRIM_ON : -TRIM_OFF, -TRIM_AIL); break; } y += FH; } DrawFunction(expoFn); int x512 = getValue(ed->srcRaw); if (ed->srcRaw >= MIXSRC_FIRST_TELEM) { putsTelemetryChannelValue(LCD_W-8, 6*FH, (ed->srcRaw - MIXSRC_FIRST_TELEM) / 3, x512, 0); if (ed->scale > 0) x512 = (x512 * 1024) / convertTelemValue(ed->srcRaw - MIXSRC_FIRST_TELEM + 1, ed->scale); } else { lcd_outdezAtt(LCD_W-8, 6*FH, calcRESXto1000(x512), PREC1); } x512 = limit(-1024, x512, 1024); int y512 = expoFn(x512); y512 = limit(-1024, y512, 1024); lcd_outdezAtt(LCD_W-8-6*FW, 1*FH, calcRESXto1000(y512), PREC1); x512 = X0+x512/(RESX/WCHART); y512 = (LCD_H-1) - ((y512+RESX)/2) * (LCD_H-1) / RESX; lcd_vline(x512, y512-3, 3*2+1); lcd_hline(x512-3, y512, 3*2+1); }