commit 93f11266062aa3c05a0154a95f5c8e2f689e4f6a
parent 06e5cceda9ca59e1a6c8d24d71e2ccedb7a6fa5a
Author: mjkloeckner <martin.cachari@gmail.com>
Date: Mon, 17 Oct 2022 19:43:41 -0300
Introduced two new types: Set and Elem
This commit introduces this two data types as well as all their methods
The Set is all the Elem (previously entries) together
The Elem data type is a rename of the now deprecated Entry data type
Diffstat:
| M | main.c | | | 49 | ++++++++++++++++++++++++------------------------- |
| M | menu.c | | | 127 | +++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------- |
| M | menu.h | | | 42 | +++++++++++++++++++++++++++--------------- |
3 files changed, 134 insertions(+), 84 deletions(-)
diff --git a/main.c b/main.c
@@ -13,7 +13,7 @@
#define BG_COLOR 0x323232FF
-static char *entries_text[TOTAL_ENTRIES] = {
+static char *elements_text[TOTAL_ENTRIES] = {
"Bubble sort",
"Bubble sort (improved)",
"Insertion sort",
@@ -40,11 +40,17 @@ TTF_Font *font;
int x, y;
Uint32 buttons;
-int main (void) {
+/* TODO: remove global variables */
+/* TODO: custom box size, margin, padding, pos, etc */
+/* TODO: linked list (?) */
+
+int main (void)
+{
SDL_Window *win;
SDL_Renderer *rend;
int min_w, min_h;
size_t i;
+ Set *set;
SDL_Init(SDL_INIT_VIDEO);
@@ -73,18 +79,11 @@ int main (void) {
win_w = WIN_DEFAULT_W;
win_h = WIN_DEFAULT_H;
- Entry entries[TOTAL_ENTRIES];
+ Set_new(&set, TOTAL_ENTRIES);
- for(i = 0; i < TOTAL_ENTRIES; i++) {
- entries[i] = (Entry) {
- .text = entries_text[i],
- .selected = false,
- .hover = false,
- .index = i,
- };
- }
+ for(i = 0; i < set->size; i++)
+ Elem_set_text(set->elements[i], elements_text[i]);
- entries[0].selected = true;
SDL_Keymod mod;
size_t index = TOTAL_ENTRIES;
while(run) {
@@ -103,30 +102,31 @@ int main (void) {
break;
case SDL_SCANCODE_J:
case SDL_SCANCODE_DOWN:
- if(mod == KMOD_NONE) select_next(entries);
+ if(mod == KMOD_NONE) Set_select_next(set);
break;
case SDL_SCANCODE_K:
case SDL_SCANCODE_UP:
- if(mod == KMOD_NONE) select_prev(entries);
+ if(mod == KMOD_NONE) Set_select_prev(set);
break;
case SDL_SCANCODE_RETURN:
for(i = 0; i < TOTAL_ENTRIES; i++)
- if(entries[i].selected)
- printf("%s\n", entries[i].text);
+ if(set->elements[i]->selected)
+ printf("%s\n", set->elements[i]->text);
break;
default: break;
}
break;
case SDL_MOUSEBUTTONDOWN:
- index = entry_at(entries, event.button.x, event.button.y);
+ index = Set_elem_at(set, event.button.x, event.button.y);
if(index != TOTAL_ENTRIES) {
- printf("%s\n", entries[index].text);
- select_index(entries, index);
+ printf("%s\n", set->elements[index]->text);
+ Set_select_index(set, index);
}
break;
case SDL_WINDOWEVENT:
switch(event.window.event) {
case SDL_WINDOWEVENT_RESIZED:
+ /* printf("INFO: window resized to: %dx%d\n", win_w, win_h); */
win_w = event.window.data1;
win_h = event.window.data2;
break;
@@ -136,18 +136,17 @@ int main (void) {
}
}
- SDL_PumpEvents(); // make sure we have the latest mouse state.
+ SDL_PumpEvents(); /* make sure we have the latest mouse state. */
buttons = SDL_GetMouseState(&x, &y);
- hover_at(entries, x, y);
+ Set_hover_at(set, x, y);
SDL_SetRenderDrawColor(rend, UNHEX(BG_COLOR));
SDL_RenderClear(rend);
- compute_entries_pos(entries, win_w, win_h);
- for(i = 0; i < TOTAL_ENTRIES; i++) {
- draw_entry(rend, font, win_w, win_h, entries[i]);
- }
+ Set_compute_pos(set, win_w, win_h);
+ for(i = 0; i < TOTAL_ENTRIES; i++)
+ Elem_draw(rend, font, win_w, win_h, set->elements[i]);
SDL_RenderPresent(rend);
SDL_Delay(1);
diff --git a/menu.c b/menu.c
@@ -1,83 +1,83 @@
#include "menu.h"
/* Finds the selected entry then selects next */
-void select_next(Entry *entries) {
- for(int i = 0; i < TOTAL_ENTRIES; i++) {
- if(entries[i].selected == true) {
- entries[i].selected = false;
- if((i + 1) == TOTAL_ENTRIES) entries[0].selected = true;
- else entries[i + 1].selected = true;
+void Set_select_next(Set *set) {
+ for(int i = 0; i < set->size; i++) {
+ if(set->elements[i]->selected == true) {
+ set->elements[i]->selected = false;
+ if((i + 1) == set->size) set->elements[0]->selected = true;
+ else set->elements[i + 1]->selected = true;
i++;
continue;
}
- entries[i].selected = false;
+ set->elements[i]->selected = false;
}
}
/* Finds the selected entry then selects previous */
-void select_prev(Entry *entries) {
- for(int i = 0; i < TOTAL_ENTRIES; i++) {
- if(entries[i].selected == true) {
- entries[i].selected = false;
+void Set_select_prev(Set *set) {
+ for(int i = 0; i < set->size; i++) {
+ if(set->elements[i]->selected == true) {
+ set->elements[i]->selected = false;
if(i == 0) {
- entries[TOTAL_ENTRIES - 1].selected = true;
+ set->elements[set->size - 1]->selected = true;
break;
}
- else entries[i - 1].selected = true;
+ else set->elements[i - 1]->selected = true;
}
}
}
-void select_index(Entry *entries, size_t index) {
+void Set_select_index(Set *set, size_t index) {
size_t i;
- for(i = 0; i < TOTAL_ENTRIES; i++) {
- if(entries[i].index == index) entries[i].selected = true;
- else if(entries[i].selected == true) entries[i].selected = false;
+ for(i = 0; i < set->size; i++) {
+ if(set->elements[i]->index == index) set->elements[i]->selected = true;
+ else if(set->elements[i]->selected == true) set->elements[i]->selected = false;
}
}
-size_t entry_at(Entry *entries, int x, int y) {
+size_t Set_elem_at(Set *set, int x, int y) {
size_t i;
- for(i = 0; i < TOTAL_ENTRIES; i++)
- if((y < entries[i].pos.y) && (y > (entries[i].pos.y - BAR_H)))
+ for(i = 0; i < set->size; i++)
+ if((y < set->elements[i]->pos.y) && (y > (set->elements[i]->pos.y - BAR_H)))
return i;
- return TOTAL_ENTRIES;
+ return set->size;
}
-void compute_entries_pos(Entry *entries, int win_w, int win_h) {
+void Set_compute_pos(Set *set, int win_w, int win_h) {
int first_entry_pos_y, win_center_y;
size_t i;
win_center_y = (win_h / 2);
first_entry_pos_y = win_center_y -
- ((((BAR_H + ELEMENTS_PADDING) * TOTAL_ENTRIES) - ELEMENTS_PADDING) / 2) + BAR_H;
+ ((((BAR_H + ELEMENTS_PADDING) * set->size) - ELEMENTS_PADDING) / 2) + BAR_H;
- for(i = 0; i < TOTAL_ENTRIES; i++) {
- entries[i].pos.x = BAR_BORDER;
- entries[i].pos.y = (first_entry_pos_y + (entries[i].index * (ELEMENTS_PADDING + BAR_H)));
+ for(i = 0; i < set->size; i++) {
+ set->elements[i]->pos.x = BAR_BORDER;
+ set->elements[i]->pos.y = (first_entry_pos_y + (set->elements[i]->index * (ELEMENTS_PADDING + BAR_H)));
}
}
-void hover_entry(Entry *entries, size_t index) {
+void Set_hover_elem(Set *set, size_t index) {
size_t i;
- for(i = 0; i < TOTAL_ENTRIES; i++)
- entries[i].hover = ((i == index) ? true : false);
+ for(i = 0; i < set->size; i++)
+ set->elements[i]->hover = ((i == index) ? true : false);
}
-void hover_at(Entry *entries, int x, int y) {
+void Set_hover_at(Set *set, int x, int y) {
size_t i;
- for(i = 0; i < TOTAL_ENTRIES; i++) {
- if((y < entries[i].pos.y) && (y > (entries[i].pos.y - BAR_H)))
- entries[i].hover = true;
- else entries[i].hover = false;
+ for(i = 0; i < set->size; i++) {
+ if((y < set->elements[i]->pos.y) && (y > (set->elements[i]->pos.y - BAR_H)))
+ set->elements[i]->hover = true;
+ else set->elements[i]->hover = false;
}
}
-void draw_entry(SDL_Renderer *rend, TTF_Font *font, int win_w, int win_h, const Entry entry) {
+void Elem_draw(SDL_Renderer *rend, TTF_Font *font, int win_w, int win_h, const Elem *elem) {
SDL_Surface *text_surface;
SDL_Texture *text_texture;
SDL_Rect text_rect, box;
@@ -87,20 +87,20 @@ void draw_entry(SDL_Renderer *rend, TTF_Font *font, int win_w, int win_h, const
text_color = mk_SDL_Color(UNHEX(FONT_COLOR));
text_color_shadow = mk_SDL_Color(UNHEX(SHADOW_COLOR));
- box = (SDL_Rect){ BAR_BORDER, entry.pos.y, win_w - (BAR_BORDER * 2), -BAR_H };
+ box = (SDL_Rect) { BAR_BORDER, elem->pos.y, win_w - (BAR_BORDER * 2), -BAR_H };
- SDL_SetRenderDrawColor(rend, UNHEX(entry.selected ? SEL_COLOR : (entry.hover ? HOVER_COLOR : NORM_COLOR)));
+ SDL_SetRenderDrawColor(rend, UNHEX(elem->selected ? SEL_COLOR : (elem->hover ? HOVER_COLOR : NORM_COLOR)));
SDL_RenderFillRect(rend, &box);
- TTF_SizeText(font, entry.text, &text_w, &text_h);
+ TTF_SizeText(font, elem->text, &text_w, &text_h);
/* Draw shadow */
- if(entry.selected) {
- text_surface = TTF_RenderText_Blended(font, entry.text, text_color_shadow);
+ if(elem->selected) {
+ text_surface = TTF_RenderText_Blended(font, elem->text, text_color_shadow);
text_texture = SDL_CreateTextureFromSurface(rend, text_surface);
text_rect.x = (win_w / 2) - (text_w / 2) + 2;
- text_rect.y = entry.pos.y - (BAR_H + 1) + 2;
+ text_rect.y = elem->pos.y - (BAR_H + 1) + 2;
text_rect.w = text_surface->w;
text_rect.h = text_surface->h;
@@ -109,11 +109,10 @@ void draw_entry(SDL_Renderer *rend, TTF_Font *font, int win_w, int win_h, const
SDL_FreeSurface(text_surface);
}
- text_surface = TTF_RenderText_Blended(font, entry.text, text_color);
+ text_surface = TTF_RenderText_Blended(font, elem->text, text_color);
text_texture = SDL_CreateTextureFromSurface(rend, text_surface);
-
text_rect.x = (win_w / 2) - (text_w / 2);
- text_rect.y = entry.pos.y - (BAR_H + 1);
+ text_rect.y = elem->pos.y - (BAR_H + 1);
text_rect.w = text_surface->w;
text_rect.h = text_surface->h;
@@ -121,3 +120,43 @@ void draw_entry(SDL_Renderer *rend, TTF_Font *font, int win_w, int win_h, const
SDL_DestroyTexture(text_texture);
SDL_FreeSurface(text_surface);
}
+
+void Set_new(Set **set, size_t size) {
+ if(size == 0) return;
+
+ (*set) = malloc(sizeof(Set));
+
+ if((*set) == NULL)
+ return;
+
+ if(((*set)->elements = malloc(sizeof(Elem) * size)) == NULL)
+ return;
+
+ for(size_t i = 0; i < size; i++)
+ if(((*set)->elements[i] = malloc(sizeof(Elem))) == NULL)
+ return;
+
+ /* Initialize elements */
+ (*set)->size = size;
+ for(size_t i = 0; i < size; i++) {
+ (*set)->elements[i]->text = NULL;
+ (*set)->elements[i]->selected = false;
+ (*set)->elements[i]->hover = false;
+ (*set)->elements[i]->index = i;
+ }
+
+ (*set)->elements[0]->selected = true;
+}
+
+void Set_destroy(Set *set) {
+ free(set->elements);
+ free(set);
+}
+
+void Elem_set_text(Elem *el, const char *src) {
+ size_t text_len = strlen(src);
+
+ el->text = calloc(text_len + 1, sizeof(char));
+
+ strcpy(el->text, src);
+}
diff --git a/menu.h b/menu.h
@@ -3,9 +3,7 @@
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
-
#include <stdbool.h>
-#include <stdlib.h>
#include "util.h"
@@ -31,23 +29,37 @@
((color) >> (8 * 1)) & 0xFF, \
((color) >> (8 * 0)) & 0xFF
-typedef struct Entry {
+typedef struct {
char *text;
bool selected, hover;
size_t index;
Coord pos;
-} Entry;
-
-void select_prev(Entry *);
-void select_next(Entry *);
-void select_index(Entry *, size_t i);
-void draw_entry(SDL_Renderer *, TTF_Font *, int, int, const Entry);
-
-void Entry_new(Entry *);
-size_t entry_at(Entry *, int, int);
-void hover_at(Entry *, int, int);
-void hover_entry(Entry *, size_t);
-void compute_entries_pos(Entry *, int, int);
+} Elem;
+
+typedef struct {
+ Elem **elements;
+ size_t size;
+} Set;
+
+void Set_new(Set **, size_t size);
+void Set_draw(Set *);
+void Set_destroy(Set *);
+
+void Set_select_prev(Set *);
+void Set_select_next(Set *);
+void Set_select_index(Set *, size_t i);
+void Set_hover_at(Set *, int, int);
+void Set_hover_elem(Set *, size_t);
+size_t Set_elem_at(Set *, int, int);
+void Set_compute_pos(Set *, int, int);
+
+
+/* void Elem_new(Elem **); */
+/* void Elem_destroy(Elem *); */
+
+void Elem_draw(SDL_Renderer *, TTF_Font *, int, int, const Elem *);
+void Elem_set_text(Elem *, const char *);
+
#endif