#include "editor.h" #include "../util/string.h" const U32 TOOLVIEW_TITLE_OFFSET = 15; const I32 TOOLVIEW_INNER_X = 10; const I32 TOOLVIEW_INNER_PAD = 20; const I32 TOOLVIEW_ROW_HEIGHT = 20; const I32 TOOLVIEW_ROW_GAP = 4; const I32 TOOLVIEW_WALL_SHAPE_LIST_HEIGHT = 54; GUI_EDITOR_TOOLVIEW* gui_editor_toolview_from_item_child( GUI_BASE* child ) { if( !child || !child->parent || !child->parent->parent ) return 0; return (GUI_EDITOR_TOOLVIEW*)child->parent->parent; } void gui_editor_toolview_sanitize_float_input( void* ptr ) { GUI_FLOATINPUT* input = (GUI_FLOATINPUT*)ptr; F32* pval = input->pval; if( pval == &editor->tool.polysides ) { if( !isfinite( *pval ) ) *pval = EDITOR_DEFAULT_POLY_SIDES; F32 rounded = floorf( *pval + 0.5f ); if( rounded < EDITOR_POLY_SIDES_MIN ) rounded = EDITOR_POLY_SIDES_MIN; if( rounded > EDITOR_POLY_SIDES_MAX ) rounded = EDITOR_POLY_SIDES_MAX; *pval = rounded; return; } if( pval == &editor->tool.wallheight ) { if( !isfinite( *pval ) ) *pval = EDITOR_DEFAULT_WALL_HEIGHT; if( *pval < 1.f ) *pval = 1.f; return; } if( pval == &editor->tool.placementheight ) { if( !isfinite( *pval ) ) *pval = EDITOR_DEFAULT_PLACEMENT_HEIGHT; } } I32 gui_editor_toolview_create_float_input( GUI_EDITOR_TOOLVIEW* view, I32 y, const char* title, F32* pval, F32 min, F32 max, F32 step, const char* fmt ) { GUI_FLOATINPUT* input = gui_floatinput( TOOLVIEW_INNER_X, y, view->w - TOOLVIEW_INNER_PAD, title, pval, min, max, step, fmt ); input->cb = gui_editor_toolview_sanitize_float_input; if( input->cb ) input->cb( input ); return y + TOOLVIEW_ROW_HEIGHT + TOOLVIEW_ROW_GAP; } void gui_editor_toolview_queue_refresh( GUI_EDITOR_TOOLVIEW* view ) { if( !view ) return; gui_push_callback( view, pfn( void* ptr ) { gui_editor_toolview_update( (GUI_EDITOR_TOOLVIEW*)ptr ); } ); } void gui_editor_toolview_wallshape_dropdown_toggle_cb( void* ptr ) { GUI_BUTTON* btn = (GUI_BUTTON*)ptr; GUI_EDITOR_TOOLVIEW* view = gui_editor_toolview_from_item_child( btn ); if( !view ) return; view->wallshape_dropdown_open = !view->wallshape_dropdown_open; gui_editor_toolview_queue_refresh( view ); } void gui_editor_toolview_wallshape_select_cb( void* ptr ) { GUI_LIST* list = (GUI_LIST*)ptr; GUI_EDITOR_TOOLVIEW* view = gui_editor_toolview_from_item_child( list ); if( !view ) return; view->wallshape_dropdown_open = 0; gui_editor_toolview_queue_refresh( view ); } I32 gui_editor_toolview_create_wallshape_dropdown( GUI_EDITOR_TOOLVIEW* view, I32 y ) { static LIST shape_entries{}; if( !shape_entries.size ) { GUI_LIST_ENTRY line{}; line.val = EDITOR_WALLSHAPE_LINE; strcpy( line.title, "line" ); shape_entries.push( line ); GUI_LIST_ENTRY polygon{}; polygon.val = EDITOR_WALLSHAPE_POLYGON; strcpy( polygon.title, "polygon" ); shape_entries.push( polygon ); } const char* shape_name = editor->tool.wallshape == EDITOR_WALLSHAPE_POLYGON ? "polygon" : "line"; char dropdown_title[64]; sprintf( dropdown_title, "shape: %s v", shape_name ); gui_button( TOOLVIEW_INNER_X, y, view->w - TOOLVIEW_INNER_PAD, TOOLVIEW_ROW_HEIGHT, dropdown_title, gui_editor_toolview_wallshape_dropdown_toggle_cb ); y += TOOLVIEW_ROW_HEIGHT + TOOLVIEW_ROW_GAP; if( !view->wallshape_dropdown_open ) return y; GUI_LIST* shape = gui_list( TOOLVIEW_INNER_X, y, view->w - TOOLVIEW_INNER_PAD, TOOLVIEW_WALL_SHAPE_LIST_HEIGHT, "shape", &shape_entries, &editor->tool.wallshape ); shape->cb = gui_editor_toolview_wallshape_select_cb; y += TOOLVIEW_WALL_SHAPE_LIST_HEIGHT + TOOLVIEW_ROW_GAP; return y; } I32 gui_editor_toolview_create_poly_sides_input( GUI_EDITOR_TOOLVIEW* view, I32 y ) { return gui_editor_toolview_create_float_input( view, y, "sides", &editor->tool.polysides, (F32)EDITOR_POLY_SIDES_MIN, (F32)EDITOR_POLY_SIDES_MAX, 1.f, "%.0f" ); } I32 gui_editor_toolview_create_wall_height_input( GUI_EDITOR_TOOLVIEW* view, I32 y ) { return gui_editor_toolview_create_float_input( view, y, "wall height", &editor->tool.wallheight, 1.f, 1024.f, 1.f, "%.0f" ); } I32 gui_editor_toolview_create_placement_height_input( GUI_EDITOR_TOOLVIEW* view, I32 y ) { return gui_editor_toolview_create_float_input( view, y, "placement z", &editor->tool.placementheight, -4096.f, 4096.f, 1.f, "%.0f" ); } void gui_editor_toolview_get_title( GUI_EDITOR_TOOLVIEW* view, char* out ) { switch( editor->tool.type ) { case EDITOR_TOOL_ENT: memcpy( out, "tool: entity", 12 ); break; case EDITOR_TOOL_WALL: memcpy( out, "tool: wall", 10 ); break; case EDITOR_TOOL_POLY: memcpy( out, "tool: polygon", 14 ); break; case EDITOR_TOOL_SELECT: memcpy( out, "tool: select", 12 ); break; case EDITOR_TOOL_SPRITE: memcpy( out, "tool: sprite", 12 ); break; default: memcpy( out, "tool: none", 10 ); break; } } void gui_editor_toolview_update( GUI_EDITOR_TOOLVIEW* view ) { if( !view ) return; GUI_VIEW* oldview = gui_get_view(); gui_set_view( view->itemview ); gui_empty_children( view->itemview ); view->itemview->initheld = 1; I32 y = 10; if( editor->tool.type == EDITOR_TOOL_WALL ) { y = gui_editor_toolview_create_wallshape_dropdown( view, y ); if( view->wallshape_dropdown_open ) { gui_set_view( oldview ); return; } if( editor->tool.wallshape == EDITOR_WALLSHAPE_POLYGON ) { y = gui_editor_toolview_create_poly_sides_input( view, y ); } y = gui_editor_toolview_create_wall_height_input( view, y ); y = gui_editor_toolview_create_placement_height_input( view, y ); } else if( editor->tool.type == EDITOR_TOOL_POLY ) { y = gui_editor_toolview_create_poly_sides_input( view, y ); y = gui_editor_toolview_create_placement_height_input( view, y ); } gui_set_view( oldview ); } void gui_editor_toolview_draw_fn( void* ptr ) { if( !editor->map ) return; GUI_EDITOR_TOOLVIEW* view = (GUI_EDITOR_TOOLVIEW*)ptr; I32 x = gui_relx( view ); I32 y = gui_rely( view ); I32 w = view->w; I32 h = view->h; STR<64> title{}; gui_editor_toolview_get_title( view, title ); gui_draw_str( x, y, ALIGN_L, FNT_JPN12, ui_clr.txt, title ); y += TOOLVIEW_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_TOOLVIEW* gui_editor_toolview( I32 x, I32 y, I32 w, I32 h ) { if( !gui_check_target() ) return 0; GUI_EDITOR_TOOLVIEW* view = new GUI_EDITOR_TOOLVIEW; view->x = x; view->y = y; view->w = w; view->h = h; view->xbound = view->w; view->ybound = view->h + TOOLVIEW_TITLE_OFFSET; strcpy( view->name, "EDITOR_PROP_VIEW" ); view->draw_fn = gui_editor_toolview_draw_fn; view->input_fn = gui_base_input_fn; view->wallshape_dropdown_open = 0; GUI_VIEW* parent = gui_get_view(); parent->children.push( view ); view->parent = parent; gui_set_view( view ); view->itemview = gui_view( 0, TOOLVIEW_TITLE_OFFSET, w, h ); gui_set_view( parent ); return view; }