SDL_Cursor *cursor_map[ k_ui_cursor_max ];
v4f colour;
+
+ f32 hue; /* lol this sucks */
}
static vg_ui = {
.scheme = {
}
};
+static struct vg_shader _shader_ui_hsv = {
+ .name = "[vg] ui_hsv",
+ .link = NULL,
+ .vs = {
+ .orig_file = NULL,
+ .static_src =
+ "layout (location=0) in vec2 a_co;"
+ "layout (location=1) in vec2 a_uv;"
+ "layout (location=2) in vec4 a_colour;"
+ "uniform mat3 uPv;"
+
+ "out vec2 aTexCoords;"
+ "out vec4 aColour;"
+ "out vec2 aWsp;"
+
+ "void main()"
+ "{"
+ "gl_Position = vec4( uPv * vec3( a_co, 1.0 ), 1.0 );"
+ "aTexCoords = a_uv * 0.00390625;"
+ "aColour = a_colour;"
+
+ "aWsp = a_co;"
+ "}",
+ },
+ .fs =
+ {
+ .orig_file = NULL,
+ .static_src =
+ "uniform float uHue;"
+ "out vec4 FragColor;"
+
+ "in vec2 aTexCoords;"
+ "in vec4 aColour;"
+ "in vec2 aWsp;"
+
+ "void main()"
+ "{"
+ "vec3 c = vec3( uHue, aTexCoords );"
+ "vec4 K = vec4(1.0,2.0/3.0,1.0/3.0,3.0);"
+ "vec3 p = abs(fract(c.xxx+K.xyz)*6.0 - K.www);"
+ "vec3 colour = c.z*mix(K.xxx,clamp(p-K.xxx,0.0,1.0),c.y);"
+ "FragColor = vec4( colour, 1.0 );"
+ "}"
+ }
+};
+
static void _vg_ui_init(void){
if( !vg_shader_compile( &_shader_ui ) ||
- !vg_shader_compile( &_shader_ui_image ) ){
+ !vg_shader_compile( &_shader_ui_image ) ||
+ !vg_shader_compile( &_shader_ui_hsv ) ){
vg_fatal_error( "Failed to compile ui shader" );
}
enum ui_shader {
k_ui_shader_colour,
- k_ui_shader_image
+ k_ui_shader_image,
+ k_ui_shader_hsv,
};
static void rect_copy( ui_rect a, ui_rect b ){
glUniform4fv( glGetUniformLocation( _shader_ui_image.id, "uColour" ), 1,
vg_ui.colour );
}
+ else if( shader == k_ui_shader_hsv ){
+ glUseProgram( _shader_ui_hsv.id );
+ glUniformMatrix3fv( glGetUniformLocation( _shader_ui_hsv.id, "uPv" ), 1,
+ GL_FALSE, (float *)view );
+ glUniform1f( glGetUniformLocation(_shader_ui_hsv.id,"uHue"), vg_ui.hue );
+ }
else
vg_fatal_error( "Invalid UI shader (%d)\n", shader );
k_ui_button_hover = 0x8
};
+/* TODO: split this out into a formatless button and one that auto fills */
static enum ui_button_state ui_colourbutton( ui_rect rect,
enum ui_scheme_colour colour,
enum ui_scheme_colour hover_colour,
- enum ui_scheme_colour hi_colour ){
+ enum ui_scheme_colour hi_colour,
+ bool const fill ){
int clickup= ui_click_up(UI_MOUSE_LEFT),
click = ui_clicking(UI_MOUSE_LEFT) | clickup,
target = ui_inside_rect( rect, vg_ui.mouse_click ) && click,
if( target ){
if( hover ){
if( clickup ){
- ui_fill( rect, col_highlight );
vg_ui.ignore_input_frames = 2;
- rect_copy( rect, vg_ui.click_fader );
+ ui_defocus_all();
- rect_copy( rect, vg_ui.click_fader_end );
- vg_ui.click_fader_end[3] = 0;
- ui_rect_center( rect, vg_ui.click_fader_end );
+ if( fill ) {
+ ui_fill( rect, col_highlight );
+ rect_copy( rect, vg_ui.click_fader );
+ rect_copy( rect, vg_ui.click_fader_end );
+ vg_ui.click_fader_end[3] = 0;
+ ui_rect_center( rect, vg_ui.click_fader_end );
+ vg_ui.click_fade_opacity = 1.0f;
+ }
- vg_ui.click_fade_opacity = 1.0f;
- ui_defocus_all();
return k_ui_button_click;
}
else{
- ui_fill( rect, col_highlight );
+ if( fill ) ui_fill( rect, col_highlight );
return k_ui_button_holding_inside;
}
}
else{
- ui_fill( rect, col_base );
+ if( fill ) ui_fill( rect, col_base );
ui_outline( rect, 1, col_highlight, 0 );
return k_ui_button_holding_outside;
}
}
else{
- ui_fill( rect, col_base );
+ if( fill ) ui_fill( rect, col_base );
return k_ui_button_none;
}
}
else{
if( hover ){
- ui_fill( rect, col_hover );
+ if( fill ) ui_fill( rect, col_hover );
return k_ui_button_hover;
}
else{
- ui_fill( rect, col_base );
+ if( fill ) ui_fill( rect, col_base );
return k_ui_button_none;
}
}
static enum ui_button_state ui_colourbutton_text(
ui_rect rect, const char *string, ui_px scale,
enum ui_scheme_colour colour ){
- enum ui_button_state state = ui_colourbutton( rect, colour, 0, 0 );
+ enum ui_button_state state = ui_colourbutton( rect, colour, 0, 0, 1 );
ui_rect t = { 0,0, ui_text_line_width( string )*scale, 14*scale };
ui_rect_center( rect, t );
ui_split( rect, k_ui_axis_v, -rect[3], 0, label, box );
ui_text( label, str_label, k_ui_scale, k_ui_align_middle_left, 0 );
- int changed = ui_colourbutton( box, k_ui_bg, 0, 0 )==1;
+ int changed = ui_colourbutton( box, k_ui_bg, 0, 0, 1 )==1;
if( changed )
*data = (*data) ^ 0x1;
* -----------------------------------------------------------------------------
*/
-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 );
-
+static enum ui_button_state _ui_slider( ui_rect box,
+ f32 min, f32 max, f32 *value, const char *format ){
f32 t;
enum ui_button_state
k_ui_button_click,
mask_brighter =
mask_using | k_ui_button_hover,
- state = ui_colourbutton( box, k_ui_bg, k_ui_bg+2, k_ui_bg+3 );
+ state = ui_colourbutton( box, k_ui_bg, k_ui_bg+2, k_ui_bg+3, 1 );
if( state & mask_using ){
t = vg_clampf( (f32)(vg_ui.mouse[0] - box[0]) / (f32)( box[2] ),
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,
+ 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] );
+
+ v4f hsv;
+ vg_rgb_hsv( value, hsv );
+ hsv[3] = value[3];
+
+ enum ui_button_state modified = 0x00;
+
+ for( u32 i=0; i<4; i ++ ){
+ modified |= _ui_slider( sliders[i], 0.0f, 1.0f, hsv+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 );
+ modified |= state;
+
+ 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 ++ ){
+ hsv[1+i] = vg_clampf(
+ (f32)(vg_ui.mouse[i] - square[i]) / (f32)(square[2+i]),
+ 0.0f, 1.0f );
+ }
+
+ 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 );
+ value[3] = hsv[3];
+ }
+
+ ui_outline( square, 1, ui_colour( state? k_ui_fg+3: k_ui_bg+3 ), 0 );
+
+ /* preview colour */
+ v4f colour;
+ 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 = hsv[0];
+ ui_flush( k_ui_shader_hsv, vg.window_x, vg.window_y );
+
+ 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-hsv[2]) * (f32)square[3],
+ square[2], 1 },
+ ly = { square[0] + hsv[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 ) );
}
/*