menu

a graphical menu within a window
Index Commits Files Refs
menu.c (3460B)
   1 #include "menu.h"
   2 
   3 /* Finds the selected entry then selects next */
   4 void select_next(Entry *entries) {
   5     for(int i = 0; i < TOTAL_ENTRIES; i++) {
   6         if(entries[i].selected == true) {
   7             entries[i].selected = false;
   8             if((i + 1) == TOTAL_ENTRIES) entries[0].selected = true;
   9             else entries[i + 1].selected = true;
  10             i++;
  11             continue;
  12         }
  13         entries[i].selected = false;
  14     }
  15 }
  16 
  17 /* Finds the selected entry then selects previous */
  18 void select_prev(Entry *entries) {
  19     for(int i = 0; i < TOTAL_ENTRIES; i++) {
  20         if(entries[i].selected == true) {
  21             entries[i].selected = false;
  22             if(i == 0) {
  23                 entries[TOTAL_ENTRIES - 1].selected = true;
  24                 break;
  25             }
  26             else entries[i - 1].selected = true;
  27         }
  28     }
  29 }
  30 
  31 void select_index(Entry *entries, size_t index) {
  32     size_t i;
  33     for(i = 0; i < TOTAL_ENTRIES; i++) {
  34         if(entries[i].index == index) entries[i].selected = true;
  35         else if(entries[i].selected == true) entries[i].selected = false;
  36     }
  37 }
  38 
  39 size_t entry_at(Entry *entries, int x, int y) {
  40     size_t i;
  41 
  42     for(i = 0; i < TOTAL_ENTRIES; i++)
  43         if((y < entries[i].pos.y) && (y > (entries[i].pos.y - BAR_H)))
  44             return i;
  45 
  46     return TOTAL_ENTRIES;
  47 }
  48 
  49 void compute_entries_pos(Entry *entries, int win_w, int win_h) {
  50     int first_entry_pos_y, win_center_y;
  51     size_t i;
  52 
  53     win_center_y = (win_h / 2);
  54     first_entry_pos_y = win_center_y -
  55         ((((BAR_H + ELEMENTS_PADDING) * TOTAL_ENTRIES) - ELEMENTS_PADDING) / 2) + BAR_H;
  56 
  57     for(i = 0; i < TOTAL_ENTRIES; i++) {
  58         entries[i].pos.x = BAR_BORDER;
  59         entries[i].pos.y = (first_entry_pos_y + (entries[i].index * (ELEMENTS_PADDING + BAR_H)));
  60     }
  61 }
  62 
  63 void hover_entry(Entry *entries, size_t index) {
  64     size_t i;
  65 
  66     for(i = 0; i < TOTAL_ENTRIES; i++)
  67         entries[i].hover = ((i == index) ? true : false);
  68 }
  69 
  70 void hover_at(Entry *entries, int x, int y) {
  71     size_t i;
  72 
  73     for(i = 0; i < TOTAL_ENTRIES; i++) {
  74         if((y < entries[i].pos.y) && (y > (entries[i].pos.y - BAR_H)))
  75             entries[i].hover = true;
  76         else entries[i].hover = false;
  77     }
  78 }
  79 
  80 void draw_entry(SDL_Renderer *rend, TTF_Font *font, int win_w, int win_h, const Entry entry) {
  81     SDL_Surface *text_surface;
  82     SDL_Texture *text_texture;
  83     SDL_Rect text_rect, box;
  84     SDL_Color text_color, text_color_shadow;
  85     int text_w, text_h;
  86 
  87     text_color = mk_SDL_Color(UNHEX(FONT_COLOR));
  88     text_color_shadow = mk_SDL_Color(UNHEX(SHADOW_COLOR));
  89 
  90     box = (SDL_Rect){ BAR_BORDER, entry.pos.y, win_w - (BAR_BORDER * 2), -BAR_H };
  91 
  92     SDL_SetRenderDrawColor(rend, UNHEX(entry.selected ? SEL_COLOR : (entry.hover ? HOVER_COLOR : NORM_COLOR)));
  93     SDL_RenderFillRect(rend, &box);
  94 
  95     TTF_SizeText(font, entry.text, &text_w, &text_h);
  96 
  97     /* Draw shadow */
  98     if(entry.selected) {
  99         text_surface = TTF_RenderText_Blended(font, entry.text, text_color_shadow);
 100         text_texture = SDL_CreateTextureFromSurface(rend, text_surface);
 101 
 102         text_rect.x = (win_w / 2) - (text_w / 2) + 2;
 103         text_rect.y = entry.pos.y - (BAR_H + 1) + 2;
 104         text_rect.w = text_surface->w;
 105         text_rect.h = text_surface->h;
 106 
 107         SDL_RenderCopy(rend, text_texture, NULL, &text_rect);
 108         SDL_DestroyTexture(text_texture);
 109         SDL_FreeSurface(text_surface);
 110     }
 111 
 112     text_surface = TTF_RenderText_Blended(font, entry.text, text_color);
 113     text_texture = SDL_CreateTextureFromSurface(rend, text_surface);
 114 
 115     text_rect.x = (win_w / 2) - (text_w / 2);
 116     text_rect.y = entry.pos.y - (BAR_H + 1);
 117     text_rect.w = text_surface->w;
 118     text_rect.h = text_surface->h;
 119 
 120     SDL_RenderCopy(rend, text_texture, NULL, &text_rect);
 121     SDL_DestroyTexture(text_texture);
 122     SDL_FreeSurface(text_surface);
 123 }