A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd

keyboard.c Use viewports, move text box pos

allows items to be moved around with less code changes

remove scrolling I was not overly impressed with it
add test_kbd plugin

Change-Id: Ic183c7221bda9405891632704f3a7bbfd79bfe83

authored by

William Wilgus and committed by
William Wilgus
d1be73cf bf3e6720

+205 -27
+1
apps/plugins/CATEGORIES
··· 172 172 test_fps,apps 173 173 test_grey,apps 174 174 test_gfx,apps 175 + test_kbd,apps 175 176 test_resize,apps 176 177 test_sampr,apps 177 178 test_scanrate,apps
+1
apps/plugins/SOURCES
··· 204 204 test_disk.c 205 205 test_fps.c 206 206 test_gfx.c 207 + test_kbd.c 207 208 #if LCD_DEPTH < 4 && !defined(SIMULATOR) 208 209 test_scanrate.c 209 210 #endif
+1
apps/plugins/SOURCES.app_build
··· 19 19 20 20 21 21 #ifdef HAVE_TEST_PLUGINS /* enable in advanced build options */ 22 + test_kbd.c 22 23 test_fps.c 23 24 #ifdef HAVE_ADJUSTABLE_CPU_FREQ 24 25 test_boost.c
+46
apps/plugins/test_kbd.c
··· 1 + /*************************************************************************** 2 + * __________ __ ___. 3 + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 + * \/ \/ \/ \/ \/ 8 + * $Id$ 9 + * 10 + * Copyright (C) 2002 Björn Stenberg 11 + * 12 + * This program is free software; you can redistribute it and/or 13 + * modify it under the terms of the GNU General Public License 14 + * as published by the Free Software Foundation; either version 2 15 + * of the License, or (at your option) any later version. 16 + * 17 + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 + * KIND, either express or implied. 19 + * 20 + ****************************************************************************/ 21 + 22 + /* welcome to the example rockbox plugin */ 23 + 24 + /* mandatory include for all plugins */ 25 + #include "plugin.h" 26 + 27 + /* this is the plugin entry point */ 28 + enum plugin_status plugin_start(const void* parameter) 29 + { 30 + /* if you don't use the parameter, you can do like 31 + this to avoid the compiler warning about it */ 32 + (void)parameter; 33 + 34 + /* "rb->" marks a plugin api call. Rockbox offers many of its built-in 35 + * functions to plugins */ 36 + /* now go ahead and have fun! */ 37 + char buffer[MAX_PATH]; 38 + rb->snprintf(buffer, sizeof(buffer), "Keyboard test; Current plugin filename: '%s'", 39 + rb->plugin_get_current_filename()); 40 + 41 + if (rb->kbd_input(buffer, sizeof(buffer), NULL) == 0) 42 + rb->splash(HZ*2, buffer); 43 + 44 + /* tell Rockbox that we have completed successfully */ 45 + return PLUGIN_OK; 46 + }
+156 -27
apps/recorder/keyboard.c
··· 37 37 #include "viewport.h" 38 38 #include "file.h" 39 39 #include "splash.h" 40 + #include "core_alloc.h" 40 41 41 42 #ifndef O_BINARY 42 43 #define O_BINARY 0 ··· 78 79 #define CHANGED_CURSOR 2 79 80 #define CHANGED_TEXT 3 80 81 82 + static int kbd_vpbuf_handle[NB_SCREENS] = {0}; 83 + 84 + enum ekbd_viewports 85 + { 86 + eKBD_VP_TEXT = 0, 87 + eKBD_VP_PICKER, 88 + eKBD_VP_MENU, 89 + eKBD_COUNT_VP_COUNT 90 + }; 91 + 81 92 struct keyboard_parameters 82 93 { 94 + struct viewport *kbd_viewports; 83 95 unsigned short kbd_buf[KBD_BUF_SIZE]; 84 96 unsigned short *kbd_buf_ptr; 85 97 unsigned short max_line_len; ··· 142 154 0x73,0x55,0x4c,0x61,0x5a,0x80 }; 143 155 #endif 144 156 157 + static void keyboard_layout(struct viewport *kbd_vp, 158 + struct keyboard_parameters *pm, 159 + struct screen *sc) 160 + { 161 + /*Note: viewports are initialized to vp_default by kbd_create_viewports */ 162 + 163 + int sc_w = sc->getwidth(); 164 + int sc_h = sc->getheight(); 165 + 166 + /* TEXT */ 167 + struct viewport *vp = &kbd_vp[eKBD_VP_TEXT]; 168 + /* make sure height is even for the text box */ 169 + int text_height = (MAX(pm->font_h, get_icon_height(sc->screen_type)) & ~1) + 2; 170 + vp->x = 0; /* LEFT */ 171 + vp->y = 0; /* TOP */ 172 + vp->width = sc_w; 173 + vp->height = text_height; 174 + vp->font = pm->curfont; 175 + text_height += vp->x + 3; 176 + 177 + /* MENU */ 178 + vp = &kbd_vp[eKBD_VP_MENU]; 179 + int menu_w = 0;//pm->font_w * MENU_CHARS; /* NOT IMPLEMENTED */ 180 + vp->x = 0; /* LEFT */ 181 + vp->y = text_height; /* TOP */ 182 + vp->width = menu_w; 183 + vp->height = 0; 184 + vp->font = pm->curfont; 185 + menu_w += vp->x; 186 + 187 + /* PICKER */ 188 + vp = &kbd_vp[eKBD_VP_PICKER]; 189 + vp->x = menu_w; /* LEFT */ 190 + vp->y = text_height - 2; /* TOP */ 191 + vp->width = sc_w - menu_w; 192 + vp->height = sc_h - vp->y; /* (MAX SIZE) - OVERWRITTEN */ 193 + vp->font = pm->curfont; 194 + } 195 + 196 + static int kbd_create_viewports(struct keyboard_parameters * kbd_param) 197 + { 198 + struct viewport *vp; 199 + size_t bufsz = (sizeof(struct viewport) * 3); /* different for remote??*/ 200 + int i, h; 201 + FOR_NB_SCREENS(l) 202 + { 203 + h = core_alloc_ex("kbd vp", bufsz, &buflib_ops_locked); 204 + if (h <= 0) 205 + return h; 206 + kbd_vpbuf_handle[l] = h; 207 + kbd_param[l].kbd_viewports = ((struct viewport *) core_get_data(h)); 208 + for (i = 0; i < eKBD_COUNT_VP_COUNT; i++) 209 + { 210 + vp = &kbd_param[l].kbd_viewports[i]; 211 + viewport_set_defaults(vp, l); 212 + vp->font = FONT_UI; 213 + } 214 + } 215 + return bufsz; 216 + } 217 + 218 + static void kbd_destroy_viewports(void) 219 + { 220 + FOR_NB_SCREENS(l) 221 + { 222 + if (kbd_vpbuf_handle[l] > 0) /* free old buffer */ 223 + { 224 + kbd_vpbuf_handle[l] = core_free(kbd_vpbuf_handle[l]); 225 + } 226 + } 227 + } 228 + 145 229 /* Loads a custom keyboard into memory 146 230 call with NULL to reset keyboard */ 147 231 int load_kbd(unsigned char* filename) ··· 309 393 k = k * pm->max_chars + x; 310 394 return (*pbuf != 0xFEFF && k < *pbuf)? pbuf[k+1]: ' '; 311 395 } 312 - 313 - static void kbd_calc_params(struct keyboard_parameters *pm, 396 + static void kbd_calc_pm_params(struct keyboard_parameters *pm, 397 + struct screen *sc, struct edit_state *state); 398 + static void kbd_calc_vp_params(struct keyboard_parameters *pm, 314 399 struct screen *sc, struct edit_state *state); 315 400 static void kbd_draw_picker(struct keyboard_parameters *pm, 316 401 struct screen *sc, struct edit_state *state); ··· 342 427 viewportmanager_theme_enable(l, false, NULL); 343 428 } 344 429 430 + if (kbd_create_viewports(param) <= 0) 431 + { 432 + splash(HZ * 2,"Error: No Viewport Allocated, OOM?"); 433 + goto cleanup; 434 + } 435 + 345 436 #ifdef HAVE_TOUCHSCREEN 346 437 /* keyboard is unusuable in pointing mode so force 3x3 for now. 347 438 * TODO - fix properly by using a bigger font and changing the layout */ 348 439 enum touchscreen_mode old_mode = touchscreen_get_mode(); 349 440 touchscreen_set_mode(TOUCHSCREEN_BUTTON); 350 441 #endif 351 - 352 442 /* initialize state */ 353 443 state.text = text; 354 444 state.buflen = buflen; ··· 443 533 pm->kbd_buf_ptr = pm->kbd_buf; /* internal layout buffer */ 444 534 445 535 struct screen *sc = &screens[l]; 446 - kbd_calc_params(pm, sc, &state); 536 + 537 + kbd_calc_pm_params(pm, sc, &state); 538 + 539 + keyboard_layout(pm->kbd_viewports, pm, sc); 540 + /* have all the params we need lets set up our viewports */ 541 + kbd_calc_vp_params(pm, sc, &state); 542 + /* We want these the same height */ 543 + pm->kbd_viewports[eKBD_VP_MENU].height = pm->main_y; 544 + pm->kbd_viewports[eKBD_VP_PICKER].height = pm->main_y; 447 545 } 448 546 449 547 if (global_settings.talk_menu) /* voice UI? */ ··· 698 796 settings_save(); 699 797 } 700 798 #endif /* HAVE_MORSE_INPUT && KBD_TOGGLE_INPUT */ 701 - 799 + cleanup: 702 800 FOR_NB_SCREENS(l) 703 801 { 704 802 screens[l].setfont(FONT_UI); 705 803 viewportmanager_theme_undo(l, false); 706 804 } 805 + kbd_destroy_viewports(); 707 806 return ret; 708 807 } 709 - 710 - static void kbd_calc_params(struct keyboard_parameters *pm, 808 + static void kbd_calc_pm_params(struct keyboard_parameters *pm, 711 809 struct screen *sc, struct edit_state *state) 712 810 { 713 811 struct font* font; 714 812 const unsigned char *p; 715 813 unsigned short ch, *pbuf; 716 - int icon_w, sc_w, sc_h, w; 717 - int i, total_lines; 814 + int i, w; 718 815 #ifdef HAVE_TOUCHSCREEN 719 - int button_h = 0; 720 - bool flippage_button = false; 721 816 pm->show_buttons = (sc->screen_type == SCREEN_MAIN && 722 817 (touchscreen_get_mode() == TOUCHSCREEN_POINT)); 723 818 #endif ··· 765 860 #ifdef HAVE_TOUCHSCREEN 766 861 pm->font_w = GRID_SIZE(sc->screen_type, pm->font_w); 767 862 #endif 863 + 864 + } 865 + 866 + static void kbd_calc_vp_params(struct keyboard_parameters *pm, 867 + struct screen *sc, struct edit_state *state) 868 + { 869 + (void) state; 870 + struct viewport *vp = &pm->kbd_viewports[eKBD_VP_PICKER]; 871 + int icon_w, sc_w, sc_h; 872 + int i, total_lines; 873 + unsigned short *pbuf; 768 874 /* calculate how many characters to put in a row. */ 769 875 icon_w = get_icon_width(sc->screen_type); 770 - sc_w = sc->getwidth(); 876 + 877 + sc_w = vp->width; /**sc->getwidth();**/ 771 878 if (pm->font_w < sc_w / pm->max_line_len) 772 879 pm->font_w = sc_w / pm->max_line_len; 773 880 pm->max_chars = sc_w / pm->font_w; ··· 776 883 pm->max_chars_text = sc_w / pm->text_w - 2; 777 884 778 885 /* calculate pm->pages and pm->lines */ 779 - sc_h = sc->getheight(); 886 + sc_h = vp->height;/**sc->getheight()**/; 780 887 #ifdef HAVE_TOUCHSCREEN 888 + int button_h = 0; 889 + bool flippage_button = false; 781 890 /* add space for buttons */ 782 891 if (pm->show_buttons) 783 892 { ··· 824 933 pm->main_y = pm->font_h*pm->lines + pm->keyboard_margin; 825 934 pm->keyboard_margin -= pm->keyboard_margin/2; 826 935 #ifdef HAVE_TOUCHSCREEN 827 - /* flip page button is put between piker and edit line */ 936 + /* flip page button is put between picker and edit line */ 828 937 if (flippage_button) 829 938 pm->main_y += button_h; 830 939 #endif ··· 843 952 static void kbd_draw_picker(struct keyboard_parameters *pm, 844 953 struct screen *sc, struct edit_state *state) 845 954 { 955 + struct viewport *last; 956 + struct viewport *vp = &pm->kbd_viewports[eKBD_VP_PICKER]; 957 + last = sc->set_viewport(vp); 958 + sc->clear_viewport(); 959 + 846 960 char outline[8]; 847 961 #ifdef HAVE_MORSE_INPUT 848 962 if (state->morse_mode) 849 963 { 850 964 const int w = 6, h = 8; /* sysfixed font width, height */ 851 965 int i, j, x, y; 852 - int sc_w = sc->getwidth(), sc_h = pm->main_y - pm->keyboard_margin - 1; 966 + int sc_w = vp->width, sc_h = vp->height;//pm->main_y - pm->keyboard_margin - 1; 853 967 854 968 /* Draw morse code screen with sysfont */ 855 969 sc->setfont(FONT_SYSFIXED); ··· 926 1040 sc->set_drawmode(DRMODE_SOLID); 927 1041 } 928 1042 } 1043 + sc->set_viewport(last); 929 1044 } 930 1045 931 1046 static void kbd_draw_edit_line(struct keyboard_parameters *pm, ··· 933 1048 { 934 1049 char outline[8]; 935 1050 unsigned char *utf8; 936 - int i = 0, j = 0, icon_w, w; 937 - int sc_w = sc->getwidth(); 938 - int y = pm->main_y - pm->keyboard_margin; 1051 + int i = 0, j = 0, w; 1052 + int icon_w, icon_y; 1053 + struct viewport *last; 1054 + struct viewport *vp = &pm->kbd_viewports[eKBD_VP_TEXT]; 1055 + last = sc->set_viewport(vp); 1056 + sc->clear_viewport(); 1057 + sc->hline(1, vp->width - 1, vp->height - 1); 1058 + 1059 + int sc_w = vp->width; 1060 + int y = (vp->height - pm->font_h) / 2; 1061 + 1062 + 939 1063 int text_margin = (sc_w - pm->text_w * pm->max_chars_text) / 2; 940 1064 1065 + #if 0 941 1066 /* Clear text area one pixel above separator line so any overdraw 942 1067 doesn't collide */ 943 1068 screen_clear_area(sc, 0, y - 1, sc_w, pm->font_h + 6); 944 1069 945 1070 sc->hline(0, sc_w - 1, y); 946 - 1071 + #endif 947 1072 /* write out the text */ 948 1073 sc->setfont(pm->curfont); 949 1074 950 1075 pm->leftpos = MAX(0, MIN(state->len_utf8, state->editpos + 2) 951 1076 - pm->max_chars_text); 1077 + 952 1078 pm->curpos = state->editpos - pm->leftpos; 953 1079 utf8 = state->text + utf8seek(state->text, pm->leftpos); 954 1080 ··· 958 1084 strlcpy(outline, utf8, j+1); 959 1085 sc->getstringsize(outline, &w, NULL); 960 1086 sc->putsxy(text_margin + i*pm->text_w + (pm->text_w-w)/2, 961 - pm->main_y, outline); 1087 + y, outline); 962 1088 utf8 += j; 963 1089 i++; 964 1090 } 965 1091 966 1092 icon_w = get_icon_width(sc->screen_type); 1093 + icon_y = (vp->height - get_icon_height(sc->screen_type)) / 2; 967 1094 if (pm->leftpos > 0) 968 1095 { 969 1096 /* Draw nicer bitmap arrow if room, else settle for "<". */ ··· 971 1098 { 972 1099 screen_put_icon_with_offset(sc, 0, 0, 973 1100 (text_margin - icon_w) / 2, 974 - pm->main_y, Icon_Reverse_Cursor); 1101 + icon_y, Icon_Reverse_Cursor); 975 1102 } 976 1103 else 977 1104 { 978 1105 sc->getstringsize("<", &w, NULL); 979 - sc->putsxy(text_margin - w, pm->main_y, "<"); 1106 + sc->putsxy(text_margin - w, y, "<"); 980 1107 } 981 1108 } 982 1109 ··· 987 1114 { 988 1115 screen_put_icon_with_offset(sc, 0, 0, 989 1116 sc_w - (text_margin + icon_w) / 2, 990 - pm->main_y, Icon_Cursor); 1117 + icon_y, Icon_Cursor); 991 1118 } 992 1119 else 993 1120 { 994 - sc->putsxy(sc_w - text_margin, pm->main_y, ">"); 1121 + sc->putsxy(sc_w - text_margin, y, ">"); 995 1122 } 996 1123 } 997 1124 ··· 999 1126 i = text_margin + pm->curpos * pm->text_w; 1000 1127 1001 1128 if (state->cur_blink) 1002 - sc->vline(i, pm->main_y, pm->main_y + pm->font_h - 1); 1129 + sc->vline(i, y, y + pm->font_h - 1); 1003 1130 1004 1131 if (state->hangul) /* draw underbar */ 1005 - sc->hline(i - pm->text_w, i, pm->main_y + pm->font_h - 1); 1132 + sc->hline(i - pm->text_w, i, y + pm->font_h - 1); 1006 1133 1007 1134 if (pm->line_edit) 1008 1135 { 1009 1136 sc->set_drawmode(DRMODE_COMPLEMENT); 1010 - sc->fillrect(0, y + 2, sc_w, pm->font_h + 2); 1137 + sc->fillrect(0, y - 1, sc_w, pm->font_h + 2); 1011 1138 sc->set_drawmode(DRMODE_SOLID); 1012 1139 } 1140 + 1141 + sc->set_viewport(last); 1013 1142 } 1014 1143 1015 1144 #ifdef HAVE_TOUCHSCREEN