diff options
| author | navewindre <boneyaard@gmail.com> | 2025-09-03 20:10:09 +0200 |
|---|---|---|
| committer | navewindre <boneyaard@gmail.com> | 2025-09-03 20:10:09 +0200 |
| commit | f8b92ce3aa08b1445c9f956d8166830946562d12 (patch) | |
| tree | 94e63a5aec9f8f52b577f56799e0c9201fd976a5 /src/editor/properties.cpp | |
a
Diffstat (limited to 'src/editor/properties.cpp')
| -rw-r--r-- | src/editor/properties.cpp | 348 |
1 files changed, 348 insertions, 0 deletions
diff --git a/src/editor/properties.cpp b/src/editor/properties.cpp new file mode 100644 index 0000000..ebae177 --- /dev/null +++ b/src/editor/properties.cpp @@ -0,0 +1,348 @@ +#include "editor.h" +#include "../render/gl.h" +#include "../game/assets.h" + +const I32 PROPVIEW_TITLE_OFFSET = 15; + +void gui_editor_propview_select( GUI_EDITOR_PROPVIEW* view, void* what, U8 seltype ) { + if( !editor->map ) + return; + + if( seltype == EDITOR_SELECT_WVERTEX ) { + MAP_WALL* s = editor->map->walls.where( fn( MAP_WALL* s ) { + return ( &s->start == what || &s->end == what ); + } ); + + if( !s ) + return gui_editor_propview_select( view, editor->map, EDITOR_SELECT_ORIGIN ); + + view->curselect = s; + view->seltype = EDITOR_SELECT_WALL; + return gui_editor_propview_update( view ); + } + + view->curselect = what; + view->seltype = seltype; + gui_editor_propview_update( view ); +} + +// returns the subentry height +I32 gui_editor_propview_surfprops_subentry( I32 x, I32 y, I32* propid, SURF_PROPS* props ) { + I32 oldy = y; + I32 space = 20; + gui_label( x, y, "prop id: %d", *propid ); + GUI_BUTTON* newprop = gui_button( x + 235, y, 20, 20, "+", pfn( void* ptr ) { + GUI_BUTTON* btn = (GUI_BUTTON*)ptr; + SURF_PROPS props; + props.tex = 0; + props.clr = { 1.f, 1.f, 1.f, 1.f }; + + editor->map->props.push( props ); + *(U32*)(btn->extra) = editor->map->props.size - 1; + gui_editor_propview_update( editor->gui.props ); + } ); + newprop->extra = propid; + GUI_BUTTON* goprop = gui_button( x + 260, y, 20, 20, "\x1A", pfn( void* ptr ) { + GUI_BUTTON* btn = (GUI_BUTTON*)ptr; + gui_editor_propview_select( editor->gui.props, btn->extra, EDITOR_SELECT_SURFPROPS ); + } ); + goprop->extra = props; + + y += space; + + if( props->tex ) + gui_label( x + 10, y, "texture: %s", props->tex->name ); + else + gui_label( x + 10, y, "texture: none" ); + + GUI_BUTTON* btn = gui_button( x + 260, y, 20, 20, "\x1A", pfn( void* ptr ) { + GUI_BUTTON* btn = (GUI_BUTTON*)ptr; + GL_TEX2D** ptex = (GL_TEX2D**)btn->extra; + GUI_EDITOR_TEXTUREPICKER* picker = gui_editor_texturepicker( 200, 100, 400, 400, ptex ); + picker->cb = pfn( void* ) { gui_editor_propview_update( editor->gui.props ); }; + } ); + + btn->extra = &props->tex; + y += space; + gui_colorinput( x + 10, y, 270, "color", &props->clr ); y += (space+18); + + return y - oldy; +} + +void gui_editor_propview_create_wallprops( GUI_EDITOR_PROPVIEW* view ) { + MAP_WALL* s = (MAP_WALL*)view->curselect; + WORLD_MAP* m = editor->map; + SURF_PROPS* props = wall_get_props( m, s ); + + I32 x = 10, y = 10; + I32 space = 20; + F32 step = editor->propgrid? editor->grid : 0.25f; + + I32 wall_idx = m->walls.idx_where( fn( MAP_WALL* ms ) { + return s == ms; + } ); + + gui_label( x, y, "idx: %d", wall_idx ); y += space; + y += gui_editor_propview_surfprops_subentry( x, y, &s->propid, props ); + + GUI_VECTORINPUT* posinput; + posinput = gui_vectorinput( x, y, 280, "start", (F32*)&s->start, 3, -INFINITY, INFINITY, step ); y += (space+18); + posinput->cb = pfn( void* ) { map_check_bounds( editor->map ); }; + posinput = gui_vectorinput( x, y, 280, "end", (F32*)&s->end, 3, -INFINITY, INFINITY, step ); y += (space+18); + posinput->cb = pfn( void* ) { map_check_bounds( editor->map ); }; +} + +void gui_editor_propview_create_polyprops( GUI_EDITOR_PROPVIEW* view ) { + MAP_POLYGON* p = (MAP_POLYGON*)view->curselect; + WORLD_MAP* m = editor->map; + SURF_PROPS* props = polygon_get_props( m, p ); + + I32 x = 10, y = 10; + I32 space = 20; + + I32 poly_idx = m->polygons.idx_where( fn( MAP_POLYGON* mp ) { + return p == mp; + } ); + + gui_label( x, y, "idx: %d", poly_idx ); y += space; + y += gui_editor_propview_surfprops_subentry( x, y, &p->propid, props ); + + gui_label( x, y, "vertices: %d", p->vertices.size ); y += space; + I32 idx = 0; + p->vertices.each( fn( MAP_VERTEX* v ) { + gui_label( x + 10, y, "[%d] -> { %.02f, %.02f, %.02f }", idx, v->pos.x, v->pos.y, v->pos.z ); + GUI_BUTTON* btn = gui_button( x + 260, y - 2, 20, 20, "\x1A", pfn( void* ptr ) { + GUI_EDITOR_PROPVIEW* view = editor->gui.props; + GUI_BUTTON* btn = (GUI_BUTTON*)ptr; + MAP_POLYGON* p = (MAP_POLYGON*)view->curselect; + I64 idx = (I64)btn->extra; + if( p ) // p100 + gui_editor_propview_select( view, &p->vertices[idx], EDITOR_SELECT_PVERTEX ); + } ); + + y += space; + btn->extra = (void*)( (I64)idx++ ); + } ); + gui_label( x, y, "mins: { %1.02f, %1.02f, %1.02f }", p->mins.x, p->mins.y, p->mins.z ); y += space; + gui_label( x, y, "maxs: { %1.02f, %1.02f, %1.02f }", p->maxs.x, p->maxs.y, p->maxs.z ); y += space; +} + +void gui_editor_propview_create_mapprops( GUI_EDITOR_PROPVIEW* view ) { + WORLD_MAP* m = (WORLD_MAP*)view->curselect; + + I32 x = 10, y = 10; + I32 space = 20; + + F32 step = editor->propgrid? editor->grid : 0.25f; + + gui_label( x, y, "name: %s", m->name ); y += space; + gui_label( x, y, "walls: %d", m->walls.size ); y += space; + gui_label( x, y, "polygons: %d", m->polygons.size ); y += space; + gui_label( x, y, "props: %d", m->props.size ); y += space; + I32 i = 0; + m->props.each( fn( SURF_PROPS* p ) { + if( p->tex ) + gui_label( x + 10, y, "[%d] -> %s", i++, assets_abspath( p->tex->name ) ); + else + gui_label( x + 10, y, "[%d] -> { %.02f, %.02f, %.02f, %.02f }", i++, p->clr.r, p->clr.g, p->clr.b, p->clr.a ); + + GUI_BUTTON* btn = gui_button( x + 260, y, 20, 20, "\x1A", pfn( void* ptr ) { + GUI_BUTTON* btn = (GUI_BUTTON*)ptr; + gui_editor_propview_select( editor->gui.props, btn->extra, EDITOR_SELECT_SURFPROPS ); + } ); + btn->extra = p; + y += space; + } ); + gui_label( x, y, "sprites: %d", m->sprites.size ); y += space; + gui_label( x, y, "loaded textures: %d", m->textures.size ); y += space; + gui_vectorinput( x, y, 280, "spawn position", (F32*)&m->startpos, 3, -INFINITY, INFINITY, step ); y += (space+18); + GUI_FLOATINPUT* ang = gui_floatinput( x, y, 280, "spawn angle", &m->startang, -180.f, 180.f, 1.f ); y += (space+18); + ang->wraparound = 1; +} + +void gui_editor_propview_create_pvertexprops( GUI_EDITOR_PROPVIEW* view ) { + MAP_VERTEX* v = (MAP_VERTEX*)view->curselect; + WORLD_MAP* m = editor->map; + + I32 x = 10, y = 10; + I32 space = 20; + + I32 vert_idx = -1; + I32 poly_idx = m->polygons.idx_where( fn( MAP_POLYGON* p ) { + vert_idx = p->vertices.idx_where( fn( MAP_VERTEX* pv ) { return (pv == v); } ); + return vert_idx != -1; + } ); + + F32 step = editor->propgrid? editor->grid : 0.25f; + + gui_label( x, y, "idx: %d", vert_idx ); y += space; + gui_label( x, y, "polygon idx: %d", poly_idx ); + + gui_button( x + 260, y - 2, 20, 20, "\x1A", pfn( void* ) { + GUI_EDITOR_PROPVIEW* view = editor->gui.props; + MAP_VERTEX* v = (MAP_VERTEX*)view->curselect; + WORLD_MAP* m = editor->map; + MAP_POLYGON* polygon = m->polygons.where( fn( MAP_POLYGON* p ) { + I32 vert_idx = p->vertices.idx_where( fn( MAP_VERTEX* pv ) { return (pv == v); } ); + return vert_idx != -1; + } ); + + if( polygon ) + gui_editor_propview_select( view, polygon, EDITOR_SELECT_POLY ); + } ); + y += space; + + GUI_VECTORINPUT* posinput = gui_vectorinput( x, y, 280, "position", (F32*)&v->pos, 3, -INFINITY, INFINITY, step ); y += (space+18); + posinput->cb = pfn( void* ptr ) { map_check_bounds( editor->map ); }; + gui_vectorinput( x, y, 280, "texture coordinates", (F32*)&v->uv, 2, 0.f, 1.f, 0.005f, "xy", "%.03f" ); y += (space+18); + gui_colorinput( x, y, 280, "color", &v->clr ); y += (space+18); +} + +void gui_editor_propview_create_spriteprops( GUI_EDITOR_PROPVIEW* view ) { + MAP_SPRITE* s = (MAP_SPRITE*)view->curselect; + WORLD_MAP* m = editor->map; + + I32 x = 10, y = 10; + I32 space = 20; + + I32 sprite_idx = m->sprites.idx_where( fn( MAP_SPRITE* ms ) { + return ms == s; + } ); + + F32 step = editor->propgrid? editor->grid : 0.25f; + + gui_label( x, y, "idx: %d", sprite_idx ); y += space; + gui_vectorinput( x, y, 280, "position", (F32*)&s->pos, 3, -INFINITY, INFINITY, step ); y += (space+18); + gui_vectorinput( x, y, 280, "size", (F32*)&s->size, 2, 1.f, INFINITY, 1.f, "wh" ); y += (space+18); + gui_colorinput( x, y, 280, "color", &s->clr ); y += (space+18); + if( s->tex ) + gui_label( x, y, "texture: %s", s->tex->name ); + else + gui_label( x, y, "texture: none" ); + + GUI_BUTTON* btn = gui_button( x + 260, y, 20, 20, "\x1A", pfn( void* ptr ) { + GUI_BUTTON* btn = (GUI_BUTTON*)ptr; + GL_TEX2D** ptex = (GL_TEX2D**)btn->extra; + GUI_EDITOR_TEXTUREPICKER* picker = gui_editor_texturepicker( 200, 100, 400, 400, ptex ); + picker->cb = pfn( void* ) { gui_editor_propview_update( editor->gui.props ); }; + } ); + btn->extra = &s->tex; + y += space; +} + +void gui_editor_propview_create_surfprops( GUI_EDITOR_PROPVIEW* view ) { + SURF_PROPS* p = (SURF_PROPS*)view->curselect; + WORLD_MAP* m = editor->map; + + I32 x = 10, y = 10; + I32 space = 20; + + I32 i = m->props.idx_where( fn( SURF_PROPS* mp ) { return mp == p; } ); + if( i == -1 ) + return; + + gui_label( x, y, "prop id: %d", i ); y += space; + if( p->tex ) + gui_label( x, y, "texture: %s", assets_abspath( p->tex->name ) ); + else + gui_label( x, y, "texture: none" ); + GUI_BUTTON* btn = gui_button( x + 260, y, 20, 20, "\x1A", pfn( void* ptr ) { + GUI_BUTTON* btn = (GUI_BUTTON*)ptr; + GL_TEX2D** ptex = (GL_TEX2D**)btn->extra; + GUI_EDITOR_TEXTUREPICKER* picker = gui_editor_texturepicker( 200, 100, 400, 400, ptex ); + picker->cb = pfn( void* ) { gui_editor_propview_update( editor->gui.props ); }; + } ); + btn->extra = &p->tex; + y += space; + gui_colorinput( x, y, 280, "color", &p->clr ); y += (space+18); +} + +void gui_editor_propview_create_entprops( GUI_EDITOR_PROPVIEW* view ) { + +} + +void gui_editor_propview_update( GUI_EDITOR_PROPVIEW* view ) { + if( !editor->map ) return; + + GUI_VIEW* target = gui_get_view(); + defer({ if( target ) gui_set_view( target ); }); + + gui_empty_children( view->itemview ); + gui_set_view( view->itemview ); + view->itemview->initheld = 1; + + switch( view->seltype ) { + case EDITOR_SELECT_WALL: gui_editor_propview_create_wallprops( view ); break; + case EDITOR_SELECT_POLY: gui_editor_propview_create_polyprops( view ); break; + case EDITOR_SELECT_ORIGIN: gui_editor_propview_create_mapprops( view ); break; + case EDITOR_SELECT_ENT: gui_editor_propview_create_entprops( view ); break; + case EDITOR_SELECT_PVERTEX: gui_editor_propview_create_pvertexprops( view ); break; + case EDITOR_SELECT_SPRITE: gui_editor_propview_create_spriteprops( view ); break; + case EDITOR_SELECT_SURFPROPS: gui_editor_propview_create_surfprops( view ); break; + default: break; + } +} + +void gui_editor_propview_get_title( GUI_EDITOR_PROPVIEW* view, char* buf ) { + switch( view->seltype ) { + case EDITOR_SELECT_NONE: sprintf( buf, "properties: " ); break; + case EDITOR_SELECT_POLY: sprintf( buf, "polygon properties: " ); break; + case EDITOR_SELECT_ORIGIN: sprintf( buf, "map [%s] properties: ", editor->map->name ); break; + case EDITOR_SELECT_ENT: sprintf( buf, "entity properties: " ); break; + case EDITOR_SELECT_SPRITE: sprintf( buf, "sprite properties: " ); break; + case EDITOR_SELECT_PVERTEX: sprintf( buf, "vertex properties: " ); break; + case EDITOR_SELECT_SURFPROPS: sprintf( buf, "surface properties: " ); break; + case EDITOR_SELECT_WVERTEX: + case EDITOR_SELECT_WALL: sprintf( buf, "wall properties: " ); break; + } +} + +void gui_editor_propview_draw_fn( void* ptr ) { + if( !editor->map ) return; + + GUI_EDITOR_PROPVIEW* view = (GUI_EDITOR_PROPVIEW*)ptr; + + I32 x = gui_relx( view ); + I32 y = gui_rely( view ); + I32 w = view->w; + I32 h = view->h; + + char title[64]; + gui_editor_propview_get_title( view, title ); + gui_draw_str( x, y, ALIGN_L, FNT_JPN12, ui_clr.txt, title ); + y += PROPVIEW_TITLE_OFFSET; + + CLR col = gui_is_fg_window( view )? ui_clr.border : ui_clr.border_inactive; + gui_draw_frect( x, y, w, h, col ); + gui_draw_frect( x+1, y+1, w-2, h-2, ui_clr.bg_sec ); + + view->itemview->draw_fn( view->itemview ); +} + +GUI_EDITOR_PROPVIEW* gui_editor_propview( I32 x, I32 y, I32 w, I32 h ) { + if( !gui_check_target() ) return 0; + + GUI_EDITOR_PROPVIEW* view = new GUI_EDITOR_PROPVIEW; + view->x = x; + view->y = y; + view->w = w; + view->h = h; + view->xbound = view->w; + view->ybound = view->h + PROPVIEW_TITLE_OFFSET; + strcpy( view->name, "EDITOR_PROP_VIEW" ); + view->draw_fn = gui_editor_propview_draw_fn; + view->input_fn = gui_base_input_fn; + + view->curselect = 0; + view->seltype = 0; + + GUI_VIEW* parent = gui_get_view(); + parent->children.push( view ); + view->parent = parent; + + gui_set_view( view ); + view->itemview = gui_view( 0, PROPVIEW_TITLE_OFFSET, w, h ); + + gui_set_view( parent ); + return view; +} |
