diff options
| author | aura <nw@moneybot.cc> | 2026-07-27 11:55:57 +0200 |
|---|---|---|
| committer | aura <nw@moneybot.cc> | 2026-07-27 11:55:57 +0200 |
| commit | 372f23024163e0fab57a847ddda41f06857efd7e (patch) | |
| tree | ca57dd38a583387a7bbcc970b7d359731df0f4bf /src/editor/view2d.cpp | |
| parent | 452e3619450ab9e7d22886445f61cc90272e4d60 (diff) | |
undo/redo props - WIP
Diffstat (limited to 'src/editor/view2d.cpp')
| -rw-r--r-- | src/editor/view2d.cpp | 180 |
1 files changed, 137 insertions, 43 deletions
diff --git a/src/editor/view2d.cpp b/src/editor/view2d.cpp index c4738dd..cca83d1 100644 --- a/src/editor/view2d.cpp +++ b/src/editor/view2d.cpp @@ -4,7 +4,6 @@ #include "../render/gl_2d.h" #include "../game/object.h" #include "../game/objlist.h" -#include "../game/world/bsp.h" const I32 EDITORVIEW_TITLE_OFFSET = 15; const I32 EDITORVIEW_GUTTERS_OFFSETX = 22; @@ -839,36 +838,9 @@ VEC2 gui_editor_2dview_input_get_drag_vec( GUI_EDITOR_2DVIEW* view ) { } U8 gui_editor_2dview_input_select_drag_obj( GUI_EDITOR_2DVIEW* view, void* obj, U8 seltype ); -U8 gui_editor_2dview_move_group( GUI_EDITOR_2DVIEW* view ) { - U8 update = 0; - if( view->dragtype == EDITOR_SELECT_WVERTEX || view->dragtype == EDITOR_SELECT_PVERTEX ) - return update; - - GUI_EDITOR_PROPVIEW* props = editor->gui.props; - // update all selected objects - for( auto& it : props->curselect ) { - if( it.obj == view->curdrag ) { - update = 1; - continue; - } +U8 gui_editor_2dview_drag_group( GUI_EDITOR_2DVIEW* view ); - // special case where a wall is selected but we are dragging one of its vertices - if( props->curselect.size == 1 && it.seltype == EDITOR_SELECT_WALL ) { - MAP_WALL* w = (MAP_WALL*)it.obj; - if( &w->start == view->curdrag || &w->end == view->curdrag ) { - update = 1; - continue; - } - } - - if( gui_editor_2dview_input_select_drag_obj( view, it.obj, it.seltype ) ) - update = 1; - } - - return update; -} - -void gui_editor_2dview_input_select_onmove( GUI_EDITOR_2DVIEW* view ) { +void gui_editor_2dview_input_select_onmove( GUI_EDITOR_2DVIEW* view, EDITOR_UNDO_PROPS* undo ) { I32 mx, my; gui_cursor_pos( &mx, &my ); @@ -883,7 +855,7 @@ void gui_editor_2dview_input_select_onmove( GUI_EDITOR_2DVIEW* view ) { GUI_EDITOR_PROPVIEW* props = editor->gui.props; U8 update = !is_zero( gui_editor_2dview_input_get_drag_vec( view ) ); if( update && gui_editor_propview_is_selected( props, view->curdrag, view->dragtype ) ) { - if( gui_editor_2dview_move_group( view ) ) + if( gui_editor_2dview_drag_group( view ) ) gui_editor_propview_update( props ); } @@ -894,45 +866,109 @@ void gui_editor_2dview_input_select_onmove( GUI_EDITOR_2DVIEW* view ) { view->dragmoved = 1; } -void gui_editor_2dview_input_select_drag_wall( GUI_EDITOR_2DVIEW* view, MAP_WALL* s ) { +void gui_editor_2dview_set_undo_prop( GUI_EDITOR_2DVIEW* view, EOBJECT* target, FNV1A hash, U32 size, void* oldv, void* newv = 0 ) { + if( !target ) + return; + + EDITOR_UNDO_PROPS::CHANGES* target_change = view->pending_undo_props.changes.where( + [&]( EDITOR_UNDO_PROPS::CHANGES* c ) { return c->obj == target; } + ); + + if( !target_change ) { + target_change = view->pending_undo_props.changes.push( { .obj = target } ); + } + + EDITOR_UNDO_PROPS::PROP_VALUE* target_prop = target_change->props.where( + [&]( EDITOR_UNDO_PROPS::PROP_VALUE* p ) { return p->hash == hash; } + ); + + if( !target_prop ) { + target_prop = target_change->props.push( { hash, size } ); + memcpy( target_prop->oldval.data, oldv, size ); + } + + if( target_prop->size != size ) { + return dlog( "gui_editor_2dview_set_undo_prop() : prop size mismatch" ); + } + + if( newv ) + memcpy( target_prop->newval.data, newv, size ); +} + +void gui_editor_2dview_input_select_drag_wall( + GUI_EDITOR_2DVIEW* view, + MAP_WALL* s +) { 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 ) ) { + VEC3 olds = s->start; + VEC3 olde = s->end; gui_editor_2dview_add_plane_delta( &s->start, mv ); gui_editor_2dview_add_plane_delta( &s->end, mv ); + + EDITOR_PROP* sprop = eprop_from_ptr( s, &s->start ); + EDITOR_PROP* eprop = eprop_from_ptr( s, &s->end ); + + gui_editor_2dview_set_undo_prop( view, s, sprop->hash, sprop->size, &olds, &s->start ); + gui_editor_2dview_set_undo_prop( view, s, eprop->hash, eprop->size, &olde, &s->end ); + map_check_bounds( editor->map ); } } -void gui_editor_2dview_input_select_drag_pos( GUI_EDITOR_2DVIEW* view, VEC3* v ) { +void gui_editor_2dview_input_select_drag_wallpos( + GUI_EDITOR_2DVIEW* view, + VEC3* v +) { gui_editor_2dview_snap_plane( v ); VEC2 mv = gui_editor_2dview_input_get_drag_vec( view ); if( !is_zero( mv ) ) { + VEC3 oldv = *v; gui_editor_2dview_add_plane_delta( v, mv ); map_check_bounds( editor->map ); + + // giga hack + EDITOR_PROP* p = (EDITOR_PROP*)( (U64)v + sizeof(VEC3) ); + MAP_WALL* s = (MAP_WALL*)( (U64)v - p->parentoff ); + gui_editor_2dview_set_undo_prop( view, s, p->hash, p->size, &oldv, v ); } } -void gui_editor_2dview_input_select_drag_vertex( GUI_EDITOR_2DVIEW* view, MAP_VERTEX* v ) { +void gui_editor_2dview_input_select_drag_vertex( + GUI_EDITOR_2DVIEW* view, + MAP_VERTEX* v +) { gui_editor_2dview_snap_plane( &v->pos ); VEC2 mv = gui_editor_2dview_input_get_drag_vec( view ); if( !is_zero( mv ) ) { + VEC3 oldv = v->pos; gui_editor_2dview_add_plane_delta( &v->pos, mv ); map_check_bounds( editor->map ); + + EDITOR_PROP* p = eprop_from_ptr( v, &v->pos ); + gui_editor_2dview_set_undo_prop( view, v, p->hash, p->size, &oldv, &v->pos ); } } -void gui_editor_2dview_input_select_drag_polygon( GUI_EDITOR_2DVIEW* view, MAP_POLYGON* p ) { +void gui_editor_2dview_input_select_drag_polygon( + GUI_EDITOR_2DVIEW* view, + MAP_POLYGON* p +) { VEC2 mv = gui_editor_2dview_input_get_drag_vec( view ); if( !is_zero( mv ) ) { p->vertices.each( fn( MAP_VERTEX* v ) { + VEC3 oldv = v->pos; gui_editor_2dview_snap_plane( &v->pos ); gui_editor_2dview_add_plane_delta( &v->pos, mv ); + + EDITOR_PROP* p = eprop_from_ptr( v, &v->pos ); + gui_editor_2dview_set_undo_prop( view, v, p->hash, p->size, &oldv, &v->pos ); } ); map_polygon_calc_bounds( p ); @@ -940,31 +976,51 @@ void gui_editor_2dview_input_select_drag_polygon( GUI_EDITOR_2DVIEW* view, MAP_P } } -void gui_editor_2dview_input_select_drag_sprite( GUI_EDITOR_2DVIEW* view, MAP_SPRITE* s ) { +void gui_editor_2dview_input_select_drag_sprite( + GUI_EDITOR_2DVIEW* view, + MAP_SPRITE* s +) { gui_editor_2dview_snap_plane( &s->pos ); VEC2 mv = gui_editor_2dview_input_get_drag_vec( view ); if( !is_zero( mv ) ) { + VEC3 oldv = s->pos; gui_editor_2dview_add_plane_delta( &s->pos, mv ); + + EDITOR_PROP* p = eprop_from_ptr( s, &s->pos ); + gui_editor_2dview_set_undo_prop( view, s, p->hash, p->size, &oldv, &s->pos ); } } - -void gui_editor_2dview_input_select_drag_entity( GUI_EDITOR_2DVIEW* view, MAP_ENTITY* e ) { +void gui_editor_2dview_input_select_drag_entity( + GUI_EDITOR_2DVIEW* view, + MAP_ENTITY* e +) { gui_editor_2dview_snap_plane( &e->pos ); VEC2 mv = gui_editor_2dview_input_get_drag_vec( view ); if( !is_zero( mv ) ) { + VEC3 oldv = e->pos; gui_editor_2dview_add_plane_delta( &e->pos, mv ); + + EDITOR_PROP* p = eprop_from_ptr( e, &e->pos ); + gui_editor_2dview_set_undo_prop( view, e, p->hash, p->size, &oldv, &e->pos ); } } -void gui_editor_2dview_input_select_drag_origin( GUI_EDITOR_2DVIEW* view, WORLD_MAP* m ) { +void gui_editor_2dview_input_select_drag_origin( + GUI_EDITOR_2DVIEW* view, + WORLD_MAP* m +) { gui_editor_2dview_snap_plane( &m->startpos ); VEC2 mv = gui_editor_2dview_input_get_drag_vec( view ); if( !is_zero( mv ) ) { + VEC3 oldv = m->startpos; gui_editor_2dview_add_plane_delta( &m->startpos, mv ); + + EDITOR_PROP* p = eprop_from_ptr( m, &m->startpos ); + gui_editor_2dview_set_undo_prop( view, m, p->hash, p->size, &oldv, &m->startpos ); } } @@ -980,7 +1036,7 @@ U8 gui_editor_2dview_input_select_drag_obj( GUI_EDITOR_2DVIEW* view, void* obj, case EDITOR_SELECT_SPRITE: gui_editor_2dview_input_select_drag_sprite( view, (MAP_SPRITE*)p ); return 1; case EDITOR_SELECT_ORIGIN: gui_editor_2dview_input_select_drag_origin( view, (WORLD_MAP*)p ); return 1; case EDITOR_SELECT_PVERTEX: gui_editor_2dview_input_select_drag_vertex( view, (MAP_VERTEX*)p ); return 1; - case EDITOR_SELECT_WVERTEX: gui_editor_2dview_input_select_drag_pos( view, (VEC3*)p ); return 1; + case EDITOR_SELECT_WVERTEX: gui_editor_2dview_input_select_drag_wallpos( view, (VEC3*)p ); return 1; } return 0; @@ -990,9 +1046,45 @@ void gui_editor_2dview_input_select_ondrop( GUI_EDITOR_2DVIEW* view ) { if( !view->dragmoved ) gui_editor_propview_select( editor->gui.props, view->curdrag, view->dragtype, !input.keys[SDL_SCANCODE_LCTRL] ); + if( view->pending_undo_props.changes.size ) { + EDITOR_UNDO_ACTION rec{ .type = EDITOR_UNDO_EDITPROPS, .props = view->pending_undo_props }; + editor->undo_actions.push( rec ); + view->pending_undo_props = {}; + } + view->curdrag = 0; } +U8 gui_editor_2dview_drag_group( GUI_EDITOR_2DVIEW* view ) { + U8 update = 0; + if( view->dragtype == EDITOR_SELECT_WVERTEX || view->dragtype == EDITOR_SELECT_PVERTEX ) + return update; + + GUI_EDITOR_PROPVIEW* props = editor->gui.props; + // update all selected objects + for( auto& it : props->curselect ) { + if( it.obj == view->curdrag ) { + update = 1; + continue; + } + + // special case where a wall is selected but we are dragging one of its vertices + if( props->curselect.size == 1 && it.seltype == EDITOR_SELECT_WALL ) { + MAP_WALL* w = (MAP_WALL*)it.obj; + if( &w->start == view->curdrag || &w->end == view->curdrag ) { + update = 1; + continue; + } + } + + if( gui_editor_2dview_input_select_drag_obj( view, it.obj, it.seltype ) ) { + update = 1; + } + } + + return update; +} + void gui_editor_2dview_input_select_drag( GUI_EDITOR_2DVIEW* view ) { U8 m1 = gui_mbutton_down( 0 ); I32 mx, my; @@ -1017,15 +1109,17 @@ void gui_editor_2dview_input_select_drag( GUI_EDITOR_2DVIEW* view ) { return; } + EDITOR_UNDO_ACTION rec{ .type = EDITOR_UNDO_EDITPROPS }; + EDITOR_UNDO_PROPS::CHANGES changes{ .obj = (EOBJECT*)view->curdrag }; if( !gui_editor_2dview_input_select_drag_obj( view, view->curdrag, view->dragtype ) ) { view->oldmx = mx; view->oldmy = my; return; } - VEC2 mv = gui_editor_2dview_input_get_drag_vec( view ); - if( !is_zero( mv ) ) { - gui_editor_2dview_input_select_onmove( view ); + if( !is_zero( gui_editor_2dview_input_get_drag_vec( view ) ) ) { + gui_editor_2dview_input_select_onmove( view, &rec.props ); + rec.props.changes.push( changes ); } } |
