}
static ui_px ui_text_line_width( const char *str );
-static void ui_split_label( ui_rect rect, const char *text, ui_px size,
- ui_px gap, ui_rect l, ui_rect r )
-{
- ui_px width = ui_text_line_width( text ) * size;
- ui_split( rect, k_ui_axis_v, width, gap, l, r );
-}
static void ui_rect_center( ui_rect parent, ui_rect rect )
{
{
if( co[0] >= rect[0] &&
co[1] >= rect[1] &&
- co[0] <= rect[0]+rect[2] &&
- co[1] <= rect[1]+rect[3] )
+ co[0] < rect[0]+rect[2] &&
+ co[1] < rect[1]+rect[3] )
{
return 1;
}
for( u32 i=0; i<vg_ui.dropdown.option_count; i++ ){
ui_rect button;
- ui_split( drawer, k_ui_axis_h, vg_ui.dropdown.rect[3], 1, button,drawer );
+ ui_split( drawer, k_ui_axis_h, vg_ui.dropdown.rect[3], 0, button,drawer );
enum ui_scheme_colour colour = k_ui_bg+3;
if( i == value->index ) colour = k_ui_orange;
}
}
+static 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 )+1) * size;
+ ui_split( rect, k_ui_axis_v, width, gap, l, r );
+ ui_text( l, text, 1, k_ui_align_middle_left, 0 );
+}
+
#endif /* VG_IMGUI_H */
--- /dev/null
+#ifndef VG_MSG_H
+#define VG_MSG_H
+#include "vg_stdint.h"
+
+enum vg_msg_code{
+ k_vg_msg_code_end = 0,
+ k_vg_msg_code_frame = 1,
+ k_vg_msg_code_endframe = 2,
+ k_vg_msg_code_kv = 10,
+ k_vg_msg_code_kvstring = 11,
+ k_vg_msg_code_kvbin = 12,
+ k_vg_msg_code_signed = 0x80, /* byte sizes stored in lower 4 bits */
+ k_vg_msg_code_unsigned = 0x40,
+ k_vg_msg_code_float = 0x20
+};
+
+typedef struct vg_msg vg_msg;
+typedef struct vg_msg_cmd vg_msg_cmd;
+struct vg_msg{
+ u32 cur,max;
+ u8 *buf;
+ u32 depth;
+
+ enum vg_msg_error{
+ k_vg_msg_error_OK,
+ k_vg_msg_error_unbalanced,
+ k_vg_msg_error_overflow,
+ k_vg_msg_error_unhandled_cmd
+ }
+ error;
+};
+
+struct vg_msg_cmd{
+ u8 code;
+
+ const char *key;
+ u32 key_djb2;
+
+ union{ const void *_buf;
+ u8 _u8; i8 _i8;
+ u16 _u16; i16 _i16;
+ u32 _u32; i32 _i32; f32 _f32;
+ u64 _u64; i64 _i64; f64 _f64;
+ } value;
+ u32 value_djb2;
+};
+
+static void vg_msg_init( vg_msg *msg, u8 *buf, u32 max ){
+ msg->cur = 0;
+ msg->max = max;
+ msg->buf = buf;
+ msg->depth = 0;
+ msg->error = k_vg_msg_error_OK;
+}
+
+static void vg_msg_exchbuf( vg_msg *msg, int write, u8 *buf, u32 len ){
+ if( msg->error != k_vg_msg_error_OK ) return;
+ if( msg->cur+len > msg->max ){
+ msg->error = k_vg_msg_error_overflow;
+ return;
+ }
+ for( u32 i=0; i<len; i++ ){
+ if( write ) msg->buf[ msg->cur ++ ] = buf[i];
+ else buf[i] = msg->buf[ msg->cur ++ ];
+ }
+}
+
+static void vg_msg_wstr( vg_msg *msg, const char *str ){
+ if( msg->error != k_vg_msg_error_OK ) return;
+ for( u32 i=0;; i++ ){
+ vg_msg_exchbuf( msg, 1, (u8[]){ str[i] }, 1 );
+ if( !str[i] ) break;
+ }
+}
+
+static const char *vg_msg_rstr( vg_msg *msg, u32 *djb2 ){
+ if( msg->error != k_vg_msg_error_OK ) return 0;
+
+ u32 hash = 5381, c;
+ const char *str = (void *)(&msg->buf[ msg->cur ]);
+
+ while( (c = msg->buf[ msg->cur ++ ]) ){
+ if( msg->cur >= msg->max ){
+ msg->error = k_vg_msg_error_overflow;
+ return 0;
+ }
+ hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
+ }
+
+ *djb2 = hash;
+ return str;
+}
+
+static void vg_msg_frame( vg_msg *msg, const char *name ){
+ if( msg->error != k_vg_msg_error_OK ) return;
+
+ msg->depth ++;
+ vg_msg_exchbuf( msg, 1, (u8[]){ k_vg_msg_code_frame }, 1 );
+ vg_msg_wstr( msg, name );
+}
+
+static void vg_msg_end_frame( vg_msg *msg ){
+ if( msg->error != k_vg_msg_error_OK ) return;
+ if( !msg->depth ){
+ msg->error = k_vg_msg_error_unbalanced;
+ return;
+ }
+ msg->depth --;
+ vg_msg_exchbuf( msg, 1, (u8[]){ k_vg_msg_code_endframe }, 1 );
+}
+
+static void vg_msg_wkvstr( vg_msg *msg, const char *key, const char *value ){
+ vg_msg_exchbuf( msg, 1, (u8[]){ k_vg_msg_code_kvstring }, 1 );
+ vg_msg_wstr( msg, key );
+ vg_msg_wstr( msg, value );
+}
+
+static void vg_msg_wkvbin( vg_msg *msg, const char *key, u8 *bin, u32 len ){
+ vg_msg_exchbuf( msg, 1, (u8[]){ k_vg_msg_code_kvbin }, 1 );
+ vg_msg_wstr( msg, key );
+ vg_msg_exchbuf( msg, 1, (u8 *)(&len), 4 );
+ vg_msg_exchbuf( msg, 1, bin, len );
+}
+
+static void vg__msg_wkvgen( vg_msg *msg, const char *key,
+ u8 basecode, void *value, u32 size ){
+ u8 code = basecode | size;
+ vg_msg_exchbuf( msg, 1, &code, 1 );
+ vg_msg_wstr( msg, key );
+ vg_msg_exchbuf( msg, 1, value, size );
+}
+
+#define vg_msg_wkvint( MSGPTR, KEY, DECL ){ \
+ DECL; \
+ vg__msg_wkvgen(MSGPTR, KEY, k_vg_msg_code_signed, &value, sizeof(value));\
+ }
+#define vg_msg_wkvuint( MSGPTR, KEY, DECL ){ \
+ DECL; \
+ vg__msg_wkvgen(MSGPTR, KEY, k_vg_msg_code_unsigned, &value, sizeof(value));\
+ }
+#define vg_msg_wkvfloat( MSGPTR, KEY, DECL ){ \
+ DECL; \
+ vg__msg_wkvgen(MSGPTR, KEY, k_vg_msg_code_float, &value, sizeof(value));\
+ }
+
+static int vg_msg_next( vg_msg *msg, vg_msg_cmd *cmd ){
+ vg_msg_exchbuf( msg, 0, &cmd->code, 1 );
+ if( msg->error != k_vg_msg_error_OK ) return 0;
+
+ if( cmd->code == k_vg_msg_code_frame ){
+ cmd->key = vg_msg_rstr( msg, &cmd->key_djb2 );
+ msg->depth ++;
+ }
+ else if( cmd->code == k_vg_msg_code_endframe ){
+ if( !msg->depth ){
+ msg->error = k_vg_msg_error_unbalanced;
+ return 0;
+ }
+ msg->depth --;
+ }
+ else if( cmd->code >= k_vg_msg_code_kv ){
+ cmd->key = vg_msg_rstr( msg, &cmd->key_djb2 );
+ cmd->value_djb2 = 0;
+ cmd->value._u64 = 0;
+
+ if( cmd->code & (k_vg_msg_code_float|k_vg_msg_code_unsigned|
+ k_vg_msg_code_signed )){
+ u8 len = cmd->code & 0xf;
+ vg_msg_exchbuf( msg, 0, (u8 *)(&cmd->value._u64), len );
+ }
+ else if( cmd->code == k_vg_msg_code_kvstring ){
+ cmd->value._buf = vg_msg_rstr( msg, &cmd->value_djb2 );
+ }
+ else if( cmd->code == k_vg_msg_code_kvbin ){
+ u32 len;
+ vg_msg_exchbuf( msg, 0, (u8 *)(&len), 4 );
+ if( msg->error != k_vg_msg_error_OK ) return 0;
+ cmd->value._buf = &msg->buf[ msg->cur ];
+ msg->cur += len;
+ if( msg->cur > msg->max ){
+ msg->error = k_vg_msg_error_overflow;
+ }
+ }
+ else{
+ msg->error = k_vg_msg_error_unhandled_cmd;
+ }
+ }
+ else{
+ msg->error = k_vg_msg_error_unhandled_cmd;
+ }
+
+ if( msg->error != k_vg_msg_error_OK ) return 0;
+ else return 1;
+}
+
+static int vg_msg_skip_frame( vg_msg *msg ){
+ vg_msg_cmd cmd;
+
+ u32 depth = msg->depth-1;
+ while( vg_msg_next( msg, &cmd ) ){
+ if( msg->depth == depth ) return 1;
+ }
+ return 0;
+}
+
+#endif /* VG_MSG_H */