+ ui_rect title;
+ ui_split( sidebar, k_ui_axis_h, 28, 0, title, sidebar );
+
+ if( workshop_form.page == k_workshop_form_edit ){
+ ui_text( title, "Editing", 1, k_ui_align_middle_center, 0 );
+ ui_split( sidebar, k_ui_axis_h, 28, 0, title, sidebar );
+
+ if( workshop_form.submission.type != k_workshop_file_type_none ){
+ char buf[512];
+ vg_str str;
+ vg_strnull( &str, buf, 512 );
+
+ if( workshop_form.submission.file_id )
+ vg_strcat( &str, "Editing an existing " );
+ else
+ vg_strcat( &str, "Creating a new " );
+
+ if( workshop_form.submission.type == k_workshop_file_type_board )
+ vg_strcat( &str, "skateboard." );
+ else if( workshop_form.submission.type == k_workshop_file_type_world )
+ vg_strcat( &str, "world." );
+ else
+ vg_strcat( &str, "???." );
+
+ ui_text( title, buf, 1, k_ui_align_middle_center,
+ ui_colour(k_ui_fg+4) );
+ }
+ return;
+ }
+
+ /*
+ * sidebar existing entries panel
+ */
+ ui_text( title, "Your submissions", 1, k_ui_align_middle_center, 0 );
+
+ ui_rect controls, btn_create_new;
+ ui_split( sidebar, k_ui_axis_h, 32, 0, controls, sidebar );
+ ui_split( sidebar, k_ui_axis_h, -32, 0, sidebar, btn_create_new );
+ ui_fill( controls, ui_colour( k_ui_bg+1 ) );
+
+ char buf[32];
+ strcpy( buf, "page " );
+ int i = 5;
+ i += highscore_intl( buf+i, workshop_form.view_published_page_id+1, 4 );
+ buf[ i ++ ] = '/';
+ i += highscore_intl( buf+i, workshop_form.view_published_page_count, 4 );
+ buf[ i ++ ] = '\0';
+
+ ui_rect_pad( controls, (ui_px[2]){0,4} );
+ ui_rect info;
+ ui_split_ratio( controls, k_ui_axis_v, 0.25f, 0, info, controls );
+ ui_text( info, buf, 1, k_ui_align_middle_center, 0 );
+
+ ui_rect btn_left, btn_right;
+ ui_split_ratio( controls, k_ui_axis_v, 0.5f, 2, btn_left, btn_right );
+
+ if( ui_button_text( btn_left, "newer", 1 ) ){
+ workshop_view_page( workshop_form.view_published_page_id-1 );
+ }
+
+ if( ui_button_text( btn_right, "older", 1 ) ){
+ workshop_view_page( workshop_form.view_published_page_count+1 );
+ }
+
+ if( ui_button_text( btn_create_new, "Create New Item", 1 ) ){
+ workshop_reset_submission_data();
+ workshop_form.submission.submit_title = 1;
+ workshop_form.submission.submit_description = 1;
+ workshop_form.submission.submit_file_and_image = 1;
+ workshop_form.page = k_workshop_form_edit;
+ workshop_find_preview_entity();
+ }
+
+ for( int i=0; i<workshop_form.published_files_list_length; i++ ){
+ ui_rect item;
+ ui_split( sidebar, k_ui_axis_h, 28, 0, item, sidebar );
+ ui_rect_pad( item, (ui_px[2]){4,4} );
+
+ struct published_file *pfile = &workshop_form.published_files_list[i];
+ if( ui_button_text( item, pfile->title, 1 ) ){
+ if( pfile->result == k_EResultOK ){
+ vg_info( "Select index: %d\n", pfile->result_index );
+ workshop_op_download_and_view_submission( pfile->result_index );
+ }
+ else{
+ vg_warn( "Cannot select that item, result not OK\n" );
+ }
+ }
+ }
+}
+
+VG_STATIC void workshop_form_gui(void)
+{
+ enum workshop_form_page stable_page = workshop_form.page;
+ if( stable_page == k_workshop_form_hidden ) return;
+
+ ui_rect null;
+ ui_rect screen = { 0, 0, vg.window_x, vg.window_y };
+ ui_rect window = { 0, 0, 1000, 700 };
+ ui_rect_center( screen, window );
+ vg_ui.wants_mouse = 1;
+
+ ui_fill( window, ui_colour( k_ui_bg+1 ) );
+ ui_outline( window, 1, ui_colour( k_ui_bg+7 ) );
+
+ ui_rect title, panel;
+ ui_split( window, k_ui_axis_h, 28, 0, title, panel );
+ ui_fill( title, ui_colour( k_ui_bg+7 ) );
+ ui_text( title, "Workshop tool", 1, k_ui_align_middle_center,
+ ui_colourcont(k_ui_bg+7) );
+
+ ui_rect quit_button;
+ ui_split( title, k_ui_axis_v, title[2]-title[3], 2, title, quit_button );
+
+ if( skaterift.async_op == k_async_op_none ){
+ if( ui_button_text( quit_button, "X", 1 ) ){
+ workshop_quit_form();
+ return;
+ }
+ }
+
+ /*
+ * temporary operation blinders, we don't yet have a nice way to show the
+ * user that we're doing something uninterruptable, so the code just
+ * escapes here and we show them a basic string
+ */
+
+ if( skaterift.async_op != k_async_op_none ){
+ const char *op_string = "The programmer has not bothered to describe "
+ "the current operation that is running.";
+
+ switch( skaterift.async_op ){
+ case k_workshop_form_op_loading_model:
+ op_string = "Operation in progress: Loading model file.";
+ break;
+ case k_workshop_form_op_publishing_update:
+ op_string = "Operation in progress: publishing submission update "
+ "to steam.";
+ break;
+ case k_workshop_form_op_downloading_submission:
+ op_string = "Operation in progress: downloading existing submission"
+ " from Steam services.";
+ break;
+ default: break;
+ }
+
+ ui_text( panel, op_string, 1, k_ui_align_middle_center, 0 );
+ return;
+ }
+
+ /* re draw board preview if need to */
+ if( (stable_page == k_workshop_form_edit) &&
+ workshop_form.view_changed &&
+ workshop_form.file_intent == k_workshop_form_file_intent_new )
+ {
+ workshop_render_preview();
+ workshop_form.view_changed = 0;
+ }
+
+ struct workshop_form *form = &workshop_form;
+
+ ui_rect sidebar, content;
+ ui_split_ratio( panel, k_ui_axis_v, 0.3f, 1, sidebar, content );
+
+ /* content page */
+ ui_rect_pad( content, (ui_px[2]){8,8} );
+
+ if( stable_page == k_workshop_form_edit ){
+ workshop_form_gui_edit_page( content );
+ }
+ else if( stable_page == k_workshop_form_open ){
+ ui_text( content, "Nothing selected.", 1, k_ui_align_middle_center,
+ ui_colour( k_ui_fg+4 ) );
+ }
+ else if( stable_page >= k_workshop_form_cclosing ){
+ ui_rect submission_row;
+ ui_split( content, k_ui_axis_h, content[3]-32-8, 0, content,
+ submission_row );
+
+ u32 colour;
+
+ if( stable_page == k_workshop_form_closing_bad )
+ colour = ui_colour( k_ui_red+k_ui_brighter );
+ else
+ colour = ui_colour( k_ui_green+k_ui_brighter );
+
+ ui_text( content, workshop_form.failure_or_success_string, 1,
+ k_ui_align_middle_center, colour );
+
+ ui_rect submission_center;
+ rect_copy( submission_row, submission_center );
+ submission_center[2] = 128;
+ ui_rect_center( submission_row, submission_center );
+ ui_rect_pad( submission_center, (ui_px[2]){8,8} );
+
+ if( ui_button_text( submission_center, "OK", 1 ) ){
+ workshop_form.page = k_workshop_form_open;
+ }
+ }
+
+ workshop_form_gui_sidebar( sidebar );
+}
+
+/*
+ * Some async api stuff
+ * -----------------------------------------------------------------------------
+ */
+
+VG_STATIC void async_workshop_get_filepath( void *data, u32 len )
+{
+ struct async_workshop_filepath_info *info = data;
+
+ u64 _size;
+ u32 _ts;
+
+ ISteamUGC *hSteamUGC = SteamAPI_SteamUGC();
+ if( !SteamAPI_ISteamUGC_GetItemInstallInfo( hSteamUGC, info->id, &_size,
+ info->buf, info->len, &_ts ))
+ {
+ vg_error( "GetItemInstallInfo failed\n" );
+ info->buf[0] = '\0';
+ }
+}
+
+VG_STATIC void async_workshop_get_installed_files( void *data, u32 len )
+{
+ struct async_workshop_installed_files_info *info = data;
+
+ ISteamUGC *hSteamUGC = SteamAPI_SteamUGC();
+ u32 count = SteamAPI_ISteamUGC_GetSubscribedItems( hSteamUGC, info->buffer,
+ *info->len );
+
+ vg_info( "Found %u subscribed items\n", count );
+
+ u32 j=0;
+ for( u32 i=0; i<count; i++ ){
+ u32 state = SteamAPI_ISteamUGC_GetItemState( hSteamUGC, info->buffer[i] );
+ if( state & k_EItemStateInstalled ){
+ info->buffer[j ++] = info->buffer[i];
+ }
+ }
+
+ *info->len = j;
+}
+
+#if 0
+VG_STATIC void vg_strsan_ascii( char *buf, u32 len )
+{
+ for( u32 i=0; i<len-1; i ++ ){
+ if( buf[i] == 0 ) return;
+
+ if( buf[i] < 32 || buf[i] > 126 ){
+ buf[i] = '?';
+ }
+ }
+ buf[len-1] = '\0';
+}
+
+#define VG_STRSAN_ASCII( X ) vg_strsan_ascii( X, vg_list_size(X) )
+
+VG_STATIC void workshop_load_metadata( const char *path,
+ struct workshop_file_info *info )
+{
+ FILE *fp = fopen( path, "rb" );
+
+ if( fp ){
+ if( fread( info, sizeof( struct workshop_file_info ), 1, fp ) ){
+ VG_STRSAN_ASCII( info->author_name );
+ VG_STRSAN_ASCII( info->title );
+ }
+ fclose( fp );
+ }
+}
+#endif