commit 8790dc184246ecace163e03412ddc0e9b1c56d7c
parent f3fad6abddd2748a24acb97c4d0467cf9561f576
Author: hhvn <dev@hhvn.uk>
Date: Sun, 4 Sep 2022 15:28:22 +0100
Make bodies selectable
Diffstat:
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 {