Index: apps/plugins/resistor.c =================================================================== --- apps/plugins/resistor.c (revisione 29317) +++ apps/plugins/resistor.c (copia locale) @@ -1,7 +1,5 @@ /* === Rockbox Resistor code/value calculator === [insert relevant/useful information here] -TODO: -[ ] Own numeric keypad */ #include "plugin.h" @@ -623,7 +621,7 @@ rb->splash(HZ*2, "(First) Input the supply voltage:"); memset(kbd_buffer,0,sizeof(kbd_buffer)); - rb->kbd_input(kbd_buffer, sizeof(kbd_buffer)); + rb->snprintf(kbd_buffer, sizeof(kbd_buffer), "%s", rb->numpad_input(0)); input_voltage = rb->atoi(kbd_buffer); if(input_voltage == 0) break; @@ -660,7 +658,7 @@ rb->lcd_clear_display(); rb->splash(HZ*2, "Input the foreward current, in mA"); memset(fwd_kbd_buffer,0,sizeof(fwd_kbd_buffer)); - rb->kbd_input(fwd_kbd_buffer, sizeof(fwd_kbd_buffer)); + rb->snprintf(fwd_kbd_buffer, sizeof(fwd_kbd_buffer), "%s", rb->numpad_input(0)); foreward_current = ((rb->atoi(fwd_kbd_buffer))/10); break; } @@ -818,9 +816,7 @@ NULL, false); if(ret<0) break; - rb->kbd_input(kbd_buffer, sizeof(kbd_buffer)); - /* As stated above somewhere, we (I) need to make a calculator-like - keypad, that keyboard isn't all that fun to use. */ + rb->snprintf(kbd_buffer, sizeof(kbd_buffer), "%s", rb->numpad_input(0)); ret = rb->do_menu(&r_to_c_menu_tol, &menu_selection_tol, NULL, false); if(ret<0) break; Index: apps/numpad.c =================================================================== --- apps/numpad.c (revisione 0) +++ apps/numpad.c (revisione 0) @@ -0,0 +1,485 @@ +/* Calculator-like numberpad input function */ +#include +#include +#include +#include "numpad.h" +#include "lcd.h" +#include "button.h" +#include "string.h" + +#define BUTTON_ROWS 4 +#define BUTTON_COLS 3 +#define REC_HEIGHT (int)(LCD_HEIGHT / (BUTTON_ROWS + 1)) +#define REC_WIDTH (int)(LCD_WIDTH / BUTTON_COLS) +#define Y_5_POS (LCD_HEIGHT) /* Leave room for the border */ +#define Y_4_POS (Y_5_POS - REC_HEIGHT) +#define Y_3_POS (Y_4_POS - REC_HEIGHT) /* y3 = 33 */ +#define Y_2_POS (Y_3_POS - REC_HEIGHT) /* y2 = 23 */ +#define Y_1_POS (Y_2_POS - REC_HEIGHT) /* y1 = 13 */ +#define Y_0_POS 0 /* y0 = 0 */ + +#define X_0_POS 0 /* x0 = 0 */ +#define X_1_POS (X_0_POS + REC_WIDTH) /* x1 = 22 */ +#define X_2_POS (X_1_POS + REC_WIDTH) /* x2 = 44 */ +#define X_3_POS (X_2_POS + REC_WIDTH) /* x3 = 66 */ + +#if LCD_HEIGHT <= 132 +#define OUT_BUFFER_Y 0 +#else +#define OUT_BUFFER_Y 2 +#endif + +#define btn_seven 00 +#define btn_eight 01 +#define btn_nine 02 +#define btn_four 10 +#define btn_five 11 +#define btn_six 12 +#define btn_one 20 +#define btn_two 21 +#define btn_three 22 +#define btn_clr 30 +#define btn_zero 31 +#define btn_ok 32 + +/* Keypaps */ +#if (CONFIG_KEYPAD == SANSA_FUZE_PAD) || \ + (CONFIG_KEYPAD == SANSA_E200_PAD) +#define NUMPAD_UP BUTTON_UP +#define NUMPAD_DOWN BUTTON_DOWN +#define NUMPAD_LEFT BUTTON_LEFT +#define NUMPAD_RIGHT BUTTON_RIGHT +#define NUMPAD_SCROLL_FWD BUTTON_SCROLL_FWD +#define NUMPAD_SCROLL_BACK BUTTON_SCROLL_BACK +#define NUMPAD_EXIT BUTTON_POWER +#define NUMPAD_SELECT BUTTON_SELECT + +#elif (CONFIG_KEYPAD == RECORDER_PAD) +#define NUMPAD_UP BUTTON_UP +#define NUMPAD_DOWN BUTTON_DOWN +#define NUMPAD_LEFT BUTTON_LEFT +#define NUMPAD_RIGHT BUTTON_RIGHT +#define NUMPAD_EXIT BUTTON_OFF +#define NUMPAD_SELECT BUTTON_PLAY + +#elif (CONFIG_KEYPAD == ARCHOS_AV300_PAD) +#define NUMPAD_UP BUTTON_UP +#define NUMPAD_DOWN BUTTON_DOWN +#define NUMPAD_LEFT BUTTON_LEFT +#define NUMPAD_RIGHT BUTTON_RIGHT +#define NUMPAD_EXIT BUTTON_OFF +#define NUMPAD_SELECT BUTTON_SELECT + +#elif (CONFIG_KEYPAD == ONDIO_PAD) +#define NUMPAD_UP BUTTON_UP +#define NUMPAD_DOWN BUTTON_DOWN +#define NUMPAD_LEFT BUTTON_LEFT +#define NUMPAD_RIGHT BUTTON_RIGHT +#define NUMPAD_EXIT BUTTON_OFF +#define NUMPAD_SELECT BUTTON_MENU + +#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ + (CONFIG_KEYPAD == IRIVER_H300_PAD) +#define NUMPAD_UP BUTTON_UP +#define NUMPAD_DOWN BUTTON_DOWN +#define NUMPAD_LEFT BUTTON_LEFT +#define NUMPAD_RIGHT BUTTON_RIGHT +#define NUMPAD_EXIT BUTTON_OFF +#define NUMPAD_INPUT BUTTON_SELECT + +#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ + (CONFIG_KEYPAD == IPOD_3G_PAD) || \ + (CONFIG_KEYPAD == IPOD_1G2G_PAD) +#define NUMPAD_LEFT BUTTON_LEFT +#define NUMPAD_RIGHT BUTTON_RIGHT +#define NUMPAD_SCROLL_FWD BUTTON_SCROLL_FWD +#define NUMPAD_SCROLL_BACK BUTTON_SCROLL_BACK +#define NUMPAD_EXIT BUTTON_MENU +#define NUMPAD_SELECT BUTTON_SELECT + +#elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD) || \ + (CONFIG_KEYPAD == GIGABEAT_PAD) || \ + (CONFIG_KEYPAD == SANSA_C200_PAD) || \ + (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \ + (CONFIG_KEYPAD == SANSA_M200_PAD) || \ + (CONFIG_KEYPAD == MROBE100_PAD) || \ + (CONFIG_KEYPAD == PHILIPS_HDD1630_PAD) +#define NUMPAD_UP BUTTON_UP +#define NUMPAD_DOWN BUTTON_DOWN +#define NUMPAD_LEFT BUTTON_LEFT +#define NUMPAD_RIGHT BUTTON_RIGHT +#define NUMPAD_EXIT BUTTON_POWER +#define NUMPAD_SELECT BUTTON_SELECT + +#elif (CONFIG_KEYPAD == IRIVER_H10_PAD) +#define NUMPAD_RIGHT BUTTON_RIGHT +#define NUMPAD_LEFT BUTTON_LEFT +#define NUMPAD_SCROLL_FWD BUTTON_SCROLL_FWD +#define NUMPAD_SCROLL_BACK BUTTON_SCROLL_BACK +#define NUMPAD_EXIT BUTTON_POWER +#define NUMPAD_SELECT BUTTON_PLAY + +#elif (CONFIG_KEYPAD == GIGABEAT_S_PAD) +#define NUMPAD_UP BUTTON_UP +#define NUMPAD_DOWN BUTTON_DOWN +#define NUMPAD_LEFT BUTTON_LEFT +#define NUMPAD_RIGHT BUTTON_RIGHT +#define NUMPAD_EXIT BUTTON_BACK +#define NUMPAD_SELECT BUTTON_SELECT + +#elif (CONFIG_KEYPAD == IAUDIO_M3_PAD) +#define NUMPAD_UP BUTTON_RC_VOL_UP +#define NUMPAD_DOWN BUTTON_RC_VOL_DOWN +#define NUMPAD_LEFT BUTTON_RC_REW +#define NUMPAD_RIGHT BUTTON_RC_FWD +#define NUMPAD_EXIT BUTTON_RC_REC +#define NUMPAD_SELECT BUTTON_RC_PLAY + +#elif (CONFIG_KEYPAD == COWON_D2_PAD) +#define NUMPAD_EXIT BUTTON_POWER + +#elif (CONFIG_KEYPAD == IAUDIO67_PAD) +#define NUMPAD_UP BUTTON_VOLUP +#define NUMPAD_DOWN BUTTON_VOLDOWN +#define NUMPAD_LEFT BUTTON_LEFT +#define NUMPAD_RIGHT BUTTON_RIGHT +#define NUMPAD_EXIT BUTTON_POWER +#define NUMPAD_SELECT BUTTON_PLAY + +#elif (CONFIG_KEYPAD == CREATIVEZVM_PAD) +#define NUMPAD_UP BUTTON_UP +#define NUMPAD_DOWN BUTTON_DOWN +#define NUMPAD_LEFT BUTTON_LEFT +#define NUMPAD_RIGHT BUTTON_RIGHT +#define NUMPAD_EXIT BUTTON_BACK +#define NUMPAD_SELECT BUTTON_SELECT + +#elif (CONFIG_KEYPAD == PHILIPS_SA9200_PAD) +#define NUMPAD_UP BUTTON_UP +#define NUMPAD_DOWN BUTTON_DOWN +#define NUMPAD_LEFT BUTTON_PREV +#define NUMPAD_RIGHT BUTTON_NEXT +#define NUMPAD_EXIT BUTTON_POWER +#define NUMPAD_SELECT BUTTON_PLAY + +#elif (CONFIG_KEYPAD == ONDAVX747_PAD) || \ + (CONFIG_KEYPAD == ONDAVX777_PAD) || \ + (CONFIG_KEYPAD == MROBE500_PAD) +#define NUMPAD_EXIT BUTTON_POWER + +#elif (CONFIG_KEYPAD == SAMSUNG_YH_PAD) +#define NUMPAD_UP BUTTON_UP +#define NUMPAD_DOWN BUTTON_DOWN +#define NUMPAD_LEFT BUTTON_LEFT +#define NUMPAD_RIGHT BUTTON_RIGHT +#define NUMPAD_EXIT BUTTON_REC +#define NUMPAD_SELECT BUTTON_PLAY + +#elif (CONFIG_KEYPAD == PBELL_VIBE500_PAD) +#define NUMPAD_UP BUTTON_UP +#define NUMPAD_DOWN BUTTON_DOWN +#define NUMPAD_LEFT BUTTON_LEFT +#define NUMPAD_RIGHT BUTTON_RIGHT +#define NUMPAD_EXIT BUTTON_REC +#define NUMPAD_SELECT BUTTON_OK + +#elif (CONFIG_KEYPAD == MPIO_HD200_PAD) +#define NUMPAD_LEFT BUTTON_PREV +#define NUMPAD_RIGHT BUTTON_NEXT +#define NUMPAD_EXIT (BUTTON_REC|BUTTON_PLAY) +#define NUMPAD_SELECT BUTTON_SELECT + +#else +#error No keymap defined +#endif + +#ifdef HAVE_TOUCHSCREEN +#ifndef NUMPAD_LEFT +#define NUMPAD_LEFT BUTTON_MIDLEFT +#endif +#ifndef NUMPAD_RIGHT +#define NUMPAD_RIGHT BUTTON_MIDRIGHT +#endif +#ifndef NUMPAD_UP +#define NUMPAD_UP BUTTON_TOPMIDDLE +#endif +#ifndef NUMPAD_DOWN +#define NUMPAD_DOWN BUTTON_BOTTOMMIDDLE +#endif +#ifndef NUMPAD_CALC +#define NUMPAD_CALC BUTTON_BOTTOMRIGHT +#endif +#ifndef NUMPAD_INPUT +#define NUMPAD_INPUT BUTTON_CENTER +#endif +#include "lib/pluginlib_touchscreen.h" +#endif + +bool masked_; +int current_sel_x = 0; +int current_sel_y = 0; +int cur_buf = 0; +int hold_flag = 0; +char buffer[32]; +char prev_buffer[32]; +char maskedbuffer[32]; +char prev_maskedbuffer[32]; + +static int numpad_button_functions[4][3] = { + { btn_seven, btn_eight, btn_nine }, + { btn_four, btn_five, btn_six }, + { btn_one, btn_two, btn_three }, + { btn_clr, btn_zero, btn_ok } +}; + +static unsigned char* numpad_buttons[4][3] = { + { "7", "8", "9" }, + { "4", "5", "6" }, + { "1", "2", "3" }, + { "Clr", "0 / .", "OK" } +}; + +static void numpad_draw_buttons(void) +{ + int i, j, w, h; + + for (i = 0; i < 4; i++){ + for (j = 0; j < 3; j++){ + lcd_getstringsize(numpad_buttons[i][j],&w,&h); + + if(i == current_sel_x && j == current_sel_y) { + lcd_set_drawmode(DRMODE_SOLID); + } else { lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);} + lcd_fillrect(X_0_POS + j*REC_WIDTH, + Y_1_POS + i*REC_HEIGHT, + REC_WIDTH, REC_HEIGHT+1); + + if(i == current_sel_x && j == current_sel_y) { + lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + } else { lcd_set_drawmode(DRMODE_SOLID); } + lcd_putsxy( X_0_POS + j*REC_WIDTH + (REC_WIDTH -w)/2, + Y_1_POS + i*REC_HEIGHT + (REC_HEIGHT - h)/2 + 1, + numpad_buttons[i][j] ); + } + } + lcd_set_drawmode(DRMODE_SOLID); +} + +static void numpad_draw_lines(void) +{ + int i; + lcd_hline(0, LCD_WIDTH, Y_1_POS-1); + lcd_hline(0, LCD_WIDTH, LCD_HEIGHT-1); + for (i = 0; i < 5 ; i++) + lcd_hline(0, LCD_WIDTH, Y_1_POS+i*REC_HEIGHT); + for (i = 0; i < 4 ; i++) + lcd_vline(X_1_POS+i*REC_WIDTH, Y_1_POS, LCD_HEIGHT); +} + + +static void move_with_wrap_and_shift( + int *dimen1, int dimen1_delta, int dimen1_modulo, + int *dimen2, int dimen2_delta, int dimen2_modulo) +{ +/* Taken straight from the Calculator plugin */ + bool wrapped = false; + + *dimen1 += dimen1_delta; + if (*dimen1 < 0) + { + *dimen1 = dimen1_modulo - 1; + wrapped = true; + } + else if (*dimen1 >= dimen1_modulo) + { + *dimen1 = 0; + wrapped = true; + } + + if (wrapped) + { + /* Make the dividend always positive to be sure about the result. + Adding dimen2_modulo does not change it since we do it modulo. */ + *dimen2 = (*dimen2 + dimen2_modulo + dimen2_delta) % dimen2_modulo; + } +} + +static void numpad_write_buffer(char * new_char) +{ + if(!strcmp("[", new_char)){ + buffer[0] = 0; + } else if(!strcmp(".", new_char)) { + int len = strlen(buffer); + buffer[len-1] = 0; /* backspace, clear the 0 */ + snprintf(prev_buffer, sizeof(prev_buffer), "%s", buffer); + snprintf(buffer, sizeof(buffer), "%s%s", prev_buffer, "."); + if(masked_ == true) { + snprintf(prev_maskedbuffer, sizeof(prev_maskedbuffer), "%s", maskedbuffer); + snprintf(maskedbuffer, sizeof(maskedbuffer), "%s%s", prev_maskedbuffer, "- "); + } + } else { + snprintf(prev_buffer, sizeof(prev_buffer), "%s", buffer); + snprintf(buffer, sizeof(buffer), "%s%s", prev_buffer, new_char); + if(masked_ == true) { + snprintf(prev_maskedbuffer, sizeof(prev_maskedbuffer), "%s", maskedbuffer); + snprintf(maskedbuffer, sizeof(maskedbuffer), "%s%s", prev_maskedbuffer, "- "); + } + } +} + +static int numpad_handle_button(int in_x, int in_y) +{ + int selected_button; + int return_val = 0; + selected_button = numpad_button_functions[in_x][in_y]; + + switch(selected_button) { + case btn_one: + numpad_write_buffer("1"); + break; + case btn_two: + numpad_write_buffer("2"); + break; + case btn_three: + numpad_write_buffer("3"); + break; + case btn_four: + numpad_write_buffer("4"); + break; + case btn_five: + numpad_write_buffer("5"); + break; + case btn_six: + numpad_write_buffer("6"); + break; + case btn_seven: + numpad_write_buffer("7"); + break; + case btn_eight: + numpad_write_buffer("8"); + break; + case btn_nine: + numpad_write_buffer("9"); + break; + case btn_zero: + if(hold_flag == 1) { numpad_write_buffer("."); } + else { numpad_write_buffer("0"); } + break; + case btn_ok: + return_val = 1; + break; + case btn_clr: + numpad_write_buffer("["); /* clear symbol */ + break; + } + return return_val; +} + +static int numpad_get_input(void) +{ + int button_in; + int return_val = 0; + hold_flag = 0; + button_in = button_get(true); + switch(button_in) { +#ifdef NUMPAD_UP + case NUMPAD_UP: + case NUMPAD_UP|BUTTON_REPEAT: + move_with_wrap_and_shift( + ¤t_sel_x, -1, BUTTON_ROWS, + ¤t_sel_y, 0, BUTTON_COLS); + return_val = 0; + break; +#endif +#ifdef NUMPAD_DOWN + case NUMPAD_DOWN: + case NUMPAD_DOWN|BUTTON_REPEAT: + move_with_wrap_and_shift( + ¤t_sel_x, 1, BUTTON_ROWS, + ¤t_sel_y, 0, BUTTON_COLS); + return_val = 0; + break; +#endif +#ifdef NUMPAD_SCROLL_FWD + case NUMPAD_SCROLL_FWD: + case NUMPAD_SCROLL_FWD|BUTTON_REPEAT: + move_with_wrap_and_shift( + ¤t_sel_x, -1, BUTTON_ROWS, + ¤t_sel_y, -1, BUTTON_COLS); + return_val = 0; + break; + case NUMPAD_SCROLL_BACK: + case NUMPAD_SCROLL_BACK|BUTTON_REPEAT: + move_with_wrap_and_shift( + ¤t_sel_x, 1, BUTTON_ROWS, + ¤t_sel_y, 1, BUTTON_COLS); + return_val = 0; + break; +#endif /* if there's one, i'm sure there's the other */ + case NUMPAD_LEFT: + case NUMPAD_LEFT|BUTTON_REPEAT: + move_with_wrap_and_shift( + ¤t_sel_y, -1, BUTTON_COLS, + ¤t_sel_x, 0, BUTTON_ROWS); + return_val = 0; + break; + case NUMPAD_RIGHT: + case NUMPAD_RIGHT|BUTTON_REPEAT: + move_with_wrap_and_shift( + ¤t_sel_y, 1, BUTTON_COLS, + ¤t_sel_x, 0, BUTTON_ROWS); + return_val = 0; + break; + case NUMPAD_SELECT: + return_val = 2; + break; + case NUMPAD_SELECT|BUTTON_REPEAT: + /* I just realized that there's no '.' button, but I really don't want + to add another row of buttons. So how about holding down on zero backspaces + (to clear typed 0) and types a '.' ? */ + hold_flag = 1; + return_val = 2; + break; + case NUMPAD_EXIT: + return_val = 1; + break; + } + lcd_update(); + return return_val; +} + +char * numpad_input(int in_masked) +{ + bool masked; + if(in_masked == 0) { masked = false; } + else { masked = true; } + masked_ = masked; + /* masked_ = global for other functions*/ + bool quit = false; + int btn_in_stat; + int btn_done_stat = 0; + memset(buffer, 0, sizeof(buffer)); + memset(prev_buffer, 0, sizeof(prev_buffer)); + memset(maskedbuffer, 0, sizeof(maskedbuffer)); + memset(prev_maskedbuffer, 0, sizeof(prev_maskedbuffer)); + /* masked = password mode, echo '*'s instead of typed numbers */ + lcd_clear_display(); + + while(!quit) { + + numpad_draw_buttons(); + numpad_draw_lines(); + lcd_update(); + btn_in_stat = numpad_get_input(); + if(btn_in_stat == 1) { quit = true; } + else if(btn_in_stat == 2) { + btn_done_stat = numpad_handle_button(current_sel_x, current_sel_y); } + if (masked) { lcd_puts(1, OUT_BUFFER_Y, maskedbuffer); } + else { lcd_puts(1, OUT_BUFFER_Y, buffer); } + lcd_update(); + if(btn_done_stat == 1) { + quit = true; + } + } + return buffer; +} Index: apps/numpad.h =================================================================== --- apps/numpad.h (revisione 0) +++ apps/numpad.h (revisione 0) @@ -0,0 +1,14 @@ +#ifndef NUMPAD_H +#define NUMPAD_H + +char * numpad_input(int masked); +/* numpad_input(): returns an ASCII string of typed numbers (and decimal) +Best called as follows: +rb->snprintf(buffer, sizeof(buffer), "%s", rb->numpad_input(false)) +options are 0 for normal, and 1 for masked (password) mode +Masked mode: 1 = echo '*'s instead of typed chars (think password input) + 0 = normal output +(GCC doesn't seem to like using bool here instead of int.) +*/ + +#endif Index: apps/plugin.c =================================================================== --- apps/plugin.c (revisione 29317) +++ apps/plugin.c (copia locale) @@ -27,6 +27,7 @@ #include "lang.h" #include "led.h" #include "keyboard.h" +#include "numpad.h" #include "buffer.h" #include "backlight.h" #include "sound_menu.h" @@ -43,6 +44,7 @@ #include "diacritic.h" #include "filefuncs.h" #include "load_code.h" +#include "numpad.h" #if CONFIG_CHARGING #include "power.h" @@ -670,6 +672,7 @@ rand, (qsort_func)qsort, kbd_input, + numpad_input, get_time, set_time, #if CONFIG_RTC Index: apps/SOURCES =================================================================== --- apps/SOURCES (revisione 29317) +++ apps/SOURCES (copia locale) @@ -43,6 +43,7 @@ #endif misc.c mp3data.c +numpad.c onplay.c playlist.c playlist_catalog.c Index: apps/plugin.h =================================================================== --- apps/plugin.h (revisione 29317) +++ apps/plugin.h (copia locale) @@ -777,6 +777,7 @@ void (*qsort)(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *)); int (*kbd_input)(char* buffer, int buflen); + char* (*numpad_input)(int masked); struct tm* (*get_time)(void); int (*set_time)(const struct tm *tm); #if CONFIG_RTC