Commit: cc0f350ea880bb7415d64be70c6f4064b14c5a8f
Parent: 8d186cf3f2ced36a6cfde113a92f6b5b1d493896
Author: Randy Palamar
Date: Mon, 6 Jan 2025 23:01:02 -0700
split ruler drawing into a seperate function
there will be further simplifcation by moving the scale bar code into a helper
Diffstat:
4 files changed, 111 insertions(+), 65 deletions(-)
diff --git a/beamformer.h b/beamformer.h
@@ -22,6 +22,9 @@
#define TEXT_HOVER_SPEED 5.0f
+#define RULER_TEXT_PAD 10.0f
+#define RULER_TICK_LENGTH 20.0f
+
#define RECT_BTN_COLOUR (Color){.r = 0x43, .g = 0x36, .b = 0x3a, .a = 0xff}
#define RECT_BTN_BORDER_COLOUR (Color){.r = 0x00, .g = 0x00, .b = 0x00, .a = 0xCC}
#define RECT_BTN_ROUNDNESS 0.3f
@@ -80,6 +83,8 @@ typedef struct {
Font font;
Font small_font;
+ f32 font_height;
+ f32 small_font_height;
InteractionState interaction;
InputState text_input_state;
diff --git a/intrinsics.c b/intrinsics.c
@@ -1,9 +1,10 @@
#define FORCE_INLINE inline __attribute__((always_inline))
/* TODO(rnp): msvc probably won't build this but there are other things preventing that as well */
-#define clz_u32(a) __builtin_clz(a)
-#define ctz_u32(a) __builtin_ctz(a)
-#define sqrt_f32(a) __builtin_sqrtf(a)
+#define clz_u32(a) __builtin_clz(a)
+#define ctz_u32(a) __builtin_ctz(a)
+#define sqrt_f32(a) __builtin_sqrtf(a)
+#define atan2_f32(y, x) __builtin_atan2f(y, x)
#ifdef __ARM_ARCH_ISA_A64
/* TODO? debuggers just loop here forever and need a manual PC increment (step over) */
diff --git a/ui.c b/ui.c
@@ -111,6 +111,48 @@ hover_text(v2 mouse, Rect text_rect, f32 *hover_t, b32 can_advance)
return hovering;
}
+/* TODO(rnp): once this has more callers decide if it would be better for this to take
+ * an orientation rather than force CCW/right-handed */
+static void
+draw_ruler(BeamformerUI *ui, Stream *buf, v2 start_point, v2 end_point,
+ f32 start_coord, f32 end_coord, u32 segments, s8 suffix,
+ Color ruler_colour, Color txt_colour)
+{
+ b32 draw_plus = SIGN(start_coord) != SIGN(end_coord);
+
+ end_point = sub_v2(end_point, start_point);
+ f32 rotation = atan2_f32(end_point.y, end_point.x) * 180 / PI;
+
+ rlPushMatrix();
+ rlTranslatef(start_point.x, start_point.y, 0);
+ rlRotatef(rotation, 0, 0, 1);
+
+ f32 inc = magnitude_v2(end_point) / segments;
+ f32 coord_inc = (end_coord - start_coord) / segments;
+ f32 coord = start_coord;
+
+ v2 sp = {0}, ep = {.y = RULER_TICK_LENGTH};
+ v2 tp = {.x = ui->small_font_height / 2, .y = ep.y + RULER_TEXT_PAD};
+ for (u32 j = 0; j <= segments; j++) {
+ DrawLineEx(sp.rl, ep.rl, 3, ruler_colour);
+
+ buf->widx = 0;
+ if (draw_plus && coord > 0) stream_append_byte(buf, '+');
+ stream_append_f64(buf, coord, 10);
+ stream_append_s8(buf, suffix);
+ draw_text(ui->small_font, stream_to_s8(buf), tp, 90, txt_colour);
+
+ coord += coord_inc;
+ sp.x += inc;
+ ep.x += inc;
+ tp.x += inc;
+ }
+ rlPopMatrix();
+}
+
+/* TODO(rnp): this is known after the first frame, we could unbind
+ * the texture for the first draw pass or just accept a slight glitch
+ * at start up (make a good default guess) */
/* NOTE: This is kinda sucks no matter how you spin it. If we want the values to be
* left aligned in the center column we need to know the longest prefix length but
* without either hardcoding one of the prefixes as the longest one or measuring all
@@ -790,6 +832,9 @@ ui_init(BeamformerCtx *ctx, Arena store)
/* TODO: build these into the binary */
ui->font = LoadFontEx("assets/IBMPlexSans-Bold.ttf", 28, 0, 0);
ui->small_font = LoadFontEx("assets/IBMPlexSans-Bold.ttf", 22, 0, 0);
+
+ ui->font_height = measure_text(ui->font, s8("8\\W")).h;
+ ui->small_font_height = measure_text(ui->small_font, s8("8\\W")).h;
}
static void
@@ -825,23 +870,17 @@ draw_ui(BeamformerCtx *ctx, BeamformerInput *input)
Rect vr = INVERTED_INFINITY_RECT;
if (output_dim.x > 1e-6 && output_dim.y > 1e-6) {
- Stream buf = stream_alloc(&ui->arena_for_frame, 64);
- stream_append_f64(&buf, -188.8f, 10);
- stream_append_s8(&buf, s8(" mm"));
- v2 txt_s = measure_text(ui->small_font, stream_to_s8(&buf));
- buf.widx = 0;
+ v2 txt_s = measure_text(ui->small_font, s8("-288.8 mm"));
rr.pos.x += 0.02 * rr.size.w;
rr.pos.y += 0.02 * rr.size.h;
rr.size.w *= 0.96;
rr.size.h *= 0.96;
- f32 tick_len = 20;
- f32 pad = 1.2 * txt_s.x + tick_len;
-
+ f32 pad = 1.2 * txt_s.x + RULER_TICK_LENGTH;
vr = rr;
- vr.pos.x += 0.5 * txt_s.y;
- vr.pos.y += 0.5 * txt_s.y;
+ vr.pos.x += 0.5 * ui->small_font_height;
+ vr.pos.y += 0.5 * ui->small_font_height;
vr.size.h = rr.size.h - pad;
vr.size.w = rr.size.w - pad;
@@ -859,59 +898,59 @@ draw_ui(BeamformerCtx *ctx, BeamformerInput *input)
DrawTextureNPatch(*output, tex_np, vr.rl, (Vector2){0}, 0, WHITE);
static f32 txt_colour_t[2];
- for (u32 i = 0; i < 2; i++) {
- u32 line_count = vr.size.E[i] / (1.5 * txt_s.h);
- f32 inc = vr.size.E[i] / line_count;
- v2 start_pos = vr.pos;
- start_pos.E[!i] += vr.size.E[!i];
-
- v2 end_pos = start_pos;
- end_pos.E[!i] += tick_len;
-
- /* NOTE: Center the Text with the Tick center */
- f32 txt_pos_scale[2] = {1, -1};
- v2 txt_pos = end_pos;
- txt_pos.E[i] += txt_pos_scale[i] * txt_s.y/2;
- txt_pos.E[!i] += 10;
-
- Rect tick_rect = {.pos = start_pos, .size = vr.size};
- tick_rect.size.E[!i] = 10 + tick_len + txt_s.x;
-
- /* TODO: don't do this nonsense; this code will need to get
- * split into a seperate function */
- /* TODO: pass this through the interaction system */
- u32 coord_idx = i == 0? 0 : 2;
- if (hover_text(mouse, tick_rect, txt_colour_t + i, 1)) {
- f32 scale[2] = {0.5e-3, 1e-3};
- f32 size_delta = GetMouseWheelMove() * scale[i];
- if (coord_idx == 0)
- bp->output_min_coordinate.E[coord_idx] -= size_delta;
- bp->output_max_coordinate.E[coord_idx] += size_delta;
- if (size_delta)
- ui_start_compute(ctx);
- }
-
- f32 mm = bp->output_min_coordinate.E[coord_idx] * 1e3;
- f32 mm_inc = inc * output_dim.E[i] * 1e3 / vr.size.E[i];
-
- Color txt_colour = colour_from_normalized(lerp_v4(FG_COLOUR, HOVERED_COLOUR,
- txt_colour_t[i]));
-
- f32 rot[2] = {90, 0};
- for (u32 j = 0; j <= line_count; j++) {
- DrawLineEx(start_pos.rl, end_pos.rl, 3, colour_from_normalized(FG_COLOUR));
- buf.widx = 0;
- if (i == 0 && mm > 0) stream_append_byte(&buf, '+');
- stream_append_f64(&buf, mm, 10);
- stream_append_s8(&buf, s8(" mm"));
- draw_text(ui->small_font, stream_to_s8(&buf), txt_pos,
- rot[i], txt_colour);
- start_pos.E[i] += inc;
- end_pos.E[i] += inc;
- txt_pos.E[i] += inc;
- mm += mm_inc;
- }
+
+ u32 line_count = vr.size.x / (1.5 * ui->small_font_height);
+ v2 start_pos = vr.pos;
+ start_pos.y += vr.size.y;
+
+ v2 end_pos = start_pos;
+ end_pos.x += vr.size.x;
+
+ Rect tick_rect = {.pos = start_pos, .size = vr.size};
+ tick_rect.size.y = RULER_TEXT_PAD + RULER_TICK_LENGTH + txt_s.x;
+
+ /* TODO: pass this through the interaction system */
+ if (hover_text(mouse, tick_rect, txt_colour_t + 0, 1)) {
+ f32 size_delta = GetMouseWheelMove() * 0.5e-3;
+ bp->output_min_coordinate.x -= size_delta;
+ bp->output_max_coordinate.x += size_delta;
+ if (size_delta)
+ ui_start_compute(ctx);
+ }
+
+ Stream buf = stream_alloc(&ui->arena_for_frame, 64);
+
+ f32 mm = bp->output_min_coordinate.x * 1e3;
+ f32 mm_end = bp->output_max_coordinate.x * 1e3;
+
+ draw_ruler(ui, &buf, start_pos, end_pos, mm, mm_end, line_count, s8(" mm"),
+ colour_from_normalized(FG_COLOUR),
+ colour_from_normalized(lerp_v4(FG_COLOUR, HOVERED_COLOUR, txt_colour_t[0])));
+
+ line_count = vr.size.y / (1.5 * ui->small_font_height);
+ start_pos = vr.pos;
+ start_pos.x += vr.size.x;
+
+ end_pos = start_pos;
+ end_pos.y += vr.size.y;
+
+ tick_rect = (Rect){.pos = start_pos, .size = vr.size};
+ tick_rect.size.x = RULER_TEXT_PAD + RULER_TICK_LENGTH + txt_s.x;
+
+ /* TODO: pass this through the interaction system */
+ if (hover_text(mouse, tick_rect, txt_colour_t + 1, 1)) {
+ f32 size_delta = GetMouseWheelMove() * 1e-3;
+ bp->output_max_coordinate.z += size_delta;
+ if (size_delta)
+ ui_start_compute(ctx);
}
+
+ mm = bp->output_min_coordinate.z * 1e3;
+ mm_end = bp->output_max_coordinate.z * 1e3;
+
+ draw_ruler(ui, &buf, end_pos, start_pos, mm_end, mm, line_count, s8(" mm"),
+ colour_from_normalized(FG_COLOUR),
+ colour_from_normalized(lerp_v4(FG_COLOUR, HOVERED_COLOUR, txt_colour_t[1])));
}
draw_settings_ui(ctx, lr, mouse);
diff --git a/util.h b/util.h
@@ -47,6 +47,7 @@
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define ORONE(x) ((x)? (x) : 1)
+#define SIGN(x) ((x) < 0? -1 : 1)
#define MEGABYTE (1024ULL * 1024ULL)
#define GIGABYTE (1024ULL * 1024ULL * 1024ULL)