* -----------------------------------------------------------------------------
*/
-static void _ui_slider( ui_rect box,
+static enum ui_button_state _ui_slider( ui_rect box,
f32 min, f32 max, f32 *value, const char *format ){
f32 t;
char buf[32];
snprintf( buf, sizeof(buf), format? format: "%.2f", *value );
ui_text( box, buf, 1, k_ui_align_middle_center, 0 );
+
+ return state;
}
static void ui_slider( ui_rect inout_panel, const char *str_label,
ui_split_ratio( sliders[0], k_ui_axis_h, 0.5f, 2, sliders[0], sliders[1] );
ui_split_ratio( sliders[2], k_ui_axis_h, 0.5f, 2, sliders[2], sliders[3] );
+ v4f hsv;
+ vg_rgb_hsv( value, hsv );
+
+ enum ui_button_state modified = 0x00;
+
for( u32 i=0; i<4; i ++ ){
- _ui_slider( sliders[i], 0.0f, 1.0f, value+i,
+ modified |= _ui_slider( sliders[i], 0.0f, 1.0f, hsv+i,
(const char *[]){ "hue %.2f",
"sat %.2f",
"lum %.2f",
ui_split_ratio( left, k_ui_axis_v, 0.8f, 8, square, preview );
u32 state = ui_colourbutton( square, 0, 0, 0, 0 );
+ modified |= state;
enum ui_button_state
mask_using =
if( state & mask_using ){
for( u32 i=0; i<2; i ++ ){
- value[1+i] = vg_clampf(
+ hsv[1+i] = vg_clampf(
(f32)(vg_ui.mouse[i] - square[i]) / (f32)(square[2+i]),
0.0f, 1.0f );
}
- value[2] = 1.0f-value[2];
+ hsv[2] = 1.0f-hsv[2];
+ }
+
+ if( modified & (k_ui_button_click|k_ui_button_holding_inside|
+ k_ui_button_holding_outside) ){
+ vg_hsv_rgb( hsv, value );
}
ui_outline( square, 1, ui_colour( state? k_ui_fg+3: k_ui_bg+3 ), 0 );
/* preview colour */
- i32 i = floorf( value[0]*6.0f );
- f32 v = value[2],
- f = value[0] * 6.0f - (f32)i,
- p = v * (1.0f-value[1]),
- q = v * (1.0f-f*value[1]),
- t = v * (1.0f-(1.0f-f)*value[1]);
-
v4f colour;
-
- switch( i % 6 ){
- case 0: colour[0] = v; colour[1] = t; colour[2] = p; break;
- case 1: colour[0] = q; colour[1] = v; colour[2] = p; break;
- case 2: colour[0] = p; colour[1] = v; colour[2] = t; break;
- case 3: colour[0] = p; colour[1] = q; colour[2] = v; break;
- case 4: colour[0] = t; colour[1] = p; colour[2] = v; break;
- case 5: colour[0] = v; colour[1] = p; colour[2] = q; break;
- }
+ vg_hsv_rgb( hsv, colour );
colour[3] = 1.0f;
ui_fill( preview, v4f_u32_colour( colour ) );
/* Draw hsv shader thingy */
ui_flush( k_ui_shader_colour, vg.window_x, vg.window_y );
ui_fill_rect( square, 0xffffffff, (ui_px[4]){ 0,256,256,0 } );
- vg_ui.hue = value[0];
+ vg_ui.hue = hsv[0];
ui_flush( k_ui_shader_hsv, vg.window_x, vg.window_y );
- ui_rect marker = { square[0] + value[1] * (f32)square[2] - 4,
- square[1] + (1.0f-value[2]) * (f32)square[3] - 4,
+ ui_rect marker = { square[0] + hsv[1] * (f32)square[2] - 4,
+ square[1] + (1.0f-hsv[2]) * (f32)square[3] - 4,
8, 8 },
lx = { square[0],
- square[1] + (1.0f-value[2]) * (f32)square[3],
+ square[1] + (1.0f-hsv[2]) * (f32)square[3],
square[2], 1 },
- ly = { square[0] + value[1] * (f32)square[2],
+ ly = { square[0] + hsv[1] * (f32)square[2],
square[1],
1, square[3] };
out_dir[2] = cosf(r);
}
+static void vg_hsv_rgb( v3f hsv, v3f rgb ){
+ i32 i = floorf( hsv[0]*6.0f );
+ f32 v = hsv[2],
+ f = hsv[0] * 6.0f - (f32)i,
+ p = v * (1.0f-hsv[1]),
+ q = v * (1.0f-f*hsv[1]),
+ t = v * (1.0f-(1.0f-f)*hsv[1]);
+
+ switch( i % 6 ){
+ case 0: rgb[0] = v; rgb[1] = t; rgb[2] = p; break;
+ case 1: rgb[0] = q; rgb[1] = v; rgb[2] = p; break;
+ case 2: rgb[0] = p; rgb[1] = v; rgb[2] = t; break;
+ case 3: rgb[0] = p; rgb[1] = q; rgb[2] = v; break;
+ case 4: rgb[0] = t; rgb[1] = p; rgb[2] = v; break;
+ case 5: rgb[0] = v; rgb[1] = p; rgb[2] = q; break;
+ }
+}
+
+static void vg_rgb_hsv( v3f rgb, v3f hsv ){
+ f32 min = v3_minf( rgb ),
+ max = v3_maxf( rgb ),
+ range = max-min,
+ k_epsilon = 0.00001f;
+
+ hsv[2] = max;
+ if( range < k_epsilon ){
+ hsv[0] = 0.0f;
+ hsv[1] = 0.0f;
+ return;
+ }
+
+ if( max > k_epsilon ){
+ hsv[1] = range/max;
+ }
+ else {
+ hsv[0] = 0.0f;
+ hsv[1] = 0.0f;
+ return;
+ }
+
+ if( rgb[0] >= max )
+ hsv[0] = (rgb[1]-rgb[2])/range;
+ else if( max == rgb[1] )
+ hsv[0] = 2.0f+(rgb[2]-rgb[0])/range;
+ else
+ hsv[0] = 4.0f+(rgb[0]-rgb[1])/range;
+
+ hsv[0] = vg_fractf( hsv[0] * (60.0f/360.0f) );
+}
+
#endif /* VG_M_H */