Some IO ops and modal changes
authorhgn <hgodden00@gmail.com>
Sat, 22 Mar 2025 16:28:53 +0000 (16:28 +0000)
committerhgn <hgodden00@gmail.com>
Sat, 22 Mar 2025 16:28:53 +0000 (16:28 +0000)
12 files changed:
.gitmodules
submodules/hashmap.c [new submodule]
vg_array_file.c [new file with mode: 0644]
vg_engine.c
vg_io.c
vg_io.h
vg_mem.c
vg_mem.h
vg_msg.h
vg_tex.h
vg_ui/imgui.c
vg_ui/imgui.h

index 00137dc2be07ba5259b378ddf037a8ca2242be70..af460476150c0fcc67f2be18a0d33b08ee37b2fb 100644 (file)
@@ -13,3 +13,6 @@
 [submodule "submodules/rax"]
        path = submodules/rax
        url = https://github.com/antirez/rax.git
+[submodule "submodules/hashmap.c"]
+       path = submodules/hashmap.c
+       url = https://github.com/tidwall/hashmap.c.git
diff --git a/submodules/hashmap.c b/submodules/hashmap.c
new file mode 160000 (submodule)
index 0000000..1c13992
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit 1c139923fe08f36143ecc0ba37cd674684f87f9c
diff --git a/vg_array_file.c b/vg_array_file.c
new file mode 100644 (file)
index 0000000..e69de29
index 4a971f5612fd4c90f615d3e20be1e1162b631c93..6f595aae010607f0b13d5128bd0853c958bc3de3 100644 (file)
@@ -366,7 +366,7 @@ static void vg_changevsync(void)
                      "Vsync not supported on this system.\n\n"
                      "You may be overriding it in your"
                      " graphics \ncontrol panel.\n",
-                     UI_MODAL_BAD );
+                     NULL, UI_MODAL_BAD, NULL );
             }
             else
             {
@@ -374,7 +374,7 @@ static void vg_changevsync(void)
                      "Adaptive Vsync is not supported by your system\n\n"
                      "You may be overriding it in your"
                      " graphics \ncontrol panel.\n",
-                     UI_MODAL_BAD );
+                     NULL, UI_MODAL_BAD, NULL );
             }
 
             vg.vsync_feature = k_vsync_feature_error;
diff --git a/vg_io.c b/vg_io.c
index 206b815e56b9902a049569afae3093089a2aea03..a061d0fead02be726ac5ebdd6867eccb81021f0f 100644 (file)
--- a/vg_io.c
+++ b/vg_io.c
@@ -15,6 +15,27 @@ const char *dir_open_result_str[] =
    [k_dir_open_invalid_path] = "Invalid path"
 };
 
