2023-10-02 13:14:38 +00:00
# include "editor_actions.h"
# include <game/editor/mapitems/image.h>
CEditorBrushDrawAction : : CEditorBrushDrawAction ( CEditor * pEditor , int Group ) :
IEditorAction ( pEditor ) , m_Group ( Group )
{
auto & Map = pEditor - > m_Map ;
for ( size_t k = 0 ; k < Map . m_vpGroups [ Group ] - > m_vpLayers . size ( ) ; k + + )
{
auto pLayer = Map . m_vpGroups [ Group ] - > m_vpLayers [ k ] ;
if ( pLayer - > m_Type = = LAYERTYPE_TILES )
{
auto pLayerTiles = std : : static_pointer_cast < CLayerTiles > ( pLayer ) ;
if ( pLayer = = Map . m_pTeleLayer )
{
if ( ! Map . m_pTeleLayer - > m_History . empty ( ) )
{
m_TeleTileChanges = std : : map ( Map . m_pTeleLayer - > m_History ) ;
Map . m_pTeleLayer - > ClearHistory ( ) ;
}
}
else if ( pLayer = = Map . m_pTuneLayer )
{
if ( ! Map . m_pTuneLayer - > m_History . empty ( ) )
{
m_TuneTileChanges = std : : map ( Map . m_pTuneLayer - > m_History ) ;
Map . m_pTuneLayer - > ClearHistory ( ) ;
}
}
else if ( pLayer = = Map . m_pSwitchLayer )
{
if ( ! Map . m_pSwitchLayer - > m_History . empty ( ) )
{
m_SwitchTileChanges = std : : map ( Map . m_pSwitchLayer - > m_History ) ;
Map . m_pSwitchLayer - > ClearHistory ( ) ;
}
}
else if ( pLayer = = Map . m_pSpeedupLayer )
{
if ( ! Map . m_pSpeedupLayer - > m_History . empty ( ) )
{
m_SpeedupTileChanges = std : : map ( Map . m_pSpeedupLayer - > m_History ) ;
Map . m_pSpeedupLayer - > ClearHistory ( ) ;
}
}
if ( ! pLayerTiles - > m_TilesHistory . empty ( ) )
{
2023-12-14 20:22:45 +00:00
m_vTileChanges . emplace_back ( k , std : : map ( pLayerTiles - > m_TilesHistory ) ) ;
2023-10-02 13:14:38 +00:00
pLayerTiles - > ClearHistory ( ) ;
}
}
}
SetInfos ( ) ;
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Brush draw (x%d) on %d layers " , m_TotalTilesDrawn , m_TotalLayers ) ;
}
void CEditorBrushDrawAction : : SetInfos ( )
{
m_TotalTilesDrawn = 0 ;
m_TotalLayers = 0 ;
// Process normal tiles
for ( auto const & Pair : m_vTileChanges )
{
int Layer = Pair . first ;
std : : shared_ptr < CLayer > pLayer = m_pEditor - > m_Map . m_vpGroups [ m_Group ] - > m_vpLayers [ Layer ] ;
m_TotalLayers + + ;
if ( pLayer - > m_Type = = LAYERTYPE_TILES )
{
std : : shared_ptr < CLayerTiles > pLayerTiles = std : : static_pointer_cast < CLayerTiles > ( pLayer ) ;
auto Changes = Pair . second ;
for ( auto & Change : Changes )
{
m_TotalTilesDrawn + = Change . second . size ( ) ;
}
}
}
// Process speedup tiles
for ( auto const & SpeedupChange : m_SpeedupTileChanges )
{
m_TotalTilesDrawn + = SpeedupChange . second . size ( ) ;
}
// Process tele tiles
for ( auto const & TeleChange : m_TeleTileChanges )
{
m_TotalTilesDrawn + = TeleChange . second . size ( ) ;
}
// Process switch tiles
for ( auto const & SwitchChange : m_SwitchTileChanges )
{
m_TotalTilesDrawn + = SwitchChange . second . size ( ) ;
}
// Process tune tiles
for ( auto const & TuneChange : m_TuneTileChanges )
{
m_TotalTilesDrawn + = TuneChange . second . size ( ) ;
}
m_TotalLayers + = ! m_SpeedupTileChanges . empty ( ) ;
m_TotalLayers + = ! m_SwitchTileChanges . empty ( ) ;
m_TotalLayers + = ! m_TeleTileChanges . empty ( ) ;
m_TotalLayers + = ! m_TuneTileChanges . empty ( ) ;
}
bool CEditorBrushDrawAction : : IsEmpty ( )
{
return m_vTileChanges . empty ( ) & & m_SpeedupTileChanges . empty ( ) & & m_SwitchTileChanges . empty ( ) & & m_TeleTileChanges . empty ( ) & & m_TuneTileChanges . empty ( ) ;
}
void CEditorBrushDrawAction : : Undo ( )
{
Apply ( true ) ;
}
void CEditorBrushDrawAction : : Redo ( )
{
Apply ( false ) ;
}
void CEditorBrushDrawAction : : Apply ( bool Undo )
{
auto & Map = m_pEditor - > m_Map ;
// Process normal tiles
for ( auto const & Pair : m_vTileChanges )
{
int Layer = Pair . first ;
std : : shared_ptr < CLayer > pLayer = Map . m_vpGroups [ m_Group ] - > m_vpLayers [ Layer ] ;
if ( pLayer - > m_Type = = LAYERTYPE_TILES )
{
std : : shared_ptr < CLayerTiles > pLayerTiles = std : : static_pointer_cast < CLayerTiles > ( pLayer ) ;
auto Changes = Pair . second ;
for ( auto & Change : Changes )
{
int y = Change . first ;
auto Line = Change . second ;
for ( auto & Tile : Line )
{
int x = Tile . first ;
STileStateChange State = Tile . second ;
pLayerTiles - > SetTileIgnoreHistory ( x , y , Undo ? State . m_Previous : State . m_Current ) ;
}
}
}
}
// Process speedup tiles
for ( auto const & SpeedupChange : m_SpeedupTileChanges )
{
int y = SpeedupChange . first ;
auto Line = SpeedupChange . second ;
for ( auto & Tile : Line )
{
int x = Tile . first ;
int Index = y * Map . m_pSpeedupLayer - > m_Width + x ;
SSpeedupTileStateChange State = Tile . second ;
SSpeedupTileStateChange : : SData Data = Undo ? State . m_Previous : State . m_Current ;
Map . m_pSpeedupLayer - > m_pSpeedupTile [ Index ] . m_Force = Data . m_Force ;
Map . m_pSpeedupLayer - > m_pSpeedupTile [ Index ] . m_MaxSpeed = Data . m_MaxSpeed ;
Map . m_pSpeedupLayer - > m_pSpeedupTile [ Index ] . m_Angle = Data . m_Angle ;
Map . m_pSpeedupLayer - > m_pSpeedupTile [ Index ] . m_Type = Data . m_Type ;
Map . m_pSpeedupLayer - > m_pTiles [ Index ] . m_Index = Data . m_Index ;
}
}
// Process tele tiles
for ( auto const & TeleChange : m_TeleTileChanges )
{
int y = TeleChange . first ;
auto Line = TeleChange . second ;
for ( auto & Tile : Line )
{
int x = Tile . first ;
int Index = y * Map . m_pTeleLayer - > m_Width + x ;
STeleTileStateChange State = Tile . second ;
STeleTileStateChange : : SData Data = Undo ? State . m_Previous : State . m_Current ;
Map . m_pTeleLayer - > m_pTeleTile [ Index ] . m_Number = Data . m_Number ;
Map . m_pTeleLayer - > m_pTeleTile [ Index ] . m_Type = Data . m_Type ;
Map . m_pTeleLayer - > m_pTiles [ Index ] . m_Index = Data . m_Index ;
}
}
// Process switch tiles
for ( auto const & SwitchChange : m_SwitchTileChanges )
{
int y = SwitchChange . first ;
auto Line = SwitchChange . second ;
for ( auto & Tile : Line )
{
int x = Tile . first ;
int Index = y * Map . m_pSwitchLayer - > m_Width + x ;
SSwitchTileStateChange State = Tile . second ;
SSwitchTileStateChange : : SData Data = Undo ? State . m_Previous : State . m_Current ;
Map . m_pSwitchLayer - > m_pSwitchTile [ Index ] . m_Number = Data . m_Number ;
Map . m_pSwitchLayer - > m_pSwitchTile [ Index ] . m_Type = Data . m_Type ;
Map . m_pSwitchLayer - > m_pSwitchTile [ Index ] . m_Flags = Data . m_Flags ;
Map . m_pSwitchLayer - > m_pSwitchTile [ Index ] . m_Delay = Data . m_Delay ;
Map . m_pSwitchLayer - > m_pTiles [ Index ] . m_Index = Data . m_Index ;
}
}
// Process tune tiles
for ( auto const & TuneChange : m_TuneTileChanges )
{
int y = TuneChange . first ;
auto Line = TuneChange . second ;
for ( auto & Tile : Line )
{
int x = Tile . first ;
int Index = y * Map . m_pTuneLayer - > m_Width + x ;
STuneTileStateChange State = Tile . second ;
STuneTileStateChange : : SData Data = Undo ? State . m_Previous : State . m_Current ;
Map . m_pTuneLayer - > m_pTuneTile [ Index ] . m_Number = Data . m_Number ;
Map . m_pTuneLayer - > m_pTuneTile [ Index ] . m_Type = Data . m_Type ;
Map . m_pTuneLayer - > m_pTiles [ Index ] . m_Index = Data . m_Index ;
}
}
}
// -------------------------------------------
CEditorActionQuadPlace : : CEditorActionQuadPlace ( CEditor * pEditor , int GroupIndex , int LayerIndex , std : : vector < CQuad > & vBrush ) :
CEditorActionLayerBase ( pEditor , GroupIndex , LayerIndex ) , m_vBrush ( vBrush )
{
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Quad place (x%d) " , ( int ) m_vBrush . size ( ) ) ;
}
void CEditorActionQuadPlace : : Undo ( )
{
std : : shared_ptr < CLayerQuads > pLayerQuads = std : : static_pointer_cast < CLayerQuads > ( m_pLayer ) ;
for ( size_t k = 0 ; k < m_vBrush . size ( ) ; k + + )
pLayerQuads - > m_vQuads . pop_back ( ) ;
m_pEditor - > m_Map . OnModify ( ) ;
}
void CEditorActionQuadPlace : : Redo ( )
{
std : : shared_ptr < CLayerQuads > pLayerQuads = std : : static_pointer_cast < CLayerQuads > ( m_pLayer ) ;
for ( auto & Brush : m_vBrush )
pLayerQuads - > m_vQuads . push_back ( Brush ) ;
m_pEditor - > m_Map . OnModify ( ) ;
}
CEditorActionSoundPlace : : CEditorActionSoundPlace ( CEditor * pEditor , int GroupIndex , int LayerIndex , std : : vector < CSoundSource > & vBrush ) :
CEditorActionLayerBase ( pEditor , GroupIndex , LayerIndex ) , m_vBrush ( vBrush )
{
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Sound place (x%d) " , ( int ) m_vBrush . size ( ) ) ;
}
void CEditorActionSoundPlace : : Undo ( )
{
std : : shared_ptr < CLayerSounds > pLayerSounds = std : : static_pointer_cast < CLayerSounds > ( m_pLayer ) ;
for ( size_t k = 0 ; k < m_vBrush . size ( ) ; k + + )
pLayerSounds - > m_vSources . pop_back ( ) ;
m_pEditor - > m_Map . OnModify ( ) ;
}
void CEditorActionSoundPlace : : Redo ( )
{
std : : shared_ptr < CLayerSounds > pLayerSounds = std : : static_pointer_cast < CLayerSounds > ( m_pLayer ) ;
for ( auto & Brush : m_vBrush )
pLayerSounds - > m_vSources . push_back ( Brush ) ;
m_pEditor - > m_Map . OnModify ( ) ;
}
// ---------------------------------------------------------------------------------------
CEditorActionDeleteQuad : : CEditorActionDeleteQuad ( CEditor * pEditor , int GroupIndex , int LayerIndex , std : : vector < int > const & vQuadsIndices , std : : vector < CQuad > const & vDeletedQuads ) :
CEditorActionLayerBase ( pEditor , GroupIndex , LayerIndex ) , m_vQuadsIndices ( vQuadsIndices ) , m_vDeletedQuads ( vDeletedQuads )
{
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Delete quad (x%d) " , ( int ) m_vDeletedQuads . size ( ) ) ;
}
void CEditorActionDeleteQuad : : Undo ( )
{
std : : shared_ptr < CLayerQuads > pLayerQuads = std : : static_pointer_cast < CLayerQuads > ( m_pLayer ) ;
for ( size_t k = 0 ; k < m_vQuadsIndices . size ( ) ; k + + )
{
pLayerQuads - > m_vQuads . insert ( pLayerQuads - > m_vQuads . begin ( ) + m_vQuadsIndices [ k ] , m_vDeletedQuads [ k ] ) ;
}
}
void CEditorActionDeleteQuad : : Redo ( )
{
std : : shared_ptr < CLayerQuads > pLayerQuads = std : : static_pointer_cast < CLayerQuads > ( m_pLayer ) ;
std : : vector < int > vQuads ( m_vQuadsIndices ) ;
for ( int i = 0 ; i < ( int ) vQuads . size ( ) ; + + i )
{
pLayerQuads - > m_vQuads . erase ( pLayerQuads - > m_vQuads . begin ( ) + vQuads [ i ] ) ;
for ( int j = i + 1 ; j < ( int ) vQuads . size ( ) ; + + j )
if ( vQuads [ j ] > vQuads [ i ] )
vQuads [ j ] - - ;
vQuads . erase ( vQuads . begin ( ) + i ) ;
i - - ;
}
}
// ---------------------------------------------------------------------------------------
CEditorActionEditQuadPoint : : CEditorActionEditQuadPoint ( CEditor * pEditor , int GroupIndex , int LayerIndex , int QuadIndex , std : : vector < CPoint > const & vPreviousPoints , std : : vector < CPoint > const & vCurrentPoints ) :
CEditorActionLayerBase ( pEditor , GroupIndex , LayerIndex ) , m_QuadIndex ( QuadIndex ) , m_vPreviousPoints ( vPreviousPoints ) , m_vCurrentPoints ( vCurrentPoints )
{
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Edit quad points " ) ;
}
void CEditorActionEditQuadPoint : : Undo ( )
{
std : : shared_ptr < CLayerQuads > pLayerQuads = std : : static_pointer_cast < CLayerQuads > ( m_pLayer ) ;
CQuad & Quad = pLayerQuads - > m_vQuads [ m_QuadIndex ] ;
for ( int k = 0 ; k < 5 ; k + + )
Quad . m_aPoints [ k ] = m_vPreviousPoints [ k ] ;
}
void CEditorActionEditQuadPoint : : Redo ( )
{
std : : shared_ptr < CLayerQuads > pLayerQuads = std : : static_pointer_cast < CLayerQuads > ( m_pLayer ) ;
CQuad & Quad = pLayerQuads - > m_vQuads [ m_QuadIndex ] ;
for ( int k = 0 ; k < 5 ; k + + )
Quad . m_aPoints [ k ] = m_vCurrentPoints [ k ] ;
}
CEditorActionEditQuadProp : : CEditorActionEditQuadProp ( CEditor * pEditor , int GroupIndex , int LayerIndex , int QuadIndex , EQuadProp Prop , int Previous , int Current ) :
CEditorActionLayerBase ( pEditor , GroupIndex , LayerIndex ) , m_QuadIndex ( QuadIndex ) , m_Prop ( Prop ) , m_Previous ( Previous ) , m_Current ( Current )
{
static const char * s_apNames [ ] = {
" order " ,
" pos X " ,
" pos Y " ,
" pos env " ,
" pos env offset " ,
" color env " ,
" color env offset " } ;
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Edit quad %s property in layer %d of group %d " , s_apNames [ ( int ) m_Prop ] , m_LayerIndex , m_GroupIndex ) ;
}
void CEditorActionEditQuadProp : : Undo ( )
{
Apply ( m_Previous ) ;
}
void CEditorActionEditQuadProp : : Redo ( )
{
Apply ( m_Current ) ;
}
void CEditorActionEditQuadProp : : Apply ( int Value )
{
std : : shared_ptr < CLayerQuads > pLayerQuads = std : : static_pointer_cast < CLayerQuads > ( m_pLayer ) ;
CQuad & Quad = pLayerQuads - > m_vQuads [ m_QuadIndex ] ;
if ( m_Prop = = EQuadProp : : PROP_POS_ENV )
Quad . m_PosEnv = Value ;
else if ( m_Prop = = EQuadProp : : PROP_POS_ENV_OFFSET )
Quad . m_PosEnvOffset = Value ;
else if ( m_Prop = = EQuadProp : : PROP_COLOR_ENV )
Quad . m_ColorEnv = Value ;
else if ( m_Prop = = EQuadProp : : PROP_COLOR_ENV_OFFSET )
Quad . m_ColorEnvOffset = Value ;
}
CEditorActionEditQuadPointProp : : CEditorActionEditQuadPointProp ( CEditor * pEditor , int GroupIndex , int LayerIndex , int QuadIndex , int PointIndex , EQuadPointProp Prop , int Previous , int Current ) :
CEditorActionLayerBase ( pEditor , GroupIndex , LayerIndex ) , m_QuadIndex ( QuadIndex ) , m_PointIndex ( PointIndex ) , m_Prop ( Prop ) , m_Previous ( Previous ) , m_Current ( Current )
{
static const char * s_apNames [ ] = {
" pos X " ,
" pos Y " ,
" color " ,
" tex U " ,
" tex V " } ;
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Edit quad point %s property in layer %d of group %d " , s_apNames [ ( int ) m_Prop ] , m_LayerIndex , m_GroupIndex ) ;
}
void CEditorActionEditQuadPointProp : : Undo ( )
{
Apply ( m_Previous ) ;
}
void CEditorActionEditQuadPointProp : : Redo ( )
{
Apply ( m_Current ) ;
}
void CEditorActionEditQuadPointProp : : Apply ( int Value )
{
std : : shared_ptr < CLayerQuads > pLayerQuads = std : : static_pointer_cast < CLayerQuads > ( m_pLayer ) ;
CQuad & Quad = pLayerQuads - > m_vQuads [ m_QuadIndex ] ;
if ( m_Prop = = EQuadPointProp : : PROP_COLOR )
{
const ColorRGBA ColorPick = ColorRGBA : : UnpackAlphaLast < ColorRGBA > ( Value ) ;
Quad . m_aColors [ m_PointIndex ] . r = ColorPick . r * 255.0f ;
Quad . m_aColors [ m_PointIndex ] . g = ColorPick . g * 255.0f ;
Quad . m_aColors [ m_PointIndex ] . b = ColorPick . b * 255.0f ;
Quad . m_aColors [ m_PointIndex ] . a = ColorPick . a * 255.0f ;
m_pEditor - > m_ColorPickerPopupContext . m_RgbaColor = ColorPick ;
m_pEditor - > m_ColorPickerPopupContext . m_HslaColor = color_cast < ColorHSLA > ( ColorPick ) ;
m_pEditor - > m_ColorPickerPopupContext . m_HsvaColor = color_cast < ColorHSVA > ( m_pEditor - > m_ColorPickerPopupContext . m_HslaColor ) ;
}
else if ( m_Prop = = EQuadPointProp : : PROP_TEX_U )
{
Quad . m_aTexcoords [ m_PointIndex ] . x = Value ;
}
else if ( m_Prop = = EQuadPointProp : : PROP_TEX_V )
{
Quad . m_aTexcoords [ m_PointIndex ] . y = Value ;
}
}
// ---------------------------------------------------------------------------------------
CEditorActionBulk : : CEditorActionBulk ( CEditor * pEditor , const std : : vector < std : : shared_ptr < IEditorAction > > & vpActions , const char * pDisplay , bool Reverse ) :
IEditorAction ( pEditor ) , m_vpActions ( vpActions ) , m_Reverse ( Reverse )
{
// Assuming we only use bulk for actions of same type, if no display was provided
if ( ! pDisplay )
{
const char * pBaseDisplay = m_vpActions [ 0 ] - > DisplayText ( ) ;
if ( m_vpActions . size ( ) = = 1 )
str_copy ( m_aDisplayText , pBaseDisplay ) ;
else
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " %s (x%d) " , pBaseDisplay , ( int ) m_vpActions . size ( ) ) ;
}
else
{
str_copy ( m_aDisplayText , pDisplay ) ;
}
}
void CEditorActionBulk : : Undo ( )
{
if ( m_Reverse )
{
for ( auto pIt = m_vpActions . rbegin ( ) ; pIt ! = m_vpActions . rend ( ) ; pIt + + )
{
auto & pAction = * pIt ;
pAction - > Undo ( ) ;
}
}
else
{
for ( auto & pAction : m_vpActions )
{
pAction - > Undo ( ) ;
}
}
}
void CEditorActionBulk : : Redo ( )
{
for ( auto & pAction : m_vpActions )
{
pAction - > Redo ( ) ;
}
}
// ---------
CEditorActionAutoMap : : CEditorActionAutoMap ( CEditor * pEditor , int GroupIndex , int LayerIndex , const EditorTileStateChangeHistory < STileStateChange > & Changes ) :
CEditorActionLayerBase ( pEditor , GroupIndex , LayerIndex ) , m_Changes ( Changes )
{
ComputeInfos ( ) ;
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Auto map (x%d) " , m_TotalChanges ) ;
}
void CEditorActionAutoMap : : Undo ( )
{
Apply ( true ) ;
}
void CEditorActionAutoMap : : Redo ( )
{
Apply ( false ) ;
}
void CEditorActionAutoMap : : Apply ( bool Undo )
{
auto & Map = m_pEditor - > m_Map ;
std : : shared_ptr < CLayerTiles > pLayerTiles = std : : static_pointer_cast < CLayerTiles > ( m_pLayer ) ;
for ( auto & Change : m_Changes )
{
int y = Change . first ;
auto Line = Change . second ;
for ( auto & Tile : Line )
{
int x = Tile . first ;
STileStateChange State = Tile . second ;
pLayerTiles - > SetTileIgnoreHistory ( x , y , Undo ? State . m_Previous : State . m_Current ) ;
}
}
Map . OnModify ( ) ;
}
void CEditorActionAutoMap : : ComputeInfos ( )
{
m_TotalChanges = 0 ;
for ( auto & Line : m_Changes )
m_TotalChanges + = Line . second . size ( ) ;
}
// ---------
CEditorActionLayerBase : : CEditorActionLayerBase ( CEditor * pEditor , int GroupIndex , int LayerIndex ) :
IEditorAction ( pEditor ) , m_GroupIndex ( GroupIndex ) , m_LayerIndex ( LayerIndex )
{
m_pLayer = pEditor - > m_Map . m_vpGroups [ GroupIndex ] - > m_vpLayers [ LayerIndex ] ;
}
// ----------
CEditorActionAddLayer : : CEditorActionAddLayer ( CEditor * pEditor , int GroupIndex , int LayerIndex , bool Duplicate ) :
CEditorActionLayerBase ( pEditor , GroupIndex , LayerIndex ) , m_Duplicate ( Duplicate )
{
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " %s %s layer in group %d " , m_Duplicate ? " Duplicate " : " New " , m_pLayer - > TypeName ( ) , m_GroupIndex ) ;
}
void CEditorActionAddLayer : : Undo ( )
{
// Undo: remove layer from vector but keep it in case we want to add it back
auto & vLayers = m_pEditor - > m_Map . m_vpGroups [ m_GroupIndex ] - > m_vpLayers ;
vLayers . erase ( vLayers . begin ( ) + m_LayerIndex ) ;
m_pEditor - > m_Map . m_vpGroups [ m_GroupIndex ] - > m_Collapse = false ;
if ( m_LayerIndex > = ( int ) vLayers . size ( ) )
m_pEditor - > SelectLayer ( vLayers . size ( ) - 1 , m_GroupIndex ) ;
m_pEditor - > m_Map . OnModify ( ) ;
}
void CEditorActionAddLayer : : Redo ( )
{
// Redo: add back the removed layer contained in this class
auto & vLayers = m_pEditor - > m_Map . m_vpGroups [ m_GroupIndex ] - > m_vpLayers ;
vLayers . insert ( vLayers . begin ( ) + m_LayerIndex , m_pLayer ) ;
m_pEditor - > m_Map . m_vpGroups [ m_GroupIndex ] - > m_Collapse = false ;
m_pEditor - > SelectLayer ( m_LayerIndex , m_GroupIndex ) ;
m_pEditor - > m_Map . OnModify ( ) ;
}
CEditorActionDeleteLayer : : CEditorActionDeleteLayer ( CEditor * pEditor , int GroupIndex , int LayerIndex ) :
CEditorActionLayerBase ( pEditor , GroupIndex , LayerIndex )
{
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Delete %s layer of group %d " , m_pLayer - > TypeName ( ) , m_GroupIndex ) ;
}
void CEditorActionDeleteLayer : : Redo ( )
{
// Redo: remove layer from vector but keep it in case we want to add it back
auto & vLayers = m_pEditor - > m_Map . m_vpGroups [ m_GroupIndex ] - > m_vpLayers ;
if ( m_pLayer - > m_Type = = LAYERTYPE_TILES )
{
std : : shared_ptr < CLayerTiles > pLayerTiles = std : : static_pointer_cast < CLayerTiles > ( m_pLayer ) ;
if ( pLayerTiles - > m_Front )
m_pEditor - > m_Map . m_pFrontLayer = nullptr ;
else if ( pLayerTiles - > m_Tele )
m_pEditor - > m_Map . m_pTeleLayer = nullptr ;
else if ( pLayerTiles - > m_Speedup )
m_pEditor - > m_Map . m_pSpeedupLayer = nullptr ;
else if ( pLayerTiles - > m_Switch )
m_pEditor - > m_Map . m_pSwitchLayer = nullptr ;
else if ( pLayerTiles - > m_Tune )
m_pEditor - > m_Map . m_pTuneLayer = nullptr ;
}
m_pEditor - > m_Map . m_vpGroups [ m_GroupIndex ] - > DeleteLayer ( m_LayerIndex ) ;
m_pEditor - > m_Map . m_vpGroups [ m_GroupIndex ] - > m_Collapse = false ;
if ( m_LayerIndex > = ( int ) vLayers . size ( ) )
m_pEditor - > SelectLayer ( vLayers . size ( ) - 1 , m_GroupIndex ) ;
m_pEditor - > m_Map . OnModify ( ) ;
}
void CEditorActionDeleteLayer : : Undo ( )
{
// Undo: add back the removed layer contained in this class
auto & vLayers = m_pEditor - > m_Map . m_vpGroups [ m_GroupIndex ] - > m_vpLayers ;
if ( m_pLayer - > m_Type = = LAYERTYPE_TILES )
{
std : : shared_ptr < CLayerTiles > pLayerTiles = std : : static_pointer_cast < CLayerTiles > ( m_pLayer ) ;
if ( pLayerTiles - > m_Front )
m_pEditor - > m_Map . m_pFrontLayer = std : : static_pointer_cast < CLayerFront > ( m_pLayer ) ;
else if ( pLayerTiles - > m_Tele )
m_pEditor - > m_Map . m_pTeleLayer = std : : static_pointer_cast < CLayerTele > ( m_pLayer ) ;
else if ( pLayerTiles - > m_Speedup )
m_pEditor - > m_Map . m_pSpeedupLayer = std : : static_pointer_cast < CLayerSpeedup > ( m_pLayer ) ;
else if ( pLayerTiles - > m_Switch )
m_pEditor - > m_Map . m_pSwitchLayer = std : : static_pointer_cast < CLayerSwitch > ( m_pLayer ) ;
else if ( pLayerTiles - > m_Tune )
m_pEditor - > m_Map . m_pTuneLayer = std : : static_pointer_cast < CLayerTune > ( m_pLayer ) ;
}
vLayers . insert ( vLayers . begin ( ) + m_LayerIndex , m_pLayer ) ;
m_pEditor - > m_Map . m_vpGroups [ m_GroupIndex ] - > m_Collapse = false ;
m_pEditor - > SelectLayer ( m_LayerIndex , m_GroupIndex ) ;
m_pEditor - > m_Map . OnModify ( ) ;
}
CEditorActionGroup : : CEditorActionGroup ( CEditor * pEditor , int GroupIndex , bool Delete ) :
IEditorAction ( pEditor ) , m_GroupIndex ( GroupIndex ) , m_Delete ( Delete )
{
m_pGroup = pEditor - > m_Map . m_vpGroups [ GroupIndex ] ;
if ( m_Delete )
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Delete group %d " , m_GroupIndex ) ;
else
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " New group " ) ;
}
void CEditorActionGroup : : Undo ( )
{
if ( m_Delete )
{
// Undo: add back the group
m_pEditor - > m_Map . m_vpGroups . insert ( m_pEditor - > m_Map . m_vpGroups . begin ( ) + m_GroupIndex , m_pGroup ) ;
m_pEditor - > m_SelectedGroup = m_GroupIndex ;
m_pEditor - > m_Map . OnModify ( ) ;
}
else
{
// Undo: delete the group
m_pEditor - > m_Map . DeleteGroup ( m_GroupIndex ) ;
m_pEditor - > m_SelectedGroup = maximum ( 0 , m_GroupIndex - 1 ) ;
}
m_pEditor - > m_Map . OnModify ( ) ;
}
void CEditorActionGroup : : Redo ( )
{
if ( ! m_Delete )
{
// Redo: add back the group
m_pEditor - > m_Map . m_vpGroups . insert ( m_pEditor - > m_Map . m_vpGroups . begin ( ) + m_GroupIndex , m_pGroup ) ;
m_pEditor - > m_SelectedGroup = m_GroupIndex ;
}
else
{
// Redo: delete the group
m_pEditor - > m_Map . DeleteGroup ( m_GroupIndex ) ;
m_pEditor - > m_SelectedGroup = maximum ( 0 , m_GroupIndex - 1 ) ;
}
m_pEditor - > m_Map . OnModify ( ) ;
}
CEditorActionEditGroupProp : : CEditorActionEditGroupProp ( CEditor * pEditor , int GroupIndex , EGroupProp Prop , int Previous , int Current ) :
IEditorAction ( pEditor ) , m_GroupIndex ( GroupIndex ) , m_Prop ( Prop ) , m_Previous ( Previous ) , m_Current ( Current )
{
static const char * s_apNames [ ] = {
" order " ,
" pos X " ,
" pos Y " ,
" para X " ,
" para Y " ,
" use clipping " ,
" clip X " ,
" clip Y " ,
" clip W " ,
" clip H " } ;
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Edit group %d %s property " , m_GroupIndex , s_apNames [ ( int ) Prop ] ) ;
}
void CEditorActionEditGroupProp : : Undo ( )
{
auto pGroup = m_pEditor - > m_Map . m_vpGroups [ m_GroupIndex ] ;
if ( m_Prop = = EGroupProp : : PROP_ORDER )
{
int CurrentOrder = m_Current ;
bool Dir = m_Current > m_Previous ;
while ( CurrentOrder ! = m_Previous )
{
CurrentOrder = m_pEditor - > m_Map . SwapGroups ( CurrentOrder , Dir ? CurrentOrder - 1 : CurrentOrder + 1 ) ;
}
m_pEditor - > m_SelectedGroup = m_Previous ;
}
else
Apply ( m_Previous ) ;
}
void CEditorActionEditGroupProp : : Redo ( )
{
auto pGroup = m_pEditor - > m_Map . m_vpGroups [ m_GroupIndex ] ;
if ( m_Prop = = EGroupProp : : PROP_ORDER )
{
int CurrentOrder = m_Previous ;
bool Dir = m_Previous > m_Current ;
while ( CurrentOrder ! = m_Current )
{
CurrentOrder = m_pEditor - > m_Map . SwapGroups ( CurrentOrder , Dir ? CurrentOrder - 1 : CurrentOrder + 1 ) ;
}
m_pEditor - > m_SelectedGroup = m_Current ;
}
else
Apply ( m_Current ) ;
}
void CEditorActionEditGroupProp : : Apply ( int Value )
{
auto pGroup = m_pEditor - > m_Map . m_vpGroups [ m_GroupIndex ] ;
if ( m_Prop = = EGroupProp : : PROP_POS_X )
pGroup - > m_OffsetX = Value ;
if ( m_Prop = = EGroupProp : : PROP_POS_Y )
pGroup - > m_OffsetY = Value ;
if ( m_Prop = = EGroupProp : : PROP_PARA_X )
pGroup - > m_ParallaxX = Value ;
if ( m_Prop = = EGroupProp : : PROP_PARA_Y )
pGroup - > m_ParallaxY = Value ;
if ( m_Prop = = EGroupProp : : PROP_USE_CLIPPING )
pGroup - > m_UseClipping = Value ;
if ( m_Prop = = EGroupProp : : PROP_CLIP_X )
pGroup - > m_ClipX = Value ;
if ( m_Prop = = EGroupProp : : PROP_CLIP_Y )
pGroup - > m_ClipY = Value ;
if ( m_Prop = = EGroupProp : : PROP_CLIP_W )
pGroup - > m_ClipW = Value ;
if ( m_Prop = = EGroupProp : : PROP_CLIP_H )
pGroup - > m_ClipH = Value ;
m_pEditor - > m_Map . OnModify ( ) ;
}
template < typename E >
CEditorActionEditLayerPropBase < E > : : CEditorActionEditLayerPropBase ( CEditor * pEditor , int GroupIndex , int LayerIndex , E Prop , int Previous , int Current ) :
CEditorActionLayerBase ( pEditor , GroupIndex , LayerIndex ) , m_Prop ( Prop ) , m_Previous ( Previous ) , m_Current ( Current )
{
}
CEditorActionEditLayerProp : : CEditorActionEditLayerProp ( CEditor * pEditor , int GroupIndex , int LayerIndex , ELayerProp Prop , int Previous , int Current ) :
CEditorActionEditLayerPropBase ( pEditor , GroupIndex , LayerIndex , Prop , Previous , Current )
{
static const char * s_apNames [ ] = {
" group " ,
" order " ,
" HQ " } ;
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Edit layer %d in group %d %s property " , m_LayerIndex , m_GroupIndex , s_apNames [ ( int ) m_Prop ] ) ;
}
void CEditorActionEditLayerProp : : Undo ( )
{
auto pCurrentGroup = m_pEditor - > m_Map . m_vpGroups [ m_GroupIndex ] ;
if ( m_Prop = = ELayerProp : : PROP_ORDER )
{
m_pEditor - > SelectLayer ( pCurrentGroup - > SwapLayers ( m_Current , m_Previous ) ) ;
}
else
Apply ( m_Previous ) ;
}
void CEditorActionEditLayerProp : : Redo ( )
{
auto pCurrentGroup = m_pEditor - > m_Map . m_vpGroups [ m_GroupIndex ] ;
if ( m_Prop = = ELayerProp : : PROP_ORDER )
{
m_pEditor - > SelectLayer ( pCurrentGroup - > SwapLayers ( m_Previous , m_Current ) ) ;
}
else
Apply ( m_Current ) ;
}
void CEditorActionEditLayerProp : : Apply ( int Value )
{
if ( m_Prop = = ELayerProp : : PROP_GROUP )
{
auto pCurrentGroup = m_pEditor - > m_Map . m_vpGroups [ Value = = m_Previous ? m_Current : m_Previous ] ;
auto Position = std : : find ( pCurrentGroup - > m_vpLayers . begin ( ) , pCurrentGroup - > m_vpLayers . end ( ) , m_pLayer ) ;
if ( Position ! = pCurrentGroup - > m_vpLayers . end ( ) )
pCurrentGroup - > m_vpLayers . erase ( Position ) ;
m_pEditor - > m_Map . m_vpGroups [ Value ] - > m_vpLayers . push_back ( m_pLayer ) ;
m_pEditor - > m_SelectedGroup = Value ;
m_pEditor - > SelectLayer ( m_pEditor - > m_Map . m_vpGroups [ Value ] - > m_vpLayers . size ( ) - 1 ) ;
}
else if ( m_Prop = = ELayerProp : : PROP_HQ )
{
m_pLayer - > m_Flags = Value ;
}
m_pEditor - > m_Map . OnModify ( ) ;
}
CEditorActionEditLayerTilesProp : : CEditorActionEditLayerTilesProp ( CEditor * pEditor , int GroupIndex , int LayerIndex , ETilesProp Prop , int Previous , int Current ) :
CEditorActionEditLayerPropBase ( pEditor , GroupIndex , LayerIndex , Prop , Previous , Current )
{
static const char * s_apNames [ ] = {
" width " ,
" height " ,
" shift " ,
" shift by " ,
" image " ,
" color " ,
" color env " ,
" color env offset " ,
" automapper " ,
" seed " } ;
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Edit tiles layer %d in group %d %s property " , m_LayerIndex , m_GroupIndex , s_apNames [ ( int ) Prop ] ) ;
}
void CEditorActionEditLayerTilesProp : : SetSavedLayers ( const std : : map < int , std : : shared_ptr < CLayer > > & SavedLayers )
{
m_SavedLayers = std : : map ( SavedLayers ) ;
}
void CEditorActionEditLayerTilesProp : : Undo ( )
{
std : : shared_ptr < CLayerTiles > pLayerTiles = std : : static_pointer_cast < CLayerTiles > ( m_pLayer ) ;
std : : shared_ptr < CLayerTiles > pSavedLayerTiles = nullptr ;
if ( m_Prop = = ETilesProp : : PROP_WIDTH | | m_Prop = = ETilesProp : : PROP_HEIGHT )
{
if ( m_Prop = = ETilesProp : : PROP_HEIGHT )
pLayerTiles - > Resize ( pLayerTiles - > m_Width , m_Previous ) ;
else if ( m_Prop = = ETilesProp : : PROP_WIDTH )
pLayerTiles - > Resize ( m_Previous , pLayerTiles - > m_Height ) ;
RestoreLayer ( LAYERTYPE_TILES , pLayerTiles ) ;
if ( pLayerTiles - > m_Game | | pLayerTiles - > m_Front | | pLayerTiles - > m_Switch | | pLayerTiles - > m_Speedup | | pLayerTiles - > m_Tune )
{
if ( m_pEditor - > m_Map . m_pFrontLayer & & ! pLayerTiles - > m_Front )
RestoreLayer ( LAYERTYPE_FRONT , m_pEditor - > m_Map . m_pFrontLayer ) ;
if ( m_pEditor - > m_Map . m_pTeleLayer & & ! pLayerTiles - > m_Tele )
RestoreLayer ( LAYERTYPE_TELE , m_pEditor - > m_Map . m_pTeleLayer ) ;
if ( m_pEditor - > m_Map . m_pSwitchLayer & & ! pLayerTiles - > m_Switch )
RestoreLayer ( LAYERTYPE_SWITCH , m_pEditor - > m_Map . m_pSwitchLayer ) ;
if ( m_pEditor - > m_Map . m_pSpeedupLayer & & ! pLayerTiles - > m_Speedup )
RestoreLayer ( LAYERTYPE_SPEEDUP , m_pEditor - > m_Map . m_pSpeedupLayer ) ;
if ( m_pEditor - > m_Map . m_pTuneLayer & & ! pLayerTiles - > m_Tune )
RestoreLayer ( LAYERTYPE_TUNE , m_pEditor - > m_Map . m_pTuneLayer ) ;
if ( ! pLayerTiles - > m_Game )
RestoreLayer ( LAYERTYPE_GAME , m_pEditor - > m_Map . m_pGameLayer ) ;
}
}
else if ( m_Prop = = ETilesProp : : PROP_SHIFT )
{
RestoreLayer ( LAYERTYPE_TILES , pLayerTiles ) ;
}
else if ( m_Prop = = ETilesProp : : PROP_SHIFT_BY )
{
m_pEditor - > m_ShiftBy = m_Previous ;
}
else if ( m_Prop = = ETilesProp : : PROP_IMAGE )
{
if ( m_Previous = = - 1 )
{
pLayerTiles - > m_Image = - 1 ;
}
else
{
pLayerTiles - > m_Image = m_Previous % m_pEditor - > m_Map . m_vpImages . size ( ) ;
pLayerTiles - > m_AutoMapperConfig = - 1 ;
}
}
else if ( m_Prop = = ETilesProp : : PROP_COLOR )
{
const ColorRGBA ColorPick = ColorRGBA : : UnpackAlphaLast < ColorRGBA > ( m_Previous ) ;
pLayerTiles - > m_Color . r = ColorPick . r * 255.0f ;
pLayerTiles - > m_Color . g = ColorPick . g * 255.0f ;
pLayerTiles - > m_Color . b = ColorPick . b * 255.0f ;
pLayerTiles - > m_Color . a = ColorPick . a * 255.0f ;
m_pEditor - > m_ColorPickerPopupContext . m_RgbaColor = ColorPick ;
m_pEditor - > m_ColorPickerPopupContext . m_HslaColor = color_cast < ColorHSLA > ( ColorPick ) ;
m_pEditor - > m_ColorPickerPopupContext . m_HsvaColor = color_cast < ColorHSVA > ( m_pEditor - > m_ColorPickerPopupContext . m_HslaColor ) ;
}
else if ( m_Prop = = ETilesProp : : PROP_COLOR_ENV )
{
pLayerTiles - > m_ColorEnv = m_Previous ;
}
else if ( m_Prop = = ETilesProp : : PROP_COLOR_ENV_OFFSET )
{
pLayerTiles - > m_ColorEnvOffset = m_Previous ;
}
else if ( m_Prop = = ETilesProp : : PROP_AUTOMAPPER )
{
pLayerTiles - > m_AutoMapperConfig = m_Previous ;
}
else if ( m_Prop = = ETilesProp : : PROP_SEED )
{
pLayerTiles - > m_Seed = m_Previous ;
}
m_pEditor - > m_Map . OnModify ( ) ;
}
void CEditorActionEditLayerTilesProp : : Redo ( )
{
std : : shared_ptr < CLayerTiles > pLayerTiles = std : : static_pointer_cast < CLayerTiles > ( m_pLayer ) ;
if ( m_Prop = = ETilesProp : : PROP_WIDTH | | m_Prop = = ETilesProp : : PROP_HEIGHT )
{
if ( m_Prop = = ETilesProp : : PROP_HEIGHT )
pLayerTiles - > Resize ( pLayerTiles - > m_Width , m_Current ) ;
else if ( m_Prop = = ETilesProp : : PROP_WIDTH )
pLayerTiles - > Resize ( m_Current , pLayerTiles - > m_Height ) ;
if ( pLayerTiles - > m_Game | | pLayerTiles - > m_Front | | pLayerTiles - > m_Switch | | pLayerTiles - > m_Speedup | | pLayerTiles - > m_Tune )
{
if ( m_pEditor - > m_Map . m_pFrontLayer & & ! pLayerTiles - > m_Front )
m_pEditor - > m_Map . m_pFrontLayer - > Resize ( pLayerTiles - > m_Width , pLayerTiles - > m_Height ) ;
if ( m_pEditor - > m_Map . m_pTeleLayer & & ! pLayerTiles - > m_Tele )
m_pEditor - > m_Map . m_pTeleLayer - > Resize ( pLayerTiles - > m_Width , pLayerTiles - > m_Height ) ;
if ( m_pEditor - > m_Map . m_pSwitchLayer & & ! pLayerTiles - > m_Switch )
m_pEditor - > m_Map . m_pSwitchLayer - > Resize ( pLayerTiles - > m_Width , pLayerTiles - > m_Height ) ;
if ( m_pEditor - > m_Map . m_pSpeedupLayer & & ! pLayerTiles - > m_Speedup )
m_pEditor - > m_Map . m_pSpeedupLayer - > Resize ( pLayerTiles - > m_Width , pLayerTiles - > m_Height ) ;
if ( m_pEditor - > m_Map . m_pTuneLayer & & ! pLayerTiles - > m_Tune )
m_pEditor - > m_Map . m_pTuneLayer - > Resize ( pLayerTiles - > m_Width , pLayerTiles - > m_Height ) ;
if ( ! pLayerTiles - > m_Game )
m_pEditor - > m_Map . m_pGameLayer - > Resize ( pLayerTiles - > m_Width , pLayerTiles - > m_Height ) ;
}
}
else if ( m_Prop = = ETilesProp : : PROP_SHIFT )
{
pLayerTiles - > Shift ( m_Current ) ;
}
else if ( m_Prop = = ETilesProp : : PROP_SHIFT_BY )
{
m_pEditor - > m_ShiftBy = m_Current ;
}
else if ( m_Prop = = ETilesProp : : PROP_IMAGE )
{
if ( m_Current = = - 1 )
{
pLayerTiles - > m_Image = - 1 ;
}
else
{
pLayerTiles - > m_Image = m_Current % m_pEditor - > m_Map . m_vpImages . size ( ) ;
pLayerTiles - > m_AutoMapperConfig = - 1 ;
}
}
else if ( m_Prop = = ETilesProp : : PROP_COLOR )
{
const ColorRGBA ColorPick = ColorRGBA : : UnpackAlphaLast < ColorRGBA > ( m_Current ) ;
pLayerTiles - > m_Color . r = ColorPick . r * 255.0f ;
pLayerTiles - > m_Color . g = ColorPick . g * 255.0f ;
pLayerTiles - > m_Color . b = ColorPick . b * 255.0f ;
pLayerTiles - > m_Color . a = ColorPick . a * 255.0f ;
m_pEditor - > m_ColorPickerPopupContext . m_RgbaColor = ColorPick ;
m_pEditor - > m_ColorPickerPopupContext . m_HslaColor = color_cast < ColorHSLA > ( ColorPick ) ;
m_pEditor - > m_ColorPickerPopupContext . m_HsvaColor = color_cast < ColorHSVA > ( m_pEditor - > m_ColorPickerPopupContext . m_HslaColor ) ;
}
else if ( m_Prop = = ETilesProp : : PROP_COLOR_ENV )
{
pLayerTiles - > m_ColorEnv = m_Current ;
}
else if ( m_Prop = = ETilesProp : : PROP_COLOR_ENV_OFFSET )
{
pLayerTiles - > m_ColorEnvOffset = m_Current ;
}
else if ( m_Prop = = ETilesProp : : PROP_AUTOMAPPER )
{
pLayerTiles - > m_AutoMapperConfig = m_Current ;
}
else if ( m_Prop = = ETilesProp : : PROP_SEED )
{
pLayerTiles - > m_Seed = m_Current ;
}
m_pEditor - > m_Map . OnModify ( ) ;
}
void CEditorActionEditLayerTilesProp : : RestoreLayer ( int Layer , const std : : shared_ptr < CLayerTiles > & pLayerTiles )
{
if ( m_SavedLayers [ Layer ] ! = nullptr )
{
std : : shared_ptr < CLayerTiles > pSavedLayerTiles = std : : static_pointer_cast < CLayerTiles > ( m_SavedLayers [ Layer ] ) ;
mem_copy ( pLayerTiles - > m_pTiles , pSavedLayerTiles - > m_pTiles , ( size_t ) pLayerTiles - > m_Width * pLayerTiles - > m_Height * sizeof ( CTile ) ) ;
if ( pLayerTiles - > m_Tele )
{
std : : shared_ptr < CLayerTele > pLayerTele = std : : static_pointer_cast < CLayerTele > ( pLayerTiles ) ;
std : : shared_ptr < CLayerTele > pSavedLayerTele = std : : static_pointer_cast < CLayerTele > ( pSavedLayerTiles ) ;
mem_copy ( pLayerTele - > m_pTeleTile , pSavedLayerTele - > m_pTeleTile , ( size_t ) pLayerTiles - > m_Width * pLayerTiles - > m_Height * sizeof ( CTeleTile ) ) ;
}
else if ( pLayerTiles - > m_Speedup )
{
std : : shared_ptr < CLayerSpeedup > pLayerSpeedup = std : : static_pointer_cast < CLayerSpeedup > ( pLayerTiles ) ;
std : : shared_ptr < CLayerSpeedup > pSavedLayerSpeedup = std : : static_pointer_cast < CLayerSpeedup > ( pSavedLayerTiles ) ;
mem_copy ( pLayerSpeedup - > m_pSpeedupTile , pSavedLayerSpeedup - > m_pSpeedupTile , ( size_t ) pLayerTiles - > m_Width * pLayerTiles - > m_Height * sizeof ( CSpeedupTile ) ) ;
}
else if ( pLayerTiles - > m_Switch )
{
std : : shared_ptr < CLayerSwitch > pLayerSwitch = std : : static_pointer_cast < CLayerSwitch > ( pLayerTiles ) ;
std : : shared_ptr < CLayerSwitch > pSavedLayerSwitch = std : : static_pointer_cast < CLayerSwitch > ( pSavedLayerTiles ) ;
mem_copy ( pLayerSwitch - > m_pSwitchTile , pSavedLayerSwitch - > m_pSwitchTile , ( size_t ) pLayerTiles - > m_Width * pLayerTiles - > m_Height * sizeof ( CSwitchTile ) ) ;
}
else if ( pLayerTiles - > m_Tune )
{
std : : shared_ptr < CLayerTune > pLayerTune = std : : static_pointer_cast < CLayerTune > ( pLayerTiles ) ;
std : : shared_ptr < CLayerTune > pSavedLayerTune = std : : static_pointer_cast < CLayerTune > ( pSavedLayerTiles ) ;
mem_copy ( pLayerTune - > m_pTuneTile , pSavedLayerTune - > m_pTuneTile , ( size_t ) pLayerTiles - > m_Width * pLayerTiles - > m_Height * sizeof ( CTuneTile ) ) ;
}
}
}
CEditorActionEditLayerQuadsProp : : CEditorActionEditLayerQuadsProp ( CEditor * pEditor , int GroupIndex , int LayerIndex , ELayerQuadsProp Prop , int Previous , int Current ) :
CEditorActionEditLayerPropBase ( pEditor , GroupIndex , LayerIndex , Prop , Previous , Current )
{
static const char * s_apNames [ ] = {
" image " } ;
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Edit quads layer %d in group %d %s property " , m_LayerIndex , m_GroupIndex , s_apNames [ ( int ) m_Prop ] ) ;
}
void CEditorActionEditLayerQuadsProp : : Undo ( )
{
Apply ( m_Previous ) ;
}
void CEditorActionEditLayerQuadsProp : : Redo ( )
{
Apply ( m_Current ) ;
}
void CEditorActionEditLayerQuadsProp : : Apply ( int Value )
{
std : : shared_ptr < CLayerQuads > pLayerQuads = std : : static_pointer_cast < CLayerQuads > ( m_pLayer ) ;
if ( m_Prop = = ELayerQuadsProp : : PROP_IMAGE )
{
if ( Value > = 0 )
pLayerQuads - > m_Image = Value % m_pEditor - > m_Map . m_vpImages . size ( ) ;
else
pLayerQuads - > m_Image = - 1 ;
}
m_pEditor - > m_Map . OnModify ( ) ;
}
// --------------------------------------------------------------
CEditorActionEditLayersGroupAndOrder : : CEditorActionEditLayersGroupAndOrder ( CEditor * pEditor , int GroupIndex , const std : : vector < int > & LayerIndices , int NewGroupIndex , const std : : vector < int > & NewLayerIndices ) :
IEditorAction ( pEditor ) , m_GroupIndex ( GroupIndex ) , m_LayerIndices ( LayerIndices ) , m_NewGroupIndex ( NewGroupIndex ) , m_NewLayerIndices ( NewLayerIndices )
{
std : : sort ( m_LayerIndices . begin ( ) , m_LayerIndices . end ( ) ) ;
std : : sort ( m_NewLayerIndices . begin ( ) , m_NewLayerIndices . end ( ) ) ;
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Edit layers group and order (x%d) " , ( int ) m_LayerIndices . size ( ) ) ;
}
void CEditorActionEditLayersGroupAndOrder : : Undo ( )
{
// Undo : restore group and order
auto & Map = m_pEditor - > m_Map ;
auto & pCurrentGroup = Map . m_vpGroups [ m_NewGroupIndex ] ;
auto & pPreviousGroup = Map . m_vpGroups [ m_GroupIndex ] ;
std : : vector < std : : shared_ptr < CLayer > > vpLayers ;
for ( auto & LayerIndex : m_NewLayerIndices )
vpLayers . push_back ( pCurrentGroup - > m_vpLayers [ LayerIndex ] ) ;
int k = 0 ;
for ( auto & pLayer : vpLayers )
{
pCurrentGroup - > m_vpLayers . erase ( std : : find ( pCurrentGroup - > m_vpLayers . begin ( ) , pCurrentGroup - > m_vpLayers . end ( ) , pLayer ) ) ;
pPreviousGroup - > m_vpLayers . insert ( pPreviousGroup - > m_vpLayers . begin ( ) + m_LayerIndices [ k + + ] , pLayer ) ;
}
m_pEditor - > m_vSelectedLayers = m_LayerIndices ;
m_pEditor - > m_SelectedGroup = m_GroupIndex ;
}
void CEditorActionEditLayersGroupAndOrder : : Redo ( )
{
// Redo : move layers
auto & Map = m_pEditor - > m_Map ;
auto & pCurrentGroup = Map . m_vpGroups [ m_GroupIndex ] ;
auto & pPreviousGroup = Map . m_vpGroups [ m_NewGroupIndex ] ;
std : : vector < std : : shared_ptr < CLayer > > vpLayers ;
for ( auto & LayerIndex : m_LayerIndices )
vpLayers . push_back ( pCurrentGroup - > m_vpLayers [ LayerIndex ] ) ;
int k = 0 ;
for ( auto & pLayer : vpLayers )
{
pCurrentGroup - > m_vpLayers . erase ( std : : find ( pCurrentGroup - > m_vpLayers . begin ( ) , pCurrentGroup - > m_vpLayers . end ( ) , pLayer ) ) ;
pPreviousGroup - > m_vpLayers . insert ( pPreviousGroup - > m_vpLayers . begin ( ) + m_NewLayerIndices [ k + + ] , pLayer ) ;
}
m_pEditor - > m_vSelectedLayers = m_NewLayerIndices ;
m_pEditor - > m_SelectedGroup = m_NewGroupIndex ;
}
// -----------------------------------
CEditorActionAppendMap : : CEditorActionAppendMap ( CEditor * pEditor , const char * pMapName , const SPrevInfo & PrevInfo , std : : vector < int > & vImageIndexMap ) :
IEditorAction ( pEditor ) , m_PrevInfo ( PrevInfo ) , m_vImageIndexMap ( vImageIndexMap )
{
str_copy ( m_aMapName , pMapName ) ;
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Append %s " , m_aMapName ) ;
}
void CEditorActionAppendMap : : Undo ( )
{
auto & Map = m_pEditor - > m_Map ;
// Undo append:
// - delete added groups
// - delete added envelopes
// - delete added images
// - delete added sounds
// Delete added groups
while ( ( int ) Map . m_vpGroups . size ( ) ! = m_PrevInfo . m_Groups )
{
Map . m_vpGroups . pop_back ( ) ;
}
// Delete added envelopes
while ( ( int ) Map . m_vpEnvelopes . size ( ) ! = m_PrevInfo . m_Envelopes )
{
Map . m_vpEnvelopes . pop_back ( ) ;
}
// Delete added sounds
while ( ( int ) Map . m_vpSounds . size ( ) ! = m_PrevInfo . m_Sounds )
{
Map . m_vpSounds . pop_back ( ) ;
}
// Delete added images
// Images are sorted when appending, so we need to revert sorting before deleting the images
if ( ! m_vImageIndexMap . empty ( ) )
{
std : : vector < int > vReverseIndexMap ;
vReverseIndexMap . resize ( m_vImageIndexMap . size ( ) ) ;
for ( int k = 0 ; k < ( int ) m_vImageIndexMap . size ( ) ; k + + )
vReverseIndexMap [ m_vImageIndexMap [ k ] ] = k ;
std : : vector < std : : shared_ptr < CEditorImage > > vpRevertedImages ;
vpRevertedImages . resize ( Map . m_vpImages . size ( ) ) ;
for ( int k = 0 ; k < ( int ) vReverseIndexMap . size ( ) ; k + + )
{
vpRevertedImages [ vReverseIndexMap [ k ] ] = Map . m_vpImages [ k ] ;
}
Map . m_vpImages = vpRevertedImages ;
Map . ModifyImageIndex ( [ vReverseIndexMap ] ( int * pIndex ) {
if ( * pIndex > = 0 )
{
* pIndex = vReverseIndexMap [ * pIndex ] ;
}
} ) ;
}
while ( ( int ) Map . m_vpImages . size ( ) ! = m_PrevInfo . m_Images )
{
Map . m_vpImages . pop_back ( ) ;
}
}
void CEditorActionAppendMap : : Redo ( )
{
// Redo is just re-appending the same map
m_pEditor - > Append ( m_aMapName , IStorage : : TYPE_ALL , true ) ;
}
// ---------------------------
CEditorActionTileArt : : CEditorActionTileArt ( CEditor * pEditor , int PreviousImageCount , const char * pTileArtFile , std : : vector < int > & vImageIndexMap ) :
IEditorAction ( pEditor ) , m_PreviousImageCount ( PreviousImageCount ) , m_vImageIndexMap ( vImageIndexMap )
{
str_copy ( m_aTileArtFile , pTileArtFile ) ;
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Tile art " ) ;
}
void CEditorActionTileArt : : Undo ( )
{
auto & Map = m_pEditor - > m_Map ;
// Delete added group
Map . m_vpGroups . pop_back ( ) ;
// Delete added images
// Images are sorted when appending, so we need to revert sorting before deleting the images
if ( ! m_vImageIndexMap . empty ( ) )
{
std : : vector < int > vReverseIndexMap ;
vReverseIndexMap . resize ( m_vImageIndexMap . size ( ) ) ;
for ( int k = 0 ; k < ( int ) m_vImageIndexMap . size ( ) ; k + + )
vReverseIndexMap [ m_vImageIndexMap [ k ] ] = k ;
std : : vector < std : : shared_ptr < CEditorImage > > vpRevertedImages ;
vpRevertedImages . resize ( Map . m_vpImages . size ( ) ) ;
for ( int k = 0 ; k < ( int ) vReverseIndexMap . size ( ) ; k + + )
{
vpRevertedImages [ vReverseIndexMap [ k ] ] = Map . m_vpImages [ k ] ;
}
Map . m_vpImages = vpRevertedImages ;
Map . ModifyImageIndex ( [ vReverseIndexMap ] ( int * pIndex ) {
if ( * pIndex > = 0 )
{
* pIndex = vReverseIndexMap [ * pIndex ] ;
}
} ) ;
}
while ( ( int ) Map . m_vpImages . size ( ) ! = m_PreviousImageCount )
{
Map . m_vpImages . pop_back ( ) ;
}
}
void CEditorActionTileArt : : Redo ( )
{
if ( ! m_pEditor - > Graphics ( ) - > LoadPNG ( & m_pEditor - > m_TileartImageInfo , m_aTileArtFile , IStorage : : TYPE_ALL ) )
{
m_pEditor - > ShowFileDialogError ( " Failed to load image from file '%s'. " , m_aTileArtFile ) ;
return ;
}
IStorage : : StripPathAndExtension ( m_aTileArtFile , m_pEditor - > m_aTileartFilename , sizeof ( m_pEditor - > m_aTileartFilename ) ) ;
m_pEditor - > AddTileart ( true ) ;
}
// ---------------------------------
CEditorCommandAction : : CEditorCommandAction ( CEditor * pEditor , EType Type , int * pSelectedCommandIndex , int CommandIndex , const char * pPreviousCommand , const char * pCurrentCommand ) :
IEditorAction ( pEditor ) , m_Type ( Type ) , m_pSelectedCommandIndex ( pSelectedCommandIndex ) , m_CommandIndex ( CommandIndex )
{
if ( pPreviousCommand ! = nullptr )
m_PreviousCommand = std : : string ( pPreviousCommand ) ;
if ( pCurrentCommand ! = nullptr )
m_CurrentCommand = std : : string ( pCurrentCommand ) ;
switch ( m_Type )
{
case EType : : ADD :
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Add command " ) ;
break ;
case EType : : EDIT :
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Edit command %d " , m_CommandIndex ) ;
break ;
case EType : : DELETE :
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Delete command %d " , m_CommandIndex ) ;
break ;
case EType : : MOVE_UP :
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Move command %d up " , m_CommandIndex ) ;
break ;
case EType : : MOVE_DOWN :
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Move command %d down " , m_CommandIndex ) ;
break ;
default :
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Edit command %d " , m_CommandIndex ) ;
break ;
}
}
void CEditorCommandAction : : Undo ( )
{
auto & Map = m_pEditor - > m_Map ;
switch ( m_Type )
{
case EType : : DELETE :
{
Map . m_vSettings . insert ( Map . m_vSettings . begin ( ) + m_CommandIndex , m_PreviousCommand . c_str ( ) ) ;
* m_pSelectedCommandIndex = m_CommandIndex ;
break ;
}
case EType : : ADD :
{
Map . m_vSettings . erase ( Map . m_vSettings . begin ( ) + m_CommandIndex ) ;
* m_pSelectedCommandIndex = Map . m_vSettings . size ( ) - 1 ;
break ;
}
case EType : : EDIT :
{
str_copy ( Map . m_vSettings [ m_CommandIndex ] . m_aCommand , m_PreviousCommand . c_str ( ) ) ;
* m_pSelectedCommandIndex = m_CommandIndex ;
break ;
}
case EType : : MOVE_DOWN :
{
std : : swap ( Map . m_vSettings [ m_CommandIndex ] , Map . m_vSettings [ m_CommandIndex + 1 ] ) ;
* m_pSelectedCommandIndex = m_CommandIndex ;
break ;
}
case EType : : MOVE_UP :
{
std : : swap ( Map . m_vSettings [ m_CommandIndex ] , Map . m_vSettings [ m_CommandIndex - 1 ] ) ;
* m_pSelectedCommandIndex = m_CommandIndex ;
break ;
}
}
}
void CEditorCommandAction : : Redo ( )
{
auto & Map = m_pEditor - > m_Map ;
switch ( m_Type )
{
case EType : : DELETE :
{
Map . m_vSettings . erase ( Map . m_vSettings . begin ( ) + m_CommandIndex ) ;
* m_pSelectedCommandIndex = Map . m_vSettings . size ( ) - 1 ;
break ;
}
case EType : : ADD :
{
Map . m_vSettings . insert ( Map . m_vSettings . begin ( ) + m_CommandIndex , m_PreviousCommand . c_str ( ) ) ;
* m_pSelectedCommandIndex = m_CommandIndex ;
break ;
}
case EType : : EDIT :
{
str_copy ( Map . m_vSettings [ m_CommandIndex ] . m_aCommand , m_CurrentCommand . c_str ( ) ) ;
* m_pSelectedCommandIndex = m_CommandIndex ;
break ;
}
case EType : : MOVE_DOWN :
{
std : : swap ( Map . m_vSettings [ m_CommandIndex ] , Map . m_vSettings [ m_CommandIndex + 1 ] ) ;
* m_pSelectedCommandIndex = m_CommandIndex ;
break ;
}
case EType : : MOVE_UP :
{
std : : swap ( Map . m_vSettings [ m_CommandIndex ] , Map . m_vSettings [ m_CommandIndex - 1 ] ) ;
* m_pSelectedCommandIndex = m_CommandIndex ;
break ;
}
}
}
// ------------------------------------------------
CEditorActionEnvelopeAdd : : CEditorActionEnvelopeAdd ( CEditor * pEditor , const std : : shared_ptr < CEnvelope > & pEnv ) :
IEditorAction ( pEditor ) , m_pEnv ( pEnv )
{
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Add new %s envelope " , pEnv - > Type ( ) = = CEnvelope : : EType : : COLOR ? " color " : ( pEnv - > Type ( ) = = CEnvelope : : EType : : POSITION ? " position " : " sound " ) ) ;
}
void CEditorActionEnvelopeAdd : : Undo ( )
{
// Undo is removing the envelope, which was added at the back of the list
m_pEditor - > m_Map . m_vpEnvelopes . pop_back ( ) ;
m_pEditor - > m_SelectedEnvelope = m_pEditor - > m_Map . m_vpEnvelopes . size ( ) - 1 ;
}
void CEditorActionEnvelopeAdd : : Redo ( )
{
// Redo is adding back at the back the saved envelope
m_pEditor - > m_Map . m_vpEnvelopes . push_back ( m_pEnv ) ;
m_pEditor - > m_SelectedEnvelope = m_pEditor - > m_Map . m_vpEnvelopes . size ( ) - 1 ;
}
CEditorActionEveloppeDelete : : CEditorActionEveloppeDelete ( CEditor * pEditor , int EnvelopeIndex ) :
IEditorAction ( pEditor ) , m_EnvelopeIndex ( EnvelopeIndex ) , m_pEnv ( pEditor - > m_Map . m_vpEnvelopes [ EnvelopeIndex ] )
{
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Delete envelope %d " , m_EnvelopeIndex ) ;
}
void CEditorActionEveloppeDelete : : Undo ( )
{
// Undo is adding back the envelope
m_pEditor - > m_Map . m_vpEnvelopes . insert ( m_pEditor - > m_Map . m_vpEnvelopes . begin ( ) + m_EnvelopeIndex , m_pEnv ) ;
m_pEditor - > m_SelectedEnvelope = m_EnvelopeIndex ;
}
void CEditorActionEveloppeDelete : : Redo ( )
{
// Redo is erasing the same envelope index
m_pEditor - > m_Map . m_vpEnvelopes . erase ( m_pEditor - > m_Map . m_vpEnvelopes . begin ( ) + m_EnvelopeIndex ) ;
if ( m_pEditor - > m_SelectedEnvelope > = ( int ) m_pEditor - > m_Map . m_vpEnvelopes . size ( ) )
m_pEditor - > m_SelectedEnvelope = m_pEditor - > m_Map . m_vpEnvelopes . size ( ) - 1 ;
}
CEditorActionEnvelopeEdit : : CEditorActionEnvelopeEdit ( CEditor * pEditor , int EnvelopeIndex , EEditType EditType , int Previous , int Current ) :
IEditorAction ( pEditor ) , m_EnvelopeIndex ( EnvelopeIndex ) , m_EditType ( EditType ) , m_Previous ( Previous ) , m_Current ( Current ) , m_pEnv ( pEditor - > m_Map . m_vpEnvelopes [ EnvelopeIndex ] )
{
static const char * s_apNames [ ] = {
" sync " ,
" order " } ;
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Edit envelope %d %s " , m_EnvelopeIndex , s_apNames [ ( int ) m_EditType ] ) ;
}
void CEditorActionEnvelopeEdit : : Undo ( )
{
switch ( m_EditType )
{
case EEditType : : ORDER :
{
m_pEditor - > m_Map . SwapEnvelopes ( m_Current , m_Previous ) ;
break ;
}
case EEditType : : SYNC :
{
m_pEnv - > m_Synchronized = m_Previous ;
break ;
}
}
m_pEditor - > m_Map . OnModify ( ) ;
m_pEditor - > m_SelectedEnvelope = m_EnvelopeIndex ;
}
void CEditorActionEnvelopeEdit : : Redo ( )
{
switch ( m_EditType )
{
case EEditType : : ORDER :
{
m_pEditor - > m_Map . SwapEnvelopes ( m_Previous , m_Current ) ;
break ;
}
case EEditType : : SYNC :
{
m_pEnv - > m_Synchronized = m_Current ;
break ;
}
}
m_pEditor - > m_Map . OnModify ( ) ;
m_pEditor - > m_SelectedEnvelope = m_EnvelopeIndex ;
}
CEditorActionEnvelopeEditPoint : : CEditorActionEnvelopeEditPoint ( CEditor * pEditor , int EnvelopeIndex , int PointIndex , int Channel , EEditType EditType , int Previous , int Current ) :
IEditorAction ( pEditor ) , m_EnvelopeIndex ( EnvelopeIndex ) , m_PointIndex ( PointIndex ) , m_Channel ( Channel ) , m_EditType ( EditType ) , m_Previous ( Previous ) , m_Current ( Current ) , m_pEnv ( pEditor - > m_Map . m_vpEnvelopes [ EnvelopeIndex ] )
{
static const char * s_apNames [ ] = {
" time " ,
" value " ,
" curve type " } ;
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Edit %s of point %d (channel %d) of env %d " , s_apNames [ ( int ) m_EditType ] , m_PointIndex , m_Channel , m_EnvelopeIndex ) ;
}
void CEditorActionEnvelopeEditPoint : : Undo ( )
{
Apply ( m_Previous ) ;
}
void CEditorActionEnvelopeEditPoint : : Redo ( )
{
Apply ( m_Current ) ;
}
void CEditorActionEnvelopeEditPoint : : Apply ( int Value )
{
if ( m_EditType = = EEditType : : TIME )
{
m_pEnv - > m_vPoints [ m_PointIndex ] . m_Time = Value ;
}
else if ( m_EditType = = EEditType : : VALUE )
{
m_pEnv - > m_vPoints [ m_PointIndex ] . m_aValues [ m_Channel ] = Value ;
if ( m_pEnv - > GetChannels ( ) = = 4 )
{
auto * pValues = m_pEnv - > m_vPoints [ m_PointIndex ] . m_aValues ;
const ColorRGBA Color = ColorRGBA ( fx2f ( pValues [ 0 ] ) , fx2f ( pValues [ 1 ] ) , fx2f ( pValues [ 2 ] ) , fx2f ( pValues [ 3 ] ) ) ;
m_pEditor - > m_ColorPickerPopupContext . m_RgbaColor = Color ;
m_pEditor - > m_ColorPickerPopupContext . m_HslaColor = color_cast < ColorHSLA > ( Color ) ;
m_pEditor - > m_ColorPickerPopupContext . m_HsvaColor = color_cast < ColorHSVA > ( m_pEditor - > m_ColorPickerPopupContext . m_HslaColor ) ;
}
}
else if ( m_EditType = = EEditType : : CURVE_TYPE )
{
m_pEnv - > m_vPoints [ m_PointIndex ] . m_Curvetype = Value ;
}
m_pEditor - > m_Map . OnModify ( ) ;
}
// ----
CEditorActionEditEnvelopePointValue : : CEditorActionEditEnvelopePointValue ( CEditor * pEditor , int EnvIndex , int PointIndex , int Channel , EType Type , int OldTime , int OldValue , int NewTime , int NewValue ) :
IEditorAction ( pEditor ) , m_EnvIndex ( EnvIndex ) , m_PtIndex ( PointIndex ) , m_Channel ( Channel ) , m_Type ( Type ) , m_OldTime ( OldTime ) , m_OldValue ( OldValue ) , m_NewTime ( NewTime ) , m_NewValue ( NewValue )
{
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Edit point %d%s value (envelope %d, channel %d) " , PointIndex , m_Type = = EType : : TANGENT_IN ? " tangent in " : ( m_Type = = EType : : TANGENT_OUT ? " tangent out " : " " ) , m_EnvIndex , m_Channel ) ;
}
void CEditorActionEditEnvelopePointValue : : Undo ( )
{
Apply ( true ) ;
}
void CEditorActionEditEnvelopePointValue : : Redo ( )
{
Apply ( false ) ;
}
void CEditorActionEditEnvelopePointValue : : Apply ( bool Undo )
{
float CurrentValue = fx2f ( Undo ? m_OldValue : m_NewValue ) ;
float CurrentTime = ( Undo ? m_OldTime : m_NewTime ) / 1000.0f ;
std : : shared_ptr < CEnvelope > pEnvelope = m_pEditor - > m_Map . m_vpEnvelopes [ m_EnvIndex ] ;
if ( m_Type = = EType : : TANGENT_IN )
{
pEnvelope - > m_vPoints [ m_PtIndex ] . m_Bezier . m_aInTangentDeltaX [ m_Channel ] = minimum < int > ( CurrentTime * 1000.0f - pEnvelope - > m_vPoints [ m_PtIndex ] . m_Time , 0 ) ;
pEnvelope - > m_vPoints [ m_PtIndex ] . m_Bezier . m_aInTangentDeltaY [ m_Channel ] = f2fx ( CurrentValue ) - pEnvelope - > m_vPoints [ m_PtIndex ] . m_aValues [ m_Channel ] ;
}
else if ( m_Type = = EType : : TANGENT_OUT )
{
pEnvelope - > m_vPoints [ m_PtIndex ] . m_Bezier . m_aOutTangentDeltaX [ m_Channel ] = maximum < int > ( CurrentTime * 1000.0f - pEnvelope - > m_vPoints [ m_PtIndex ] . m_Time , 0 ) ;
pEnvelope - > m_vPoints [ m_PtIndex ] . m_Bezier . m_aOutTangentDeltaY [ m_Channel ] = f2fx ( CurrentValue ) - pEnvelope - > m_vPoints [ m_PtIndex ] . m_aValues [ m_Channel ] ;
}
else
{
if ( pEnvelope - > GetChannels ( ) = = 4 )
CurrentValue = clamp ( CurrentValue , 0.0f , 1.0f ) ;
pEnvelope - > m_vPoints [ m_PtIndex ] . m_aValues [ m_Channel ] = f2fx ( CurrentValue ) ;
if ( m_PtIndex ! = 0 )
{
pEnvelope - > m_vPoints [ m_PtIndex ] . m_Time = CurrentTime * 1000.0f ;
if ( pEnvelope - > m_vPoints [ m_PtIndex ] . m_Time < pEnvelope - > m_vPoints [ m_PtIndex - 1 ] . m_Time )
pEnvelope - > m_vPoints [ m_PtIndex ] . m_Time = pEnvelope - > m_vPoints [ m_PtIndex - 1 ] . m_Time + 1 ;
if ( static_cast < size_t > ( m_PtIndex ) + 1 ! = pEnvelope - > m_vPoints . size ( ) & & pEnvelope - > m_vPoints [ m_PtIndex ] . m_Time > pEnvelope - > m_vPoints [ m_PtIndex + 1 ] . m_Time )
pEnvelope - > m_vPoints [ m_PtIndex ] . m_Time = pEnvelope - > m_vPoints [ m_PtIndex + 1 ] . m_Time - 1 ;
}
else
{
pEnvelope - > m_vPoints [ m_PtIndex ] . m_Time = 0.0f ;
}
}
m_pEditor - > m_Map . OnModify ( ) ;
m_pEditor - > m_UpdateEnvPointInfo = true ;
}
// ---------------------
CEditorActionResetEnvelopePointTangent : : CEditorActionResetEnvelopePointTangent ( CEditor * pEditor , int EnvIndex , int PointIndex , int Channel , bool In ) :
IEditorAction ( pEditor ) , m_EnvIndex ( EnvIndex ) , m_PointIndex ( PointIndex ) , m_Channel ( Channel ) , m_In ( In )
{
std : : shared_ptr < CEnvelope > pEnvelope = pEditor - > m_Map . m_vpEnvelopes [ EnvIndex ] ;
if ( In )
{
m_Previous [ 0 ] = pEnvelope - > m_vPoints [ PointIndex ] . m_Bezier . m_aInTangentDeltaX [ Channel ] ;
m_Previous [ 1 ] = pEnvelope - > m_vPoints [ PointIndex ] . m_Bezier . m_aInTangentDeltaY [ Channel ] ;
}
else
{
m_Previous [ 0 ] = pEnvelope - > m_vPoints [ PointIndex ] . m_Bezier . m_aOutTangentDeltaX [ Channel ] ;
m_Previous [ 1 ] = pEnvelope - > m_vPoints [ PointIndex ] . m_Bezier . m_aOutTangentDeltaY [ Channel ] ;
}
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Reset point %d of env %d tangent %s " , m_PointIndex , m_EnvIndex , m_In ? " in " : " out " ) ;
}
void CEditorActionResetEnvelopePointTangent : : Undo ( )
{
std : : shared_ptr < CEnvelope > pEnvelope = m_pEditor - > m_Map . m_vpEnvelopes [ m_EnvIndex ] ;
if ( m_In )
{
pEnvelope - > m_vPoints [ m_PointIndex ] . m_Bezier . m_aInTangentDeltaX [ m_Channel ] = m_Previous [ 0 ] ;
pEnvelope - > m_vPoints [ m_PointIndex ] . m_Bezier . m_aInTangentDeltaY [ m_Channel ] = m_Previous [ 1 ] ;
}
else
{
pEnvelope - > m_vPoints [ m_PointIndex ] . m_Bezier . m_aOutTangentDeltaX [ m_Channel ] = m_Previous [ 0 ] ;
pEnvelope - > m_vPoints [ m_PointIndex ] . m_Bezier . m_aOutTangentDeltaY [ m_Channel ] = m_Previous [ 1 ] ;
}
m_pEditor - > m_Map . OnModify ( ) ;
}
void CEditorActionResetEnvelopePointTangent : : Redo ( )
{
std : : shared_ptr < CEnvelope > pEnvelope = m_pEditor - > m_Map . m_vpEnvelopes [ m_EnvIndex ] ;
if ( m_In )
{
pEnvelope - > m_vPoints [ m_PointIndex ] . m_Bezier . m_aInTangentDeltaX [ m_Channel ] = 0.0f ;
pEnvelope - > m_vPoints [ m_PointIndex ] . m_Bezier . m_aInTangentDeltaY [ m_Channel ] = 0.0f ;
}
else
{
pEnvelope - > m_vPoints [ m_PointIndex ] . m_Bezier . m_aOutTangentDeltaX [ m_Channel ] = 0.0f ;
pEnvelope - > m_vPoints [ m_PointIndex ] . m_Bezier . m_aOutTangentDeltaY [ m_Channel ] = 0.0f ;
}
m_pEditor - > m_Map . OnModify ( ) ;
}
// ------------------
CEditorActionAddEnvelopePoint : : CEditorActionAddEnvelopePoint ( CEditor * pEditor , int EnvIndex , int Time , ColorRGBA Channels ) :
IEditorAction ( pEditor ) , m_EnvIndex ( EnvIndex ) , m_Time ( Time ) , m_Channels ( Channels )
{
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Add new point in envelope %d at time %f " , m_EnvIndex , Time / 1000.0 ) ;
}
void CEditorActionAddEnvelopePoint : : Undo ( )
{
// Delete added point
auto pEnvelope = m_pEditor - > m_Map . m_vpEnvelopes [ m_EnvIndex ] ;
auto pIt = std : : find_if ( pEnvelope - > m_vPoints . begin ( ) , pEnvelope - > m_vPoints . end ( ) , [ this ] ( const CEnvPoint_runtime & Point ) {
return Point . m_Time = = m_Time ;
} ) ;
if ( pIt ! = pEnvelope - > m_vPoints . end ( ) )
{
pEnvelope - > m_vPoints . erase ( pIt ) ;
}
m_pEditor - > m_Map . OnModify ( ) ;
}
void CEditorActionAddEnvelopePoint : : Redo ( )
{
auto pEnvelope = m_pEditor - > m_Map . m_vpEnvelopes [ m_EnvIndex ] ;
pEnvelope - > AddPoint ( m_Time ,
f2fx ( m_Channels . r ) , f2fx ( m_Channels . g ) ,
f2fx ( m_Channels . b ) , f2fx ( m_Channels . a ) ) ;
m_pEditor - > m_Map . OnModify ( ) ;
}
CEditorActionDeleteEnvelopePoint : : CEditorActionDeleteEnvelopePoint ( CEditor * pEditor , int EnvIndex , int PointIndex ) :
IEditorAction ( pEditor ) , m_EnvIndex ( EnvIndex ) , m_PointIndex ( PointIndex ) , m_Point ( pEditor - > m_Map . m_vpEnvelopes [ EnvIndex ] - > m_vPoints [ PointIndex ] )
{
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Delete point %d of envelope %d " , m_PointIndex , m_EnvIndex ) ;
}
void CEditorActionDeleteEnvelopePoint : : Undo ( )
{
std : : shared_ptr < CEnvelope > pEnvelope = m_pEditor - > m_Map . m_vpEnvelopes [ m_EnvIndex ] ;
pEnvelope - > m_vPoints . insert ( pEnvelope - > m_vPoints . begin ( ) + m_PointIndex , m_Point ) ;
m_pEditor - > m_Map . OnModify ( ) ;
}
void CEditorActionDeleteEnvelopePoint : : Redo ( )
{
std : : shared_ptr < CEnvelope > pEnvelope = m_pEditor - > m_Map . m_vpEnvelopes [ m_EnvIndex ] ;
pEnvelope - > m_vPoints . erase ( pEnvelope - > m_vPoints . begin ( ) + m_PointIndex ) ;
auto pSelectedPointIt = std : : find_if ( m_pEditor - > m_vSelectedEnvelopePoints . begin ( ) , m_pEditor - > m_vSelectedEnvelopePoints . end ( ) , [ this ] ( const std : : pair < int , int > Pair ) {
return Pair . first = = m_PointIndex ;
} ) ;
if ( pSelectedPointIt ! = m_pEditor - > m_vSelectedEnvelopePoints . end ( ) )
m_pEditor - > m_vSelectedEnvelopePoints . erase ( pSelectedPointIt ) ;
m_pEditor - > m_Map . OnModify ( ) ;
}
// -------------------------------
CEditorActionEditLayerSoundsProp : : CEditorActionEditLayerSoundsProp ( CEditor * pEditor , int GroupIndex , int LayerIndex , ELayerSoundsProp Prop , int Previous , int Current ) :
CEditorActionEditLayerPropBase ( pEditor , GroupIndex , LayerIndex , Prop , Previous , Current )
{
static const char * s_apNames [ ] = {
" sound " } ;
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Edit sounds layer %d in group %d %s property " , m_LayerIndex , m_GroupIndex , s_apNames [ ( int ) m_Prop ] ) ;
}
void CEditorActionEditLayerSoundsProp : : Undo ( )
{
Apply ( m_Previous ) ;
}
void CEditorActionEditLayerSoundsProp : : Redo ( )
{
Apply ( m_Current ) ;
}
void CEditorActionEditLayerSoundsProp : : Apply ( int Value )
{
std : : shared_ptr < CLayerSounds > pLayerSounds = std : : static_pointer_cast < CLayerSounds > ( m_pLayer ) ;
if ( m_Prop = = ELayerSoundsProp : : PROP_SOUND )
{
if ( Value > = 0 )
pLayerSounds - > m_Sound = Value % m_pEditor - > m_Map . m_vpSounds . size ( ) ;
else
pLayerSounds - > m_Sound = - 1 ;
}
m_pEditor - > m_Map . OnModify ( ) ;
}
// ---
CEditorActionDeleteSoundSource : : CEditorActionDeleteSoundSource ( CEditor * pEditor , int GroupIndex , int LayerIndex , int SourceIndex ) :
CEditorActionLayerBase ( pEditor , GroupIndex , LayerIndex ) , m_SourceIndex ( SourceIndex )
{
std : : shared_ptr < CLayerSounds > pLayerSounds = std : : static_pointer_cast < CLayerSounds > ( m_pLayer ) ;
m_Source = pLayerSounds - > m_vSources [ SourceIndex ] ;
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Delete sound source %d in layer %d of group %d " , SourceIndex , LayerIndex , GroupIndex ) ;
}
void CEditorActionDeleteSoundSource : : Undo ( )
{
std : : shared_ptr < CLayerSounds > pLayerSounds = std : : static_pointer_cast < CLayerSounds > ( m_pLayer ) ;
pLayerSounds - > m_vSources . insert ( pLayerSounds - > m_vSources . begin ( ) + m_SourceIndex , m_Source ) ;
m_pEditor - > m_SelectedSource = m_SourceIndex ;
m_pEditor - > m_Map . OnModify ( ) ;
}
void CEditorActionDeleteSoundSource : : Redo ( )
{
std : : shared_ptr < CLayerSounds > pLayerSounds = std : : static_pointer_cast < CLayerSounds > ( m_pLayer ) ;
pLayerSounds - > m_vSources . erase ( pLayerSounds - > m_vSources . begin ( ) + m_SourceIndex ) ;
m_pEditor - > m_SelectedSource - - ;
m_pEditor - > m_Map . OnModify ( ) ;
}
// ---------------
CEditorActionEditSoundSource : : CEditorActionEditSoundSource ( CEditor * pEditor , int GroupIndex , int LayerIndex , int SourceIndex , EEditType Type , int Value ) :
CEditorActionLayerBase ( pEditor , GroupIndex , LayerIndex ) , m_SourceIndex ( SourceIndex ) , m_EditType ( Type ) , m_CurrentValue ( Value ) , m_pSavedObject ( nullptr )
{
Save ( ) ;
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Edit sound source %d in layer %d of group %d " , SourceIndex , LayerIndex , GroupIndex ) ;
}
void CEditorActionEditSoundSource : : Undo ( )
{
std : : shared_ptr < CLayerSounds > pLayerSounds = std : : static_pointer_cast < CLayerSounds > ( m_pLayer ) ;
CSoundSource * pSource = & pLayerSounds - > m_vSources [ m_SourceIndex ] ;
if ( m_EditType = = EEditType : : SHAPE )
{
CSoundShape * pSavedShape = ( CSoundShape * ) m_pSavedObject ;
pSource - > m_Shape . m_Type = pSavedShape - > m_Type ;
// set default values
switch ( pSource - > m_Shape . m_Type )
{
case CSoundShape : : SHAPE_CIRCLE :
{
pSource - > m_Shape . m_Circle . m_Radius = pSavedShape - > m_Circle . m_Radius ;
break ;
}
case CSoundShape : : SHAPE_RECTANGLE :
{
pSource - > m_Shape . m_Rectangle . m_Width = pSavedShape - > m_Rectangle . m_Width ;
pSource - > m_Shape . m_Rectangle . m_Height = pSavedShape - > m_Rectangle . m_Height ;
break ;
}
}
}
m_pEditor - > m_Map . OnModify ( ) ;
}
void CEditorActionEditSoundSource : : Redo ( )
{
std : : shared_ptr < CLayerSounds > pLayerSounds = std : : static_pointer_cast < CLayerSounds > ( m_pLayer ) ;
CSoundSource * pSource = & pLayerSounds - > m_vSources [ m_SourceIndex ] ;
if ( m_EditType = = EEditType : : SHAPE )
{
pSource - > m_Shape . m_Type = m_CurrentValue ;
// set default values
switch ( pSource - > m_Shape . m_Type )
{
case CSoundShape : : SHAPE_CIRCLE :
{
pSource - > m_Shape . m_Circle . m_Radius = 1000.0f ;
break ;
}
case CSoundShape : : SHAPE_RECTANGLE :
{
pSource - > m_Shape . m_Rectangle . m_Width = f2fx ( 1000.0f ) ;
pSource - > m_Shape . m_Rectangle . m_Height = f2fx ( 800.0f ) ;
break ;
}
}
}
m_pEditor - > m_Map . OnModify ( ) ;
}
void CEditorActionEditSoundSource : : Save ( )
{
std : : shared_ptr < CLayerSounds > pLayerSounds = std : : static_pointer_cast < CLayerSounds > ( m_pLayer ) ;
CSoundSource * pSource = & pLayerSounds - > m_vSources [ m_SourceIndex ] ;
if ( m_EditType = = EEditType : : SHAPE )
{
CSoundShape * pShapeInfo = new CSoundShape ;
pShapeInfo - > m_Type = pSource - > m_Shape . m_Type ;
switch ( pSource - > m_Shape . m_Type )
{
case CSoundShape : : SHAPE_CIRCLE :
{
pShapeInfo - > m_Circle . m_Radius = pSource - > m_Shape . m_Circle . m_Radius ;
break ;
}
case CSoundShape : : SHAPE_RECTANGLE :
{
pShapeInfo - > m_Rectangle . m_Width = pSource - > m_Shape . m_Rectangle . m_Width ;
pShapeInfo - > m_Rectangle . m_Height = pSource - > m_Shape . m_Rectangle . m_Height ;
break ;
}
}
m_pSavedObject = pShapeInfo ;
}
}
CEditorActionEditSoundSource : : ~ CEditorActionEditSoundSource ( )
{
if ( m_EditType = = EEditType : : SHAPE )
{
CSoundShape * pSavedShape = ( CSoundShape * ) m_pSavedObject ;
delete pSavedShape ;
}
}
// -----
CEditorActionEditSoundSourceProp : : CEditorActionEditSoundSourceProp ( CEditor * pEditor , int GroupIndex , int LayerIndex , int SourceIndex , ESoundProp Prop , int Previous , int Current ) :
CEditorActionEditLayerPropBase ( pEditor , GroupIndex , LayerIndex , Prop , Previous , Current ) , m_SourceIndex ( SourceIndex )
{
static const char * s_apNames [ ] = {
" pos X " ,
" pos Y " ,
" loop " ,
" pan " ,
" time delay " ,
" falloff " ,
" pos env " ,
" pos env offset " ,
" sound env " ,
" sound env offset " } ;
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Edit sound source %d in layer %d of group %d %s property " , SourceIndex , LayerIndex , GroupIndex , s_apNames [ ( int ) Prop ] ) ;
}
void CEditorActionEditSoundSourceProp : : Undo ( )
{
Apply ( m_Previous ) ;
}
void CEditorActionEditSoundSourceProp : : Redo ( )
{
Apply ( m_Current ) ;
}
void CEditorActionEditSoundSourceProp : : Apply ( int Value )
{
std : : shared_ptr < CLayerSounds > pLayerSounds = std : : static_pointer_cast < CLayerSounds > ( m_pLayer ) ;
CSoundSource * pSource = & pLayerSounds - > m_vSources [ m_SourceIndex ] ;
if ( m_Prop = = ESoundProp : : PROP_POS_X )
{
pSource - > m_Position . x = Value ;
}
else if ( m_Prop = = ESoundProp : : PROP_POS_Y )
{
pSource - > m_Position . y = Value ;
}
else if ( m_Prop = = ESoundProp : : PROP_LOOP )
{
pSource - > m_Loop = Value ;
}
else if ( m_Prop = = ESoundProp : : PROP_PAN )
{
pSource - > m_Pan = Value ;
}
else if ( m_Prop = = ESoundProp : : PROP_TIME_DELAY )
{
pSource - > m_TimeDelay = Value ;
}
else if ( m_Prop = = ESoundProp : : PROP_FALLOFF )
{
pSource - > m_Falloff = Value ;
}
else if ( m_Prop = = ESoundProp : : PROP_POS_ENV )
{
pSource - > m_PosEnv = Value ;
}
else if ( m_Prop = = ESoundProp : : PROP_POS_ENV_OFFSET )
{
pSource - > m_PosEnvOffset = Value ;
}
else if ( m_Prop = = ESoundProp : : PROP_SOUND_ENV )
{
pSource - > m_SoundEnv = Value ;
}
else if ( m_Prop = = ESoundProp : : PROP_SOUND_ENV_OFFSET )
{
pSource - > m_SoundEnvOffset = Value ;
}
m_pEditor - > m_Map . OnModify ( ) ;
}
CEditorActionEditRectSoundSourceShapeProp : : CEditorActionEditRectSoundSourceShapeProp ( CEditor * pEditor , int GroupIndex , int LayerIndex , int SourceIndex , ERectangleShapeProp Prop , int Previous , int Current ) :
CEditorActionEditLayerPropBase ( pEditor , GroupIndex , LayerIndex , Prop , Previous , Current ) , m_SourceIndex ( SourceIndex )
{
static const char * s_apNames [ ] = {
" width " ,
" height " } ;
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Edit sound source %d in layer %d of group %d sound shape %s property " , m_SourceIndex , m_LayerIndex , m_GroupIndex , s_apNames [ ( int ) Prop ] ) ;
}
void CEditorActionEditRectSoundSourceShapeProp : : Undo ( )
{
Apply ( m_Previous ) ;
}
void CEditorActionEditRectSoundSourceShapeProp : : Redo ( )
{
Apply ( m_Current ) ;
}
void CEditorActionEditRectSoundSourceShapeProp : : Apply ( int Value )
{
std : : shared_ptr < CLayerSounds > pLayerSounds = std : : static_pointer_cast < CLayerSounds > ( m_pLayer ) ;
CSoundSource * pSource = & pLayerSounds - > m_vSources [ m_SourceIndex ] ;
if ( m_Prop = = ERectangleShapeProp : : PROP_RECTANGLE_WIDTH )
{
pSource - > m_Shape . m_Rectangle . m_Width = Value ;
}
else if ( m_Prop = = ERectangleShapeProp : : PROP_RECTANGLE_HEIGHT )
{
pSource - > m_Shape . m_Rectangle . m_Height = Value ;
}
m_pEditor - > m_Map . OnModify ( ) ;
}
CEditorActionEditCircleSoundSourceShapeProp : : CEditorActionEditCircleSoundSourceShapeProp ( CEditor * pEditor , int GroupIndex , int LayerIndex , int SourceIndex , ECircleShapeProp Prop , int Previous , int Current ) :
CEditorActionEditLayerPropBase ( pEditor , GroupIndex , LayerIndex , Prop , Previous , Current ) , m_SourceIndex ( SourceIndex )
{
static const char * s_apNames [ ] = {
" radius " } ;
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " Edit sound source %d in layer %d of group %d sound shape %s property " , m_SourceIndex , m_LayerIndex , m_GroupIndex , s_apNames [ ( int ) Prop ] ) ;
}
void CEditorActionEditCircleSoundSourceShapeProp : : Undo ( )
{
Apply ( m_Previous ) ;
}
void CEditorActionEditCircleSoundSourceShapeProp : : Redo ( )
{
Apply ( m_Current ) ;
}
void CEditorActionEditCircleSoundSourceShapeProp : : Apply ( int Value )
{
std : : shared_ptr < CLayerSounds > pLayerSounds = std : : static_pointer_cast < CLayerSounds > ( m_pLayer ) ;
CSoundSource * pSource = & pLayerSounds - > m_vSources [ m_SourceIndex ] ;
if ( m_Prop = = ECircleShapeProp : : PROP_CIRCLE_RADIUS )
{
pSource - > m_Shape . m_Circle . m_Radius = Value ;
}
m_pEditor - > m_Map . OnModify ( ) ;
}
// --------------------------
CEditorActionNewEmptySound : : CEditorActionNewEmptySound ( CEditor * pEditor , int GroupIndex , int LayerIndex , int x , int y ) :
CEditorActionLayerBase ( pEditor , GroupIndex , LayerIndex ) , m_X ( x ) , m_Y ( y )
{
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " New sound in layer %d of group %d " , LayerIndex , GroupIndex ) ;
}
void CEditorActionNewEmptySound : : Undo ( )
{
// Undo is simply deleting the added source
std : : shared_ptr < CLayerSounds > pLayerSounds = std : : static_pointer_cast < CLayerSounds > ( m_pLayer ) ;
pLayerSounds - > m_vSources . pop_back ( ) ;
m_pEditor - > m_Map . OnModify ( ) ;
}
void CEditorActionNewEmptySound : : Redo ( )
{
auto & Map = m_pEditor - > m_Map ;
std : : shared_ptr < CLayerSounds > pLayerSounds = std : : static_pointer_cast < CLayerSounds > ( m_pLayer ) ;
pLayerSounds - > NewSource ( m_X , m_Y ) ;
Map . OnModify ( ) ;
}
CEditorActionNewEmptyQuad : : CEditorActionNewEmptyQuad ( CEditor * pEditor , int GroupIndex , int LayerIndex , int x , int y ) :
CEditorActionLayerBase ( pEditor , GroupIndex , LayerIndex ) , m_X ( x ) , m_Y ( y )
{
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " New quad in layer %d of group %d " , LayerIndex , GroupIndex ) ;
}
void CEditorActionNewEmptyQuad : : Undo ( )
{
// Undo is simply deleting the added quad
std : : shared_ptr < CLayerQuads > pLayerQuads = std : : static_pointer_cast < CLayerQuads > ( m_pLayer ) ;
pLayerQuads - > m_vQuads . pop_back ( ) ;
m_pEditor - > m_Map . OnModify ( ) ;
}
void CEditorActionNewEmptyQuad : : Redo ( )
{
auto & Map = m_pEditor - > m_Map ;
std : : shared_ptr < CLayerQuads > pLayerQuads = std : : static_pointer_cast < CLayerQuads > ( m_pLayer ) ;
int Width = 64 ;
int Height = 64 ;
if ( pLayerQuads - > m_Image > = 0 )
{
Width = Map . m_vpImages [ pLayerQuads - > m_Image ] - > m_Width ;
Height = Map . m_vpImages [ pLayerQuads - > m_Image ] - > m_Height ;
}
pLayerQuads - > NewQuad ( m_X , m_Y , Width , Height ) ;
Map . OnModify ( ) ;
}
// -------------
CEditorActionNewQuad : : CEditorActionNewQuad ( CEditor * pEditor , int GroupIndex , int LayerIndex ) :
CEditorActionLayerBase ( pEditor , GroupIndex , LayerIndex )
{
std : : shared_ptr < CLayerQuads > pLayerQuads = std : : static_pointer_cast < CLayerQuads > ( m_pLayer ) ;
m_Quad = pLayerQuads - > m_vQuads [ pLayerQuads - > m_vQuads . size ( ) - 1 ] ;
str_format ( m_aDisplayText , sizeof ( m_aDisplayText ) , " New quad in layer %d of group %d " , LayerIndex , GroupIndex ) ;
}
void CEditorActionNewQuad : : Undo ( )
{
std : : shared_ptr < CLayerQuads > pLayerQuads = std : : static_pointer_cast < CLayerQuads > ( m_pLayer ) ;
pLayerQuads - > m_vQuads . pop_back ( ) ;
}
void CEditorActionNewQuad : : Redo ( )
{
std : : shared_ptr < CLayerQuads > pLayerQuads = std : : static_pointer_cast < CLayerQuads > ( m_pLayer ) ;
pLayerQuads - > m_vQuads . emplace_back ( m_Quad ) ;
}