commit d8ca35ed8b3db9d9ea68a84901f03ccf84443b03
parent 8cd537cf8b09e05ab7eb7eac9765ce49828909ec
Author: hhvn <dev@hhvn.uk>
Date: Sun, 21 Aug 2022 11:19:33 +0100
Geom type for multiple geometries
Diffstat:
4 files changed, 74 insertions(+), 31 deletions(-)
diff --git a/src/main.h b/src/main.h
@@ -39,11 +39,11 @@ void ui_update_screen(void);
void ui_deinit(void);
void ui_print(int x, int y, Color col, char *format, ...);
int ui_textsize(char *text);
-int ui_collides(Rect rect, Vector2 point);
+int ui_collides(Geom geom, Vector2 point);
int ui_onscreen(Vector2 point);
int ui_onscreen_ring(Vector2 centre, float r);
int ui_onscreen_circle(Vector2 centre, float r);
-void ui_clickable_register(int x, int y, int w, int h, enum UiElements type, void *elem);
+void ui_clickable_register(Geom geom, enum UiElements type, void *elem);
void ui_clickable_handle(Vector2 mouse, MouseButton button, Clickable *clickable);
int ui_clickable_update(void);
void ui_clickable_clear(void);
diff --git a/src/struct.h b/src/struct.h
@@ -75,6 +75,8 @@ typedef struct {
char *systems;
char *fleets;
} db;
+ System *systems;
+ size_t systems_len;
System *homesys;
} Save;
@@ -86,6 +88,24 @@ typedef struct {
} Rect;
typedef struct {
+ Vector2 centre;
+ int r;
+} Circle;
+
+enum Geometries {
+ UI_RECT,
+ UI_CIRCLE,
+};
+
+typedef struct {
+ enum Geometries type;
+ union {
+ Rect rect;
+ Circle circle;
+ };
+} Geom;
+
+typedef struct {
float w, h;
float diag;
Vector2 centre;
@@ -126,7 +146,7 @@ enum UiElements {
#define CLICKABLE_MAX 64
typedef struct {
- Rect geom;
+ Geom geom;
enum UiElements type;
void *elem;
} Clickable;
diff --git a/src/ui.c b/src/ui.c
@@ -9,8 +9,13 @@
#define VIEWS_HEIGHT 25
#define WINDOW_TAB_HEIGHT 20
#define TARGET_FPS 60
-#define EXPLODE_RECT(rect) rect.x, rect.y, rect.w, rect.h
-#define RLIFY_RECT(rect) ((Rectangle){ EXPLODE_RECT(rect) })
+#define EXPLODE_RECT(r) r.x, r.y, r.w, r.h
+#define EXPLODE_CIRCLE(c) c.centre, c.r
+#define RLIFY_RECT(r) ((Rectangle){ EXPLODE_RECT(r) })
+#define GEOMIFY_RECT(r) ((Geom){UI_RECT, .rect = r})
+#define GEOMIFY_CIRCLE(c) ((Geom){UI_CIRCLE, .circle = c})
+#define GEOM_RECT(x, y, w, h) ((Geom){UI_RECT, .rect = {x, y, w, h}})
+#define GEOM_CIRCLE(centre, r) ((Geom){UI_CIRCLE, .circle = {centre, r})
static Clickable clickable[CLICKABLE_MAX];
@@ -83,10 +88,13 @@ View_main view_main = {
},
.comettail = {1, 1, "Comet tails"}, /* TODO */
.geom = {
- .x = 10,
- .y = VIEWS_HEIGHT + 10,
- .w = 200,
- .h = 400,
+ .type = UI_RECT,
+ .rect = {
+ .x = 10,
+ .y = VIEWS_HEIGHT + 10,
+ .w = 200,
+ .h = 400,
+ },
},
},
.pan = 0,
@@ -176,17 +184,19 @@ ui_textsize(char *text) {
}
int
-ui_collides(Rect rect, Vector2 point) {
- if (point.x >= rect.x && point.x <= rect.x + rect.w &&
- point.y >= rect.y && point.y <= rect.y + rect.h)
- return 1;
- else
- return 0;
+ui_collides(Geom geom, Vector2 point) {
+ switch (geom.type) {
+ case UI_CIRCLE:
+ return CheckCollisionPointCircle(point,
+ EXPLODE_CIRCLE(geom.circle));
+ case UI_RECT: default: /* -Wreturn-type bitches without default */
+ return CheckCollisionPointRec(point, RLIFY_RECT(geom.rect));
+ }
}
int
ui_onscreen(Vector2 point) {
- return ui_collides(screen.rect, point);
+ return ui_collides(GEOMIFY_RECT(screen.rect), point);
}
int
@@ -222,15 +232,16 @@ ui_onscreen_circle(Vector2 centre, float r) {
}
void
-ui_clickable_register(int x, int y, int w, int h, enum UiElements type, void *elem) {
+ui_clickable_register(Geom geom, enum UiElements type, void *elem) {
int i;
for (i = 0; i < CLICKABLE_MAX; i++) {
if (!clickable[i].elem) {
- clickable[i].geom.x = x;
- clickable[i].geom.y = y;
- clickable[i].geom.w = w;
- clickable[i].geom.h = h;
+ clickable[i].geom.type = geom.type;
+ switch (geom.type) {
+ case UI_RECT: clickable[i].geom.rect = geom.rect; break;
+ case UI_CIRCLE: clickable[i].geom.circle = geom.circle; break;
+ }
clickable[i].type = type;
clickable[i].elem = elem;
return;
@@ -244,24 +255,29 @@ void
ui_clickable_handle(Vector2 mouse, MouseButton button, Clickable *clickable) {
Tabs *tabs;
Checkbox *checkbox;
+ Rect *rect;
+ /* Circle *circle; */
int ftabw, fw, fn, tabw, x;
int i;
+ rect = &clickable->geom.rect;
+ /* circle = &clickable->geom.circle; */
+
switch (clickable->type) {
case UI_TAB:
if (button != MOUSE_BUTTON_LEFT)
return;
tabs = clickable->elem;
- for (fw = clickable->geom.w, fn = i = 0; i < tabs->n; i++) {
+ for (fw = rect->w, fn = i = 0; i < tabs->n; i++) {
if (!tabs->tabs[i].w)
fn++;
else
fw -= tabs->tabs[i].w;
}
ftabw = fw / fn;
- for (i = 0, x = clickable->geom.x; i < tabs->n; x += tabw, i++) {
+ for (i = 0, x = rect->x; i < tabs->n; x += tabw, i++) {
if (i == tabs->n - 1)
- tabw = clickable->geom.x + clickable->geom.w - x;
+ tabw = rect->x + rect->w - x;
else if (!tabs->tabs[i].w)
tabw = ftabw;
else
@@ -302,6 +318,12 @@ ui_clickable_update(void) {
}
}
+ /* Handle bodies seperately for efficiency:
+ * - body->pxloc can be used instead of a geometry passed to
+ * ui_clickable_register()
+ * - bodies offscreen can't be clicked, so they can be skipped.
+ */
+
return ret;
}
@@ -422,7 +444,7 @@ ui_draw_tabs(int x, int y, int w, int h, Tabs *tabs) {
if (tabs->sel == 0) DrawRectangle(x, y + 1, 1, h - 1, COL_BG); /* undraw left border */
if (tabs->sel == tabs->n - 1) DrawRectangle(x + w - 1, y + 1, 1, h - 1, COL_BG); /* undraw right border */
- ui_clickable_register(x, y, w, h, UI_TAB, tabs);
+ ui_clickable_register(GEOM_RECT(x, y, w, h), UI_TAB, tabs);
}
void
@@ -435,7 +457,9 @@ ui_draw_checkbox(int x, int y, Checkbox *box) {
box->enabled ? (box->val ? COL_FG : COL_BG) : COL_BORDER);
ui_print(x + w + (w / 2), y + (h / 6), COL_FG, "%s", box->label);
if (box->enabled)
- ui_clickable_register(x, y, w + (w / 2) + ui_textsize(box->label), h, UI_CHECKBOX, box);
+ ui_clickable_register(GEOM_RECT(x, y,
+ w + (w / 2) + ui_textsize(box->label), h),
+ UI_CHECKBOX, box);
}
Vector2
@@ -718,11 +742,10 @@ ui_draw_view_main(void) {
COL_INFO, "%s", strkmdist(dist));
/* infobox */
- ui_draw_tabbed_window(view_main.infobox.geom.x, view_main.infobox.geom.y,
- view_main.infobox.geom.w, view_main.infobox.geom.h,
+ ui_draw_tabbed_window(EXPLODE_RECT(view_main.infobox.geom.rect),
&view_main.infobox.tabs);
- x = view_main.infobox.geom.x + FONT_SIZE;
- y = view_main.infobox.geom.y + WINDOW_TAB_HEIGHT;
+ x = view_main.infobox.geom.rect.x + FONT_SIZE;
+ y = view_main.infobox.geom.rect.y + WINDOW_TAB_HEIGHT;
ui_draw_checkbox(x, y += FONT_SIZE*1.5, &view_main.infobox.names.dwarf);
ui_draw_checkbox(x, y += FONT_SIZE*1.5, &view_main.infobox.names.dwarfn);
ui_draw_checkbox(x, y += FONT_SIZE*1.5, &view_main.infobox.names.asteroid);
diff --git a/src/views.h b/src/views.h
@@ -14,7 +14,7 @@ typedef struct {
Checkbox comet;
} orbit;
Checkbox comettail;
- Rect geom;
+ Geom geom;
} infobox;
int pan;
struct {