+bool vg_path_exists( const char *path )
+{
+#ifdef _WIN32
+   DWORD attributes = GetFileAttributes( path );
+   if( attributes == INVALID_FILE_ATTRIBUTES )
+      return 0;
+   return 1;
+#else
+   return access(path, F_OK) != -1;
+#endif
+}
+
+bool vg_make_directory( const char *path )
+{
+#ifdef _WIN32
+   return CreateDirectory( path, NULL )? 1:0;
+#else
+   return mkdir( path, S_IRWXU|S_IRWXG|S_IRWXO ) == 0;
+#endif
+}
+
 enum dir_open_result vg_dir_open( vg_dir *dir, const char *name )
 {
 #ifdef _WIN32
@@ -26,7 +47,11 @@ enum dir_open_result vg_dir_open( vg_dir *dir, const char *name )
    if( !vg_strgood(&q) ) 
       return k_dir_open_path_too_long;
 
-   if( !(GetFileAttributes( q.buffer ) & FILE_ATTRIBUTE_DIRECTORY) )
+   DWORD attributes = GetFileAttributes( q.buffer );
+   if( attributes == INVALID_FILE_ATTRIBUTES )
+      return k_dir_open_invalid_path;
+
+   if( !(attributes & FILE_ATTRIBUTE_DIRECTORY) )
       return k_dir_open_is_file;
 
    vg_info( "FindFirstFile( '%s' )\n", q.buffer );
diff --git a/vg_io.h b/vg_io.h
index 3c73de5c31ea6ce1d990c2e137002950f036ed3d..4f549b8d4c9ed0cf6c7e6ae1e7167ae2ec94071d 100644 (file)
--- a/vg_io.h
+++ b/vg_io.h
@@ -8,6 +8,8 @@
 typedef struct vg_dir vg_dir;
 #ifndef _WIN32
  #include <dirent.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
  struct vg_dir{
    DIR *h;
    struct dirent *data;
@@ -45,6 +47,9 @@ bool vg_dir_next_entry( vg_dir *dir );
 enum vg_entry_type vg_dir_entry_type( vg_dir *dir );
 void vg_dir_close( vg_dir *dir );
 
+bool vg_path_exists( const char *path );
+bool vg_make_directory( const char *path );
+
 /*
  * File I/O
  */
index 9451572f168ab129499cbeaf496fe876ff300170..63c422b5440067f661d420e8200344eedde50c2e 100644 (file)
--- a/vg_mem.c
+++ b/vg_mem.c
@@ -9,6 +9,12 @@
 
 struct vg_global_mem vg_mem;
 
+u32 vg_align16( u32 s )
+{
+   u32 m = (s + 15) >> 4;
+   return m << 4;
+}
+
 u32 vg_align8( u32 s )
 {
    u32 m = (s + 7) >> 3;
index 8d9441c8b3b07b1359880f2fb6aa802fc1fd4ef4..b5b036632b064a6dc9f92a66a36821b801736d9e 100644 (file)
--- a/vg_mem.h
+++ b/vg_mem.h
@@ -46,6 +46,7 @@ struct vg_linear_allocator
 };
 #pragma pack(pop)
 
+u32 vg_align16( u32 s );
 u32 vg_align8( u32 s );
 u32 vg_align4( u32 s );
 
index 0b1302418ef710f55fa11faa58787e30a0034e42..83d5105168652da59e06adc3366f2b86c19d642e 100644 (file)
--- a/vg_msg.h
+++ b/vg_msg.h
@@ -130,7 +130,6 @@ struct vg_msg
    u32 max;
    u8 *buf;
 
-   /* reading */
    struct vg_msg_cursor 
    {
       u32 co, depth;
@@ -168,8 +167,7 @@ void vg_msg_frame( vg_msg *msg, const char *name );
 void vg_msg_end_frame( vg_msg *msg );
 void vg_msg_wkvstr( vg_msg *msg, const char *key, const char *value );
 void vg_msg_wkvbin( vg_msg *msg, const char *key, u8 *bin, u32 len );
-void vg_msg_wkvnum( vg_msg *msg, const char *key,
-                    u8 type, u8 count, void *data );
+void vg_msg_wkvnum( vg_msg *msg, const char *key, u8 type, u8 count, void *data );
 u32 vg_msg_cmd_array_count( u8 code );
 u32 vg_msg_cmd_type_size( u8 code );
 u32 vg_msg_cmd_bytecount( u8 code );
index ea197b2ef68a692f0b34ddb493dda09995834553..b25780808efd936daa3df4d7d8da12926044118e 100644 (file)
--- a/vg_tex.h
+++ b/vg_tex.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2021-2024 Harry Godden (hgn) - All Rights Reserved 
+/* Copyright (C) 2021-2025 Harry Godden (hgn) - All Rights Reserved 
  *
  * A portion of this file is copied and altered from the QOI projects' source,
  * Originally written by Dominic Szablewski. It is slightly modified.
index cd758f607d2443557d124d630a8eb18d2fb8caa3..06a3eee2f38a172ea2a94002f793e8f1996a3e4d 100644 (file)
@@ -817,7 +817,7 @@ void ui_postrender( ui_context *ctx, f32 delta_time )
    {
       ui_rect screen = { 0,0, ctx->area[0], ctx->area[1] };
       ui_fill( ctx, screen, 0xa0000000 );
-      ui_rect box = {0,0,400,200};
+      ui_rect box = {0,0,416,216};
 
       u32 colour = ui_colour(ctx,k_ui_fg),
           type = ctx->modal.options & UI_MODAL_TYPE_BITS;
@@ -828,26 +828,48 @@ void ui_postrender( ui_context *ctx, f32 delta_time )
       ui_rect_center( screen, box );
       ui_fill( ctx, box, ui_colour(ctx,k_ui_bg) );
       ui_outline( ctx, box, -1, colour, 0 );
+      ui_rect_pad( box, (ui_px[]){8,8} );
 
       ui_rect message;
       rect_copy( box, message );
-      message[3] = 100;
+      message[3] = 150;
       ui_rect_center( box, message );
       
-      ui_rect row0, row1, btn;
-      ui_split_ratio( message, k_ui_axis_h, 0.76f, 0, row0, row1 );
+      ui_rect row0, row1;
+      ui_split( message, k_ui_axis_h, -28, 0, row0, row1 );
       row0[0] += ctx->font->sx;
-      ui_ntext( ctx, row0, ctx->modal.message, (box[2]/ctx->font->sx)-2, 1, 
-                k_ui_align_left, colour );
+      ui_ntext( ctx, row0, ctx->modal.message, (box[2]/ctx->font->sx)-2, 1, k_ui_align_left, colour );
+
+      ui_rect btn_ok;
+      ui_split( row1, k_ui_axis_v, -120, 8, row1, btn_ok );
 
-      rect_copy( row1, btn );
-      btn[2] = 86;
-      btn[3] = 28;
-      ui_rect_center( row1, btn );
-      
       ctx->focused_control_type = k_ui_control_none; /* HACK */
-      if( ui_button_text( ctx, btn, "OK", 1 ) != 1 )
+
+      bool close_modal = 0;
+      if( ctx->modal.options & UI_MODAL_CANCEL )
+      {
+         ui_rect btn_cancel;
+         ui_split( row1, k_ui_axis_v, -120, 8, row1, btn_cancel );
+         if( ui_button_text( ctx, btn_cancel, "Cancel", 1 ) == k_ui_button_click )
+         {
+            if( ctx->modal.callbacks.close )
+               ctx->modal.callbacks.close( UI_MODAL_CANCEL );
+
+            close_modal = 1;
+         }
+      }
+
+      if( ui_button_text( ctx, btn_ok, ctx->modal.ok_text, 1 ) == k_ui_button_click )
+      {
+         if( ctx->modal.callbacks.close )
+            ctx->modal.callbacks.close( 0 );
+
+         close_modal = 1;
+      }
+
+      if( !close_modal )
          ctx->focused_control_hit = 1;
+
       ctx->focused_control_type = k_ui_control_modal; /* HACK */
       ctx->wants_mouse = 1;
    }
@@ -1251,7 +1273,6 @@ static void _ui_textbox_change_callback( ui_context *ctx )
    }
 }
 
