Users home drive & sort files using radix tree
authorhgn <hgodden00@gmail.com>
Thu, 20 Mar 2025 16:48:10 +0000 (16:48 +0000)
committerhgn <hgodden00@gmail.com>
Thu, 20 Mar 2025 16:48:10 +0000 (16:48 +0000)
.gitmodules
submodules/rax [new submodule]
vg_log.h
vg_msg.c
vg_string.h
vg_ui/filebrowser.c

index 13a708d7c528723f2d56ca1fe8c6f89ee240f74b..00137dc2be07ba5259b378ddf037a8ca2242be70 100644 (file)
@@ -10,3 +10,6 @@
 [submodule "submodules/SDL_GameControllerDB"]
        path = submodules/SDL_GameControllerDB
        url = https://github.com/gabomdq/SDL_GameControllerDB.git
+[submodule "submodules/rax"]
+       path = submodules/rax
+       url = https://github.com/antirez/rax.git
diff --git a/submodules/rax b/submodules/rax
new file mode 160000 (submodule)
index 0000000..1927550
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit 1927550cb218ec3c3dda8b39d82d1d019bf0476d
index 1af78722250c5cf6da7708fd60c7cb0abb5fbfd6..37e827ebf7c0d139b60140e17cbf0d9d063e747b 100644 (file)
--- a/vg_log.h
+++ b/vg_log.h
@@ -33,7 +33,7 @@
 #define PRINTF_v3f( V3 ) "%.4f %.4f %.4f\n",      V3[0], V3[1], V3[2]
 #define PRINTF_v4f( V4 ) "%.4f %.4f %.4f %.4f\n", V4[0], V4[1], V4[2], V4[3]
 
-#if VG_32
+#ifdef _WIN32
  #define PRINTF_U64 "%llu"
 #else
  #define PRINTF_U64 "%lu"
