/*luadoc @function killEvents(key) Stops key state machine. @param key (number) key to be killed, can also include event type (only key part is used) @status current Introduced in 2.0.0 TODO table of events/masks */ static int luaKillEvents(lua_State *L) { uint8_t key = EVT_KEY_MASK(luaL_checkinteger(L, 1)); // prevent killing PAGE, ENT and EXIT (only in telemetry scripts) // todo add which tpye of scrip is running before p_call() if (key != KEY_EXIT && key != KEY_ENTER && key != KEY_PAGE) { killEvents(key); } return 0; }
uint8_t getEvent(bool trim) { uint8_t evt = s_evt; int8_t k = EVT_KEY_MASK(s_evt) - TRM_BASE; bool trim_evt = (k>=0 && k<8); if (trim == trim_evt) { s_evt = 0; return evt; } else { return 0; } }
void menuGeneralSdManager(uint8_t _event) { if (s_warning_result) { s_warning_result = 0; displayPopup(STR_FORMATTING); closeLogs(); audioQueue.stopSD(); if (f_mkfs(0, 1, 0) == FR_OK) { f_chdir("/"); REFRESH_FILES(); } else { POPUP_WARNING(STR_SDCARD_ERROR); } } int lastPos = m_posVert; uint8_t event = (EVT_KEY_MASK(_event) == KEY_ENTER ? 0 : _event); SIMPLE_MENU(SD_IS_HC() ? STR_SDHC_CARD : STR_SD_CARD, menuTabGeneral, e_Sd, reusableBuffer.sdmanager.count); int index = m_posVert-s_pgOfs; switch(_event) { case EVT_ENTRY: f_chdir(ROOT_PATH); REFRESH_FILES(); lastPos = -1; break; case EVT_KEY_LONG(KEY_MENU): if (!READ_ONLY() && s_editMode == 0) { killEvents(_event); MENU_ADD_ITEM(STR_SD_INFO); MENU_ADD_ITEM(STR_SD_FORMAT); menuHandler = onSdManagerMenu; } break; case EVT_KEY_BREAK(KEY_EXIT): REFRESH_FILES(); break; case EVT_KEY_BREAK(KEY_ENTER): if (s_editMode > 0) { break; } else { if (!reusableBuffer.sdmanager.lines[index][SD_SCREEN_FILE_LENGTH+1]) { f_chdir(reusableBuffer.sdmanager.lines[index]); s_pgOfs = 0; m_posVert = 1; index = 1; REFRESH_FILES(); killEvents(_event); return; } } // no break case EVT_KEY_LONG(KEY_ENTER): if (s_editMode == 0) { killEvents(_event); char *line = reusableBuffer.sdmanager.lines[index]; char *ext = getFileExtension(line, SD_SCREEN_FILE_LENGTH+1); if (ext) { if (!strcasecmp(ext, SOUNDS_EXT)) { MENU_ADD_ITEM(STR_PLAY_FILE); } else if (!strcasecmp(ext, BITMAPS_EXT)) { if (!READ_ONLY() && (ext-line) <= (int)sizeof(g_model.header.bitmap)) { MENU_ADD_ITEM(STR_ASSIGN_BITMAP); } } else if (!strcasecmp(ext, TEXT_EXT)) { MENU_ADD_ITEM(STR_VIEW_TEXT); } #if defined(LUA) else if (!strcasecmp(ext, SCRIPTS_EXT)) { MENU_ADD_ITEM(STR_EXECUTE_FILE); } #endif else if (!READ_ONLY() && !strcasecmp(ext, FIRMWARE_EXT)) { TCHAR lfn[_MAX_LFN + 1]; getSelectionFullPath(lfn); if (isBootloader(lfn)) { MENU_ADD_ITEM(STR_FLASH_BOOTLOADER); } } else if (!READ_ONLY() && !strcasecmp(ext, SPORT_FIRMWARE_EXT)) { MENU_ADD_ITEM(STR_FLASH_EXTERNAL_DEVICE); MENU_ADD_ITEM(STR_FLASH_INTERNAL_MODULE); } } if (!READ_ONLY()) { if (line[SD_SCREEN_FILE_LENGTH+1]) // it's a file MENU_ADD_ITEM(STR_COPY_FILE); if (clipboard.type == CLIPBOARD_TYPE_SD_FILE) MENU_ADD_ITEM(STR_PASTE); MENU_ADD_ITEM(STR_RENAME_FILE); MENU_ADD_ITEM(STR_DELETE_FILE); } menuHandler = onSdManagerMenu; } break; } if (reusableBuffer.sdmanager.offset != s_pgOfs) { FILINFO fno; DIR dir; char *fn; /* This function is assuming non-Unicode cfg. */ TCHAR lfn[_MAX_LFN + 1]; fno.lfname = lfn; fno.lfsize = sizeof(lfn); if (s_pgOfs == 0) { reusableBuffer.sdmanager.offset = 0; memset(reusableBuffer.sdmanager.lines, 0, sizeof(reusableBuffer.sdmanager.lines)); } else if (s_pgOfs == reusableBuffer.sdmanager.count-7) { reusableBuffer.sdmanager.offset = s_pgOfs; memset(reusableBuffer.sdmanager.lines, 0, sizeof(reusableBuffer.sdmanager.lines)); } else if (s_pgOfs > reusableBuffer.sdmanager.offset) { memmove(reusableBuffer.sdmanager.lines[0], reusableBuffer.sdmanager.lines[1], 6*sizeof(reusableBuffer.sdmanager.lines[0])); memset(reusableBuffer.sdmanager.lines[6], 0xff, SD_SCREEN_FILE_LENGTH); reusableBuffer.sdmanager.lines[6][SD_SCREEN_FILE_LENGTH+1] = 1; } else { memmove(reusableBuffer.sdmanager.lines[1], reusableBuffer.sdmanager.lines[0], 6*sizeof(reusableBuffer.sdmanager.lines[0])); memset(reusableBuffer.sdmanager.lines[0], 0, sizeof(reusableBuffer.sdmanager.lines[0])); } reusableBuffer.sdmanager.count = 0; FRESULT res = f_opendir(&dir, "."); /* Open the directory */ if (res == FR_OK) { for (;;) { res = f_readdir(&dir, &fno); /* Read a directory item */ if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ if (fno.fname[0] == '.' && fno.fname[1] == '\0') continue; /* Ignore dot entry */ #if _USE_LFN fn = *fno.lfname ? fno.lfname : fno.fname; #else fn = fno.fname; #endif if (strlen(fn) > SD_SCREEN_FILE_LENGTH) continue; reusableBuffer.sdmanager.count++; bool isfile = !(fno.fattrib & AM_DIR); if (s_pgOfs == 0) { for (int i=0; i<NUM_BODY_LINES; i++) { char *line = reusableBuffer.sdmanager.lines[i]; if (line[0] == '\0' || isFilenameLower(isfile, fn, line)) { if (i < 6) memmove(reusableBuffer.sdmanager.lines[i+1], line, sizeof(reusableBuffer.sdmanager.lines[i]) * (6-i)); memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[i])); strcpy(line, fn); line[SD_SCREEN_FILE_LENGTH+1] = isfile; break; } } } else if (reusableBuffer.sdmanager.offset == s_pgOfs) { for (int8_t i=6; i>=0; i--) { char *line = reusableBuffer.sdmanager.lines[i]; if (line[0] == '\0' || isFilenameGreater(isfile, fn, line)) { if (i > 0) memmove(reusableBuffer.sdmanager.lines[0], reusableBuffer.sdmanager.lines[1], sizeof(reusableBuffer.sdmanager.lines[0]) * i); memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[i])); strcpy(line, fn); line[SD_SCREEN_FILE_LENGTH+1] = isfile; break; } } } else if (s_pgOfs > reusableBuffer.sdmanager.offset) { if (isFilenameGreater(isfile, fn, reusableBuffer.sdmanager.lines[5]) && isFilenameLower(isfile, fn, reusableBuffer.sdmanager.lines[6])) { memset(reusableBuffer.sdmanager.lines[6], 0, sizeof(reusableBuffer.sdmanager.lines[0])); strcpy(reusableBuffer.sdmanager.lines[6], fn); reusableBuffer.sdmanager.lines[6][SD_SCREEN_FILE_LENGTH+1] = isfile; } } else { if (isFilenameLower(isfile, fn, reusableBuffer.sdmanager.lines[1]) && isFilenameGreater(isfile, fn, reusableBuffer.sdmanager.lines[0])) { memset(reusableBuffer.sdmanager.lines[0], 0, sizeof(reusableBuffer.sdmanager.lines[0])); strcpy(reusableBuffer.sdmanager.lines[0], fn); reusableBuffer.sdmanager.lines[0][SD_SCREEN_FILE_LENGTH+1] = isfile; } } } } } reusableBuffer.sdmanager.offset = s_pgOfs; for (int i=0; i<NUM_BODY_LINES; i++) { coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH; lcdNextPos = 0; LcdFlags attr = (index == i ? BSS|INVERS : BSS); if (reusableBuffer.sdmanager.lines[i][0]) { if (!reusableBuffer.sdmanager.lines[i][SD_SCREEN_FILE_LENGTH+1]) { lcd_putcAtt(0, y, '[', s_editMode == EDIT_MODIFY_STRING ? 0 : attr); } if (s_editMode == EDIT_MODIFY_STRING && attr) { editName(lcdNextPos, y, reusableBuffer.sdmanager.lines[i], SD_SCREEN_FILE_LENGTH-4, _event, attr, 0); if (s_editMode == 0) { unsigned int len = effectiveLen(reusableBuffer.sdmanager.lines[i], SD_SCREEN_FILE_LENGTH-LEN_FILE_EXTENSION); char * ext = getFileExtension(reusableBuffer.sdmanager.originalName, sizeof(reusableBuffer.sdmanager.originalName)); if (ext) { strAppend(&reusableBuffer.sdmanager.lines[i][len], ext); } f_rename(reusableBuffer.sdmanager.originalName, reusableBuffer.sdmanager.lines[i]); REFRESH_FILES(); } } else { lcd_putsAtt(lcdNextPos, y, reusableBuffer.sdmanager.lines[i], attr); } if (!reusableBuffer.sdmanager.lines[i][SD_SCREEN_FILE_LENGTH+1]) { lcd_putcAtt(lcdNextPos, y, ']', s_editMode == EDIT_MODIFY_STRING ? 0 : attr); } } } char *ext = getFileExtension(reusableBuffer.sdmanager.lines[index], SD_SCREEN_FILE_LENGTH+1); if (ext && !strcasecmp(ext, BITMAPS_EXT)) { if (lastPos != m_posVert) { if (bmpLoad(modelBitmap, reusableBuffer.sdmanager.lines[index], MODEL_BITMAP_WIDTH, MODEL_BITMAP_HEIGHT)) { memcpy(modelBitmap, logo_taranis, MODEL_BITMAP_SIZE); } } lcd_bmp(22*FW+2, 2*FH+FH/2, modelBitmap); } }
int16_t checkIncDec(uint8_t event, int16_t val, int16_t i_min, int16_t i_max, uint8_t i_flags) { int16_t newval = val; #if defined(DBLKEYS) uint8_t in = KEYS_PRESSED(); if (!(i_flags & NO_DBLKEYS) && (EVT_KEY_MASK(event))) { bool dblkey = true; if (DBLKEYS_PRESSED_RGT_LFT(in)) newval = -val; else if (DBLKEYS_PRESSED_RGT_UP(in)) { newval = (i_max > 100 ? 100 : i_max); } else if (DBLKEYS_PRESSED_LFT_DWN(in)) { newval = (i_min < -100 ? -100 : i_min); } else if (DBLKEYS_PRESSED_UP_DWN(in)) { newval = 0; } else { dblkey = false; } if (dblkey) { killEvents(KEY_UP); killEvents(KEY_DOWN); killEvents(KEY_RIGHT); killEvents(KEY_LEFT); event = 0; } } #endif if (event==EVT_KEY_FIRST(KEY_RIGHT) || event==EVT_KEY_REPT(KEY_RIGHT) || (s_editMode>0 && (IS_ROTARY_RIGHT(event) || event==EVT_KEY_FIRST(KEY_UP) || event==EVT_KEY_REPT(KEY_UP)))) { newval++; AUDIO_KEYPAD_UP(); } else if (event==EVT_KEY_FIRST(KEY_LEFT) || event==EVT_KEY_REPT(KEY_LEFT) || (s_editMode>0 && (IS_ROTARY_LEFT(event) || event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_REPT(KEY_DOWN)))) { newval--; AUDIO_KEYPAD_DOWN(); } if (!READ_ONLY() && i_min==0 && i_max==1 && (event==EVT_KEY_BREAK(KEY_ENTER) || IS_ROTARY_BREAK(event))) { s_editMode = 0; newval = !val; } #if defined(NAVIGATION_POT1) // change values based on P1 newval -= p1valdiff; p1valdiff = 0; #endif #if defined(AUTOSWITCH) if (i_flags & INCDEC_SWITCH) { newval = checkIncDecMovedSwitch(newval); } #endif #if defined(AUTOSOURCE) if (i_flags & INCDEC_SOURCE) { if (s_editMode>0) { int8_t source = GET_MOVED_SOURCE(i_min, i_max); if (source) { newval = source; } #if defined(AUTOSWITCH) else { uint8_t swtch = abs(getMovedSwitch()); if (swtch) { newval = switchToMix(swtch); } } #endif } } #endif if (newval > i_max || newval < i_min) { newval = (newval > i_max ? i_max : i_min); killEvents(event); AUDIO_WARNING2(); } if (newval != val) { if (!(i_flags & NO_INCDEC_MARKS) && (newval != i_max) && (newval != i_min) && (newval==0 || newval==-100 || newval==+100) && !IS_ROTARY_EVENT(event)) { pauseEvents(event); // delay before auto-repeat continues if (newval>val) // without AUDIO it's optimized, because the 2 sounds are the same AUDIO_KEYPAD_UP(); else AUDIO_KEYPAD_DOWN(); } eeDirty(i_flags & (EE_GENERAL|EE_MODEL)); checkIncDec_Ret = (newval > val ? 1 : -1); } else { checkIncDec_Ret = 0; } return newval; }
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); } } }
int16_t checkIncDec(uint8_t event, int16_t val, int16_t i_min, int16_t i_max, uint8_t i_flags) #endif { int16_t newval = val; #if defined(DBLKEYS) uint8_t in = KEYS_PRESSED(); if (EVT_KEY_MASK(event)) { bool dblkey = true; if (DBLKEYS_PRESSED_RGT_LFT(in)) newval = -val; else if (DBLKEYS_PRESSED_RGT_UP(in)) { newval = (i_max > 100 ? 100 : i_max); #if defined(CPUARM) if (i_flags & DBLKEYS_1000) newval *= 10; #endif } else if (DBLKEYS_PRESSED_LFT_DWN(in)) { newval = (i_min < -100 ? -100 : i_min); #if defined(CPUARM) if (i_flags & DBLKEYS_1000) newval *= 10; #endif } else if (DBLKEYS_PRESSED_UP_DWN(in)) newval = 0; else dblkey = false; #if defined(CPUARM) #endif if (dblkey) { killEvents(KEY_UP); killEvents(KEY_DOWN); killEvents(KEY_RIGHT); killEvents(KEY_LEFT); #if defined(PCBTARANIS) killEvents(KEY_PAGE); killEvents(KEY_MENU); killEvents(KEY_ENTER); killEvents(KEY_EXIT); #endif event = 0; } } #endif #if defined(PCBTARANIS) if (s_editMode>0 && (IS_ROTARY_RIGHT(event) || event==EVT_KEY_FIRST(KEY_UP) || event==EVT_KEY_REPT(KEY_UP))) { #else if (event==EVT_KEY_FIRST(KEY_RIGHT) || event==EVT_KEY_REPT(KEY_RIGHT) || (s_editMode>0 && (IS_ROTARY_RIGHT(event) || event==EVT_KEY_FIRST(KEY_UP) || event==EVT_KEY_REPT(KEY_UP)))) { #endif #if defined(CPUARM) do { if (IS_KEY_REPT(event) && (i_flags & INCDEC_REP10)) { newval += min(10, i_max-val); } else { newval++; } } while (isValueAvailable && !isValueAvailable(newval) && newval<=i_max); if (newval > i_max) { newval = val; killEvents(event); AUDIO_WARNING2(); } else #else newval++; #endif AUDIO_KEYPAD_UP(); } #if defined(PCBTARANIS) else if (s_editMode>0 && (IS_ROTARY_LEFT(event) || event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_REPT(KEY_DOWN))) { #else else if (event==EVT_KEY_FIRST(KEY_LEFT) || event==EVT_KEY_REPT(KEY_LEFT) || (s_editMode>0 && (IS_ROTARY_LEFT(event) || event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_REPT(KEY_DOWN)))) { #endif #if defined(CPUARM) do { if (IS_KEY_REPT(event) && (i_flags & INCDEC_REP10)) { newval -= min(10, val-i_min); } else { newval--; } } while (isValueAvailable && !isValueAvailable(newval) && newval>=i_min); if (newval < i_min) { newval = val; killEvents(event); AUDIO_WARNING2(); } else #else newval--; #endif AUDIO_KEYPAD_DOWN(); } if (!READ_ONLY() && i_min==0 && i_max==1 && (event==EVT_KEY_BREAK(KEY_ENTER) || IS_ROTARY_BREAK(event))) { s_editMode = 0; newval = !val; } #if defined(NAVIGATION_POT1) // change values based on P1 newval -= p1valdiff; p1valdiff = 0; #endif #if defined(AUTOSWITCH) if (i_flags & INCDEC_SWITCH) { if (s_editMode>0) { int8_t swtch = getMovedSwitch(); if (swtch) { #if defined(PCBTARANIS) if(swtch == SWSRC_SH2) newval = (newval == SWSRC_SH2 ? SWSRC_SH0 : SWSRC_SH2); else if(swtch != SWSRC_SH0) newval = swtch; #else if (IS_MOMENTARY(newval) && IS_MOMENTARY(swtch)) newval = -newval; else newval = swtch; #endif } } } #endif #if defined(AUTOSOURCE) if (i_flags & INCDEC_SOURCE) { if (s_editMode>0) { int8_t source = GET_MOVED_SOURCE(i_min, i_max); if (source) { newval = source; } #if defined(AUTOSWITCH) else { uint8_t swtch = abs(getMovedSwitch()); if (swtch) { newval = switchToMix(swtch); } } #endif } } #endif if (newval > i_max || newval < i_min) { newval = (newval > i_max ? i_max : i_min); killEvents(event); AUDIO_WARNING2(); } if (newval != val) { if (!(i_flags & NO_INCDEC_MARKS) && (newval != i_max) && (newval != i_min) && (newval==0 || newval==-100 || newval==+100) && !IS_ROTARY_EVENT(event)) { pauseEvents(event); // delay before auto-repeat continues if (newval>val) // without AUDIO it's optimized, because the 2 sounds are the same AUDIO_KEYPAD_UP(); else AUDIO_KEYPAD_DOWN(); } eeDirty(i_flags & (EE_GENERAL|EE_MODEL)); checkIncDec_Ret = (newval > val ? 1 : -1); } else { checkIncDec_Ret = 0; } return newval; } #if defined(CPUM64) int8_t checkIncDecModel(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max) { return checkIncDec(event, i_val, i_min, i_max, EE_MODEL); } int8_t checkIncDecModelZero(uint8_t event, int8_t i_val, int8_t i_max) { return checkIncDecModel(event, i_val, 0, i_max); } int8_t checkIncDecGen(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max) { return checkIncDec(event, i_val, i_min, i_max, EE_GENERAL); } #endif bool check_simple(check_event_t event, uint8_t curr, const MenuFuncP *menuTab, uint8_t menuTabSize, vertpos_t maxrow) { return check(event, curr, menuTab, menuTabSize, 0, 0, maxrow); } bool check_submenu_simple(check_event_t event, uint8_t maxrow) { return check_simple(event, 0, 0, 0, maxrow); } void title(const pm_char * s) { lcd_putsAtt(0, 0, s, INVERS); } #define SCROLL_TH 64 #define SCROLL_POT1_TH 32 #if defined(CPUARM) #define CURSOR_NOT_ALLOWED_IN_ROW(row) ((int8_t)MAXCOL(row) < 0) #else #define CURSOR_NOT_ALLOWED_IN_ROW(row) (MAXCOL(row) == TITLE_ROW) #endif #if defined(PCBTARANIS) #define MAXCOL_RAW(row) (horTab ? pgm_read_byte(horTab+min(row, (vertpos_t)horTabMax)) : (const uint8_t)0) #define MAXCOL(row) (MAXCOL_RAW(row) >= HIDDEN_ROW ? MAXCOL_RAW(row) : (const uint8_t)(MAXCOL_RAW(row) & (~NAVIGATION_LINE_BY_LINE))) #define COLATTR(row) (MAXCOL_RAW(row) == (uint8_t)-1 ? (const uint8_t)0 : (const uint8_t)(MAXCOL_RAW(row) & NAVIGATION_LINE_BY_LINE)) #else #define MAXCOL(row) (horTab ? pgm_read_byte(horTab+min(row, (vertpos_t)horTabMax)) : (const uint8_t)0) #endif #define INC(val, min, max) if (val<max) {val++;} else {val=min;} #define DEC(val, min, max) if (val>min) {val--;} else {val=max;} #if LCD_W >= 212 uint8_t scrollbar_X = LCD_W-1; #endif #if defined(CPUARM) bool modelHasNotes() { char filename[sizeof(MODELS_PATH)+1+sizeof(g_model.header.name)+sizeof(TEXT_EXT)] = MODELS_PATH "/"; char *buf = strcat_modelname(&filename[sizeof(MODELS_PATH)], g_eeGeneral.currModel); strcpy(buf, TEXT_EXT); return isFileAvailable(filename); }
int checkIncDec(unsigned int event, int val, int i_min, int i_max, unsigned int i_flags, IsValueAvailable isValueAvailable, const CheckIncDecStops &stops) { int newval = val; #if defined(DBLKEYS) uint32_t in = KEYS_PRESSED(); if (!(i_flags & NO_DBLKEYS) && (EVT_KEY_MASK(event))) { bool dblkey = true; if (DBLKEYS_PRESSED_RGT_LFT(in)) { if (!isValueAvailable || isValueAvailable(-val)) { newval = -val; } } else if (DBLKEYS_PRESSED_RGT_UP(in)) { newval = (i_max > stops.max() ? stops.max() : i_max); while (isValueAvailable && !isValueAvailable(newval) && newval>i_min) { --newval; } } else if (DBLKEYS_PRESSED_LFT_DWN(in)) { newval = (i_min < stops.min() ? stops.min() : i_min); while (isValueAvailable && !isValueAvailable(newval) && newval<i_max) { ++newval; } } else if (DBLKEYS_PRESSED_UP_DWN(in)) { newval = 0; } else { dblkey = false; } if (dblkey) { killEvents(KEY_UP); killEvents(KEY_DOWN); killEvents(KEY_RIGHT); killEvents(KEY_LEFT); killEvents(KEY_PAGE); killEvents(KEY_MENU); killEvents(KEY_ENTER); killEvents(KEY_EXIT); event = 0; } } #endif if (s_editMode>0 && (IS_ROTARY_RIGHT(event) || event==EVT_KEY_FIRST(KEY_UP) || event==EVT_KEY_REPT(KEY_UP))) { do { if (IS_KEY_REPT(event) && (i_flags & INCDEC_REP10)) { newval += min(10, i_max-val); } else { newval++; } } while (isValueAvailable && !isValueAvailable(newval) && newval<=i_max); if (newval > i_max) { newval = val; killEvents(event); AUDIO_WARNING2(); } else { AUDIO_KEYPAD_UP(); } } else if (s_editMode>0 && (IS_ROTARY_LEFT(event) || event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_REPT(KEY_DOWN))) { do { if (IS_KEY_REPT(event) && (i_flags & INCDEC_REP10)) { newval -= min(10, val-i_min); } else { newval--; } } while (isValueAvailable && !isValueAvailable(newval) && newval>=i_min); if (newval < i_min) { newval = val; killEvents(event); AUDIO_WARNING2(); } else { AUDIO_KEYPAD_DOWN(); } } if (!READ_ONLY() && i_min==0 && i_max==1 && (event==EVT_KEY_BREAK(KEY_ENTER) || IS_ROTARY_BREAK(event))) { s_editMode = 0; newval = !val; } #if defined(AUTOSWITCH) if (i_flags & INCDEC_SWITCH) { newval = checkIncDecMovedSwitch(newval); } #endif #if defined(AUTOSOURCE) if (i_flags & INCDEC_SOURCE) { if (s_editMode>0) { int source = GET_MOVED_SOURCE(i_min, i_max); if (source) { newval = source; } #if defined(AUTOSWITCH) else { unsigned int swtch = abs(getMovedSwitch()); if (swtch) { newval = switchToMix(swtch); } } #endif } } #endif if (newval > i_max || newval < i_min) { newval = (newval > i_max ? i_max : i_min); killEvents(event); AUDIO_WARNING2(); } if (newval != val) { if (!(i_flags & NO_INCDEC_MARKS) && (newval != i_max) && (newval != i_min) && stops.contains(newval) && !IS_ROTARY_EVENT(event)) { bool pause = (newval > val ? !stops.contains(newval+1) : !stops.contains(newval-1)); if (pause) { pauseEvents(event); // delay before auto-repeat continues if (newval>val) // without AUDIO it's optimized, because the 2 sounds are the same AUDIO_KEYPAD_UP(); else AUDIO_KEYPAD_DOWN(); } } eeDirty(i_flags & (EE_GENERAL|EE_MODEL)); checkIncDec_Ret = (newval > val ? 1 : -1); } else { checkIncDec_Ret = 0; } if (i_flags & INCDEC_SOURCE) { if (event == EVT_KEY_LONG(KEY_ENTER)) { killEvents(event); checkIncDecSelection = MIXSRC_NONE; if (i_min <= MIXSRC_FIRST_INPUT && i_max >= MIXSRC_FIRST_INPUT) { if (getFirstAvailable(MIXSRC_FIRST_INPUT, MIXSRC_LAST_INPUT, isInputAvailable) != MIXSRC_NONE) { POPUP_MENU_ADD_ITEM(STR_MENU_INPUTS); } } #if defined(LUA_MODEL_SCRIPTS) if (i_min <= MIXSRC_FIRST_LUA && i_max >= MIXSRC_FIRST_LUA) { if (getFirstAvailable(MIXSRC_FIRST_LUA, MIXSRC_LAST_LUA, isSourceAvailable) != MIXSRC_NONE) { POPUP_MENU_ADD_ITEM(STR_MENU_LUA); } } #endif if (i_min <= MIXSRC_FIRST_STICK && i_max >= MIXSRC_FIRST_STICK) POPUP_MENU_ADD_ITEM(STR_MENU_STICKS); if (i_min <= MIXSRC_FIRST_POT && i_max >= MIXSRC_FIRST_POT) POPUP_MENU_ADD_ITEM(STR_MENU_POTS); if (i_min <= MIXSRC_MAX && i_max >= MIXSRC_MAX) POPUP_MENU_ADD_ITEM(STR_MENU_MAX); #if defined(HELI) if (i_min <= MIXSRC_FIRST_HELI && i_max >= MIXSRC_FIRST_HELI) POPUP_MENU_ADD_ITEM(STR_MENU_HELI); #endif if (i_min <= MIXSRC_FIRST_TRIM && i_max >= MIXSRC_FIRST_TRIM) POPUP_MENU_ADD_ITEM(STR_MENU_TRIMS); if (i_min <= MIXSRC_FIRST_SWITCH && i_max >= MIXSRC_FIRST_SWITCH) POPUP_MENU_ADD_ITEM(STR_MENU_SWITCHES); if (i_min <= MIXSRC_FIRST_TRAINER && i_max >= MIXSRC_FIRST_TRAINER) POPUP_MENU_ADD_ITEM(STR_MENU_TRAINER); if (i_min <= MIXSRC_FIRST_CH && i_max >= MIXSRC_FIRST_CH) POPUP_MENU_ADD_ITEM(STR_MENU_CHANNELS); if (i_min <= MIXSRC_FIRST_GVAR && i_max >= MIXSRC_FIRST_GVAR && isValueAvailable(MIXSRC_FIRST_GVAR)) { POPUP_MENU_ADD_ITEM(STR_MENU_GVARS); } if (i_min <= MIXSRC_FIRST_TELEM && i_max >= MIXSRC_FIRST_TELEM) { for (int i = 0; i < MAX_SENSORS; i++) { TelemetrySensor * sensor = & g_model.telemetrySensors[i]; if (sensor->isAvailable()) { POPUP_MENU_ADD_ITEM(STR_MENU_TELEMETRY); break; } } } popupMenuHandler = onSourceLongEnterPress; } if (checkIncDecSelection != 0) { newval = checkIncDecSelection; if (checkIncDecSelection != MIXSRC_MAX) s_editMode = EDIT_MODIFY_FIELD; checkIncDecSelection = 0; } } else if (i_flags & INCDEC_SWITCH) { if (event == EVT_KEY_LONG(KEY_ENTER)) { killEvents(event); checkIncDecSelection = SWSRC_NONE; if (i_min <= SWSRC_FIRST_SWITCH && i_max >= SWSRC_LAST_SWITCH) POPUP_MENU_ADD_ITEM(STR_MENU_SWITCHES); if (i_min <= SWSRC_FIRST_TRIM && i_max >= SWSRC_LAST_TRIM) POPUP_MENU_ADD_ITEM(STR_MENU_TRIMS); if (i_min <= SWSRC_FIRST_LOGICAL_SWITCH && i_max >= SWSRC_LAST_LOGICAL_SWITCH) { for (int i = 0; i < NUM_LOGICAL_SWITCH; i++) { if (isValueAvailable && isValueAvailable(SWSRC_FIRST_LOGICAL_SWITCH+i)) { POPUP_MENU_ADD_ITEM(STR_MENU_LOGICAL_SWITCHES); break; } } } if (isValueAvailable && isValueAvailable(SWSRC_ON)) POPUP_MENU_ADD_ITEM(STR_MENU_OTHER); if (isValueAvailable && isValueAvailable(-newval)) POPUP_MENU_ADD_ITEM(STR_MENU_INVERT); popupMenuHandler = onSwitchLongEnterPress; s_editMode = EDIT_MODIFY_FIELD; } if (checkIncDecSelection != 0) { newval = (checkIncDecSelection == SWSRC_INVERT ? -newval : checkIncDecSelection); s_editMode = EDIT_MODIFY_FIELD; checkIncDecSelection = 0; } } return newval; }