-void ui_start_modal( ui_context *ctx, const char *message, u32 options );
 void _ui_textbox_clipboard_paste( ui_context *ctx )
 {
    if( !ctx->have_clipboard_text() )
@@ -1265,9 +1286,9 @@ void _ui_textbox_clipboard_paste( ui_context *ctx )
    int datastart = _ui_textbox_delete_char( ctx, 0 );
        int length = strlen( text );
 
-   if( (ctx->textbox.len - strlen(ctx->textbuf)) < length ){
-      ui_start_modal( ctx, 
-                     "Clipboard content exceeds buffer size.", UI_MODAL_BAD );
+   if( (ctx->textbox.len - strlen(ctx->textbuf)) < length )
+   {
+      ui_start_modal( ctx, "Clipboard content exceeds buffer size.", NULL, UI_MODAL_BAD, NULL );
       return;
    }
 
@@ -1921,13 +1942,18 @@ void ui_tabs( ui_context *ctx, ui_rect inout_panel, ui_rect out_content_panel,
  * Modal UI
  * -----------------------------------------------------------------------------
  */
-void ui_start_modal( ui_context *ctx, const char *message, u32 options )
+void ui_start_modal( ui_context *ctx, const char *message, const char *ok_text,
+                                      u32 options, const struct ui_modal_callbacks *callbacks )
 {
    ctx->focused_control_type = k_ui_control_modal;
    ctx->modal.message = message;
-   ctx->modal.callbacks.close = NULL;
+   ctx->modal.ok_text = ok_text? ok_text: "OK";
+   if( callbacks )
+      ctx->modal.callbacks = *callbacks;
+   else
+      ctx->modal.callbacks.close = NULL;
+
    ctx->modal.options = options;
-   
    u32 type = options & UI_MODAL_TYPE_BITS;
    if(      type == UI_MODAL_OK )   vg_info( message );
    else if( type == UI_MODAL_WARN ) vg_warn( message );
index b64fd3d1c07826decdd347cd3a4748032cd02d86..8bea3b5282cf70911920dadd4771ff491aa7a507 100644 (file)
@@ -76,6 +76,7 @@ enum ui_scheme_colour
 #define UI_MODAL_BAD       0x2
 #define UI_MODAL_WARN      0x3
 #define UI_MODAL_TYPE_BITS 0x3
+#define UI_MODAL_CANCEL    0x8
 
 #define UI_MOUSE_LEFT 1
 #define UI_MOUSE_MIDDLE 2
@@ -169,7 +170,7 @@ struct ui_context
 
        struct ui_modal
    {
-               const char *message;
+               const char *message, *ok_text;
                u32 options;
                
                struct ui_modal_callbacks
@@ -341,7 +342,8 @@ enum ui_colour_type
 bool ui_colourpicker( ui_context *ctx, ui_rect inout_panel, const char *str_label, v4f value, enum ui_colour_type type );
 void _ui_textbox_move_cursor( ui_context *ctx, int *cursor0, int *cursor1, int dir, int snap_together );
 int _ui_textbox_delete_char( ui_context *ctx, int direction );
-void ui_start_modal( ui_context *ctx, const char *message, u32 options );
+void ui_start_modal( ui_context *ctx, const char *message, const char *ok_text,
+                                      u32 options, const struct ui_modal_callbacks *callbacks );
 
 void _ui_textbox_put_char( ui_context *ctx, char c );
 void _ui_textbox_left_select( ui_context *ctx );
@@ -369,8 +371,6 @@ void ui_tabs( ui_context *ctx, ui_rect inout_panel, ui_rect out_content_panel,
               const char **titles, u32 count, i32 *page );
 void ui_defocus_all( ui_context *ctx );
 
-void ui_start_modal( ui_context *ctx, const char *message, u32 options );
-
 void ui_proc_utf8( ui_context *ctx, const char *text );
 void ui_dev_colourview( ui_context *ctx );