/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id: keyboard.c,v 1.1 2002/06/16 23:21:57 adiamas Exp $ * * Copyright (C) 2002 Robert E. Hak (rhak at ramapo.edu) * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include "config.h" #ifdef HAVE_LCD_BITMAP #include "keyboard.h" #include "lcd.h" #include "button.h" #include "kernel.h" #include #ifdef SIMULATOR #include #endif #define MAX_CHARS_PER_LINE 12 #define TOTAL_CHARS 36 #define FONT_SIZE 0 #define KB_LINE 0 #define MENU_OPTIONS 3 static char *kboard = "abcdefghijklmnopqrstuvwxyz0123456789-_[]().<> :,"; static char *menu = "Del Shift Save"; static int font_w, font_h, initial_x; static int current_line; static int current_char; static int lines; static int menu_line; static int text_line_y; static int text_line_x; static bool shifted; static int max_input; static char *input; /* Len is the count of last char in the buffer Index is where you are placing the _current_ char */ static int input_index; static int input_len; void draw_text_entry() { int index = 0; if ((input_len*font_w) >= LCD_WIDTH) index = input_len - (LCD_WIDTH/font_w); else index = 0; lcd_clearrect(text_line_x, text_line_y, LCD_WIDTH, font_h); lcd_putsxy(text_line_x, text_line_y, input+index, FONT_SIZE); lcd_update_rect(text_line_x, text_line_y, LCD_WIDTH, font_h); } /* This _only_ displays the keyboard and menu. We do not clear display because that would clear the entry line */ void display_keyboard() { int i = 0, j = 0; unsigned char buf[2]; lcd_clear_display(); for(i=KB_LINE, j=0; i < lines+KB_LINE; i++) { int k = 0; int pad = 0; for(k = 0; k < MAX_CHARS_PER_LINE; k++) { if (shifted && (kboard[j] >= 'a') && (kboard[j] <= 'z')) buf[0] = kboard[j++] - 0x20; else buf[0] = kboard[j++]; buf[1] = 0; lcd_putsxy(LCD_WIDTH/2-initial_x+pad, font_h*i+1, buf, FONT_SIZE); pad+=font_w+2; } } /* draw the menu in */ j = (LCD_WIDTH/2)-strlen(menu)/2*font_w; lcd_putsxy(j, menu_line, menu, FONT_SIZE); /* draw cursor */ lcd_invertrect(LCD_WIDTH/2-initial_x+(current_char*(font_w+2)), current_line*font_h+1, font_w, font_h); lcd_update(); draw_text_entry(); } /* Draw a selected key on the entry line */ void select_key() { int index = 0; if (input_len == (max_input-1)) { lcd_clearrect(0, LCD_HEIGHT-(font_h*3), LCD_WIDTH, LCD_HEIGHT); lcd_putsxy(0, LCD_HEIGHT-(font_h*2), "Input Buffer Full", FONT_SIZE); lcd_update_rect(text_line_x, text_line_y, LCD_WIDTH, font_h); sleep(HZ/2); lcd_putsxy(0, LCD_HEIGHT-(font_h*2), input+input_len-LCD_WIDTH, FONT_SIZE); lcd_update_rect(text_line_x, text_line_y, LCD_WIDTH, font_h); return; } index = ((current_line-KB_LINE) * MAX_CHARS_PER_LINE) + current_char; if (shifted && (kboard[index] >= 'a') && (kboard[index] <= 'z')) input[input_index++] = kboard[index] - 0x20; else input[input_index++] = kboard[index]; input_len++; draw_text_entry(); } /* Move the cursor up, down, left, right */ void move_cursor(int b) { int x_loc = 0; int y_loc = 0; int old_line = current_line; int old_char = current_char; switch(b) { case BUTTON_LEFT: case BUTTON_LEFT | BUTTON_REPEAT: if (current_char == 0) current_char = MAX_CHARS_PER_LINE-1; else current_char--; break; case BUTTON_RIGHT: case BUTTON_RIGHT | BUTTON_REPEAT: if (current_char == (MAX_CHARS_PER_LINE - 1)) current_char=0; else current_char++; break; case BUTTON_UP: case BUTTON_UP | BUTTON_REPEAT: if (current_line == KB_LINE) current_line = lines+KB_LINE-1; else current_line--; break; case BUTTON_DOWN: case BUTTON_DOWN | BUTTON_REPEAT: if (current_line == (lines+KB_LINE-1)) current_line = KB_LINE; else current_line++; break; } /* Set new cursor on chars */ /* Initial placement + char widths + padding */ x_loc = LCD_WIDTH/2-initial_x+(font_w*current_char)+(current_char * 2); y_loc = (current_line*font_h)+1; lcd_invertrect(x_loc, y_loc, font_w, font_h); /* Erase old cursor */ x_loc = LCD_WIDTH/2-initial_x+(font_w*old_char)+(old_char * 2); y_loc = (old_line*font_h)+1; lcd_invertrect(x_loc, y_loc, font_w, font_h); lcd_update(); } /* Delete the last displayed char in the entry text */ void delete_key() { int index = 0; input[--input_index] = 0; input_len--; if ((input_len*font_w) >= LCD_WIDTH) index = input_len - (LCD_WIDTH/font_w); else index = 0; /* delete the entire line and redraw it */ lcd_clearrect(0, LCD_HEIGHT-(font_h*3), LCD_WIDTH, font_h); lcd_putsxy(0, LCD_HEIGHT-(font_h*3), input+index, FONT_SIZE); lcd_update(); } void keyboard(char *buffer, int len) { int b = 0, l = 0; /* prep all the global values we need */ lcd_getfontsize(FONT_SIZE, &font_w, &font_h); current_line = KB_LINE; shifted = false; max_input = len; input = buffer; current_char = 0; input_index = 0; input_len = 0; menu_line = LCD_HEIGHT-font_h; text_line_y = LCD_HEIGHT-(font_h*3); text_line_x = 0; memset(input, 0, max_input); l = strlen(kboard); lines = l / MAX_CHARS_PER_LINE; if ((lines * MAX_CHARS_PER_LINE) != l) lines++; /* center keyboard */ /* We add MAX_CHARS_PER_LINE*2 for padding between letters */ initial_x = (MAX_CHARS_PER_LINE * font_w) + MAX_CHARS_PER_LINE*2; if (initial_x%2 != 0) initial_x = ((initial_x+1/2)+(font_w/2)); else initial_x /= 2; /* Display initial keyboard */ lcd_clear_display(); display_keyboard(); while(1) { switch(b = button_get_w_tmo(HZ/2)) { case BUTTON_OFF: memset(input, 0, max_input); return; case BUTTON_F1: delete_key(); break; case BUTTON_F2: shifted ? (shifted=false) : (shifted=true); display_keyboard(); break; case BUTTON_F3: return; break; case BUTTON_PLAY: select_key(); break; default: move_cursor(b); } } } #endif