void debugMessage(char* text1, char* text2, int value) { int key; MsgBoxPush(4); mPrintXY(3,2,(char*)text1, TEXT_MODE_TRANSPARENT_BACKGROUND, TEXT_COLOR_BLACK); char buffer1[10]; itoa(value, (unsigned char*)buffer1); char buffer2[15]; strcpy(buffer2, text2); strcat(buffer2, buffer1); mPrintXY(3,3,(char*)buffer2, TEXT_MODE_TRANSPARENT_BACKGROUND, TEXT_COLOR_BLACK); mGetKey(&key); MsgBoxPop(); }
void textfileEditor(char* filename, char* basefolder) { int newfile = (filename == NULL); char sText[TEXT_BUFFER_SIZE] = ""; if(!newfile) { newfile = 0; int openerror = 0; int hFile = fileOpen(filename); // Get handle if(hFile >= 0) // Check if it opened { //opened unsigned int filesize = Bfile_GetFileSize_OS(hFile); if(!filesize || filesize > TEXT_BUFFER_SIZE) { openerror = 1; } else { Bfile_ReadFile_OS(hFile, sText, TEXT_BUFFER_SIZE, 0); } Bfile_CloseFile_OS(hFile); } else { openerror = 1; } if(openerror) { //Error opening file, abort AUX_DisplayErrorMessage(0x2B); // Data ERROR return; } } textEdit input; //input.forcetext=1; input.charlimit=TEXT_BUFFER_SIZE; input.buffer = (char*)sText; // calculate checksum so we can check for changes unsigned char origHash[20] = ""; sha1((unsigned char*)sText, strlen(sText), origHash); while(1) { input.key=0; int res = doTextEdit(&input); int exit = 0; switch(res) { case TEXTEDIT_RETURN_EXIT: { exit = 1; unsigned char newHash[20] = ""; sha1((unsigned char*)sText, strlen(sText), newHash); if(!memcmp(origHash, newHash, 20)) return; else { mMsgBoxPush(4); mPrintXY(3, 2, "Save this file?", TEXT_MODE_TRANSPARENT_BACKGROUND, TEXT_COLOR_BLACK); if(closeMsgBox(1, 4)) { // fall through } else { return; } } } case TEXTEDIT_RETURN_CONFIRM: { char newfilename[MAX_FILENAME_SIZE]; unsigned short newfilenameshort[0x10A]; if(newfile) { int backToEditor = 0; SetBackGround(13); drawScreenTitle("Text Editor", "Save file as:"); drawFkeyLabels(0x036F); // < textInput ninput; ninput.forcetext=1; ninput.charlimit=MAX_NAME_SIZE; char nfilename[MAX_NAME_SIZE]; nfilename[0] = 0; ninput.buffer = (char*)nfilename; while(1) { ninput.key = 0; int nres = doTextInput(&ninput); if (nres==INPUT_RETURN_EXIT || (nres==INPUT_RETURN_KEYCODE && ninput.key==KEY_CTRL_F1)) { // user aborted backToEditor = 1; break; } else if (nres==INPUT_RETURN_CONFIRM) { if(stringEndsInG3A(nfilename)) { mMsgBoxPush(4); multiPrintXY(3, 2, "g3a files can't\nbe created by\nan add-in.", TEXT_MODE_TRANSPARENT_BACKGROUND, TEXT_COLOR_BLACK); closeMsgBox(); } else { // create and save file strcpy(newfilename, basefolder); strcat(newfilename, nfilename); Bfile_StrToName_ncpy(newfilenameshort, newfilename, 0x10A); break; } } } if(backToEditor) continue; } else { // delete, then create and save file Bfile_StrToName_ncpy(newfilenameshort, filename, 0x10A); Bfile_DeleteEntry(newfilenameshort); } size_t size = strlen(sText); if(Bfile_CreateEntry_OS(newfilenameshort, CREATEMODE_FILE, &size) < 0) { //create the file // it appears file exists, overwrite? if(overwriteFilePrompt(newfilename)) { Bfile_DeleteEntry(newfilenameshort); Bfile_CreateEntry_OS(newfilenameshort, CREATEMODE_FILE, &size); } else continue; // abort file save so user can discard the file, or type another filename. } int h = Bfile_OpenFile_OS(newfilenameshort, READWRITE, 0); if(h >= 0) { // Still failing? //Write file contents Bfile_WriteFile_OS(h, sText, size); Bfile_CloseFile_OS(h); // clear unsaved changes "flag": sha1((unsigned char*)sText, strlen(sText), origHash); } if(exit) return; } break; } } }
int addTransactionWizard(char* wallet) { Transaction tx; tx.date.year = getCurrentYear(); tx.date.month = getCurrentMonth(); tx.date.day = getCurrentDay(); tx.time.hour = getCurrentHour(); tx.time.minute = getCurrentMinute(); tx.time.second = getCurrentSecond(); strcpy(tx.description, (char*)""); int curstep = 0; while(1) { SetBackGround(0x0A); drawScreenTitle("Add transaction"); // < (first label), SELECT of on date step, and Next or Finish (last label) drawFkeyLabels(curstep>0 ? 0x036F : -1, curstep == 2 ? 0x000F : 0, 0, 0, 0, curstep==4 ? 0x04A4 : 0x04A3); if(curstep == 0) { MenuItem menuitems[5]; menuitems[0].text = (char*)"Debit"; menuitems[1].text = (char*)"Credit"; Menu menu; menu.items=menuitems; menu.type=MENUTYPE_FKEYS; menu.numitems=2; menu.height=2; menu.startY=3; menu.pBaRtR=1; int inloop=1; while(inloop) { // this must be here, inside this loop: SetBackGround(0x0A); drawScreenTitle("Add transaction", "Select type:"); drawFkeyLabels(-1, -1, -1, -1, -1, 0x04A3); int res = doMenu(&menu); if(res == MENU_RETURN_EXIT) return 0; else if(res == KEY_CTRL_F6 || res == MENU_RETURN_SELECTION) { tx.credit = menu.selection == 2; curstep++; break; } } } else if(curstep == 1) { drawScreenTitle(NULL, "Amount:"); char samount[20] = ""; if(tx.amount.val) { currencyToString(samount, &tx.amount); } textInput input; input.charlimit=12; input.acceptF6=1; input.symbols = 0; // allow the decimal separator input.forcetext = 1; input.buffer = (char*)samount; input.type = INPUTTYPE_NUMERIC; while(1) { input.key=0; int res = doTextInput(&input); if (res==INPUT_RETURN_EXIT) return 0; // user aborted else if (res==INPUT_RETURN_CONFIRM) { if(!stringToCurrency(&tx.amount, samount)) { if(!tx.amount.val) { AUX_DisplayErrorMessage(0x4B); } else { curstep++; } break; } else AUX_DisplayErrorMessage(0x43); } else if (res==INPUT_RETURN_KEYCODE && input.key == KEY_CTRL_F1) { curstep--; break; } } } else if(curstep == 2) { drawScreenTitle(NULL, "Date:"); mPrintXY(7, 4, getInputDateFormatHint(), TEXT_MODE_TRANSPARENT_BACKGROUND, TEXT_COLOR_BLACK); textInput input; input.x=7; input.width=8; input.charlimit=8; input.acceptF6=1; input.type=INPUTTYPE_DATE; char datebuffer[15]; fillInputDate(&tx.date, datebuffer); input.buffer = (char*)datebuffer; while(1) { input.key=0; int res = doTextInput(&input); if (res==INPUT_RETURN_EXIT) return 0; // user aborted else if (res==INPUT_RETURN_CONFIRM) { int len = strlen(datebuffer); if(len == input.charlimit) { int yr,m,d; stringToDate(datebuffer, &yr, &m, &d); if(isDateValid(yr, m, d)) { tx.date.year = yr; tx.date.month = m; tx.date.day = d; curstep++; break; // continue to next step } else invalidFieldMsg(0); } else invalidFieldMsg(0); } else if (res==INPUT_RETURN_KEYCODE) { if(input.key==KEY_CTRL_F1) { curstep=curstep-1; break; } else if(input.key==KEY_CTRL_F2) { int ey=0, em=0, ed=0; if(!selectDateScreen(&ey, &em, &ed, (char*)"Select transaction date:", NULL, 1)) { tx.date.year = ey; tx.date.month = em; tx.date.day = ed; curstep++; break; // continue to next step } break; //redraw } } } } else if(curstep == 3) { drawScreenTitle(NULL, "Time:"); mPrintXY(8, 4, "HHMMSS", TEXT_MODE_TRANSPARENT_BACKGROUND, TEXT_COLOR_BLACK); textInput input; input.x=8; input.width=6; input.charlimit=6; input.acceptF6=1; input.type=INPUTTYPE_TIME; char tbuffer[15]; fillInputTime(&tx.time, tbuffer); input.buffer = (char*)tbuffer; while(1) { input.key=0; int res = doTextInput(&input); if (res==INPUT_RETURN_EXIT) return 0; // user aborted else if (res==INPUT_RETURN_CONFIRM) { if((int)strlen(tbuffer) == input.charlimit) { int h, m, s; stringToTime(tbuffer, &h, &m, &s); if(isTimeValid(h, m, s)) { tx.time.hour = h; tx.time.minute = m; tx.time.second = s; curstep++; break; // continue to next step } else invalidFieldMsg(1); } else invalidFieldMsg(1); } else if (res==INPUT_RETURN_KEYCODE && input.key==KEY_CTRL_F1) { curstep--; break; } } } else if(curstep == 4) { drawScreenTitle(NULL, "Description:"); textInput input; input.charlimit=128; input.acceptF6=1; input.buffer = (char*)tx.description; int inloop = 1; while(inloop) { input.key=0; int res = doTextInput(&input); if (res==INPUT_RETURN_EXIT) return 0; // user aborted else if (res==INPUT_RETURN_CONFIRM) inloop = 0; // all fields complete, continue with transaction adding else if (res==INPUT_RETURN_KEYCODE && input.key == KEY_CTRL_F1) { curstep--; break; } } if(!inloop) break; } } addTransaction(&tx, wallet); return 1; }
int doMenu(Menu* menu, MenuItemIcon* icontable) { // returns code telling what user did. selection is on menu->selection. menu->selection starts at 1! int itemsStartY=menu->startY; // char Y where to start drawing the menu items. Having a title increases this by one int itemsHeight=menu->height; int showtitle = menu->title != NULL; if (showtitle) { itemsStartY++; itemsHeight--; } if(menu->selection > menu->scroll+(menu->numitems>itemsHeight ? itemsHeight : menu->numitems)) menu->scroll = menu->selection -(menu->numitems>itemsHeight ? itemsHeight : menu->numitems); if(menu->selection-1 < menu->scroll) menu->scroll = menu->selection -1; while(1) { if(menu->statusText != NULL) DefineStatusMessage(menu->statusText, 1, 0, 0); // Clear the area of the screen we are going to draw on if(0 == menu->pBaRtR) drawRectangle(18*(menu->startX-1), 24*(menu->miniMiniTitle ? itemsStartY:menu->startY), 18*menu->width+(menu->scrollbar && menu->scrollout?6:0), 24*menu->height-(menu->miniMiniTitle ? 24:0), COLOR_WHITE); if (menu->numitems>0) { for(int curitem=0; curitem < menu->numitems; curitem++) { // print the menu item only when appropriate if(menu->scroll < curitem+1 && menu->scroll > curitem-itemsHeight) { char menuitem[70] = ""; if(menu->type == MENUTYPE_MULTISELECT) strcpy(menuitem, " "); //allow for the folder and selection icons on MULTISELECT menus (e.g. file browser) strncat(menuitem, menu->items[curitem].text, 68); if(menu->items[curitem].type != MENUITEM_SEPARATOR) { //make sure we have a string big enough to have background when item is selected: // MB_ElementCount is used instead of strlen because multibyte chars count as two with strlen, while graphically they are just one char, making fillerRequired become wrong int fillerRequired = menu->width - MB_ElementCount(menu->items[curitem].text) - (menu->type == MENUTYPE_MULTISELECT ? 2 : 0); for(int i = 0; i < fillerRequired; i++) strcat(menuitem, " "); mPrintXY(menu->startX,curitem+itemsStartY-menu->scroll,(char*)menuitem, (menu->selection == curitem+1 ? TEXT_MODE_INVERT : TEXT_MODE_TRANSPARENT_BACKGROUND), menu->items[curitem].color); } else { /*int textX = (menu->startX-1) * 18; int textY = curitem*24+itemsStartY*24-menu->scroll*24-24+6; clearLine(menu->startX, curitem+itemsStartY-menu->scroll, (menu->selection == curitem+1 ? textColorToFullColor(menu->items[curitem].color) : COLOR_WHITE)); drawLine(textX, textY+24-4, LCD_WIDTH_PX-2, textY+24-4, COLOR_GRAY); PrintMini(&textX, &textY, (unsigned char*)menuitem, 0, 0xFFFFFFFF, 0, 0, (menu->selection == curitem+1 ? COLOR_WHITE : textColorToFullColor(menu->items[curitem].color)), (menu->selection == curitem+1 ? textColorToFullColor(menu->items[curitem].color) : COLOR_WHITE), 1, 0);*/ } // deal with menu items of type MENUITEM_CHECKBOX if(menu->items[curitem].type == MENUITEM_CHECKBOX) { mPrintXY(menu->startX+menu->width-1,curitem+itemsStartY-menu->scroll, (menu->items[curitem].value == MENUITEM_VALUE_CHECKED ? (char*)"\xe6\xa9" : (char*)"\xe6\xa5"), (menu->selection == curitem+1 ? TEXT_MODE_INVERT : (menu->pBaRtR == 1? TEXT_MODE_TRANSPARENT_BACKGROUND : TEXT_MODE_NORMAL)), menu->items[curitem].color); } // deal with multiselect menus if(menu->type == MENUTYPE_MULTISELECT) { if((curitem+itemsStartY-menu->scroll)>=itemsStartY && (curitem+itemsStartY-menu->scroll)<=(itemsStartY+itemsHeight) && icontable != NULL ) { if (menu->items[curitem].isfolder == 1) { // assumes first icon in icontable is the folder icon CopySpriteMasked(icontable[0].data, (menu->startX)*18, (curitem+itemsStartY-menu->scroll)*24, 0x12, 0x18, 0xf81f ); } else { if(menu->items[curitem].icon >= 0) CopySpriteMasked(icontable[menu->items[curitem].icon].data, (menu->startX)*18, (curitem+itemsStartY-menu->scroll)*24, 0x12, 0x18, 0xf81f ); } } if (menu->items[curitem].isselected) { if (menu->selection == curitem+1) { mPrintXY(menu->startX,curitem+itemsStartY-menu->scroll,(char*)"\xe6\x9b", TEXT_MODE_TRANSPARENT_BACKGROUND, (menu->items[curitem].color == TEXT_COLOR_GREEN ? TEXT_COLOR_BLUE : TEXT_COLOR_GREEN)); } else { mPrintXY(menu->startX,curitem+itemsStartY-menu->scroll,(char*)"\xe6\x9b", TEXT_MODE_NORMAL, TEXT_COLOR_PURPLE); } } } } } if (menu->scrollbar) { TScrollbar sb; sb.I1 = 0; sb.I5 = 0; sb.indicatormaximum = menu->numitems; sb.indicatorheight = itemsHeight; sb.indicatorpos = menu->scroll; sb.barheight = itemsHeight*24; sb.bartop = (itemsStartY-1)*24; sb.barleft = menu->startX*18+menu->width*18 - 18 - (menu->scrollout ? 0 : 5); sb.barwidth = 6; Scrollbar(&sb); } //if(menu->type==MENUTYPE_MULTISELECT && menu->fkeypage == 0) drawFkeyLabels(0x0037); // SELECT (white) } else { printCentered((unsigned char*)menu->nodatamsg, (itemsStartY*24)+(itemsHeight*24)/2-12, COLOR_BLACK, COLOR_WHITE); } if(showtitle) { if(menu->miniMiniTitle) { int textX = 0, textY=(menu->startY-1)*24; PrintMiniMini( &textX, &textY, (unsigned char*)menu->title, 16, menu->titleColor, 0 ); } else mPrintXY(menu->startX, menu->startY, menu->title, TEXT_MODE_TRANSPARENT_BACKGROUND, menu->titleColor); if(menu->subtitle != NULL) { int textX=(MB_ElementCount(menu->title)+menu->startX-1)*18+10, textY=6; PrintMini(&textX, &textY, (unsigned char*)menu->subtitle, 0, 0xFFFFFFFF, 0, 0, COLOR_BLACK, COLOR_WHITE, 1, 0); } } /*if(menu->darken) { DrawFrame(COLOR_BLACK); VRAMInvertArea(menu->startX*18-18, menu->startY*24, menu->width*18-(menu->scrollout || !menu->scrollbar ? 0 : 5), menu->height*24); }*/ if(menu->type == MENUTYPE_NO_KEY_HANDLING) return MENU_RETURN_INSTANT; // we don't want to handle keys int key; GetKey(&key); switch(key) { case KEY_CTRL_DOWN: if(menu->selection == menu->numitems) { if(menu->returnOnInfiniteScrolling) { return MENU_RETURN_SCROLLING; } else { menu->selection = 1; menu->scroll = 0; } } else { menu->selection++; if(menu->selection > menu->scroll+(menu->numitems>itemsHeight ? itemsHeight : menu->numitems)) menu->scroll = menu->selection -(menu->numitems>itemsHeight ? itemsHeight : menu->numitems); } if(menu->pBaRtR==1) return MENU_RETURN_INSTANT; break; case KEY_CTRL_UP: if(menu->selection == 1) { if(menu->returnOnInfiniteScrolling) { return MENU_RETURN_SCROLLING; } else { menu->selection = menu->numitems; menu->scroll = menu->selection-(menu->numitems>itemsHeight ? itemsHeight : menu->numitems); } } else { menu->selection--; if(menu->selection-1 < menu->scroll) menu->scroll = menu->selection -1; } if(menu->pBaRtR==1) return MENU_RETURN_INSTANT; break; case KEY_CTRL_F1: if(menu->type==MENUTYPE_MULTISELECT && menu->fkeypage == 0 && menu->numitems > 0) { /*if(menu->items[menu->selection-1].isselected) { menu->items[menu->selection-1].isselected=0; menu->numselitems = menu->numselitems-1; } else { menu->items[menu->selection-1].isselected=1; menu->numselitems = menu->numselitems+1; } return key; //return on F1 too so that parent subroutines have a chance to e.g. redraw fkeys*/ } else if (menu->type == MENUTYPE_FKEYS) { return key; } break; case KEY_CTRL_F2: case KEY_CTRL_F3: case KEY_CTRL_F4: case KEY_CTRL_F5: case KEY_CTRL_F6: if (menu->type == MENUTYPE_FKEYS || menu->type==MENUTYPE_MULTISELECT) return key; // MULTISELECT also returns on Fkeys break; case KEY_CTRL_PASTE: if (menu->type==MENUTYPE_MULTISELECT) return key; // MULTISELECT also returns on paste case KEY_CTRL_OPTN: if (menu->type==MENUTYPE_FKEYS || menu->type==MENUTYPE_MULTISELECT) return key; break; case KEY_CTRL_FORMAT: if (menu->type==MENUTYPE_FKEYS) return key; // return on the Format key so that event lists can prompt to change event category break; case KEY_CTRL_RIGHT: if(menu->type != MENUTYPE_MULTISELECT) break; // else fallthrough case KEY_CTRL_EXE: if(menu->numitems>0) return MENU_RETURN_SELECTION; break; case KEY_CTRL_LEFT: if(menu->type != MENUTYPE_MULTISELECT) break; // else fallthrough case KEY_CTRL_EXIT: return MENU_RETURN_EXIT; break; case KEY_CHAR_1: case KEY_CHAR_2: case KEY_CHAR_3: case KEY_CHAR_4: case KEY_CHAR_5: case KEY_CHAR_6: case KEY_CHAR_7: case KEY_CHAR_8: case KEY_CHAR_9: if(menu->numitems>=(key-0x30)) {menu->selection = (key-0x30); return MENU_RETURN_SELECTION; } break; case KEY_CHAR_0: if(menu->numitems>=10) {menu->selection = 10; return MENU_RETURN_SELECTION; } break; case KEY_CTRL_XTT: if(menu->numitems>=11) {menu->selection = 11; return MENU_RETURN_SELECTION; } break; case KEY_CHAR_LOG: if(menu->numitems>=12) {menu->selection = 12; return MENU_RETURN_SELECTION; } break; case KEY_CHAR_LN: if(menu->numitems>=13) {menu->selection = 13; return MENU_RETURN_SELECTION; } break; case KEY_CHAR_SIN: case KEY_CHAR_COS: case KEY_CHAR_TAN: if(menu->numitems>=(key-115)) {menu->selection = (key-115); return MENU_RETURN_SELECTION; } break; case KEY_CHAR_FRAC: if(menu->numitems>=17) {menu->selection = 17; return MENU_RETURN_SELECTION; } break; case KEY_CTRL_FD: if(menu->numitems>=18) {menu->selection = 18; return MENU_RETURN_SELECTION; } break; case KEY_CHAR_LPAR: case KEY_CHAR_RPAR: if(menu->numitems>=(key-21)) {menu->selection = (key-21); return MENU_RETURN_SELECTION; } break; case KEY_CHAR_COMMA: if(menu->numitems>=21) {menu->selection = 21; return MENU_RETURN_SELECTION; } break; case KEY_CHAR_STORE: if(menu->numitems>=22) {menu->selection = 22; return MENU_RETURN_SELECTION; } break; } } return MENU_RETURN_EXIT; }