Commit: 4c2545a25a1029b986dc7165db81ddff0ec516aa
Parent: 8e4d0f1457ef72ba9568d858e8c0ea65fefb2d08
Author: Randy Palamar
Date: Sat, 8 Jun 2024 11:35:30 -0600
draw modifiable sliders
Diffstat:
M | colourpicker.c | | | 152 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- |
M | main.c | | | 9 | ++++++++- |
M | util.c | | | 25 | +++++++++++++++++++++++++ |
3 files changed, 170 insertions(+), 16 deletions(-)
diff --git a/colourpicker.c b/colourpicker.c
@@ -2,6 +2,124 @@
#include <raylib.h>
#include "util.c"
+static v2
+center_text_in_rect(Rect r, const char *text, Font font, f32 fontsize)
+{
+ v2 ts = { .rv = MeasureTextEx(font, text, fontsize, 0) };
+ v2 delta = { .w = r.size.w - ts.w, .h = r.size.h - ts.h };
+ return (v2) {
+ .x = r.pos.x + 0.5 * delta.w,
+ .y = r.pos.y + 0.5 * delta.h,
+ };
+}
+
+static Rect
+cut_rect_middle(Rect r, f32 left, f32 right)
+{
+ ASSERT(left <= right);
+ r.pos.x += r.size.w * left;
+ r.size.w = r.size.w * (right - left);
+ return r;
+}
+
+static Rect
+cut_rect_left(Rect r, f32 fraction)
+{
+ r.size.w *= fraction;
+ return r;
+}
+
+static Rect
+cut_rect_right(Rect r, f32 fraction)
+{
+ r.pos.x += fraction * r.size.w;
+ r.size.w *= (1 - fraction);
+ return r;
+}
+
+static f32
+do_slider(Rect r, char *label, f32 current, Font font)
+{
+ Rect lr = cut_rect_left(r, 0.1);
+ Rect vr = cut_rect_right(r, 0.85);
+
+ Rect sr = cut_rect_middle(r, 0.1, 0.85);
+ sr.size.h *= 0.75;
+ sr.pos.y += r.size.h * 0.125;
+
+ v2 fpos = center_text_in_rect(lr, label, font, 48);
+ DrawTextEx(font, label, fpos.rv, 48, 0, LIGHTGRAY);
+
+ v2 mouse = { .rv = GetMousePosition() };
+ if (CheckCollisionPointRec(mouse.rv, sr.rr)) {
+ f32 wheel = GetMouseWheelMove();
+ if (IsMouseButtonDown(MOUSE_BUTTON_LEFT))
+ current = (mouse.x - sr.pos.x) / sr.size.w;
+ current += 4 * wheel / sr.size.w;
+ CLAMP(current, 0.0, 1.0);
+ }
+
+ DrawRectangleRounded(sr.rr, 1.0, 0, PURPLE);
+ v2 start = {
+ .x = sr.pos.x + current * sr.size.w,
+ .y = sr.pos.y + sr.size.h,
+ };
+ v2 end = start;
+ end.y -= sr.size.h;
+ DrawLineEx(start.rv, end.rv, 8, BLACK);
+
+ const char *value = TextFormat("%0.02f", current);
+ fpos = center_text_in_rect(vr, value, font, 36);
+ DrawTextEx(font, value, fpos.rv, 36, 0, LIGHTGRAY);
+
+ return current;
+}
+
+static enum colour_picker_mode
+do_status_bar(Rect r, enum colour_picker_mode mode, Color colour, Font font)
+{
+ Rect hr = cut_rect_left(r, 0.5);
+ Rect sr = cut_rect_right(r, 0.7);
+
+ const char *hex = TextFormat("%02x%02x%02x%02x",
+ colour.r, colour.b, colour.g,
+ colour.a);
+ v2 fpos = center_text_in_rect(hr, hex, font, 48);
+ DrawTextEx(font, hex, fpos.rv, 48, 0, LIGHTGRAY);
+
+ v2 mouse = { .rv = GetMousePosition() };
+
+ if (CheckCollisionPointRec(mouse.rv, hr.rr)) {
+ if (IsMouseButtonDown(MOUSE_BUTTON_LEFT))
+ SetClipboardText(hex);
+ }
+
+ if (CheckCollisionPointRec(mouse.rv, sr.rr)) {
+ if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
+ if (mode == HSV)
+ mode = RGB;
+ else
+ mode++;
+ }
+ if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) {
+ if (mode == RGB)
+ mode = HSV;
+ else
+ mode--;
+ }
+ }
+
+ char *mtext;
+ switch (mode) {
+ case RGB: mtext = "RGB"; break;
+ case HSV: mtext = "HSV"; break;
+ }
+ fpos = center_text_in_rect(sr, mtext, font, 48);
+ DrawTextEx(font, mtext, fpos.rv, 48, 0, LIGHTGRAY);
+
+ return mode;
+}
+
void
do_colour_picker(ColourPickerCtx *ctx)
{
@@ -9,12 +127,12 @@ do_colour_picker(ColourPickerCtx *ctx)
DrawFPS(20, 20);
uv2 ws = ctx->window_size;
+ Color colour = ColorFromNormalized(ctx->colour.rv);
{
v2 cc = { .x = (f32)ws.w / 2, .y = (f32)ws.h / 4 };
DrawCircleSector(cc.rv, 0.6 * cc.x, 0, 360, 69, RED);
- DrawCircleSector(cc.rv, 0.58 * cc.x, 0, 360, 69, BLACK);
- DrawText("Hello World!", ws.w * 0.3, ws.h / 4, 48, BLUE);
+ DrawCircleSector(cc.rv, 0.58 * cc.x, 0, 360, 69, colour);
}
{
@@ -24,24 +142,28 @@ do_colour_picker(ColourPickerCtx *ctx)
}
{
- v2 subregion = {
- .x = (f32)ws.w * 0.9,
- .y = (f32)ws.h / 2 * 0.9,
+ Rect subregion = {
+ .pos = { .x = 0.05 * (f32)ws.w, .y = (f32)ws.h / 2, },
+ .size = { .w = (f32)ws.w * 0.9, .h = (f32)ws.h / 2 * 0.9 },
};
- v2 starting_pos = {
- .x = 0.05 * (f32)ws.w,
- .y = (f32)ws.h / 2 + 0.25 * ((f32)ws.h / 2),
- };
+ Rect sb = subregion;
+ sb.size.h *= 0.25;
+ ctx->mode = do_status_bar(sb, ctx->mode, colour, ctx->font);
+
+ Rect r = subregion;
+ r.pos.y += 0.25 * ((f32)ws.h / 2);
+ r.size.h *= 0.15;
- v2 size = { .x = subregion.x, .y = 0.15 * subregion.y };
+ ctx->colour.r = do_slider(r, "R:", ctx->colour.r, ctx->font);
- DrawRectangleV(starting_pos.rv, size.rv, DARKGREEN);
+ r.pos.y += r.size.h + 0.03 * ((f32)ws.h / 2);
+ ctx->colour.g = do_slider(r, "G:", ctx->colour.g, ctx->font);
- starting_pos.y += size.y + 0.1 * ((f32)ws.h / 2);
- DrawRectangleV(starting_pos.rv, size.rv, DARKGREEN);
+ r.pos.y += r.size.h + 0.03 * ((f32)ws.h / 2);
+ ctx->colour.b = do_slider(r, "B:", ctx->colour.b, ctx->font);
- starting_pos.y += size.y + 0.1 * ((f32)ws.h / 2);
- DrawRectangleV(starting_pos.rv, size.rv, DARKGREEN);
+ r.pos.y += r.size.h + 0.03 * ((f32)ws.h / 2);
+ ctx->colour.a = do_slider(r, "A:", ctx->colour.a, ctx->font);
}
}
diff --git a/main.c b/main.c
@@ -2,6 +2,7 @@
#include <dlfcn.h>
#include <fcntl.h>
#include <raylib.h>
+#include <stdio.h>
#include <sys/stat.h>
#include "util.c"
@@ -11,6 +12,8 @@ typedef struct timespec Filetime;
static const char *libname = "./libcolourpicker.so";
static void *libhandle;
+static const char *fontpath = "/home/rnp/.local/share/fonts/Aozora Mincho Medium.ttf";
+
typedef void (do_colour_picker_fn)(ColourPickerCtx *);
static do_colour_picker_fn *do_colour_picker;
@@ -35,18 +38,22 @@ load_library(const char *lib)
dlclose(libhandle);
libhandle = dlopen(lib, RTLD_NOW|RTLD_LOCAL);
do_colour_picker = dlsym(libhandle, "do_colour_picker");
+ if (!libhandle || !do_colour_picker)
+ fprintf(stderr, "Couldn't Hot Reload ColourPicker\n");
}
int
main(void)
{
- ColourPickerCtx ctx;
+ ColourPickerCtx ctx = {0};
ctx.window_size = (uv2){.w = 720, .h = 960};
SetConfigFlags(FLAG_VSYNC_HINT);
InitWindow(ctx.window_size.w, ctx.window_size.h, "Colour Picker");
load_library(libname);
+ ctx.font = LoadFontEx(fontpath, 128, 0, 0);
+
Filetime updated_time = get_filetime(libname);
while(!WindowShouldClose()) {
BeginDrawing();
diff --git a/util.c b/util.c
@@ -2,6 +2,8 @@
#include <stddef.h>
#include <stdint.h>
+#define ASSERT(c) do { if (!(c)) __builtin_debugtrap(); } while (0);
+
typedef int32_t i32;
typedef uint32_t u32;
typedef float f32;
@@ -16,10 +18,33 @@ typedef union {
typedef union {
struct { f32 x, y; };
+ struct { f32 w, h; };
Vector2 rv;
f32 E[2];
} v2;
+typedef union {
+ struct { f32 x, y, z, w; };
+ struct { f32 r, g, b, a; };
+ Vector4 rv;
+ f32 E[4];
+} v4;
+
+typedef union {
+ struct { v2 pos, size; };
+ Rectangle rr;
+} Rect;
+
+enum colour_picker_mode {
+ RGB,
+ HSV,
+};
+
typedef struct {
uv2 window_size;
+ Font font;
+ v4 colour;
+ enum colour_picker_mode mode;
} ColourPickerCtx;
+
+#define CLAMP(x, a, b) ((x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x))