Xcode-iOS/Demos/src/keyboard.c
changeset 11306 45fbdef6a227
parent 10370 d90965a3b100
child 11307 003462e40c4f
equal deleted inserted replaced
11305:93ff3c6bff82 11306:45fbdef6a227
     8 #include "common.h"
     8 #include "common.h"
     9 
     9 
    10 #define GLYPH_SIZE_IMAGE 16     /* size of glyphs (characters) in the bitmap font file */
    10 #define GLYPH_SIZE_IMAGE 16     /* size of glyphs (characters) in the bitmap font file */
    11 #define GLYPH_SIZE_SCREEN 32    /* size of glyphs (characters) as shown on the screen */
    11 #define GLYPH_SIZE_SCREEN 32    /* size of glyphs (characters) as shown on the screen */
    12 
    12 
       
    13 #define MAX_CHARS 1024
       
    14 
    13 static SDL_Texture *texture; /* texture where we'll hold our font */
    15 static SDL_Texture *texture; /* texture where we'll hold our font */
    14 
       
    15 /* function declarations */
       
    16 void cleanup(void);
       
    17 void drawBlank(int x, int y);
       
    18 
    16 
    19 static SDL_Renderer *renderer;
    17 static SDL_Renderer *renderer;
    20 static int numChars = 0;        /* number of characters we've typed so far */
    18 static int numChars = 0;        /* number of characters we've typed so far */
    21 static SDL_bool lastCharWasColon = 0;   /* we use this to detect sequences such as :) */
       
    22 static SDL_Color bg_color = { 50, 50, 100, 255 };       /* color of background */
    19 static SDL_Color bg_color = { 50, 50, 100, 255 };       /* color of background */
       
    20 
       
    21 static int glyphs[MAX_CHARS];
    23 
    22 
    24 /* this structure maps a scancode to an index in our bitmap font.
    23 /* this structure maps a scancode to an index in our bitmap font.
    25    it also contains data about under which modifiers the mapping is valid
    24    it also contains data about under which modifiers the mapping is valid
    26    (for example, we don't want shift + 1 to produce the character '1',
    25    (for example, we don't want shift + 1 to produce the character '1',
    27    but rather the character '!')
    26    but rather the character '!')
   105     index is returned.
   104     index is returned.
   106 
   105 
   107     If there is no entry for the key, -1 is returned
   106     If there is no entry for the key, -1 is returned
   108 */
   107 */
   109 int
   108 int
   110 keyToIndex(SDL_Keysym key)
   109 keyToGlyphIndex(SDL_Keysym key)
   111 {
   110 {
   112     int i, index = -1;
   111     int i, index = -1;
   113     for (i = 0; i < TABLE_SIZE; i++) {
   112     for (i = 0; i < TABLE_SIZE; i++) {
   114         fontMapping compare = map[i];
   113         fontMapping compare = map[i];
   115         if (key.scancode == compare.scancode) {
   114         if (key.scancode == compare.scancode) {
   139     int y_padding = 32;         /* padding space at top of screen */
   138     int y_padding = 32;         /* padding space at top of screen */
   140     /* figure out the number of characters that can fit horizontally across the screen */
   139     /* figure out the number of characters that can fit horizontally across the screen */
   141     int max_x_chars = (renderW - 2 * x_padding) / GLYPH_SIZE_SCREEN;
   140     int max_x_chars = (renderW - 2 * x_padding) / GLYPH_SIZE_SCREEN;
   142     int line_separation = 5;    /* pixels between each line */
   141     int line_separation = 5;    /* pixels between each line */
   143     *x = (n % max_x_chars) * GLYPH_SIZE_SCREEN + x_padding;
   142     *x = (n % max_x_chars) * GLYPH_SIZE_SCREEN + x_padding;
   144     *y = (n / max_x_chars) * (GLYPH_SIZE_SCREEN + line_separation) +
   143     *y = (n / max_x_chars) * (GLYPH_SIZE_SCREEN + line_separation) + y_padding;
   145         y_padding;
       
   146 }
   144 }
   147 
   145 
   148 void
   146 void
   149 drawIndex(int index)
   147 drawGlyph(int glyph, int positionIndex)
   150 {
   148 {
   151     int x, y;
   149     int x, y;
   152     getPositionForCharNumber(numChars, &x, &y);
   150     getPositionForCharNumber(positionIndex, &x, &y);
   153     SDL_Rect srcRect =
   151     SDL_Rect srcRect = { GLYPH_SIZE_IMAGE * glyph, 0, GLYPH_SIZE_IMAGE, GLYPH_SIZE_IMAGE };
   154         { GLYPH_SIZE_IMAGE * index, 0, GLYPH_SIZE_IMAGE, GLYPH_SIZE_IMAGE };
       
   155     SDL_Rect dstRect = { x, y, GLYPH_SIZE_SCREEN, GLYPH_SIZE_SCREEN };
   152     SDL_Rect dstRect = { x, y, GLYPH_SIZE_SCREEN, GLYPH_SIZE_SCREEN };
   156     drawBlank(x, y);
       
   157     SDL_RenderCopy(renderer, texture, &srcRect, &dstRect);
   153     SDL_RenderCopy(renderer, texture, &srcRect, &dstRect);
   158 }
       
   159 
       
   160 /*  draws the cursor icon at the current end position of the text */
       
   161 void
       
   162 drawCursor(void)
       
   163 {
       
   164     drawIndex(29);              /* cursor is at index 29 in the bitmap font */
       
   165 }
       
   166 
       
   167 /* paints over a glyph sized region with the background color
       
   168    in effect it erases the area
       
   169 */
       
   170 void
       
   171 drawBlank(int x, int y)
       
   172 {
       
   173     SDL_Rect rect = { x, y, GLYPH_SIZE_SCREEN, GLYPH_SIZE_SCREEN };
       
   174     SDL_SetRenderDrawColor(renderer, bg_color.r, bg_color.g, bg_color.b, bg_color.a);
       
   175     SDL_RenderFillRect(renderer, &rect);
       
   176 }
       
   177 
       
   178 /* moves backwards one character, erasing the last one put down */
       
   179 void
       
   180 backspace(void)
       
   181 {
       
   182     int x, y;
       
   183     if (numChars > 0) {
       
   184         getPositionForCharNumber(numChars, &x, &y);
       
   185         drawBlank(x, y);
       
   186         numChars--;
       
   187         getPositionForCharNumber(numChars, &x, &y);
       
   188         drawBlank(x, y);
       
   189         drawCursor();
       
   190     }
       
   191 }
   154 }
   192 
   155 
   193 /* this function loads our font into an SDL_Texture and returns the SDL_Texture  */
   156 /* this function loads our font into an SDL_Texture and returns the SDL_Texture  */
   194 SDL_Texture*
   157 SDL_Texture*
   195 loadFont(void)
   158 loadFont(void)
   212         SDL_Surface *converted =
   175         SDL_Surface *converted =
   213             SDL_CreateRGBSurface(0, surface->w, surface->h, bpp, Rmask, Gmask,
   176             SDL_CreateRGBSurface(0, surface->w, surface->h, bpp, Rmask, Gmask,
   214                                  Bmask, Amask);
   177                                  Bmask, Amask);
   215         SDL_BlitSurface(surface, NULL, converted, NULL);
   178         SDL_BlitSurface(surface, NULL, converted, NULL);
   216         /* create our texture */
   179         /* create our texture */
   217         texture =
   180         texture = SDL_CreateTextureFromSurface(renderer, converted);
   218             SDL_CreateTextureFromSurface(renderer, converted);
       
   219         if (texture == 0) {
   181         if (texture == 0) {
   220             printf("texture creation failed: %s\n", SDL_GetError());
   182             printf("texture creation failed: %s\n", SDL_GetError());
   221         } else {
   183         } else {
   222             /* set blend mode for our texture */
   184             /* set blend mode for our texture */
   223             SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
   185             SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
   226         SDL_FreeSurface(converted);
   188         SDL_FreeSurface(converted);
   227         return texture;
   189         return texture;
   228     }
   190     }
   229 }
   191 }
   230 
   192 
       
   193 void
       
   194 draw()
       
   195 {
       
   196     SDL_SetRenderDrawColor(renderer, bg_color.r, bg_color.g, bg_color.b, bg_color.a);
       
   197     SDL_RenderClear(renderer);
       
   198 
       
   199     for (int i = 0; i < numChars; i++) {
       
   200         drawGlyph(glyphs[i], i);
       
   201     }
       
   202 
       
   203     drawGlyph(29, numChars); /* cursor is at index 29 in the bitmap font */
       
   204 
       
   205     SDL_RenderPresent(renderer);
       
   206 }
       
   207 
   231 int
   208 int
   232 main(int argc, char *argv[])
   209 main(int argc, char *argv[])
   233 {
   210 {
   234     int index;                  /* index of last key we pushed in the bitmap font */
   211     int index;                  /* index of last key we pushed in the bitmap font */
   235     SDL_Window *window;
   212     SDL_Window *window;
   236     SDL_Event event;            /* last event received */
   213     SDL_Event event;            /* last event received */
   237     SDL_Keymod mod;             /* key modifiers of last key we pushed */
       
   238     SDL_Scancode scancode;      /* scancode of last key we pushed */
   214     SDL_Scancode scancode;      /* scancode of last key we pushed */
   239     int width;
   215     int width;
   240     int height;
   216     int height;
   241 
   217 
   242     if (SDL_Init(SDL_INIT_VIDEO) < 0) {
   218     if (SDL_Init(SDL_INIT_VIDEO) < 0) {
   243         printf("Error initializing SDL: %s", SDL_GetError());
   219         printf("Error initializing SDL: %s", SDL_GetError());
   244     }
   220     }
   245     /* create window */
   221     /* create window */
   246     window = SDL_CreateWindow("iPhone keyboard test", 0, 0, 320, 480, SDL_WINDOW_ALLOW_HIGHDPI);
   222     window = SDL_CreateWindow("iPhone keyboard test", 0, 0, 320, 480, SDL_WINDOW_ALLOW_HIGHDPI);
   247     /* create renderer */
   223     /* create renderer */
   248     renderer = SDL_CreateRenderer(window, -1, 0);
   224     renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC);
   249 
   225 
   250     SDL_GetWindowSize(window, &width, &height);
   226     SDL_GetWindowSize(window, &width, &height);
   251     SDL_RenderSetLogicalSize(renderer, width, height);
   227     SDL_RenderSetLogicalSize(renderer, width, height);
   252 
   228 
   253     /* load up our font */
   229     /* load up our font */
   254     loadFont();
   230     loadFont();
   255 
   231 
   256     /* draw the background, we'll just paint over it */
       
   257     SDL_SetRenderDrawColor(renderer, bg_color.r, bg_color.g, bg_color.b, bg_color.a);
       
   258     SDL_RenderFillRect(renderer, NULL);
       
   259     SDL_RenderPresent(renderer);
       
   260 
       
   261     int done = 0;
   232     int done = 0;
   262     /* loop till we get SDL_Quit */
   233 
   263     while (!done && SDL_WaitEvent(&event)) {
   234     while (!done) {
   264         switch (event.type) {
   235         while (SDL_PollEvent(&event)) {
   265         case SDL_QUIT:
   236             switch (event.type) {
   266             done = 1;
   237             case SDL_QUIT:
   267             break;
   238                 done = 1;
   268         case SDL_KEYDOWN:
   239                 break;
   269             index = keyToIndex(event.key.keysym);
   240             case SDL_TEXTINPUT:
   270             scancode = event.key.keysym.scancode;
   241                 break;
   271             mod = event.key.keysym.mod;
   242             case SDL_KEYDOWN:
   272             if (scancode == SDL_SCANCODE_DELETE) {
   243                 if (event.key.keysym.scancode == SDL_SCANCODE_BACKSPACE) {
   273                 /* if user hit delete, delete the last character */
   244                     if (numChars > 0) {
   274                 backspace();
   245                         numChars--;
   275                 lastCharWasColon = 0;
   246                     }
   276             } else if (lastCharWasColon && scancode == SDL_SCANCODE_0
   247                 } else if (numChars + 1 < MAX_CHARS) {
   277                        && (mod & KMOD_SHIFT)) {
   248                     int index = keyToGlyphIndex(event.key.keysym);
   278                 /* if our last key was a colon and this one is a close paren, the make a hoppy face */
   249                     if (index >= 0) {
   279                 backspace();
   250                         glyphs[numChars++] = index;
   280                 drawIndex(32);  /* index for happy face */
   251                     }
   281                 numChars++;
   252                 }
   282                 drawCursor();
   253                 break;
   283                 lastCharWasColon = 0;
   254             case SDL_MOUSEBUTTONUP:
   284             } else if (index != -1) {
   255                 /* mouse up toggles onscreen keyboard visibility */
   285                 /* if we aren't doing a happy face, then just draw the normal character */
   256                 if (SDL_IsTextInputActive()) {
   286                 drawIndex(index);
   257                     SDL_StopTextInput();
   287                 numChars++;
   258                 } else {
   288                 drawCursor();
   259                     SDL_StartTextInput();
   289                 lastCharWasColon =
   260                 }
   290                     (event.key.keysym.scancode == SDL_SCANCODE_SEMICOLON
   261                 break;
   291                      && (event.key.keysym.mod & KMOD_SHIFT));
       
   292             }
   262             }
   293             /* check if the key was a colon */
       
   294             /* draw our updates to the screen */
       
   295             SDL_RenderPresent(renderer);
       
   296             break;
       
   297         case SDL_MOUSEBUTTONUP:
       
   298             /*      mouse up toggles onscreen keyboard visibility */
       
   299             if (SDL_IsTextInputActive()) {
       
   300                 SDL_StopTextInput();
       
   301             } else {
       
   302                 SDL_StartTextInput();
       
   303             }
       
   304             break;
       
   305         }
   263         }
   306     }
   264 
   307     cleanup();
   265         draw();
       
   266         SDL_Delay(15);
       
   267     }
       
   268 
       
   269     SDL_DestroyTexture(texture);
       
   270     SDL_DestroyRenderer(renderer);
       
   271     SDL_DestroyWindow(window);
   308     return 0;
   272     return 0;
   309 }
   273 }
   310 
       
   311 /* clean up after ourselves like a good kiddy */
       
   312 void
       
   313 cleanup(void)
       
   314 {
       
   315     SDL_DestroyTexture(texture);
       
   316     SDL_Quit();
       
   317 }