diff options
Diffstat (limited to 'src/editor/texturepicker.cpp')
| -rw-r--r-- | src/editor/texturepicker.cpp | 356 |
1 files changed, 356 insertions, 0 deletions
diff --git a/src/editor/texturepicker.cpp b/src/editor/texturepicker.cpp new file mode 100644 index 0000000..a24e955 --- /dev/null +++ b/src/editor/texturepicker.cpp @@ -0,0 +1,356 @@ +#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.gl2d_font, + { (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.gl2d->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.gl2d->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.gl2d->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.gl2d->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.gl2d->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; +} |
