menu

a graphical menu within a window
Index Commits Files Refs
main.c (3431B)
   1 #include <stdbool.h>
   2 
   3 #include <SDL2/SDL.h>
   4 #include <SDL2/SDL_ttf.h>
   5 
   6 #include "menu.h"
   7 
   8 #define FONT_SIZE    12
   9 #define FONT_NAME    "./VictorMono-Bold.ttf"
  10 
  11 #define WIN_DEFAULT_W    800
  12 #define WIN_DEFAULT_H    600
  13 
  14 #define BG_COLOR    0x323232FF
  15 
  16 static char *entries_text[TOTAL_ENTRIES] = {
  17     "Bubble sort",
  18     "Bubble sort (improved)",
  19     "Insertion sort",
  20     "Binary insertion sort",
  21     "Merge sort",
  22     "Quick sort",
  23     "Quick sort (dual pivots)",
  24     "Quick sort (LR pointers)",
  25     "Quick sort (LL pointers)",
  26     "Shell sort",
  27     "Radix sort",
  28     "Heap sort",
  29     "Cocktail shaker sort",
  30     "Gnome sort",
  31     "Odd-even sort",
  32     "Tim sort",
  33     "Bogo sort",
  34     "Stooge sort",
  35     "Spaghetti sort"
  36 };
  37 
  38 int win_w, win_h;
  39 TTF_Font *font;
  40 int x, y;
  41 Uint32 buttons;
  42 
  43 int main (void) {
  44     SDL_Window *win;
  45     SDL_Renderer *rend;
  46     int min_w, min_h;
  47     size_t i;
  48 
  49     SDL_Init(SDL_INIT_VIDEO);
  50 
  51     win = SDL_CreateWindow(
  52         "menu",
  53         SDL_WINDOWPOS_CENTERED,
  54         SDL_WINDOWPOS_CENTERED,
  55         WIN_DEFAULT_W,
  56         WIN_DEFAULT_H,
  57         SDL_WINDOW_RESIZABLE
  58     );
  59 
  60     rend = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
  61 
  62     if (!win || !rend) return 1;
  63     else if(TTF_Init() == -1) return 1;
  64 
  65     font = TTF_OpenFont(FONT_NAME, FONT_SIZE);
  66 
  67     min_h = (TOTAL_ENTRIES * (BAR_H + ELEMENTS_PADDING)) + ELEMENTS_PADDING;
  68     min_w = (((float)min_h * 4) / 3);
  69     SDL_SetWindowMinimumSize(win, min_w, min_h);
  70 
  71     bool run = true;
  72     SDL_Event event;
  73     win_w = WIN_DEFAULT_W;
  74     win_h = WIN_DEFAULT_H;
  75 
  76     Entry entries[TOTAL_ENTRIES];
  77 
  78     for(i = 0; i < TOTAL_ENTRIES; i++) {
  79         entries[i] = (Entry) {
  80             .text = entries_text[i],
  81             .selected = false,
  82             .hover = false,
  83             .index = i,
  84         };
  85     }
  86 
  87     entries[0].selected = true;
  88     SDL_Keymod mod;
  89     size_t index = TOTAL_ENTRIES;
  90     while(run) {
  91         while(SDL_PollEvent(&event)) {
  92             switch(event.type) {
  93                 case SDL_QUIT:
  94                     run = false;
  95                     break;
  96                 default: break;
  97             case SDL_KEYDOWN:
  98                 /* printf("SDL_GetModState() == %X\n", SDL_GetModState()); */
  99                 mod = SDL_GetModState();
 100                 switch(event.key.keysym.scancode) {
 101                     case SDL_SCANCODE_Q:
 102                         run = false;
 103                         break;
 104                     case SDL_SCANCODE_J:
 105                     case SDL_SCANCODE_DOWN:
 106                         if(mod == KMOD_NONE) select_next(entries);
 107                         break;
 108                     case SDL_SCANCODE_K:
 109                     case SDL_SCANCODE_UP:
 110                         if(mod == KMOD_NONE) select_prev(entries);
 111                         break;
 112                     case SDL_SCANCODE_RETURN:
 113                         for(i = 0; i < TOTAL_ENTRIES; i++)
 114                             if(entries[i].selected)
 115                                 printf("%s\n", entries[i].text);
 116                         break;
 117                     default: break;
 118                 }
 119                 break;
 120             case SDL_MOUSEBUTTONDOWN:
 121                 index = entry_at(entries, event.button.x, event.button.y);
 122                 if(index != TOTAL_ENTRIES) {
 123                     printf("%s\n", entries[index].text);
 124                     select_index(entries, index);
 125                 }
 126                 break;
 127             case SDL_WINDOWEVENT:
 128                 switch(event.window.event) {
 129                 case SDL_WINDOWEVENT_RESIZED:
 130                     win_w = event.window.data1;
 131                     win_h = event.window.data2;
 132                     break;
 133                 default: break;
 134                 }
 135                 break;
 136             }
 137         }
 138 
 139         SDL_PumpEvents();  // make sure we have the latest mouse state.
 140 
 141         buttons = SDL_GetMouseState(&x, &y);
 142         hover_at(entries, x, y);
 143 
 144         SDL_SetRenderDrawColor(rend, UNHEX(BG_COLOR));
 145         SDL_RenderClear(rend);
 146 
 147         compute_entries_pos(entries, win_w, win_h);
 148         for(i = 0; i < TOTAL_ENTRIES; i++) {
 149             draw_entry(rend, font, win_w, win_h, entries[i]);
 150         }
 151 
 152         SDL_RenderPresent(rend);
 153         SDL_Delay(1);
 154     }
 155 
 156     TTF_CloseFont(font);
 157 
 158     SDL_DestroyRenderer(rend);
 159     SDL_DestroyWindow(win);
 160 
 161     TTF_Quit();
 162     SDL_Quit();
 163     return 0;
 164 }