X-Git-Url: https://harrygodden.com/git/?p=vg.git;a=blobdiff_plain;f=vg_imgui.c;fp=vg_imgui.c;h=a4af9aecb3c922005ef90081792be4fc3747cd92;hp=08209b7d2ef44c1d3259416f529df2da3ab2ce0f;hb=70530f5055e116c22ab1b433884573944e9c4f64;hpb=0b8f57a12f41b67b6f088fb56855a0a70ecc7ca8 diff --git a/vg_imgui.c b/vg_imgui.c index 08209b7..a4af9ae 100644 --- a/vg_imgui.c +++ b/vg_imgui.c @@ -24,26 +24,7 @@ ui_px k_ui_widget_height = 28, k_ui_scale = 1, k_ui_padding = 8; -ui_font vg_ui_font_small = { - .glyph_width = 8, - .glyph_height = 14, - .glyph_baseline = 4, - .line_height = 14, - .sheet_size = 256, - .spacing = 8, - .ascii_start = ' ', - .offset_y = 0 -}, -vg_ui_font_big = { - .glyph_width = 12, - .glyph_height = 21, - .glyph_baseline = 6, - .line_height = 21, - .sheet_size = 256, - .spacing = 10, - .ascii_start = ' ', - .offset_y = 84 -}; +#include "vg/vg_default_font.gc" struct vg_imgui vg_ui = { .scheme = { @@ -82,7 +63,7 @@ struct vg_imgui vg_ui = { [ k_ui_purple + k_ui_brighter ] = UI_RGB( 0xd3869b ), [ k_ui_gray + k_ui_brighter ] = UI_RGB( 0xa89984 ), }, - .font = &vg_ui_font_small, + .font = &vgf_default_small, .colour = {1.0f,1.0f,1.0f,1.0f}, .bg_inverse_ratio = {1,1} }; @@ -97,6 +78,7 @@ static struct vg_shader _shader_ui ={ "layout (location=2) in vec4 a_colour;" "uniform mat3 uPv;" "uniform vec2 uBGInverseRatio;" + "uniform vec2 uInverseFontSheet;" "" "out vec4 aTexCoords;" "out vec4 aColour;" @@ -104,7 +86,7 @@ static struct vg_shader _shader_ui ={ "void main(){" "vec4 proj_pos = vec4( uPv * vec3( a_co, 1.0 ), 1.0 );" "gl_Position = proj_pos;" - "aTexCoords = vec4( a_uv * 0.00390625, " + "aTexCoords = vec4( a_uv * uInverseFontSheet, " " (proj_pos.xy*0.5+0.5) * uBGInverseRatio );" "aColour = a_colour;" "}", @@ -312,28 +294,36 @@ void vg_ui_init(void) */ /* Load default font */ - u32 compressed[] = { - #include "vg/vg_pxfont_thin.h" - }; - u32 pixels = 0, total = 256*256, data = 0; - u8 image[256*256]; + vg_font_sheet *sheet = &vg_default_font_sheet; + u32 pixels = 0, + total = sheet->w*sheet->h, + data = 0; + + vg_linear_clear( vg_mem.scratch ); + u8 *image = vg_linear_alloc( vg_mem.scratch, total ); - while( pixels < total ){ - for( int b = 31; b >= 0; b-- ){ - image[ pixels ++ ] = (compressed[data] & (0x1u << b))? 0xffu: 0x00u; + while( pixels < total ) + { + for( int b = 31; b >= 0; b-- ) + { + image[ pixels ++ ] = (sheet->bitmap[data] & (0x1u << b))? 0xffu: 0x00u; - if( pixels >= total ){ + if( pixels >= total ) + { total = 0; break; } } data++; } + + vg_ui.inverse_font_sheet[0] = 1.0/(f64)sheet->w; + vg_ui.inverse_font_sheet[1] = 1.0/(f64)sheet->h; glGenTextures( 1, &vg_ui.tex_glyphs ); glBindTexture( GL_TEXTURE_2D, vg_ui.tex_glyphs ); - glTexImage2D( GL_TEXTURE_2D, 0, GL_R8, 256, 256, 0, + glTexImage2D( GL_TEXTURE_2D, 0, GL_R8, sheet->w, sheet->h, 0, GL_RED, GL_UNSIGNED_BYTE, image ); VG_CHECK_GL_ERR(); @@ -411,6 +401,8 @@ void ui_flush( enum ui_shader shader, f32 w, f32 h ){ vg_ui.frosting ); glUniform2fv( glGetUniformLocation( _shader_ui.id, "uBGInverseRatio" ), 1, vg_ui.bg_inverse_ratio ); + glUniform2fv( glGetUniformLocation( _shader_ui.id, "uInverseFontSheet" ), + 1, vg_ui.inverse_font_sheet ); } else if( shader == k_ui_shader_image ){ glUseProgram( _shader_ui_image.id ); @@ -604,7 +596,7 @@ ui_px ui_text_line_width( const char *str ) else if( c == '\n' ) break; } - return length * vg_ui.font->spacing; + return length * vg_ui.font->sx; } ui_px ui_text_string_height( const char *str ) @@ -613,11 +605,12 @@ ui_px ui_text_string_height( const char *str ) const char *_c = str; u8 c; - while( (c = *(_c ++)) ){ + while( (c = *(_c ++)) ) + { if( c == '\n' ) height ++; } - return height * 14; + return height * vg_ui.font->sy; } ui_px ui_text_aligned_x( const char *str, ui_rect rect, ui_px scale, @@ -782,18 +775,15 @@ u32 v4f_u32_colour( v4f colour ) return r | (g<<8) | (b<<16) | (a<<24); } -static void ui_text_glyph( const struct ui_font *font, ui_px scale, - u8 glyph, ui_rect out_texcoords ){ - glyph -= font->ascii_start; +static void ui_text_glyph( const struct vg_font_face *ff, + u8 glyph, ui_rect out_texcoords ) +{ + const vg_font_char *ch = &ff->map[ glyph ]; - ui_px per_row = font->sheet_size / font->glyph_width, - column = (ui_px)glyph % per_row, - row = (glyph - column) / per_row; - - out_texcoords[0] = column * font->glyph_width; - out_texcoords[1] = row * font->glyph_height + font->offset_y; - out_texcoords[2] = out_texcoords[0] + font->glyph_width; - out_texcoords[3] = out_texcoords[1] + font->glyph_height; + out_texcoords[0] = ch->x; + out_texcoords[1] = ch->y; + out_texcoords[2] = ch->x + ff->cw; + out_texcoords[3] = ch->y + ff->ch; } u32 ui_opacity( u32 colour, f32 opacity ) @@ -815,12 +805,13 @@ u32 ui_ntext( ui_rect rect, const char *str, u32 len, ui_px scale, text_cursor[0] = ui_text_aligned_x( str, rect, scale, align ); text_cursor[1] = rect[1]; - text_cursor[2] = vg_ui.font->glyph_width*scale; - text_cursor[3] = vg_ui.font->glyph_height*scale; + text_cursor[2] = vg_ui.font->cw*scale; + text_cursor[3] = vg_ui.font->ch*scale; u32 printed_chars = 0; - if( align & (k_ui_align_middle|k_ui_align_bottom) ){ + if( align & (k_ui_align_middle|k_ui_align_bottom) ) + { ui_px height = ui_text_string_height( str ) * scale; if( align & k_ui_align_bottom ) @@ -829,41 +820,50 @@ u32 ui_ntext( ui_rect rect, const char *str, u32 len, ui_px scale, text_cursor[1] += (rect[3]-height)/2; } - while( (c = *(_c ++)) ){ - if( printed_chars >= len ){ + while( (c = *(_c ++)) ) + { + if( printed_chars >= len ) + { printed_chars = 0; - text_cursor[1] += vg_ui.font->line_height*scale; + text_cursor[1] += vg_ui.font->sy*scale; text_cursor[0] = ui_text_aligned_x( _c, rect, scale, align ); - text_cursor[0] -= vg_ui.font->spacing*scale; + text_cursor[0] -= vg_ui.font->sx*scale; ui_rect glyph; - ui_text_glyph( vg_ui.font, scale, '\xb6' /*FIXME*/, glyph ); + ui_text_glyph( vg_ui.font, '\xb6' /*FIXME*/, glyph ); ui_fill_rect( text_cursor, 0x00ffffff, glyph ); - text_cursor[0] += vg_ui.font->spacing*scale; + text_cursor[0] += vg_ui.font->sx*scale; } - if( c == '\n' ){ - text_cursor[1] += vg_ui.font->line_height*scale; + if( c == '\n' ) + { + text_cursor[1] += vg_ui.font->sy*scale; text_cursor[0] = ui_text_aligned_x( _c, rect, scale, align ); printed_chars = 0; continue; } - else if( c >= 33 ){ + else if( c >= 33 ) + { ui_rect glyph; - ui_text_glyph( vg_ui.font, scale, c, glyph ); + ui_text_glyph( vg_ui.font, c, glyph ); ui_rect cursor_clipped; - if( ui_clip( rect, text_cursor, cursor_clipped ) ){ + if( ui_clip( rect, text_cursor, cursor_clipped ) ) + { ui_fill_rect( cursor_clipped, colour, glyph ); } } - else if( c == '\x1B' ){ + else if( c == '\x1B' ) + { /* vt codes */ _c ++; u16 colour_id = 0; - for( int i=0; i<3; i ++ ){ - if( _c[i] ){ - if( _c[i] == 'm' ){ + for( int i=0; i<3; i ++ ) + { + if( _c[i] ) + { + if( _c[i] == 'm' ) + { _c = _c + i + 1; switch( colour_id ){ @@ -884,7 +884,8 @@ u32 ui_ntext( ui_rect rect, const char *str, u32 len, ui_px scale, colour_id |= _c[i] << (i*8); } - else{ + else + { _c = _c +i; break; } @@ -892,13 +893,14 @@ u32 ui_ntext( ui_rect rect, const char *str, u32 len, ui_px scale, continue; } - else if( c == '\t' ){ - text_cursor[0] += vg_ui.font->spacing*scale*4; + else if( c == '\t' ) + { + text_cursor[0] += vg_ui.font->sx*scale*4; printed_chars += 4; continue; } - text_cursor[0] += vg_ui.font->spacing*scale; + text_cursor[0] += vg_ui.font->sx*scale; printed_chars ++; } @@ -911,6 +913,11 @@ void ui_text( ui_rect rect, const char *str, ui_px scale, ui_ntext( rect, str, 1024, scale, align, colour ); } +void ui_font_face( vg_font_face *ff ) +{ + vg_ui.font = ff; +} + /* * Standard layout stuff * ----------------------------------------------------------------------------- @@ -928,14 +935,14 @@ void ui_label( ui_rect rect, const char *text, ui_px size, ui_px gap, ui_rect r ) { ui_rect l; - ui_px width = (ui_text_line_width(text)+vg_ui.font->spacing) * size; + ui_px width = (ui_text_line_width(text)+vg_ui.font->sx) * size; ui_split( rect, k_ui_axis_v, width, gap, l, r ); ui_text( l, text, 1, k_ui_align_middle_left, 0 ); } void ui_standard_widget( ui_rect inout_panel, ui_rect out_rect, ui_px count ) { - ui_px height = (count * vg_ui.font->glyph_height + 18) * k_ui_scale; + ui_px height = (count * vg_ui.font->sy + 18) * k_ui_scale; ui_split( inout_panel, k_ui_axis_h, height, k_ui_padding, out_rect, inout_panel ); } @@ -1122,8 +1129,8 @@ void ui_postrender(void) ui_rect row0, row1, btn; ui_split_ratio( message, k_ui_axis_h, 0.5f, 0, row0, row1 ); - row0[0] += vg_ui.font->spacing; - ui_ntext( row0, vg_ui.modal.message, (box[2]/vg_ui.font->spacing)-2, 1, + row0[0] += vg_ui.font->sx; + ui_ntext( row0, vg_ui.modal.message, (box[2]/vg_ui.font->sx)-2, 1, k_ui_align_left, colour ); rect_copy( row1, btn ); @@ -1877,7 +1884,7 @@ int ui_textbox( ui_rect inout_panel, const char *label, rect_copy( rect, text_rect ); if( flags & UI_TEXTBOX_MULTILINE ) text_rect[3] = rect[3]-16; - else text_rect[3] = vg_ui.font->line_height; + else text_rect[3] = vg_ui.font->sy; text_rect[2] -= 16; ui_rect_center( rect, text_rect ); @@ -1885,41 +1892,47 @@ int ui_textbox( ui_rect inout_panel, const char *label, ui_px wrap_length = 1024; if( flags & UI_TEXTBOX_WRAP ) - wrap_length = text_rect[2] / vg_ui.font->spacing; + wrap_length = text_rect[2] / vg_ui.font->sx; - if( hover ){ + if( hover ) + { vg_ui.cursor = k_ui_cursor_ibeam; } - if( vg_ui.focused_control_id == buf ){ + if( vg_ui.focused_control_id == buf ) + { ui_fill( rect, col_base ); ui_ntext( text_rect, buf, wrap_length, 1, k_ui_align_left, 0 ); - if( !(flags & UI_TEXTBOX_AUTOFOCUS) && ((clickup||clickdown) && !target)){ + if( !(flags & UI_TEXTBOX_AUTOFOCUS) && ((clickup||clickdown) && !target)) + { ui_defocus_all(); } - else{ + else + { vg_ui.focused_control_hit = 1; if( click && target ){ int p0[3] ={ - (vg_ui.mouse_click[0] - text_rect[0]) / vg_ui.font->spacing, - (vg_ui.mouse_click[1] - text_rect[1]) / vg_ui.font->line_height, + (vg_ui.mouse_click[0] - text_rect[0]) / vg_ui.font->sx, + (vg_ui.mouse_click[1] - text_rect[1]) / vg_ui.font->sy, -1 }, p1[3] = { - (vg_ui.mouse[0] - text_rect[0]) / vg_ui.font->spacing, - (vg_ui.mouse[1] - text_rect[1]) / vg_ui.font->line_height, + (vg_ui.mouse[0] - text_rect[0]) / vg_ui.font->sx, + (vg_ui.mouse[1] - text_rect[1]) / vg_ui.font->sy, -1 }; - if( flags & UI_TEXTBOX_MULTILINE ){ + if( flags & UI_TEXTBOX_MULTILINE ) + { _ui_textbox_calc_index_from_grid( p0, wrap_length ); _ui_textbox_calc_index_from_grid( p1, wrap_length ); vg_ui.textbox.cursor_pos = p0[2]; vg_ui.textbox.cursor_user = p1[2]; } - else{ + else + { int max = strlen( buf ); vg_ui.textbox.cursor_pos = VG_MAX( 0, VG_MIN( max, p0[0] )), vg_ui.textbox.cursor_user = VG_MAX( 0, VG_MIN( max, p1[0] )); @@ -1936,28 +1949,32 @@ int ui_textbox( ui_rect inout_panel, const char *label, end = VG_MAX( c0, c1 ), chars = end-start; - if( flags & (UI_TEXTBOX_WRAP|UI_TEXTBOX_MULTILINE) ){ + if( flags & (UI_TEXTBOX_WRAP|UI_TEXTBOX_MULTILINE) ) + { int pos[3], remaining = chars; pos[2] = start; _ui_textbox_index_calc_coords( pos, wrap_length ); - if( start==end ){ - cursor[0] = text_rect[0] + pos[0]*vg_ui.font->spacing-1; + if( start==end ) + { + cursor[0] = text_rect[0] + pos[0]*vg_ui.font->sx-1; cursor[1] = text_rect[1] + pos[1]*14; cursor[2] = 2; cursor[3] = 13; ui_fill( cursor, col_cursor ); rect_copy( cursor, vg_ui.click_fader_end ); } - else{ - while( remaining ){ + else + { + while( remaining ) + { int run = _ui_textbox_run_remaining( pos, wrap_length ); run = VG_MIN( run, remaining ); - cursor[0] = text_rect[0] + pos[0]*vg_ui.font->spacing-1; + cursor[0] = text_rect[0] + pos[0]*vg_ui.font->sx-1; cursor[1] = text_rect[1] + pos[1]*14; - cursor[2] = (float)(run)*(float)vg_ui.font->spacing; + cursor[2] = (float)(run)*(float)vg_ui.font->sx; cursor[3] = 13; ui_fill( cursor, col_cursor ); @@ -1970,20 +1987,24 @@ int ui_textbox( ui_rect inout_panel, const char *label, rect_copy( cursor, vg_ui.click_fader_end ); } } - else{ - cursor[0] = text_rect[0] + start*vg_ui.font->spacing-1; + else + { + cursor[0] = text_rect[0] + start*vg_ui.font->sx-1; cursor[1] = text_rect[1]; cursor[3] = 13; - if( start==end ){ + if( start==end ) + { cursor[2] = 2; } - else{ - cursor[2] = (float)(chars)*(float)vg_ui.font->spacing; + else + { + cursor[2] = (float)(chars)*(float)vg_ui.font->sx; } if( (vg_ui.click_fade_opacity<=0.0f) && - ui_clip( rect, cursor, cursor ) ){ + ui_clip( rect, cursor, cursor ) ) + { ui_fill( cursor, col_cursor ); } @@ -1994,8 +2015,10 @@ int ui_textbox( ui_rect inout_panel, const char *label, return 0; } - if( click || (flags & UI_TEXTBOX_AUTOFOCUS) ){ - if( (target && hover) || (flags & UI_TEXTBOX_AUTOFOCUS) ){ + if( click || (flags & UI_TEXTBOX_AUTOFOCUS) ) + { + if( (target && hover) || (flags & UI_TEXTBOX_AUTOFOCUS) ) + { ui_defocus_all(); ui_fill( rect, col_highlight ); @@ -2012,10 +2035,12 @@ int ui_textbox( ui_rect inout_panel, const char *label, vg_ui.textbox.cursor_pos = 0; vg_ui.textbox.cursor_user = 0; - if( callbacks ){ + if( callbacks ) + { vg_ui.textbox.callbacks = *callbacks; } - else{ + else + { vg_ui.textbox.callbacks.change = NULL; vg_ui.textbox.callbacks.down = NULL; vg_ui.textbox.callbacks.up = NULL; @@ -2028,7 +2053,8 @@ int ui_textbox( ui_rect inout_panel, const char *label, ui_fill( rect, col_base ); - if( hover ){ + if( hover ) + { ui_outline( rect, -1, col_highlight, 0 ); } @@ -2062,7 +2088,8 @@ void ui_tabs( ui_rect inout_panel, ui_rect out_content_panel, ui_rect_pad( out_content_panel, (ui_px[2]){ k_ui_padding, k_ui_padding } ); /* place buttons */ - for( i32 i=0; i