index facd66b1b9d9b8d5d7cef8d0dde162824e7907d5..7e1eee10a1cc7bb3cd4773369d9cc042bbb8c3d0 100644 (file)
--- a/vg_msg.c
+++ b/vg_msg.c
@@ -472,7 +472,7 @@ void vg_msg_print( vg_msg *msg, u32 len )
 
                if( base == k_vg_msg_unsigned ){
                   printf( 
-#ifdef VG_32
+#ifdef _WIN32
                   "%llu"
 #else
                   "%lu"
@@ -481,7 +481,7 @@ void vg_msg_print( vg_msg *msg, u32 len )
                }
                else if( base == k_vg_msg_signed ){
                   printf(
-#ifdef VG_32
+#ifdef _WIN32
                   "%lld"
 #else
                   "%ld"
index b8aa2098cc6bf21ecf75bf1f655ceb3780f5cd1a..767f40d127e2146abbd1dd305db2a3ebe60e4284 100644 (file)
@@ -59,8 +59,7 @@ enum strncpy_behaviour
    k_strncpy_overflow_fatal = 2
 };
 
-u32 vg_strncpy( const char *src, char *dst, u32 len,
-                enum strncpy_behaviour behaviour );
+u32 vg_strncpy( const char *src, char *dst, u32 len, enum strncpy_behaviour behaviour );
 u32 vg_strdjb2( const char *str );
 int vg_strdjb2_eq( const char *s1, u32 h1, const char *s2, u32 h2 );
 
index 94cc9e7febb5b334be4c6a8fe79af62ece1647a3..64fd295178979f00785812b1103bd53e4e0ac77f 100644 (file)
@@ -1,4 +1,11 @@
 #include "vg/vg_ui/filebrowser.h"
+#ifdef _WIN32
+#include <windows.h>
+#include <shlobj.h>
+#endif
+
+#include "vg/submodules/rax/rax.h"
+#include "vg/submodules/rax/rax.c"
 
 void vg_filebrowser_init( struct vg_filebrowser *browser )
 {
@@ -16,8 +23,25 @@ void vg_filebrowser_init( struct vg_filebrowser *browser )
 
 void vg_filebrowser_set_path_to_home( struct vg_filebrowser *browser )
 {
-   // TODO
-   strcpy( browser->current_path, "/home/harry" );
+#ifdef _WIN32
+   u16 *path = NULL;
+   if( SHGetKnownFolderPath( &FOLDERID_Documents, 0, NULL, &path ) == S_OK )
+   {
+      if( !WideCharToMultiByte( CP_UTF8, 0, path, -1, browser->current_path, sizeof(browser->current_path), NULL, NULL ) )
+      {
+         vg_error( "WideCharToMultiByte failed... defaulting to C:/\n" ); 
+         vg_strncpy( "C:/", browser->current_path, sizeof(browser->current_path), k_strncpy_always_add_null );
+      }
+   }
+   else
+   {
+      vg_error( "SHGetKnownFolderPath failed... defaulting to C:/\n" ); 
+      vg_strncpy( "C:/", browser->current_path, sizeof(browser->current_path), k_strncpy_always_add_null );
+   }
+   CoTaskMemFree( path );
+#else
+   vg_strncpy( getenv("HOME"), browser->current_path, sizeof(browser->current_path), k_strncpy_always_add_null );
+#endif
 }
 
 static bool vg_filebrowser_up( struct vg_filebrowser *browser )
@@ -322,10 +346,6 @@ void vg_filebrowser_populate( struct vg_filebrowser *browser )
    browser->view_top_index = 0;
    browser->slider_value = 0.0f;
 
-   struct vg_filebrowser_entry *folder_list_head = NULL,
-                               *folder_list_tail = NULL,
-                               *file_list_head = NULL;
-
    if( browser->open_result == k_dir_open_is_file )
    {
       if( vg_filebrowser_up( browser ) )
@@ -339,6 +359,9 @@ void vg_filebrowser_populate( struct vg_filebrowser *browser )
       return;
    }
 
+   rax *rt_files = raxNew(),
+       *rt_dirs = raxNew();
+
    while( vg_dir_next_entry( &dir ) )
    {
       enum vg_entry_type type = vg_dir_entry_type( &dir );
@@ -391,31 +414,56 @@ void vg_filebrowser_populate( struct vg_filebrowser *browser )
       u32 len = strlen( entry_name );
       struct vg_filebrowser_entry *entry = malloc( sizeof(struct vg_filebrowser_entry) + len + 1 );
       entry->next = NULL;
+      entry->prev = NULL;
       entry->type = type;
       entry->media_type = media_type;
       strcpy( entry->name, entry_name );
 
       if( type == k_vg_entry_type_dir )
       {
-         entry->prev = folder_list_head;
-         if( folder_list_head )
-            folder_list_head->next = entry;
-         else
-            folder_list_tail = entry;
-         folder_list_head = entry;
+         raxInsert( rt_dirs, (u8 *)entry->name, strlen(entry->name), entry, NULL );
       }
       else if( type == k_vg_entry_type_file )
       {
-         entry->prev = file_list_head;
-         if( file_list_head )
-            file_list_head->next = entry;
-         file_list_head = entry;
+         raxInsert( rt_files, (u8 *)entry->name, strlen(entry->name), entry, NULL );
       }
+      else 
+         continue;
 
       browser->entry_count ++;
    }
    vg_dir_close( &dir );
 
+   /* compile lists */
+   struct vg_filebrowser_entry *folder_list_head = NULL,
+                               *folder_list_tail = NULL,
+                               *file_list_head = NULL;
+   raxIterator rt_iter;
+   raxStart( &rt_iter, rt_files );
+   raxSeek( &rt_iter, "$", NULL, 0 );
+   while( raxPrev( &rt_iter ) )
+   {
+      struct vg_filebrowser_entry *entry = rt_iter.data;
+      entry->prev = file_list_head;
+      if( file_list_head )
+         file_list_head->next = entry;
+      file_list_head = entry;
+   }
+
+   raxStart( &rt_iter, rt_dirs );
+   raxSeek( &rt_iter, "$", NULL, 0 );
+   while( raxPrev( &rt_iter ) )
+   {
+      struct vg_filebrowser_entry *entry = rt_iter.data;
+      entry->prev = folder_list_head;
+      if( folder_list_head )
+         folder_list_head->next = entry;
+      else
+         folder_list_tail = entry;
+      folder_list_head = entry;
+   }
+
+   /* attatch the two lists */
    if( folder_list_head )
    {
       browser->whole_list = folder_list_head;
@@ -430,4 +478,7 @@ void vg_filebrowser_populate( struct vg_filebrowser *browser )
    }
 
    browser->view_top_entry = browser->whole_list;
+
+   raxFree( rt_files );
+   raxFree( rt_dirs );
 }