cepheid

An Aurora 4X clone
Log | Files | Refs | README

commit 8790dc184246ecace163e03412ddc0e9b1c56d7c
parent f3fad6abddd2748a24acb97c4d0467cf9561f576
Author: hhvn <dev@hhvn.uk>
Date:   Sun,  4 Sep 2022 15:28:22 +0100

Make bodies selectable

Diffstat:
Msrc/main.h | 1+
Msrc/ui.c | 6++++++
Msrc/ui/bodies.c | 188++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Msrc/ui/struct.h | 13+++++++++++--
4 files changed, 133 insertions(+), 75 deletions(-)

diff --git a/src/main.h b/src/main.h @@ -58,6 +58,7 @@ int ui_textsize(char *text); float ui_get_scroll(void); int ui_checkbox_size(Checkbox *checkbox); int ui_collides(Geom geom, Vector2 point); +int ui_collides_rect(Rect rect, Vector2 point); int ui_onscreen(Vector2 point); int ui_onscreen_ring(Vector2 centre, float r); int ui_onscreen_circle(Vector2 centre, float r); diff --git a/src/ui.c b/src/ui.c @@ -137,6 +137,12 @@ ui_collides(Geom geom, Vector2 point) { } int +ui_collides_rect(Rect rect, Vector2 point) { + Geom geom = {UI_RECT, .rect = rect}; + return ui_collides(geom, point); +} + +int ui_onscreen(Vector2 point) { if (!pane_visible(point.y, point.y)) return 0; diff --git a/src/ui/bodies.c b/src/ui/bodies.c @@ -6,8 +6,10 @@ #define BUTTONS 50 #define W MIN(screen.w / 20, 50) +static View_bodies *v = &view_bodies; View_bodies view_bodies = { .sys = NULL, + .selstar = NULL, .sel = NULL, .show = { .planet = {1, 1, "Show planets"}, @@ -15,120 +17,160 @@ View_bodies view_bodies = { .dwarf = {1, 1, "Show dwarf planets"}, .asteroid = {1, 1, "Show asteroids"}, .comet = {1, 1, "Show comets"}, - .nomineral = {1, 1, "Show bodies without minerals"}, + .nomineral = {1, 1, "Show bodies without mins"}, + }, + .pane = { + .stars = PANESCROLL, + .bodies = PANESCROLL, }, - .stars = PANESCROLL, - .bodies = PANESCROLL, }; -void -ui_handle_view_bodies(int nowsel) { - if (!view_bodies.sys) - view_bodies.sys = sys_default(); - if (nowsel) - ui_title("Bodies in %s", view_bodies.sys->name); -} - -static int -draw_star(int x, int y, Body *star) { - ui_print(x, y, col_fg, "%s", star->name); - return y + FONT_SIZE; -} - -static int -draw_body(int x, int y, Body *body) { - ui_print(x, y, col_fg, "%s", body->name); - ui_print(x + 3*W, y, col_fg, "%s", body->parent ? body->parent->name : "-"); - ui_print(x + 5*W, y, col_fg, "%s", bodytype_strify(body)); - return y + FONT_SIZE; -} - static int display_body(Body *body) { if (body->type == BODY_STAR || !body->parent) return 0; - if (body->type == BODY_MOON && !view_bodies.show.moon.val) + if (body->type == BODY_MOON && !v->show.moon.val) return 0; if ((body->type == BODY_PLANET || body->parent->type == BODY_PLANET) && - !view_bodies.show.planet.val) + !v->show.planet.val) return 0; if ((body->type == BODY_DWARF || body->parent->type == BODY_DWARF) && - !view_bodies.show.dwarf.val) + !v->show.dwarf.val) return 0; if ((body->type == BODY_ASTEROID || body->parent->type == BODY_ASTEROID) && - !view_bodies.show.asteroid.val) + !v->show.asteroid.val) return 0; if ((body->type == BODY_COMET || body->parent->type == BODY_COMET) && - !view_bodies.show.comet.val) + !v->show.comet.val) return 0; - /* TODO: exclude bodies with no minerals */ + /* TODO: exclude bodies with no mins */ return 1; } void +ui_handle_view_bodies(int nowsel) { + Vector2 m = GetMousePosition(); + int pos, i, j; + + if (!v->sys) + v->sys = sys_default(); + + if (!nowsel) { + if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && + ui_collides_rect(v->bodies, m)) { + pos = (m.y + v->pane.bodies.off - v->bodies.y - PAD) + / FONT_SIZE; + for (i = j = 0; i < v->sys->bodies_len && j < pos; i++) + if (display_body(v->sys->bodies[i])) + if (++j == pos) + v->sel = v->sys->bodies[i]; + } + } + + if (nowsel) + ui_title("Bodies in %s", v->sys->name); +} + +static int +draw_star(int x, int y, Body *star) { + ui_print(x, y, col_fg, "%s", star->name); + return y + FONT_SIZE; +} + +static int +draw_body(int x, int y, Body *body) { + Color col; + + if (body == v->sel) + col = col_info; + else + col = col_fg; + + ui_print(x, y, col, "%s", body->name); + ui_print(x + 3*W, y, col, "%s", body->parent ? body->parent->name : "-"); + ui_print(x + 5*W, y, col, "%s", bodytype_strify(body)); + return y + FONT_SIZE; +} + +void ui_draw_view_bodies(void) { - Rect stars = { PAD, VIEWS_HEIGHT + PAD * 2 + FONT_SIZE, + int x, y; + int i; + Body *body; + + v->stars = (Rect){ PAD, VIEWS_HEIGHT + PAD * 2 + FONT_SIZE, screen.w - PAD * 2, FONT_SIZE * 6 }; - Rect checkboxes = { stars.x, stars.y + stars.h + PAD, - stars.w, FONT_SIZE + PAD}; - Rect bodies = { checkboxes.x, checkboxes.y + checkboxes.h + PAD/2, - checkboxes.w, screen.h - bodies.y - INFOBOX_H - BUTTONS }; - Rect location = { bodies.x, bodies.y + bodies.h + PAD, + v->disp = (Rect){ v->stars.x, v->stars.y + v->stars.h + PAD, + v->stars.w, FONT_SIZE + PAD}; + v->bodies = (Rect){ v->disp.x, v->disp.y + v->disp.h + PAD/2, + v->disp.w, screen.h - v->bodies.y - INFOBOX_H - BUTTONS }; + v->loc = (Rect){ v->bodies.x, v->bodies.y + v->bodies.h + PAD, INFOBOX_W, INFOBOX_H }; - Rect minerals = { location.x + location.w + PAD, location.y, + v->mins = (Rect){ v->loc.x + v->loc.w + PAD, v->loc.y, INFOBOX_W, INFOBOX_H }; - Rect habitat = { minerals.x + minerals.w + PAD, minerals.y, + v->hab = (Rect){ v->mins.x + v->mins.w + PAD, v->mins.y, INFOBOX_W, INFOBOX_H }; - int x, y; - int i; - Body *body; - if (!view_bodies.sel) - bodies.h += INFOBOX_H; + if (!v->sel) + v->bodies.h += INFOBOX_H; ui_print(PAD, VIEWS_HEIGHT + PAD, col_fg, "[System selection dropdown]"); - ui_draw_border_around(EXPLODE_RECT(stars), 1); - view_bodies.stars.geom = &stars; - pane_begin(&view_bodies.stars); - x = stars.x + PAD/2; - y = stars.y + PAD/2; + ui_draw_border_around(EXPLODE_RECT(v->stars), 1); + v->pane.stars.geom = &v->stars; + pane_begin(&v->pane.stars); + x = v->stars.x + PAD/2; + y = v->stars.y + PAD/2; ui_print(x, y, col_fg, "Name"); y += FONT_SIZE * 1.5; - for (i = 0; i < view_bodies.sys->bodies_len; i++) - if (view_bodies.sys->bodies[i]->type == BODY_STAR) - y = draw_star(x, y, view_bodies.sys->bodies[i]); + for (i = 0; i < v->sys->bodies_len; i++) + if (v->sys->bodies[i]->type == BODY_STAR) + y = draw_star(x, y, v->sys->bodies[i]); pane_end(); - x = checkboxes.x + PAD/2; - y = checkboxes.y + PAD/2; - x += ui_draw_checkbox(x, y, &view_bodies.show.planet) + PAD * 2; - x += ui_draw_checkbox(x, y, &view_bodies.show.moon) + PAD * 2; - x += ui_draw_checkbox(x, y, &view_bodies.show.dwarf) + PAD * 2; - x += ui_draw_checkbox(x, y, &view_bodies.show.asteroid) + PAD * 2; - x += ui_draw_checkbox(x, y, &view_bodies.show.comet) + PAD * 2; - x += ui_draw_checkbox(x, y, &view_bodies.show.nomineral); - ui_draw_border_around(checkboxes.x, checkboxes.y, x, checkboxes.h, 1); - - ui_draw_border_around(EXPLODE_RECT(bodies), 1); - view_bodies.bodies.geom = &bodies; - pane_begin(&view_bodies.bodies); - x = bodies.x + PAD/2; - y = bodies.y + PAD/2; + x = v->disp.x + PAD/2; + y = v->disp.y + PAD/2; + x += ui_draw_checkbox(x, y, &v->show.planet) + PAD * 2; + x += ui_draw_checkbox(x, y, &v->show.moon) + PAD * 2; + x += ui_draw_checkbox(x, y, &v->show.dwarf) + PAD * 2; + x += ui_draw_checkbox(x, y, &v->show.asteroid) + PAD * 2; + x += ui_draw_checkbox(x, y, &v->show.comet) + PAD * 2; + x += ui_draw_checkbox(x, y, &v->show.nomineral); + ui_draw_border_around(v->disp.x, v->disp.y, x, v->disp.h, 1); + + ui_draw_border_around(EXPLODE_RECT(v->bodies), 1); + v->pane.bodies.geom = &v->bodies; + pane_begin(&v->pane.bodies); + x = v->bodies.x + PAD/2; + y = v->bodies.y + PAD/2; ui_print(x, y, col_fg, "Name"); ui_print(x + 3*W, y, col_fg, "Parent"); ui_print(x + 5*W, y, col_fg, "Type"); y += FONT_SIZE * 1.5; - for (i = 0; i < view_bodies.sys->bodies_len; i++) { - body = view_bodies.sys->bodies[i]; + for (i = 0; i < v->sys->bodies_len; i++) { + body = v->sys->bodies[i]; if (display_body(body)) y = draw_body(x, y, body); } pane_end(); - if (view_bodies.sel) { - ui_draw_border_around(EXPLODE_RECT(location), 1); - ui_draw_border_around(EXPLODE_RECT(minerals), 1); - ui_draw_border_around(EXPLODE_RECT(habitat), 1); + if (v->sel) { + ui_draw_border_around(EXPLODE_RECT(v->loc), 1); + x = v->loc.x + PAD/2; + y = v->loc.y + PAD/2; + ui_print(x, y, col_info, "Orbital period:"); + ui_print(x + INFOBOX_W / 2, y, col_fg, + "%.2f days", v->sel->orbdays); + if (v->sel->type != BODY_COMET) { + ui_print(x, y += FONT_SIZE, col_info, "Orbital distance:"); + ui_print(x + INFOBOX_W / 2, y, col_fg, + "%s (%s)", strkmdist(v->sel->dist), + strlightdist(v->sel->dist)); + } + + ui_draw_border_around(EXPLODE_RECT(v->mins), 1); + ui_draw_border_around(EXPLODE_RECT(v->hab), 1); } + + DrawFPS(50, 50); } diff --git a/src/ui/struct.h b/src/ui/struct.h @@ -33,6 +33,7 @@ typedef struct { typedef struct { System *sys; + Body *selstar; Body *sel; struct { Checkbox planet; @@ -42,8 +43,16 @@ typedef struct { Checkbox comet; Checkbox nomineral; } show; - Pane stars; - Pane bodies; + struct { + Pane stars; + Pane bodies; + } pane; + Rect stars; + Rect disp; + Rect bodies; + Rect loc; + Rect mins; + Rect hab; } View_bodies; typedef struct {