repos/menu

A graphical menu within a window
Commits Files Refs
main.c (163 lines)
   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 *elements_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 /* TODO: remove global variables */
  44 /* TODO: custom box size, margin, padding, pos, etc */
  45 /* TODO: linked list (?) */
  46 
  47 int main (void)
  48 {
  49     SDL_Window *win;
  50     SDL_Renderer *rend;
  51     int min_w, min_h;
  52     size_t i;
  53     Set *set;
  54 
  55     SDL_Init(SDL_INIT_VIDEO);
  56 
  57     win = SDL_CreateWindow(
  58         "menu",
  59         SDL_WINDOWPOS_CENTERED,
  60         SDL_WINDOWPOS_CENTERED,
  61         WIN_DEFAULT_W,
  62         WIN_DEFAULT_H,
  63         SDL_WINDOW_RESIZABLE
  64     );
  65 
  66     rend = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
  67 
  68     if (!win || !rend) return 1;
  69     else if(TTF_Init() == -1) return 1;
  70 
  71     font = TTF_OpenFont(FONT_NAME, FONT_SIZE);
  72 
  73     min_h = (TOTAL_ENTRIES * (BAR_H + ELEMENTS_PADDING)) + ELEMENTS_PADDING;
  74     min_w = (((float)min_h * 4) / 3);
  75     SDL_SetWindowMinimumSize(win, min_w, min_h);
  76 
  77     bool run = true;
  78     SDL_Event event;
  79     win_w = WIN_DEFAULT_W;
  80     win_h = WIN_DEFAULT_H;
  81 
  82     Set_new(&set, TOTAL_ENTRIES);
  83 
  84     for(i = 0; i < set->size; i++)
  85         Elem_set_text(set->elements[i], elements_text[i]);
  86 
  87     SDL_Keymod mod;
  88     size_t index = TOTAL_ENTRIES;
  89     while(run) {
  90         while(SDL_PollEvent(&event)) {
  91             switch(event.type) {
  92                 case SDL_QUIT:
  93                     run = false;
  94                     break;
  95                 default: break;
  96             case SDL_KEYDOWN:
  97                 /* printf("SDL_GetModState() == %X\n", SDL_GetModState()); */
  98                 mod = SDL_GetModState();
  99                 switch(event.key.keysym.scancode) {
 100                     case SDL_SCANCODE_Q:
 101                         run = false;
 102                         break;
 103                     case SDL_SCANCODE_J:
 104                     case SDL_SCANCODE_DOWN:
 105                         if(mod == KMOD_NONE) Set_select_next(set);
 106                         break;
 107                     case SDL_SCANCODE_K:
 108                     case SDL_SCANCODE_UP:
 109                         if(mod == KMOD_NONE) Set_select_prev(set);
 110                         break;
 111                     case SDL_SCANCODE_RETURN:
 112                         for(i = 0; i < TOTAL_ENTRIES; i++)
 113                             if(set->elements[i]->selected)
 114                                 printf("%s\n", set->elements[i]->text);
 115                         break;
 116                     default: break;
 117                 }
 118                 break;
 119             case SDL_MOUSEBUTTONDOWN:
 120                 index = Set_elem_at(set, event.button.x, event.button.y);
 121                 if(index != TOTAL_ENTRIES) {
 122                     printf("%s\n", set->elements[index]->text);
 123                     Set_select_index(set, index);
 124                 }
 125                 break;
 126             case SDL_WINDOWEVENT:
 127                 switch(event.window.event) {
 128                 case SDL_WINDOWEVENT_RESIZED:
 129                     /* printf("INFO: window resized to: %dx%d\n", win_w, win_h); */
 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         Set_hover_at(set, x, y);
 143 
 144         SDL_SetRenderDrawColor(rend, UNHEX(BG_COLOR));
 145         SDL_RenderClear(rend);
 146 
 147         Set_compute_pos(set, win_w, win_h);
 148         for(i = 0; i < TOTAL_ENTRIES; i++)
 149             Elem_draw(rend, font, win_w, win_h, set->elements[i]);
 150 
 151         SDL_RenderPresent(rend);
 152         SDL_Delay(1);
 153     }
 154 
 155     TTF_CloseFont(font);
 156 
 157     SDL_DestroyRenderer(rend);
 158     SDL_DestroyWindow(win);
 159 
 160     TTF_Quit();
 161     SDL_Quit();
 162     return 0;
 163 }