#include "editor.h" #include "../game/assets.h" #include "../render/gl_2d.h" I32 TEXTUREVIEW_TOP_OFFSET = 20; I32 TEXTUREVIEW_BOTTOM_OFFSET = 28; const char* TEXTURE_EXTENSIONS[] = { "png", 0 }; I32 gui_editor_texturepicker_get_scrollheight( GUI_EDITOR_TEXTUREPICKER* wnd ) { return 0; } void gui_editor_texturepicker_handle_scroll( GUI_EDITOR_TEXTUREPICKER* wnd ) { I32 x = wnd->x; I32 y = wnd->y + TEXTUREVIEW_TOP_OFFSET; I32 w = wnd->w; I32 h = wnd->h - TEXTUREVIEW_TOP_OFFSET - TEXTUREVIEW_BOTTOM_OFFSET; I32 mx, my; gui_cursor_pos( &mx, &my ); U8 inbounds = mx >= x && mx <= x + w && my >= y && my <= y + h; if( !inbounds ) return; U8 scroll = gui_mbutton_down( GUI_MBTNSCROLL ); gui_capture_scroll(); if( scroll == 1 ) wnd->scrolloff -= 20; } void gui_editor_texturepicker_trim_texname( GUI_EDITOR_TEXTUREPICKER* wnd, char* trimname ) { I32 size = (wnd->w - 20) / wnd->rowcount - 10; I32 tw; while( 1 ) { gui_draw_get_str_bounds( &tw, 0, FNT_JPN12, trimname ); if( tw >= size ) { if( trimname[0] != '.' && trimname[1] != '.' && trimname[2] != '.' ) { sprintf( trimname, "...%s", trimname ); } for( U32 i = 3; !!trimname[i]; ++i ) trimname[i] = trimname[i + 1]; } else break; } } void gui_editor_texturepicker_draw_file_str( I32 x, I32 y, const char* str, U8 issel ) { if( !issel ) { return gui_draw_str( x, y, ALIGN_C, FNT_JPN12, ui_clr.txt, str ); } I32 w, h; gui_draw_get_str_bounds( &w, &h, FNT_JPN12, str ); w += 2; gui_draw_frect( x - w / 2, y + 1, w, h, ui_clr.border ); gui_draw_str( x, y, ALIGN_C, FNT_JPN12, ui_clr.bg_alt, str ); } void gui_editor_texturepicker_draw_files( GUI_EDITOR_TEXTUREPICKER* wnd ) { I32 x = wnd->x + 11; I32 y = wnd->y + TEXTUREVIEW_TOP_OFFSET; I32 w = wnd->w - 22; I32 size = (w + 10) / wnd->rowcount - 10; I32 colcnt = (I32)floorf( (F32)w / size ); CLR clr = gui_is_fg_window( wnd )? ui_clr.border : ui_clr.border_inactive; U32 i = 0; wnd->textures.each( fn( GL_TEX2D** ptr ) { GL_TEX2D* tex = *ptr; if( strlen( wnd->search ) > 0 && !strstr( tex->name, wnd->search ) ) return; I32 tx = x + (i % colcnt) * (size + 10); I32 ty = y + (i / colcnt) * (size + 18); gui_draw_frect( tx - 1, ty - 1, size + 2, size + 2, clr ); gui_draw_frect( tx, ty, size, size, clr ); gl_2d_textured_frect( _gui.batch, { (F32)tx, (F32)ty }, { (F32)size, (F32)size }, tex, CLR::WHITE() ); char trimname[256]; strcpy( trimname, assets_abspath( tex->name ) ); gui_editor_texturepicker_trim_texname( wnd, trimname ); gui_editor_texturepicker_draw_file_str( tx + size / 2, ty + size + 1, trimname, wnd->curselect == tex ); ++i; } ); } void gui_editor_texturepicker_draw_fn( void* ptr ) { GUI_EDITOR_TEXTUREPICKER* wnd = (GUI_EDITOR_TEXTUREPICKER*)ptr; CLR clr = gui_is_fg_window( wnd )? ui_clr.border : ui_clr.border_inactive; gui_draw_frect( wnd->x, wnd->y, wnd->w, wnd->h, clr ); gui_draw_frect( wnd->x + 1, wnd->y + 1, wnd->w - 2, wnd->h - 2, ui_clr.bg ); //gui_draw_str( wnd->x + 2, wnd->y + 2, ALIGN_LEFT, FNT_JPN12, ui_clr.txt, "texture list" ); gui_editor_texturepicker_draw_files( wnd ); if( !wnd->loaded ) { gui_draw_str( wnd->x + wnd->w - 2, wnd->y, ALIGN_R, FNT_JPN12, ui_clr.txt, "loading... [%d/%d]", wnd->curload + 1, wnd->files.size ); } wnd->children.each( fn( GUI_BASE** childptr ) { GUI_BASE* child = *childptr; if( !child->enabled ) return; if( child->draw_fn ) child->draw_fn( child ); } ); } void gui_editor_textureview_delete_textures( GUI_EDITOR_TEXTUREPICKER* wnd ) { wnd->textures.each( fn( GL_TEX2D** ptr ) { GL_TEX2D* tex = *ptr; gl_texture_destroy( _gui.batch->gl, tex ); } ); wnd->textures.clear(); } void gui_editor_texturepicker_load_texture( void* ptr ) { GUI_EDITOR_TEXTUREPICKER* wnd = (GUI_EDITOR_TEXTUREPICKER*)ptr; FILE_ENTRY* f = &wnd->files[wnd->curload]; const char* name = assets_abspath( f->name ); GL_TEX2D* tex = gl_texture_from_file( _gui.batch->gl, name ); if( !tex ) { dlog( "gui_editor_textureview_create_textures() : error creating texture %s", name ); return; } wnd->textures.push( tex ); if( ++wnd->curload < wnd->files.size ) gui_push_callback( wnd, gui_editor_texturepicker_load_texture ); else wnd->loaded = 1; } void gui_editor_textureview_create_textures( GUI_EDITOR_TEXTUREPICKER* wnd ) { wnd->curload = 0; GL_TEX2D* emptytex = gl_texture_create( _gui.batch->gl, "" ); strcpy( emptytex->name, "none" ); emptytex->width = emptytex->height = 1; wnd->textures.push( emptytex ); gui_push_callback( wnd, gui_editor_texturepicker_load_texture ); } void gui_editor_textureview_accept( GUI_EDITOR_TEXTUREPICKER* wnd ) { if( !wnd->curselect ) return; U8 isnone = !strcmp( wnd->curselect->name, "none" ); wnd->textures.each( fn( GL_TEX2D** ptr ) { GL_TEX2D* tex = *ptr; if( !isnone && tex == wnd->curselect ) return; gl_texture_destroy( _gui.batch->gl, tex ); } ); if( !isnone ) { if( map_add_texture_ref( editor->map, wnd->curselect ) == STAT_ALREADYEXISTS ) { const char* name = assets_abspath( wnd->curselect->name ); GL_TEX2D* tex = map_find_texture( editor->map, name ); *wnd->target = tex; gl_texture_destroy( _gui.batch->gl, wnd->curselect ); } else { *wnd->target = wnd->curselect; } } else { *wnd->target = 0; } if( wnd->cb ) wnd->cb( wnd ); wnd->textures.clear(); gui_push_callback( wnd, pfn( void* p ) { gui_free( (GUI_BASE*)p ); } ); } U8 gui_editor_texturepicker_input_files( GUI_EDITOR_TEXTUREPICKER* wnd ) { I32 x = wnd->x + 11; I32 y = wnd->y + TEXTUREVIEW_TOP_OFFSET; I32 w = wnd->w - 22; I32 size = (w + 10) / wnd->rowcount - 10; I32 colcnt = (I32)floorf( (F32)w / size ); I32 i = 0; U8 m1 = gui_mbutton_down( 0 ); I32 mx, my; gui_cursor_pos( &mx, &my ); wnd->textures.each( fn( GL_TEX2D** ptr ) { GL_TEX2D* tex = *ptr; // yea technically this is slow as fuck but whatever if( strlen( wnd->search ) > 0 && !strstr( tex->name, wnd->search ) ) return; I32 tx = x + (i % colcnt) * (size + 10); I32 ty = y + (i / colcnt) * (size + 18); U8 inbounds = ( (mx >= tx) && (mx < tx + size) && (my >= ty) && (my < ty + size + 18) ); if( inbounds && m1 && !wnd->heldselect ) { wnd->heldselect = tex; } if( !m1 && wnd->heldselect == tex ) { wnd->curselect = tex; } ++i; } ); if( !m1 ) { wnd->heldselect = 0; } return 0; } void gui_editor_texturepicker_input_fn( void* ptr ) { GUI_EDITOR_TEXTUREPICKER* wnd = (GUI_EDITOR_TEXTUREPICKER*)ptr; if( !gui_editor_texturepicker_input_files( wnd ) ) gui_base_input_fn( ptr ); } void gui_editor_texturepicker_update_density( GUI_EDITOR_TEXTUREPICKER* wnd ) { wnd->scrollheight = gui_editor_texturepicker_get_scrollheight( wnd ); sprintf( wnd->densitylabel->name, "density: %d", wnd->rowcount ); } void gui_editor_textureview_create_bottom_row( GUI_EDITOR_TEXTUREPICKER* wnd ) { I32 x = 10; gui_label( x, 2, "filter:" ); GUI_TEXTBOX* tb = gui_textbox( x + 50, -15, 92, 20, "", 256 ); tb->cb = pfn( void* ptr ) { GUI_TEXTBOX* tb = (GUI_TEXTBOX*)ptr; GUI_EDITOR_TEXTUREPICKER* wnd = (GUI_EDITOR_TEXTUREPICKER*)tb->parent->parent; strcpy( wnd->search, tb->value ); }; x += 150; wnd->densitylabel = gui_label( x, 2, "density: %d", wnd->rowcount ); gui_button( x + 66, 0, 20, 20, "+", pfn( void* ptr ) { GUI_BUTTON* btn = (GUI_BUTTON*)ptr; GUI_EDITOR_TEXTUREPICKER* wnd = (GUI_EDITOR_TEXTUREPICKER*)btn->parent->parent; if( wnd->rowcount < 9 ) wnd->rowcount++; gui_editor_texturepicker_update_density( wnd ); } ); gui_button( x + 91, 0, 20, 20, "-", pfn( void* ptr ) { GUI_BUTTON* btn = (GUI_BUTTON*)ptr; GUI_EDITOR_TEXTUREPICKER* wnd = (GUI_EDITOR_TEXTUREPICKER*)btn->parent->parent; if( wnd->rowcount > 3 ) wnd->rowcount--; gui_editor_texturepicker_update_density( wnd ); } ); gui_button( wnd->w - 120, 0, 50, 20, "cancel", pfn( void* ptr ) { GUI_BUTTON* btn = (GUI_BUTTON*)ptr; GUI_EDITOR_TEXTUREPICKER* wnd = (GUI_EDITOR_TEXTUREPICKER*)btn->parent->parent; gui_editor_textureview_delete_textures( wnd ); gui_push_callback( wnd, pfn( void* p ) { gui_free( (GUI_BASE*)p ); } ); } ); gui_button( wnd->w - 60, 0, 50, 20, "ok", pfn( void* ptr ) { GUI_BUTTON* btn = (GUI_BUTTON*)ptr; GUI_EDITOR_TEXTUREPICKER* wnd = (GUI_EDITOR_TEXTUREPICKER*)btn->parent->parent; gui_editor_textureview_accept( wnd ); } ); } void gui_editor_texturepicker_init( void* ptr ) { GUI_EDITOR_TEXTUREPICKER* wnd = (GUI_EDITOR_TEXTUREPICKER*)ptr; wnd->files = assets_get_files_by_ext( TEXTURE_EXTENSIONS ); gui_editor_textureview_create_textures( wnd ); } GUI_EDITOR_TEXTUREPICKER* gui_editor_texturepicker( I32 x, I32 y, I32 w, I32 h, GL_TEX2D **target ) { GUI_EDITOR_TEXTUREPICKER* wnd = new GUI_EDITOR_TEXTUREPICKER; wnd->x = x; wnd->y = y; wnd->w = w; wnd->h = h; wnd->ontop = 1; wnd->locked = 0; wnd->draw_fn = gui_editor_texturepicker_draw_fn; wnd->input_fn = gui_editor_texturepicker_input_fn; strcpy( wnd->name, "TEXTURE_PICKER_WINDOW" ); wnd->cb = 0; _gui.windows.push( wnd ); gui_set_window( wnd ); wnd->target = target; wnd->rowcount = 3; wnd->curselect = 0; wnd->scrolloff = 0; wnd->scrollheight = gui_editor_texturepicker_get_scrollheight( wnd ); wnd->search[0] = 0; wnd->loaded = 0; gui_push_callback( wnd, gui_editor_texturepicker_init ); GUI_VIEW* view = gui_get_view(); gui_set_view( 0 ); gui_view( 0, 0, w, 20 ); gui_title( "texture picker" ); gui_set_view( 0 ); gui_view( 0, h - TEXTUREVIEW_BOTTOM_OFFSET - 1, w, TEXTUREVIEW_BOTTOM_OFFSET ); gui_editor_textureview_create_bottom_row( wnd ); gui_set_view( view ); return wnd; }