From 413ef78504278d37080b9b59a652e4bbd5e2a0fc Mon Sep 17 00:00:00 2001 From: kasull Date: Sun, 1 Mar 2026 20:18:08 -0500 Subject: editor ui rework add responsive editor relayout for window resize rework header with back/save, view mode buttons, and 2d view type selector add clipped, scrollable assets and contextual tool panels simplify tool button wiring and repeated layout logic simplify 2d top-down editor internals and shared grid update hooks --- src/editor/view2d.cpp | 288 +++++++++++++++++++++++++++++++------------------- 1 file changed, 178 insertions(+), 110 deletions(-) (limited to 'src/editor/view2d.cpp') diff --git a/src/editor/view2d.cpp b/src/editor/view2d.cpp index 92988df..6814fd2 100644 --- a/src/editor/view2d.cpp +++ b/src/editor/view2d.cpp @@ -8,8 +8,43 @@ const I32 EDITORVIEW_TITLE_OFFSET = 15; const I32 EDITORVIEW_GUTTERS_OFFSETX = 22; const I32 EDITORVIEW_GUTTERS_OFFSETY = 16; const I32 EDITORVIEW_TOOLBAR_OFFSET = 20; +const I32 EDITOR_POLY_SIDES_RUNTIME_MAX = 256; VEC2 gui_editor_2dview_screen_to_world( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ); +VEC2 gui_editor_2dview_world_to_screen( GUI_EDITOR_2DVIEW* view, VEC2 world ); +F32 gui_editor_2dview_placement_z(); + +VEC3 gui_editor_2dview_plane_to_world3( VEC2 plane, F32 depth ) { + return { plane.x, plane.y, depth }; +} + +void gui_editor_2dview_set_plane( VEC3* v, VEC2 plane ) { + if( !v ) + return; + + v->x = plane.x; + v->y = plane.y; +} + +void gui_editor_2dview_add_plane_delta( VEC3* v, VEC2 delta ) { + if( !v ) + return; + + v->x += delta.x; + v->y += delta.y; +} + +void gui_editor_2dview_snap_plane( VEC3* v ) { + if( !v ) + return; + + v->x = m_snap_to_grid( v->x, editor->grid ); + v->y = m_snap_to_grid( v->y, editor->grid ); +} + +VEC2 gui_editor_2dview_world3_to_screen( GUI_EDITOR_2DVIEW* view, const VEC3& v ) { + return gui_editor_2dview_world_to_screen( view, { v.x, v.y } ); +} F32 gui_editor_2dview_ground_z() { WORLD_MAP* map = editor->map; @@ -177,9 +212,16 @@ void gui_editor_2dview_draw_gizmo( I32 x, I32 y, CLR clr, U8 selected = 0 ) { } I32 gui_editor_2dview_poly_sides() { - I32 sides = (I32)floorf( editor->tool.polysides + 0.5f ); + F32 raw = editor->tool.polysides; + if( !isfinite( raw ) ) + raw = EDITOR_DEFAULT_POLY_SIDES; + + if( raw > (F32)EDITOR_POLY_SIDES_RUNTIME_MAX ) + raw = (F32)EDITOR_POLY_SIDES_RUNTIME_MAX; + + I32 sides = (I32)floorf( raw + 0.5f ); if( sides < EDITOR_POLY_SIDES_MIN ) sides = EDITOR_POLY_SIDES_MIN; - if( sides > EDITOR_POLY_SIDES_MAX ) sides = EDITOR_POLY_SIDES_MAX; + if( sides > EDITOR_POLY_SIDES_RUNTIME_MAX ) sides = EDITOR_POLY_SIDES_RUNTIME_MAX; return sides; } @@ -199,7 +241,7 @@ U8 gui_editor_2dview_is_poly_drag_tool() { } I32 gui_editor_2dview_poly_points( VEC2 start, VEC2 end, I32 sides, U8 regular, VEC2* out_points ) { - if( !out_points || sides < EDITOR_POLY_SIDES_MIN || sides > EDITOR_POLY_SIDES_MAX ) + if( !out_points || sides < EDITOR_POLY_SIDES_MIN ) return 0; F32 minx = start.x < end.x ? start.x : end.x; @@ -246,7 +288,7 @@ struct EDITORVIEW_DRAG_RECT { struct EDITORVIEW_DRAG_SHAPE { EDITORVIEW_DRAG_RECT rect; - VEC2 points[EDITOR_POLY_SIDES_MAX]; + LIST points; I32 pointc; }; @@ -266,13 +308,14 @@ U8 gui_editor_2dview_build_drag_shape( GUI_EDITOR_2DVIEW* view, EDITORVIEW_DRAG_ return 0; I32 sides = gui_editor_2dview_poly_sides(); + out_shape->points.resize( sides ); U8 regular = gui_editor_2dview_poly_keep_regular( sides ); out_shape->pointc = gui_editor_2dview_poly_points( view->poly_start, view->poly_end, sides, regular, - out_shape->points + out_shape->points.data ); return out_shape->pointc >= 3; @@ -371,15 +414,16 @@ void gui_editor_2dview_create_poly_from_drag( GUI_EDITOR_2DVIEW* view ) { MAP_POLYGON newp{}; newp.propid = 0; newp.type = MPT_FLOOR; - F32 placez = gui_editor_2dview_placement_z(); + F32 depth = gui_editor_2dview_placement_z(); F32 invw = 1.f / shape.rect.w; F32 invh = 1.f / shape.rect.h; for( I32 i = 0; i < shape.pointc; ++i ) { VEC2 p = shape.points[i]; + VEC3 world = gui_editor_2dview_plane_to_world3( p, depth ); MAP_VERTEX v{}; - v.pos = { p.x, p.y, placez }; + v.pos = world; v.uv = { ( p.x - shape.rect.minx ) * invw, ( shape.rect.maxy - p.y ) * invh @@ -400,15 +444,18 @@ void gui_editor_2dview_create_wallpoly_from_drag( GUI_EDITOR_2DVIEW* view ) { I32 propid = gui_editor_2dview_find_or_create_wallpoly_propid(); - F32 basez = gui_editor_2dview_placement_z(); + F32 depth = gui_editor_2dview_placement_z(); F32 wallheight = gui_editor_2dview_wall_height(); for( I32 i = 0; i < shape.pointc; ++i ) { VEC2 p0 = shape.points[i]; VEC2 p1 = shape.points[(i + 1) % shape.pointc]; + VEC3 w0 = gui_editor_2dview_plane_to_world3( p0, depth ); + VEC3 w1 = gui_editor_2dview_plane_to_world3( p1, depth ); MAP_WALL wall{}; - wall.start = { p0.x, p0.y, basez }; - wall.end = { p1.x, p1.y, wallheight }; + wall.start = w0; + wall.end = w1; + wall.end.z = wallheight; wall.propid = propid; editor->map->walls.push( wall ); } @@ -420,6 +467,10 @@ void gui_editor_2dview_draw_gutters( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) { WORLD_MAP* m = editor->map; F32 w = view->w; F32 h = view->h; + F32 min_u = m->mins.x; + F32 max_u = m->maxs.x; + F32 min_v = m->mins.y; + F32 max_v = m->maxs.y; gui_draw_str( x + 2, y, ALIGN_L, FNT_JPN12, ui_clr.txt, "%1.f,%1.f", view->posx, view->posy ); for( U32 i = 1; i <= 5; ++i ) { @@ -428,7 +479,7 @@ void gui_editor_2dview_draw_gutters( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) { F32 tp = (tx - x) / w; - F32 scaledx = m->mins.x + (m->maxs.x - m->mins.x) * tp; + F32 scaledx = min_u + ( max_u - min_u ) * tp; if( w > h ) scaledx *= ( w / h ); scaledx /= view->scale; @@ -443,7 +494,7 @@ void gui_editor_2dview_draw_gutters( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) { F32 tp = (ty - y) / h; - F32 scaledy = m->mins.y + (m->maxs.y - m->mins.y) * tp; + F32 scaledy = min_v + ( max_v - min_v ) * tp; if( w < h ) scaledy *= h / w; scaledy /= view->scale; @@ -456,19 +507,19 @@ void gui_editor_2dview_draw_gutters( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) { void gui_editor_2dview_draw_polygons( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) { WORLD_MAP* m = editor->map; - F32 scale = gui_editor_2dview_calc_scale( view ); - F32 xoff = m->mins.x + view->posx; - F32 yoff = m->mins.y + view->posy; - m->polygons.each( fn( MAP_POLYGON* p ) { + SURF_PROPS fallback_props{ .tex = 0, .clr = CLR::WHITE() }; SURF_PROPS* props = polygon_get_props( m, p ); + if( !props ) + props = &fallback_props; if( !editor->wireframe ) { LIST vertices; p->vertices.each( fn( MAP_VERTEX* v ) { + VEC2 screen = gui_editor_2dview_world3_to_screen( view, v->pos ); VERTEX v2; v2.uv = v->uv; - v2.pos.x = x + (v->pos.x - xoff) * scale; - v2.pos.y = y + (v->pos.y - yoff) * scale; + v2.pos.x = screen.x; + v2.pos.y = screen.y; v2.clr = props->clr; vertices.push( v2 ); } ); @@ -482,11 +533,13 @@ void gui_editor_2dview_draw_polygons( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) { for( U32 i = 0; i < p->vertices.size; ++i ) { MAP_VERTEX* v1 = &p->vertices[i]; MAP_VERTEX* v2 = &p->vertices[(i+1) % p->vertices.size]; + VEC2 s0 = gui_editor_2dview_world3_to_screen( view, v1->pos ); + VEC2 s1 = gui_editor_2dview_world3_to_screen( view, v2->pos ); - I32 x0 = x + (I32)( (v1->pos.x - xoff) * scale ); - I32 y0 = y + (I32)( (v1->pos.y - yoff) * scale ); - I32 x1 = x + (I32)( (v2->pos.x - xoff) * scale ); - I32 y1 = y + (I32)( (v2->pos.y - yoff) * scale ); + I32 x0 = (I32)s0.x; + I32 y0 = (I32)s0.y; + I32 x1 = (I32)s1.x; + I32 y1 = (I32)s1.y; gui_draw_line( x0, y0, x1, y1, props->clr ); } @@ -496,8 +549,9 @@ void gui_editor_2dview_draw_polygons( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) { return; // draw gizmos p->vertices.each( fn( MAP_VERTEX* v ) { - I32 vx = (I32)( x + (v->pos.x - xoff) * scale ); - I32 vy = (I32)( y + (v->pos.y - yoff) * scale ); + VEC2 screen = gui_editor_2dview_world3_to_screen( view, v->pos ); + I32 vx = (I32)screen.x; + I32 vy = (I32)screen.y; U8 selected = gui_editor_2dview_is_gizmo_active( view, v, EDITOR_SELECT_PVERTEX ) || gui_editor_2dview_is_gizmo_active( view, p, EDITOR_SELECT_POLY ); @@ -509,17 +563,20 @@ void gui_editor_2dview_draw_polygons( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) { void gui_editor_2dview_draw_walls( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) { WORLD_MAP* m = editor->map; - F32 scale = gui_editor_2dview_calc_scale( view ); - F32 xoff = m->mins.x + view->posx; - F32 yoff = m->mins.y + view->posy; - m->walls.each( fn( MAP_WALL* s ) { + SURF_PROPS fallback_props{ .tex = 0, .clr = CLR::WHITE() }; SURF_PROPS* props = wall_get_props( m, s ); - - I32 x0 = (I32)( x + (s->start.x - xoff) * scale ); - I32 y0 = (I32)( y + (s->start.y - yoff) * scale ); - I32 x1 = (I32)( x + (s->end.x - xoff) * scale ); - I32 y1 = (I32)( y + (s->end.y - yoff) * scale ); + if( !props ) + props = &fallback_props; + VEC3 w0 = { s->start.x, s->start.y, s->start.z }; + VEC3 w1 = { s->end.x, s->end.y, s->end.z }; + VEC2 p0 = gui_editor_2dview_world3_to_screen( view, w0 ); + VEC2 p1 = gui_editor_2dview_world3_to_screen( view, w1 ); + + I32 x0 = (I32)p0.x; + I32 y0 = (I32)p0.y; + I32 x1 = (I32)p1.x; + I32 y1 = (I32)p1.y; gui_draw_line( x0, y0, x1, y1, props->clr ); if( gui_editor_2dview_is_gizmo_active( view, s, EDITOR_SELECT_WALL ) ) { @@ -535,10 +592,14 @@ void gui_editor_2dview_draw_walls( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) { // gizmos m->walls.each( fn( MAP_WALL* s ) { - I32 x0 = (I32)( x + (s->start.x - xoff) * scale ); - I32 y0 = (I32)( y + (s->start.y - yoff) * scale ); - I32 x1 = (I32)( x + (s->end.x - xoff) * scale ); - I32 y1 = (I32)( y + (s->end.y - yoff) * scale ); + VEC3 w0 = { s->start.x, s->start.y, s->start.z }; + VEC3 w1 = { s->end.x, s->end.y, s->end.z }; + VEC2 p0 = gui_editor_2dview_world3_to_screen( view, w0 ); + VEC2 p1 = gui_editor_2dview_world3_to_screen( view, w1 ); + I32 x0 = (I32)p0.x; + I32 y0 = (I32)p0.y; + I32 x1 = (I32)p1.x; + I32 y1 = (I32)p1.y; U8 sel = gui_editor_2dview_is_gizmo_active( view, s, EDITOR_SELECT_WALL ); U8 sel1 = gui_editor_2dview_is_gizmo_active( view, &s->start, EDITOR_SELECT_WVERTEX ); @@ -552,19 +613,12 @@ void gui_editor_2dview_draw_walls( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) { void gui_editor_2dview_draw_sprites( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) { WORLD_MAP* m = editor->map; - F32 scale = gui_editor_2dview_calc_scale( view ); - F32 xoff = m->mins.x + view->posx; - F32 yoff = m->mins.y + view->posy; - m->sprites.each( fn( MAP_SPRITE* s ) { F32 wantedsize = editor->spritesize; F32 aspect = s->size.x / s->size.y; F32 w = (aspect > 1.0f)? wantedsize : wantedsize * aspect; F32 h = (aspect < 1.0f)? wantedsize : wantedsize / aspect; - VEC2 pos = { - (F32)x + (s->pos.x - xoff) * scale, - (F32)y + (s->pos.y - yoff) * scale - }; + VEC2 pos = gui_editor_2dview_world3_to_screen( view, s->pos ); U8 sel= gui_editor_2dview_is_gizmo_active( view, s, EDITOR_SELECT_SPRITE ); if( sel ) { @@ -582,27 +636,18 @@ void gui_editor_2dview_draw_sprites( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) { } void gui_editor_2dview_draw_player( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) { - WORLD_MAP* m = editor->map; if( !objl->pl ) return; - F32 scale = gui_editor_2dview_calc_scale( view ); - F32 xoff = m->mins.x + view->posx; - F32 yoff = m->mins.y + view->posy; - VEC3 pos = objl->pl->pos; - - VEC2 pos2d = { - (F32)x + (pos.x - xoff) * scale, - (F32)y + (pos.y - yoff) * scale - }; + VEC2 pos2d = gui_editor_2dview_world3_to_screen( view, pos ); F32 yaw = objl->pl->rot.y; VEC2 dir = m_radial_offset( yaw, 20.f ); VEC2 ray = pos2d + dir; - gui_draw_line( (I32)pos2d.x, (I32)pos2d.y, (I32)ray.x, (I32)ray.y, CLR::GREEN() ); + gui_draw_frect( (I32)pos2d.x-4, (I32)pos2d.y-4, 8, 8, CLR::WHITE() ); gui_draw_frect( (I32)pos2d.x-3, (I32)pos2d.y-3, 6, 6, CLR::RED() ); } @@ -610,13 +655,10 @@ void gui_editor_2dview_draw_player( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) { void gui_editor_2dview_draw_origin( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) { WORLD_MAP* m = editor->map; - F32 scale = gui_editor_2dview_calc_scale( view ); - F32 xoff = m->mins.x + view->posx; - F32 yoff = m->mins.y + view->posy; - VEC3 pos = m->startpos; - I32 screenx = (I32)( x + (pos.x - xoff) * scale ); - I32 screeny = (I32)( y + (pos.y - yoff) * scale ); + VEC2 screen = gui_editor_2dview_world3_to_screen( view, pos ); + I32 screenx = (I32)screen.x; + I32 screeny = (I32)screen.y; if( gui_editor_2dview_is_gizmo_active( view, m, EDITOR_SELECT_ORIGIN ) ) { I32 w, h; @@ -758,15 +800,13 @@ void gui_editor_2dview_input_select_onmove( GUI_EDITOR_2DVIEW* view ) { void gui_editor_2dview_input_select_drag_wall( GUI_EDITOR_2DVIEW* view ) { MAP_WALL* s = (MAP_WALL*)view->curdrag; - s->start.x = m_snap_to_grid( s->start.x, editor->grid ); - s->start.y = m_snap_to_grid( s->start.y, editor->grid ); - s->end.x = m_snap_to_grid( s->end.x, editor->grid ); - s->end.y = m_snap_to_grid( s->end.y, editor->grid ); + gui_editor_2dview_snap_plane( &s->start ); + gui_editor_2dview_snap_plane( &s->end ); VEC2 mv = gui_editor_2dview_input_get_drag_vec( view ); if( !is_zero( mv ) ) { - s->start += mv; - s->end += mv; + gui_editor_2dview_add_plane_delta( &s->start, mv ); + gui_editor_2dview_add_plane_delta( &s->end, mv ); map_check_bounds( editor->map ); gui_editor_2dview_input_select_onmove( view ); @@ -774,13 +814,25 @@ void gui_editor_2dview_input_select_drag_wall( GUI_EDITOR_2DVIEW* view ) { } void gui_editor_2dview_input_select_drag_vertex( GUI_EDITOR_2DVIEW* view ) { - VEC2* v = (VEC2*)view->curdrag; - v->x = m_snap_to_grid( v->x, editor->grid ); - v->y = m_snap_to_grid( v->y, editor->grid ); + if( view->dragtype == EDITOR_SELECT_WVERTEX ) { + VEC3* v = (VEC3*)view->curdrag; + gui_editor_2dview_snap_plane( v ); + + VEC2 mv = gui_editor_2dview_input_get_drag_vec( view ); + if( !is_zero( mv ) ) { + gui_editor_2dview_add_plane_delta( v, mv ); + map_check_bounds( editor->map ); + gui_editor_2dview_input_select_onmove( view ); + } + return; + } + + MAP_VERTEX* v = (MAP_VERTEX*)view->curdrag; + gui_editor_2dview_snap_plane( &v->pos ); VEC2 mv = gui_editor_2dview_input_get_drag_vec( view ); if( !is_zero( mv ) ) { - *v += mv; + gui_editor_2dview_add_plane_delta( &v->pos, mv ); map_check_bounds( editor->map ); gui_editor_2dview_input_select_onmove( view ); @@ -793,11 +845,8 @@ void gui_editor_2dview_input_select_drag_polygon( GUI_EDITOR_2DVIEW* view ) { VEC2 mv = gui_editor_2dview_input_get_drag_vec( view ); if( !is_zero( mv ) ) { p->vertices.each( fn( MAP_VERTEX* v ) { - v->pos.x = m_snap_to_grid( v->pos.x, editor->grid ); - v->pos.y = m_snap_to_grid( v->pos.y, editor->grid ); - - v->pos.x += mv.x; - v->pos.y += mv.y; + gui_editor_2dview_snap_plane( &v->pos ); + gui_editor_2dview_add_plane_delta( &v->pos, mv ); } ); map_polygon_calc_bounds( p ); @@ -809,12 +858,11 @@ void gui_editor_2dview_input_select_drag_polygon( GUI_EDITOR_2DVIEW* view ) { void gui_editor_2dview_input_select_drag_sprite( GUI_EDITOR_2DVIEW* view ) { MAP_SPRITE* s = (MAP_SPRITE*)view->curdrag; - s->pos.x = m_snap_to_grid( s->pos.x, editor->grid ); - s->pos.y = m_snap_to_grid( s->pos.y, editor->grid ); + gui_editor_2dview_snap_plane( &s->pos ); VEC2 mv = gui_editor_2dview_input_get_drag_vec( view ); if( !is_zero( mv ) ) { - s->pos += mv; + gui_editor_2dview_add_plane_delta( &s->pos, mv ); gui_editor_2dview_input_select_onmove( view ); } } @@ -822,12 +870,11 @@ void gui_editor_2dview_input_select_drag_sprite( GUI_EDITOR_2DVIEW* view ) { void gui_editor_2dview_input_select_drag_origin( GUI_EDITOR_2DVIEW* view ) { WORLD_MAP* m = editor->map; - m->startpos.x = m_snap_to_grid( m->startpos.x, editor->grid ); - m->startpos.y = m_snap_to_grid( m->startpos.y, editor->grid ); + gui_editor_2dview_snap_plane( &m->startpos ); VEC2 mv = gui_editor_2dview_input_get_drag_vec( view ); if( !is_zero( mv ) ) { - m->startpos += mv; + gui_editor_2dview_add_plane_delta( &m->startpos, mv ); gui_editor_2dview_input_select_onmove( view ); } } @@ -890,10 +937,10 @@ void gui_editor_2dview_input_select_walls( GUI_EDITOR_2DVIEW* view ) { for( U32 i = 0; i < m->walls.size; ++i ) { MAP_WALL* w = &m->walls[i]; - VEC2 w1 = { w->start.x, w->start.y }; - VEC2 w2 = { w->end.x, w->end.y }; - w1 = gui_editor_2dview_world_to_screen( view, w1 ); - w2 = gui_editor_2dview_world_to_screen( view, w2 ); + VEC3 wp0 = { w->start.x, w->start.y, w->start.z }; + VEC3 wp1 = { w->end.x, w->end.y, w->end.z }; + VEC2 w1 = gui_editor_2dview_world3_to_screen( view, wp0 ); + VEC2 w2 = gui_editor_2dview_world3_to_screen( view, wp1 ); F32 d1 = vec_dist( mpos, w1 ); F32 d2 = vec_dist( mpos, w2 ); @@ -938,8 +985,7 @@ void gui_editor_2dview_input_select_polygons( GUI_EDITOR_2DVIEW* view ) { LIST plist; p->vertices.each( fn( MAP_VERTEX* v ) { - VEC2 world = { v->pos.x, v->pos.y }; - VEC2 screen = gui_editor_2dview_world_to_screen( view, world ); + VEC2 screen = gui_editor_2dview_world3_to_screen( view, v->pos ); F32 d = vec_dist( mpos, screen ); if( d < mindist ) { gui_editor_2dview_select( view, v, EDITOR_SELECT_PVERTEX ); @@ -975,8 +1021,7 @@ void gui_editor_2dview_input_select_sprites( GUI_EDITOR_2DVIEW* view ) { for( U32 i = 0; i < m->sprites.size; ++i ) { MAP_SPRITE* s = &m->sprites[i]; - VEC2 world = { s->pos.x, s->pos.y }; - VEC2 screen = gui_editor_2dview_world_to_screen( view, world ); + VEC2 screen = gui_editor_2dview_world3_to_screen( view, s->pos ); if( mpos.x >= screen.x - hsize && mpos.x <= screen.x + hsize && mpos.y >= screen.y - hsize && mpos.y <= screen.y + hsize ) @@ -1002,8 +1047,7 @@ void gui_editor_2dview_input_select_origin( GUI_EDITOR_2DVIEW* view ) { gui_cursor_pos( &mx, &my ); VEC2 mpos = { (F32)mx, (F32)my }; - VEC2 world = { m->startpos.x, m->startpos.y }; - VEC2 screen = gui_editor_2dview_world_to_screen( view, world ); + VEC2 screen = gui_editor_2dview_world3_to_screen( view, m->startpos ); I32 w, h; gui_draw_get_str_bounds( &w, &h, FNT_JPN12, "(origin)" ); @@ -1109,13 +1153,16 @@ void gui_editor_2dview_input_tool_wall( GUI_EDITOR_2DVIEW* view ) { VEC2 world = gui_editor_2dview_screen_to_world( view, mx, my ); if( !view->held ) { - F32 basez = gui_editor_2dview_placement_z(); + F32 depth = gui_editor_2dview_placement_z(); + VEC3 wp = gui_editor_2dview_plane_to_world3( world, depth ); MAP_WALL neww; neww.start = neww.end = { - m_snap_to_grid( world.x, editor->grid ), - m_snap_to_grid( world.y, editor->grid ), - basez + wp.x, + wp.y, + wp.z }; + gui_editor_2dview_snap_plane( &neww.start ); + gui_editor_2dview_snap_plane( &neww.end ); neww.end.z = gui_editor_2dview_wall_height(); neww.propid = 0; @@ -1133,8 +1180,8 @@ void gui_editor_2dview_input_tool_wall( GUI_EDITOR_2DVIEW* view ) { VEC3* end = (VEC3*)view->curdrag; if( end ) { - end->x = m_snap_to_grid( world.x, editor->grid ); - end->y = m_snap_to_grid( world.y, editor->grid ); + gui_editor_2dview_set_plane( end, world ); + gui_editor_2dview_snap_plane( end ); } } @@ -1180,13 +1227,15 @@ void gui_editor_2dview_input_tool_sprite( GUI_EDITOR_2DVIEW* view ) { VEC2 world = gui_editor_2dview_screen_to_world( view, mx, my ); if( !view->held ) { + VEC3 wpos = gui_editor_2dview_plane_to_world3( world, gui_editor_2dview_placement_z() ); MAP_SPRITE news; - news.pos = { world.x, world.y, 20.f }; + news.pos = wpos; + gui_editor_2dview_snap_plane( &news.pos ); news.size = { 20.f, 20.f }; news.clr = { 1.f, 1.f, 1.f, 1.f }; news.tex = 0; - I32 idx = editor->map->walls.size; + I32 idx = editor->map->sprites.size; editor->map->sprites.push( news ); view->curdrag = &editor->map->sprites[idx]; view->held = 1; @@ -1344,30 +1393,44 @@ void gui_editor_2dview_input_fn( void* ptr ) { } } +static U8 GRID_DEP_LABEL_TAG; +static U8 GRID_DEP_PROPVIEW_TAG; +static U8 GRID_DEP_TOOLVIEW_TAG; + void update_view_settings( GAME_EDITOR* e ) { GAME_EDITOR::EDITOR_GUI* egui = &e->gui; + if( !egui->gridlabel ) + return; sprintf( egui->gridlabel->name, "grid: %1.2f", e->grid ); } +void editor_grid_dependency_update_label( GAME_EDITOR* e ) { + update_view_settings( e ); +} + +void editor_grid_dependency_update_propview( GAME_EDITOR* e ) { + if( e->propgrid && e->gui.props ) + editor_update_properties_column( e ); +} + +void editor_grid_dependency_update_toolview( GAME_EDITOR* e ) { + if( e->gui.tool ) + gui_editor_toolview_update( e->gui.tool ); +} + void grid_increment_cb( void* ) { if( editor->grid < 16.f ) editor->grid *= 2.f; - update_view_settings( editor ); - - if( editor->propgrid ) - editor_update_properties_column( editor ); + editor_notify_grid_change( editor ); } void grid_decrement_cb( void* ) { if( editor->grid > 0.25f ) editor->grid *= 0.5f; - update_view_settings( editor ); - - if( editor->propgrid ) - editor_update_properties_column( editor ); + editor_notify_grid_change( editor ); } void grid_propgrid_cb( void* ) { - editor_update_properties_column( editor ); + editor_notify_grid_change( editor ); } void gui_editor_2dview_create_toolbar( GUI_EDITOR_2DVIEW* view ) { @@ -1375,6 +1438,9 @@ void gui_editor_2dview_create_toolbar( GUI_EDITOR_2DVIEW* view ) { I32 x = 150, y = view->h - 4; editor->gui.gridlabel = gui_label( x, y + 1, "grid: %1.2f", e->grid ); + editor_register_grid_dependency( e, &GRID_DEP_LABEL_TAG, editor_grid_dependency_update_label ); + editor_register_grid_dependency( e, &GRID_DEP_PROPVIEW_TAG, editor_grid_dependency_update_propview ); + editor_register_grid_dependency( e, &GRID_DEP_TOOLVIEW_TAG, editor_grid_dependency_update_toolview ); x += 70; gui_button( x, y, 18, 18, "+", grid_increment_cb ); gui_button( x + 23, y, 18, 18, "-", grid_decrement_cb ); @@ -1383,6 +1449,8 @@ void gui_editor_2dview_create_toolbar( GUI_EDITOR_2DVIEW* view ) { check->cb = grid_propgrid_cb; x += 120; gui_checkbox( x, y, "wireframe", &e->wireframe ); + + editor_notify_grid_change( e ); } GUI_EDITOR_2DVIEW* gui_editor_2dview( I32 x, I32 y, I32 w, I32 h ) { -- cgit v1.2.3