+static void ui_slider( ui_rect inout_panel, const char *str_label,
+ f32 min, f32 max, f32 *value, const char *format ){
+ ui_rect rect, label, box;
+ ui_standard_widget( inout_panel, rect, 1 );
+ ui_label( rect, str_label, k_ui_scale, 0, box );
+ _ui_slider( box, min, max, value, format );
+}
+
+/*
+ * Colour picker
+ * -----------------------------------------------------------------------------
+ */
+
+static void ui_colourpicker( ui_rect inout_panel, const char *str_label,
+ v4f value ){
+ ui_rect widget, left, right;
+ ui_standard_widget( inout_panel, widget, 8 );
+ ui_split_ratio( widget, k_ui_axis_v, 0.5f, 8, left, right );
+
+ ui_rect sliders[4];
+ ui_split_ratio( right, k_ui_axis_h, 0.5f, 2, sliders[0], sliders[2] );
+ 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] );
+
+ for( u32 i=0; i<4; i ++ ){
+ _ui_slider( sliders[i], 0.0f, 1.0f, value+i,
+ (const char *[]){ "hue %.2f",
+ "sat %.2f",
+ "lum %.2f",
+ "alpha %.2f" }[i] );
+ }
+
+ ui_rect preview, square;
+ ui_split_ratio( left, k_ui_axis_v, 0.8f, 8, square, preview );
+
+ u32 state = ui_colourbutton( square, 0, 0, 0, 0 );
+
+ enum ui_button_state
+ mask_using =
+ k_ui_button_holding_inside |
+ k_ui_button_holding_outside |
+ k_ui_button_click;
+
+ if( state & mask_using ){
+ for( u32 i=0; i<2; i ++ ){
+ value[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];
+ }
+
+ 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;
+ }
+ 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];
+ 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,
+ 8, 8 },
+ lx = { square[0],
+ square[1] + (1.0f-value[2]) * (f32)square[3],
+ square[2], 1 },
+ ly = { square[0] + value[1] * (f32)square[2],
+ square[1],
+ 1, square[3] };
+
+ ui_fill( marker, ui_colour( k_ui_fg ) );
+ ui_fill( lx, ui_colour( k_ui_fg ) );
+ ui_fill( ly, ui_colour( k_ui_fg ) );
+}
+