Commit: 052c2355a309ed9b16e1a5f98adfeb2ec757129b
Parent: 6793015fa0710745829d18fc0478b7e62b07efa7
Author: Randy Palamar
Date: Sun, 28 Jul 2024 22:19:13 -0600
fancy text input
Diffstat:
M | colourpicker.c | | | 334 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------- |
M | main.c | | | 4 | +++- |
M | util.c | | | 37 | +++++++++++++++++++++++++++++++++---- |
3 files changed, 300 insertions(+), 75 deletions(-)
diff --git a/colourpicker.c b/colourpicker.c
@@ -1,6 +1,7 @@
/* See LICENSE for copyright details */
#include <raylib.h>
#include <stdio.h>
+#include <string.h> /* memmove */
#include "util.c"
@@ -43,17 +44,6 @@ left_align_text_in_rect(Rect r, const char *text, Font font, f32 fontsize)
return (v2) { .x = r.pos.x, .y = r.pos.y + 0.5 * delta.h, };
}
-static v2
-right_align_text_in_rect(Rect r, const char *text, Font font, f32 fontsize)
-{
- v2 ts = { .rv = MeasureTextEx(font, text, fontsize, 0) };
- v2 delta = { .h = r.size.h - ts.h };
- return (v2) {
- .x = r.pos.x + r.size.w - ts.w,
- .y = r.pos.y + 0.5 * delta.h,
- };
-}
-
static Rect
scale_rect_centered(Rect r, v2 scale)
{
@@ -239,15 +229,174 @@ static void
get_slider_subrects(Rect r, Rect *label, Rect *slider, Rect *value)
{
if (label) *label = cut_rect_left(r, 0.08);
- if (value) *value = cut_rect_right(r, 0.87);
+ if (value) *value = cut_rect_right(r, 0.83);
if (slider) {
- *slider = cut_rect_middle(r, 0.1, 0.85);
+ *slider = cut_rect_middle(r, 0.1, 0.79);
slider->size.h *= 0.7;
slider->pos.y += r.size.h * 0.15;
}
}
static void
+parse_and_store_text_input(ColourPickerCtx *ctx)
+{
+
+ v4 new_colour = {0};
+ enum colour_mode new_mode = CM_LAST;
+ if (ctx->is.idx == INPUT_HEX) {
+ u32 ri, gi, bi, ai;
+ sscanf(ctx->is.buf, "%02x%02x%02x%02x", &ri, &gi, &bi, &ai);
+ new_colour = (v4){.rv = ColorNormalize((Color){.r = ri, .g = gi,
+ .b = bi, .a = ai})};
+ new_mode = CM_RGB;
+ } else {
+ new_mode = ctx->colour_mode;
+ new_colour = ctx->colour;
+ f32 fv;
+ sscanf(ctx->is.buf, "%f", &fv);
+ CLAMP01(fv);
+ switch(ctx->is.idx) {
+ case INPUT_R: new_colour.r = fv; break;
+ case INPUT_G: new_colour.g = fv; break;
+ case INPUT_B: new_colour.b = fv; break;
+ case INPUT_A: new_colour.a = fv; break;
+ default: break;
+ }
+ }
+
+ if (new_mode != CM_LAST)
+ store_formatted_colour(ctx, new_colour, new_mode);
+}
+
+static void
+set_text_input_idx(ColourPickerCtx *ctx, enum input_indices idx, Rect r, v2 mouse)
+{
+ if (ctx->is.idx != idx)
+ parse_and_store_text_input(ctx);
+
+ if (idx == INPUT_HEX) {
+ Color hc = colour_from_normalized(get_formatted_colour(ctx, CM_RGB));
+ ctx->is.buf_len = snprintf(ctx->is.buf, ARRAY_COUNT(ctx->is.buf),
+ "%02x%02x%02x%02x", hc.r, hc.g, hc.b, hc.a);
+ } else {
+ f32 fv = 0;
+ switch (idx) {
+ case INPUT_R: fv = ctx->colour.r; break;
+ case INPUT_G: fv = ctx->colour.g; break;
+ case INPUT_B: fv = ctx->colour.b; break;
+ case INPUT_A: fv = ctx->colour.a; break;
+ default: break;
+ }
+ ctx->is.buf_len = snprintf(ctx->is.buf, ARRAY_COUNT(ctx->is.buf), "%0.02f", fv);
+ }
+
+ ctx->is.idx = idx;
+ ctx->is.cursor = -1;
+ CLAMP(ctx->is.idx, -1, INPUT_A);
+ if (ctx->is.idx == -1)
+ return;
+
+ ASSERT(CheckCollisionPointRec(mouse.rv, r.rr));
+ ctx->is.cursor_p = (mouse.x - r.pos.x) / r.size.w;
+ CLAMP01(ctx->is.cursor_p);
+}
+
+static void
+do_text_input(ColourPickerCtx *ctx, enum input_indices idx, Rect r, Color colour)
+{
+ static i32 max_chars[INPUT_A + 1] = {
+ [INPUT_HEX] = 8,
+ [INPUT_R] = 4,
+ [INPUT_B] = 4,
+ [INPUT_G] = 4,
+ [INPUT_A] = 4,
+ };
+
+ v2 ts = {.rv = MeasureTextEx(ctx->font, ctx->is.buf, ctx->font_size, 0)};
+ v2 pos = {.x = r.pos.x, .y = r.pos.y + (r.size.y - ts.y) / 2};
+
+ i32 buf_delta = ctx->is.buf_len - max_chars[idx];
+ if (buf_delta < 0) buf_delta = 0;
+ char *buf = ctx->is.buf + buf_delta;
+ DrawTextEx(ctx->font, buf, pos.rv, ctx->font_size, 0, colour);
+
+ if (idx != ctx->is.idx)
+ return;
+
+ ctx->is.cursor_t = move_towards_f32(ctx->is.cursor_t, ctx->is.cursor_t_target,
+ 1.5 * ctx->dt);
+ if (ctx->is.cursor_t == ctx->is.cursor_t_target) {
+ if (ctx->is.cursor_t_target == 0) ctx->is.cursor_t_target = 1;
+ else ctx->is.cursor_t_target = 0;
+ }
+
+ v4 bg = ctx->hover_colour;
+ bg.a = 0;
+ Color cursor_colour = colour_from_normalized(lerp_v4(bg, ctx->hover_colour,
+ ctx->is.cursor_t));
+
+ /* NOTE: guess a cursor position */
+ if (ctx->is.cursor == -1) {
+ f32 narrow_char_scale = 1.1;
+ if (ctx->is.idx != INPUT_HEX) narrow_char_scale = 1.45;
+ ctx->is.cursor = ctx->is.cursor_p * ctx->is.buf_len * narrow_char_scale;
+ CLAMP(ctx->is.cursor, 0, ctx->is.buf_len);
+ }
+
+ /* NOTE: Braindead NULL termination stupidity */
+ char saved_c = buf[ctx->is.cursor - buf_delta];
+ buf[ctx->is.cursor - buf_delta] = 0;
+
+ v2 sts = {.rv = MeasureTextEx(ctx->font, buf, ctx->font_size, 0)};
+ f32 cursor_x = r.pos.x + sts.x;
+ f32 cursor_width = ctx->is.cursor == ctx->is.buf_len ? 20 : 6;
+
+ buf[ctx->is.cursor - buf_delta] = saved_c;
+
+ Rect cursor_r = {
+ .pos = {.x = cursor_x, .y = pos.y},
+ .size = {.w = cursor_width, .h = ts.h},
+ };
+
+ DrawRectangleRec(cursor_r.rr, cursor_colour);
+
+ /* NOTE: handle multiple input keys on a single frame */
+ i32 key = GetCharPressed();
+ while (key > 0) {
+ if (ctx->is.buf_len == (ARRAY_COUNT(ctx->is.buf) - 1)) {
+ ctx->is.buf[ARRAY_COUNT(ctx->is.buf) - 1] = 0;
+ break;
+ }
+
+ /* TODO: remove memmove */
+ memmove(ctx->is.buf + ctx->is.cursor + 1,
+ ctx->is.buf + ctx->is.cursor,
+ ctx->is.buf_len - ctx->is.cursor + 1);
+
+ ctx->is.buf[ctx->is.cursor++] = key;
+ ctx->is.buf_len++;
+ key = GetCharPressed();
+ }
+
+ if ((IsKeyPressed(KEY_LEFT) || IsKeyPressedRepeat(KEY_LEFT)) && ctx->is.cursor > 0)
+ ctx->is.cursor--;
+
+ if ((IsKeyPressed(KEY_RIGHT) || IsKeyPressedRepeat(KEY_RIGHT)) &&
+ ctx->is.cursor < ctx->is.buf_len)
+ ctx->is.cursor++;
+
+ if ((IsKeyPressed(KEY_BACKSPACE) || IsKeyPressedRepeat(KEY_BACKSPACE)) &&
+ ctx->is.cursor > 0) {
+ /* TODO: remove memmove */
+ ctx->is.cursor--;
+ memmove(ctx->is.buf + ctx->is.cursor,
+ ctx->is.buf + ctx->is.cursor + 1,
+ ctx->is.buf_len - ctx->is.cursor - 1);
+ ctx->is.buf[--ctx->is.buf_len] = 0;
+ }
+}
+
+static void
do_slider(ColourPickerCtx *ctx, Rect r, i32 label_idx, v2 relative_origin)
{
Rect lr, sr, vr;
@@ -318,16 +467,13 @@ do_slider(ColourPickerCtx *ctx, Rect r, i32 label_idx, v2 relative_origin)
SLIDER_BORDER_COLOUR);
{
- /* TODO: move this to ctx */
- static f32 slider_scale[4] = { 1, 1, 1, 1 };
- f32 scale_target = 1.5;
- f32 scale_delta = (scale_target - 1.0) * 8 * ctx->dt;
-
+ f32 scale_delta = (SLIDER_SCALE_TARGET - 1.0) * SLIDER_SCALE_SPEED * ctx->dt;
b32 should_scale = (ctx->held_idx == -1 && hovering) ||
(ctx->held_idx != -1 && label_idx == ctx->held_idx);
- f32 scale = slider_scale[label_idx];
- scale = move_towards_f32(scale, should_scale? scale_target : 1.0, scale_delta);
- slider_scale[label_idx] = scale;
+ f32 scale = ctx->ss.scale_t[label_idx];
+ scale = move_towards_f32(scale, should_scale? SLIDER_SCALE_TARGET: 1.0,
+ scale_delta);
+ ctx->ss.scale_t[label_idx] = scale;
v2 tri_scale = {.x = scale, .y = scale};
v2 tri_mid = {.x = sr.pos.x + current * sr.size.w, .y = sr.pos.y};
@@ -336,18 +482,56 @@ do_slider(ColourPickerCtx *ctx, Rect r, i32 label_idx, v2 relative_origin)
draw_cardinal_triangle(tri_mid, SLIDER_TRI_SIZE, tri_scale, NORTH, ctx->fg);
}
- const char *value = TextFormat("%0.02f", current);
- fpos = right_align_text_in_rect(vr, value, ctx->font, ctx->font_size);
- DrawTextEx(ctx->font, value, fpos.rv, ctx->font_size, 0, ctx->fg);
+ {
+ SliderState *s = &ctx->ss;
+ b32 collides = CheckCollisionPointRec(test_pos.rv, vr.rr);
+ if (collides && ctx->is.idx != (label_idx + 1)) {
+ s->colour_t[label_idx] += TEXT_HOVER_SPEED * ctx->dt;
+ } else {
+ s->colour_t[label_idx] -= TEXT_HOVER_SPEED * ctx->dt;
+ }
+ CLAMP01(s->colour_t[label_idx]);
+
+ if (!collides && ctx->is.idx == (label_idx + 1) &&
+ IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
+ set_text_input_idx(ctx, -1, vr, test_pos);
+ current = ctx->colour.E[label_idx];
+ }
+
+ v4 colour = lerp_v4(normalize_colour(pack_rl_colour(ctx->fg)),
+ ctx->hover_colour, s->colour_t[label_idx]);
+ Color colour_rl = colour_from_normalized(colour);
+
+ if (collides && IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
+ set_text_input_idx(ctx, label_idx + 1, vr, test_pos);
+
+ if (ctx->is.idx != (label_idx + 1)) {
+ const char *value = TextFormat("%0.02f", current);
+ fpos = left_align_text_in_rect(vr, value, ctx->font, ctx->font_size);
+ DrawTextEx(ctx->font, value, fpos.rv, ctx->font_size, 0, colour_rl);
+ } else {
+ do_text_input(ctx, label_idx + 1, vr, colour_rl);
+ }
+ }
}
static void
do_status_bar(ColourPickerCtx *ctx, Rect r, v2 relative_origin)
{
Rect hex_r = cut_rect_left(r, 0.5);
- Rect mode_r = cut_rect_right(r, 0.85);
- mode_r.pos.y += mode_r.size.h * 0.15;
- mode_r.size.h *= 0.7;
+ Rect mode_r;
+ get_slider_subrects(r, 0, 0, &mode_r);
+
+
+ char *mode_txt;
+ switch (ctx->colour_mode) {
+ case CM_RGB: mode_txt = "RGB"; break;
+ case CM_HSV: mode_txt = "HSV"; break;
+ case CM_LAST: ASSERT(0); break;
+ }
+ v2 mode_ts = {.rv = MeasureTextEx(ctx->font, mode_txt, ctx->font_size, 0)};
+ mode_r.pos.y += (mode_r.size.h - mode_ts.h) / 2;
+ mode_r.size.w = mode_ts.w;
v2 test_pos = ctx->mouse_pos;
test_pos.x -= relative_origin.x;
@@ -360,12 +544,31 @@ do_status_bar(ColourPickerCtx *ctx, Rect r, v2 relative_origin)
step_colour_mode(ctx, -1);
}
+ Color hc = colour_from_normalized(get_formatted_colour(ctx, CM_RGB));
+ const char *hex = TextFormat("%02x%02x%02x%02x", hc.r, hc.g, hc.b, hc.a);
const char *label = "RGB: ";
+
v2 label_size = {.rv = MeasureTextEx(ctx->font, label, ctx->font_size, 0)};
+ v2 hex_size = {.rv = MeasureTextEx(ctx->font, hex, ctx->font_size, 0)};
+
+ f32 extra_input_scale = 1.07;
+ hex_r.size.w = extra_input_scale * (label_size.w + hex_size.w);
+
Rect label_r = cut_rect_left(hex_r, label_size.x / hex_r.size.w);
hex_r = cut_rect_right(hex_r, label_size.x / hex_r.size.w);
i32 hex_collides = CheckCollisionPointRec(test_pos.rv, hex_r.rr);
+
+ if (!hex_collides && ctx->is.idx == INPUT_HEX &&
+ IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
+ set_text_input_idx(ctx, -1, hex_r, test_pos);
+ hc = colour_from_normalized(get_formatted_colour(ctx, CM_RGB));
+ hex = TextFormat("%02x%02x%02x%02x", hc.r, hc.g, hc.b, hc.a);
+ }
+
+ if (hex_collides && IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
+ set_text_input_idx(ctx, INPUT_HEX, hex_r, test_pos);
+ #if 0
if (hex_collides && IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) {
const char *new = TextToLower(GetClipboardText());
u32 r, g, b, a;
@@ -373,23 +576,17 @@ do_status_bar(ColourPickerCtx *ctx, Rect r, v2 relative_origin)
v4 new_colour = {.rv = ColorNormalize((Color){.r = r, .g = g, .b = b, .a = a})};
store_formatted_colour(ctx, new_colour, CM_RGB);
}
+ #endif
- Color hc = colour_from_normalized(get_formatted_colour(ctx, CM_RGB));
- const char *hex = TextFormat("%02x%02x%02x%02x", hc.r, hc.g, hc.b, hc.a);
+ if (hex_collides && ctx->is.idx != INPUT_HEX)
+ ctx->sbs.hex_hover_t += TEXT_HOVER_SPEED * ctx->dt;
+ else
+ ctx->sbs.hex_hover_t -= TEXT_HOVER_SPEED * ctx->dt;
- if (hex_collides && IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
- SetClipboardText(hex);
+ if (mode_collides) ctx->sbs.mode_hover_t += TEXT_HOVER_SPEED * ctx->dt;
+ else ctx->sbs.mode_hover_t -= TEXT_HOVER_SPEED * ctx->dt;
- f32 scale = -5;
- if (hex_collides) scale *= -1;
-
- ctx->sbs.hex_hover_t += scale * ctx->dt;
CLAMP01(ctx->sbs.hex_hover_t);
-
- scale = -5;
- if (mode_collides) scale *= -1;
-
- ctx->sbs.mode_hover_t += scale * ctx->dt;
CLAMP01(ctx->sbs.mode_hover_t);
v4 fg = normalize_colour(pack_rl_colour(ctx->fg));
@@ -399,17 +596,16 @@ do_status_bar(ColourPickerCtx *ctx, Rect r, v2 relative_origin)
v2 fpos = left_align_text_in_rect(label_r, label, ctx->font, ctx->font_size);
DrawTextEx(ctx->font, label, fpos.rv, ctx->font_size, 0, ctx->fg);
- fpos = left_align_text_in_rect(hex_r, hex, ctx->font, ctx->font_size);
- DrawTextEx(ctx->font, hex, fpos.rv, ctx->font_size, 0, colour_from_normalized(hex_colour));
-
- char *mtext;
- switch (ctx->colour_mode) {
- case CM_RGB: mtext = "RGB"; break;
- case CM_HSV: mtext = "HSV"; break;
- case CM_LAST: ASSERT(0); break;
+ Color hex_colour_rl = colour_from_normalized(hex_colour);
+ if (ctx->is.idx != INPUT_HEX) {
+ fpos = left_align_text_in_rect(hex_r, hex, ctx->font, ctx->font_size);
+ DrawTextEx(ctx->font, hex, fpos.rv, ctx->font_size, 0, hex_colour_rl);
+ } else {
+ do_text_input(ctx, INPUT_HEX, hex_r, hex_colour_rl);
}
- fpos = right_align_text_in_rect(mode_r, mtext, ctx->font, ctx->font_size);
- DrawTextEx(ctx->font, mtext, fpos.rv, ctx->font_size, 0, colour_from_normalized(mode_colour));
+
+ DrawTextEx(ctx->font, mode_txt, mode_r.pos.rv, ctx->font_size, 0,
+ colour_from_normalized(mode_colour));
}
static void
@@ -455,9 +651,13 @@ do_colour_stack(ColourPickerCtx *ctx, Rect sa)
{
ColourStackState *css = &ctx->colour_stack;
+ /* NOTE: Small adjusment to align with mode text. TODO: Cleanup? */
+ sa.pos.y += 0.025 * sa.size.h;
+ sa.size.h *= 0.98;
+
Rect r = sa;
r.size.h *= 1.0 / (ARRAY_COUNT(css->items) + 3);
- r.size.w *= 0.5;
+ r.size.w *= 0.75;
r.pos.x += (sa.size.w - r.size.w) * 0.5;
f32 y_pos_delta = r.size.h + 10;
@@ -507,12 +707,9 @@ do_colour_stack(ColourPickerCtx *ctx, Rect sa)
draw_cardinal_triangle(tri_mid, tri_size, tri_scale, NORTH, ctx->fg);
if (push_collides && IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
- css->fade_param -= 1e-6;
- v4 colour = get_formatted_colour(ctx, CM_RGB);
-
- css->last = css->items[css->widx];
- css->items[css->widx++] = colour;
-
+ css->fade_param -= 1e-6;
+ css->last = css->items[css->widx];
+ css->items[css->widx++] = get_formatted_colour(ctx, CM_RGB);
if (css->widx == ARRAY_COUNT(css->items))
css->widx = 0;
}
@@ -529,18 +726,17 @@ do_colour_selector(ColourPickerCtx *ctx, Rect r)
DrawRectangleRec(cs[1].rr, colour);
v4 fg = normalize_colour(pack_rl_colour(ctx->fg));
- f32 scale = 5;
char *labels[2] = {"Revert", "Apply"};
i32 pressed_idx = -1;
for (i32 i = 0; i < ARRAY_COUNT(cs); i++) {
if (CheckCollisionPointRec(ctx->mouse_pos.rv, cs[i].rr) && ctx->held_idx == -1) {
- ctx->selection_hover_t[i] += scale * ctx->dt;
+ ctx->selection_hover_t[i] += TEXT_HOVER_SPEED * ctx->dt;
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
pressed_idx = i;
} else {
- ctx->selection_hover_t[i] -= scale * ctx->dt;
+ ctx->selection_hover_t[i] -= TEXT_HOVER_SPEED * ctx->dt;
}
CLAMP01(ctx->selection_hover_t[i]);
@@ -663,13 +859,13 @@ do_vertical_slider(ColourPickerCtx *ctx, v2 test_pos, Rect r, i32 idx,
{
/* TODO: move this to ctx */
static f32 slider_scale[2] = { 1, 1 };
- f32 scale_target = 1.5;
- f32 scale_delta = (scale_target - 1.0) * 8 * ctx->dt;
+ f32 scale_delta = (SLIDER_SCALE_TARGET - 1.0f) * SLIDER_SCALE_SPEED * ctx->dt;
b32 should_scale = (ctx->held_idx == -1 && hovering) ||
(ctx->held_idx != -1 && ctx->held_idx == idx);
f32 scale = slider_scale[idx];
- scale = move_towards_f32(scale, should_scale? scale_target : 1.0, scale_delta);
+ scale = move_towards_f32(scale, should_scale? SLIDER_SCALE_TARGET : 1.0,
+ scale_delta);
slider_scale[idx] = scale;
v2 tri_scale = {.x = scale, .y = scale};
@@ -777,13 +973,11 @@ do_picker_mode(ColourPickerCtx *ctx, v2 relative_origin)
{
/* TODO: move this to ctx */
static f32 slider_scale = 1;
- f32 scale_target = 1.5;
- f32 scale_delta = (scale_target - 1.0) * 8 * ctx->dt;
-
+ f32 scale_delta = (SLIDER_SCALE_TARGET - 1.0) * SLIDER_SCALE_SPEED * ctx->dt;
b32 should_scale = (ctx->held_idx == -1 && hovering) ||
(ctx->held_idx != -1 && ctx->held_idx == PM_RIGHT);
- slider_scale = move_towards_f32(slider_scale, should_scale? scale_target : 1.0,
- scale_delta);
+ slider_scale = move_towards_f32(slider_scale, should_scale?
+ SLIDER_SCALE_TARGET : 1.0, scale_delta);
/* NOTE: North-East */
f32 line_len = 8;
@@ -850,8 +1044,8 @@ do_colour_picker(ColourPickerCtx *ctx)
.size = {.w = ws.w - 2 * pad.x, .h = ws.h * 0.4 - 1 * pad.y},
};
- Rect ma = cut_rect_left(upper, 0.8);
- Rect sa = cut_rect_right(upper, 0.8);
+ Rect ma = cut_rect_left(upper, 0.84);
+ Rect sa = cut_rect_right(upper, 0.84);
do_colour_stack(ctx, sa);
{
diff --git a/main.c b/main.c
@@ -111,7 +111,7 @@ int
main(i32 argc, char *argv[])
{
ColourPickerCtx ctx = {
- .window_size = { .w = 720, .h = 860 },
+ .window_size = { .w = 640, .h = 860 },
.mode = CPM_PICKER,
.colour_mode = CM_HSV,
@@ -119,7 +119,9 @@ main(i32 argc, char *argv[])
.colour = {.r = 0.53, .g = 0.82, .b = 0.59, .a = 1.0},
+ .is = {.idx = -1, .cursor_t = 1, .cursor_t_target = 0},
.mcs = {.mode_visible_t = 1, .next_mode = -1},
+ .ss = {.scale_t = {1, 1, 1, 1}},
.bg = { .r = 0x26, .g = 0x1e, .b = 0x22, .a = 0xff },
.fg = { .r = 0xea, .g = 0xe1, .b = 0xb4, .a = 0xff },
diff --git a/util.c b/util.c
@@ -63,21 +63,33 @@ enum colour_picker_flags {
CPF_REFILL_TEXTURE = 1 << 0,
};
+enum input_indices {
+ INPUT_HEX,
+ INPUT_R,
+ INPUT_G,
+ INPUT_B,
+ INPUT_A
+};
+
enum cardinal_direction { NORTH, EAST, SOUTH, WEST };
-#define SLIDER_BORDER_WIDTH 3.0f
#define SLIDER_BORDER_COLOUR (Color){.r = 0x00, .g = 0x00, .b = 0x00, .a = 0xCC}
+#define SLIDER_BORDER_WIDTH 3.0f
#define SLIDER_ROUNDNESS 0.5f
+#define SLIDER_SCALE_SPEED 8.0f
+#define SLIDER_SCALE_TARGET 1.5f
#define SLIDER_TRI_SIZE (v2){.x = 6, .y = 8}
-#define STACK_BORDER_WIDTH SLIDER_BORDER_WIDTH
#define STACK_BORDER_COLOUR SLIDER_BORDER_COLOUR
+#define STACK_BORDER_WIDTH SLIDER_BORDER_WIDTH
#define STACK_ROUNDNESS 0.3f
-#define SELECTOR_BORDER_WIDTH SLIDER_BORDER_WIDTH
#define SELECTOR_BORDER_COLOUR SLIDER_BORDER_COLOUR
+#define SELECTOR_BORDER_WIDTH SLIDER_BORDER_WIDTH
#define SELECTOR_ROUNDNESS 0.3f
+#define TEXT_HOVER_SPEED 5.0f
+
#define COLOUR_STACK_ITEMS 8
typedef struct {
v4 last;
@@ -89,6 +101,11 @@ typedef struct {
} ColourStackState;
typedef struct {
+ f32 scale_t[4];
+ f32 colour_t[4];
+} SliderState;
+
+typedef struct {
f32 hex_hover_t;
f32 mode_hover_t;
} StatusBarState;
@@ -105,6 +122,16 @@ typedef struct {
} PickerModeState;
typedef struct {
+ i32 idx;
+ i32 cursor;
+ f32 cursor_p;
+ f32 cursor_t;
+ f32 cursor_t_target;
+ i32 buf_len;
+ char buf[64];
+} InputState;
+
+typedef struct {
v4 colour, previous_colour;
ColourStackState colour_stack;
@@ -113,9 +140,11 @@ typedef struct {
uv2 window_size;
Color bg, fg;
- StatusBarState sbs;
+ InputState is;
ModeChangeState mcs;
PickerModeState pms;
+ SliderState ss;
+ StatusBarState sbs;
i32 held_idx;