mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
Add editor undo function (by MAP94)
This commit is contained in:
parent
24fcc8c8b0
commit
d092b8007d
|
@ -949,6 +949,13 @@ void CGraphics_SDL::TakeScreenshot(const char *pFilename)
|
|||
m_DoScreenshot = true;
|
||||
}
|
||||
|
||||
void CGraphics_SDL::TakeCustomScreenshot(const char *pFilename)
|
||||
{
|
||||
str_copy(m_aScreenshotName, pFilename, sizeof(m_aScreenshotName));
|
||||
m_DoScreenshot = true;
|
||||
}
|
||||
|
||||
|
||||
void CGraphics_SDL::Swap()
|
||||
{
|
||||
if(m_DoScreenshot)
|
||||
|
|
|
@ -143,6 +143,7 @@ public:
|
|||
virtual int WindowOpen();
|
||||
|
||||
virtual void TakeScreenshot(const char *pFilename);
|
||||
virtual void TakeCustomScreenshot(const char *pFilename);
|
||||
virtual void Swap();
|
||||
|
||||
virtual int GetVideoModes(CVideoMode *pModes, int MaxModes);
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
#include <base/math.h>
|
||||
#include <base/tl/threading.h>
|
||||
|
||||
#if defined(CONF_FAMILY_UNIX)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include <base/system.h>
|
||||
#include <engine/external/pnglite/pnglite.h>
|
||||
|
||||
|
@ -446,19 +450,29 @@ void CGraphics_Threaded::KickCommandBuffer()
|
|||
m_pCommandBuffer->Reset();
|
||||
}
|
||||
|
||||
void CGraphics_Threaded::ScreenshotDirect(const char *pFilename)
|
||||
void CGraphics_Threaded::ScreenshotDirect()
|
||||
{
|
||||
void *ScreenshotThread = thread_create(ScreenshotDirectThread, this);
|
||||
#if defined(CONF_FAMILY_UNIX)
|
||||
pthread_detach((pthread_t)ScreenshotThread);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CGraphics_Threaded::ScreenshotDirectThread(void *pData)
|
||||
{
|
||||
CGraphics_Threaded *pGraphics = (CGraphics_Threaded *) pData;
|
||||
|
||||
// add swap command
|
||||
CImageInfo Image;
|
||||
mem_zero(&Image, sizeof(Image));
|
||||
|
||||
CCommandBuffer::SCommand_Screenshot Cmd;
|
||||
Cmd.m_pImage = &Image;
|
||||
m_pCommandBuffer->AddCommand(Cmd);
|
||||
pGraphics->m_pCommandBuffer->AddCommand(Cmd);
|
||||
|
||||
// kick the buffer and wait for the result
|
||||
KickCommandBuffer();
|
||||
WaitForIdle();
|
||||
pGraphics->KickCommandBuffer();
|
||||
pGraphics->WaitForIdle();
|
||||
|
||||
if(Image.m_pData)
|
||||
{
|
||||
|
@ -466,14 +480,14 @@ void CGraphics_Threaded::ScreenshotDirect(const char *pFilename)
|
|||
char aWholePath[1024];
|
||||
png_t Png; // ignore_convention
|
||||
|
||||
IOHANDLE File = m_pStorage->OpenFile(pFilename, IOFLAG_WRITE, IStorage::TYPE_SAVE, aWholePath, sizeof(aWholePath));
|
||||
IOHANDLE File = pGraphics->m_pStorage->OpenFile(pGraphics->m_aScreenshotName, IOFLAG_WRITE, IStorage::TYPE_SAVE, aWholePath, sizeof(aWholePath));
|
||||
if(File)
|
||||
io_close(File);
|
||||
|
||||
// save png
|
||||
char aBuf[256];
|
||||
str_format(aBuf, sizeof(aBuf), "saved screenshot to '%s'", aWholePath);
|
||||
m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf);
|
||||
pGraphics->m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf);
|
||||
png_open_file_write(&Png, aWholePath); // ignore_convention
|
||||
png_set_data(&Png, Image.m_Width, Image.m_Height, 8, PNG_TRUECOLOR, (unsigned char *)Image.m_pData); // ignore_convention
|
||||
png_close_file(&Png); // ignore_convention
|
||||
|
@ -813,13 +827,19 @@ void CGraphics_Threaded::TakeScreenshot(const char *pFilename)
|
|||
m_DoScreenshot = true;
|
||||
}
|
||||
|
||||
void CGraphics_Threaded::TakeCustomScreenshot(const char *pFilename)
|
||||
{
|
||||
str_copy(m_aScreenshotName, pFilename, sizeof(m_aScreenshotName));
|
||||
m_DoScreenshot = true;
|
||||
}
|
||||
|
||||
void CGraphics_Threaded::Swap()
|
||||
{
|
||||
// TODO: screenshot support
|
||||
if(m_DoScreenshot)
|
||||
{
|
||||
if(WindowActive())
|
||||
ScreenshotDirect(m_aScreenshotName);
|
||||
ScreenshotDirect();
|
||||
m_DoScreenshot = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -398,7 +398,8 @@ public:
|
|||
virtual int LoadTexture(const char *pFilename, int StorageType, int StoreFormat, int Flags);
|
||||
virtual int LoadPNG(CImageInfo *pImg, const char *pFilename, int StorageType);
|
||||
|
||||
void ScreenshotDirect(const char *pFilename);
|
||||
void ScreenshotDirect();
|
||||
static void ScreenshotDirectThread(void *pData);
|
||||
|
||||
virtual void TextureSet(int TextureID);
|
||||
|
||||
|
@ -431,6 +432,7 @@ public:
|
|||
virtual void Shutdown();
|
||||
|
||||
virtual void TakeScreenshot(const char *pFilename);
|
||||
virtual void TakeCustomScreenshot(const char *pFilename);
|
||||
virtual void Swap();
|
||||
|
||||
virtual int GetVideoModes(CVideoMode *pModes, int MaxModes);
|
||||
|
|
|
@ -133,6 +133,7 @@ public:
|
|||
virtual void SetColor(float r, float g, float b, float a) = 0;
|
||||
|
||||
virtual void TakeScreenshot(const char *pFilename) = 0;
|
||||
virtual void TakeCustomScreenshot(const char *pFilename) = 0;
|
||||
virtual int GetVideoModes(CVideoMode *pModes, int MaxModes) = 0;
|
||||
|
||||
virtual void Swap() = 0;
|
||||
|
|
|
@ -65,6 +65,7 @@ public:
|
|||
fs_makedir(GetPath(TYPE_SAVE, "dumps", aPath, sizeof(aPath)));
|
||||
fs_makedir(GetPath(TYPE_SAVE, "demos", aPath, sizeof(aPath)));
|
||||
fs_makedir(GetPath(TYPE_SAVE, "demos/auto", aPath, sizeof(aPath)));
|
||||
fs_makedir(GetPath(TYPE_SAVE, "editor", aPath, sizeof(aPath)));
|
||||
fs_makedir(GetPath(TYPE_SAVE, "ghosts", aPath, sizeof(aPath)));
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
|
||||
#include <base/system.h>
|
||||
|
||||
#if defined(CONF_FAMILY_UNIX)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include <engine/shared/datafile.h>
|
||||
#include <engine/shared/config.h>
|
||||
#include <engine/client.h>
|
||||
|
@ -137,6 +141,7 @@ void CLayerGroup::Render()
|
|||
void CLayerGroup::AddLayer(CLayer *l)
|
||||
{
|
||||
m_pMap->m_Modified = true;
|
||||
m_pMap->m_UndoModified++;
|
||||
m_lLayers.add(l);
|
||||
}
|
||||
|
||||
|
@ -146,6 +151,7 @@ void CLayerGroup::DeleteLayer(int Index)
|
|||
delete m_lLayers[Index];
|
||||
m_lLayers.remove_index(Index);
|
||||
m_pMap->m_Modified = true;
|
||||
m_pMap->m_UndoModified++;
|
||||
}
|
||||
|
||||
void CLayerGroup::GetSize(float *w, float *h)
|
||||
|
@ -160,13 +166,13 @@ void CLayerGroup::GetSize(float *w, float *h)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
int CLayerGroup::SwapLayers(int Index0, int Index1)
|
||||
{
|
||||
if(Index0 < 0 || Index0 >= m_lLayers.size()) return Index0;
|
||||
if(Index1 < 0 || Index1 >= m_lLayers.size()) return Index0;
|
||||
if(Index0 == Index1) return Index0;
|
||||
m_pMap->m_Modified = true;
|
||||
m_pMap->m_UndoModified++;
|
||||
swap(m_lLayers[Index0], m_lLayers[Index1]);
|
||||
return Index1;
|
||||
}
|
||||
|
@ -719,6 +725,8 @@ void CEditor::CallbackOpenMap(const char *pFileName, int StorageType, void *pUse
|
|||
pEditor->SortImages();
|
||||
pEditor->m_Dialog = DIALOG_NONE;
|
||||
pEditor->m_Map.m_Modified = false;
|
||||
pEditor->m_Map.m_UndoModified = 0;
|
||||
pEditor->m_LastUndoUpdateTime = time_get();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -755,6 +763,8 @@ void CEditor::CallbackSaveMap(const char *pFileName, int StorageType, void *pUse
|
|||
str_copy(pEditor->m_aFileName, pFileName, sizeof(pEditor->m_aFileName));
|
||||
pEditor->m_ValidSaveFilename = StorageType == IStorage::TYPE_SAVE && pEditor->m_pFileDialogPath == pEditor->m_aFileDialogCurrentFolder;
|
||||
pEditor->m_Map.m_Modified = false;
|
||||
pEditor->m_Map.m_UndoModified = 0;
|
||||
pEditor->m_LastUndoUpdateTime = time_get();
|
||||
}
|
||||
|
||||
pEditor->m_Dialog = DIALOG_NONE;
|
||||
|
@ -2058,6 +2068,7 @@ void CEditor::DoMapEditor(CUIRect View, CUIRect ToolBar)
|
|||
// release mouse
|
||||
if(!UI()->MouseButton(0))
|
||||
{
|
||||
m_Map.m_UndoModified++;
|
||||
s_Operation = OP_NONE;
|
||||
UI()->SetActiveItem(0);
|
||||
}
|
||||
|
@ -2193,7 +2204,7 @@ void CEditor::DoMapEditor(CUIRect View, CUIRect ToolBar)
|
|||
|
||||
DoQuadEnvelopes(pLayer->m_lQuads, TexID);
|
||||
m_ShowEnvelopePreview = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Graphics()->MapScreen(UI()->Screen()->x, UI()->Screen()->y, UI()->Screen()->w, UI()->Screen()->h);
|
||||
//UI()->ClipDisable();
|
||||
|
@ -2385,6 +2396,8 @@ void CEditor::RenderLayers(CUIRect ToolBox, CUIRect ToolBar, CUIRect View)
|
|||
if(Input()->KeyPresses(KEY_MOUSE_WHEEL_DOWN))
|
||||
s_ScrollValue = clamp(s_ScrollValue + 1.0f/ScrollNum, 0.0f, 1.0f);
|
||||
}
|
||||
else
|
||||
ScrollNum = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2706,6 +2719,8 @@ void CEditor::RenderImages(CUIRect ToolBox, CUIRect ToolBar, CUIRect View)
|
|||
if(Input()->KeyPresses(KEY_MOUSE_WHEEL_DOWN))
|
||||
s_ScrollValue = clamp(s_ScrollValue + 1.0f/ScrollNum, 0.0f, 1.0f);
|
||||
}
|
||||
else
|
||||
ScrollNum = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3174,6 +3189,12 @@ void CEditor::RenderStatusbar(CUIRect View)
|
|||
if(DoButton_Editor(&s_EnvelopeButton, "Envelopes", m_ShowEnvelopeEditor, &Button, 0, "Toggles the envelope editor."))
|
||||
m_ShowEnvelopeEditor = (m_ShowEnvelopeEditor+1)%4;
|
||||
|
||||
View.VSplitRight(5.0f, &View, &Button);
|
||||
View.VSplitRight(60.0f, &View, &Button);
|
||||
static int s_UndolistButton = 0;
|
||||
if(DoButton_Editor(&s_UndolistButton, "Undolist", m_ShowUndo, &Button, 0, "Toggles the undo list."))
|
||||
m_ShowUndo = (m_ShowUndo + 1) % 2;
|
||||
|
||||
if(m_pTooltip)
|
||||
{
|
||||
if(ms_pUiGotContext && ms_pUiGotContext == UI()->HotItem())
|
||||
|
@ -3187,6 +3208,66 @@ void CEditor::RenderStatusbar(CUIRect View)
|
|||
}
|
||||
}
|
||||
|
||||
void CEditor::RenderUndoList(CUIRect View)
|
||||
{
|
||||
CUIRect List, Preview, Scroll, Button;
|
||||
View.VSplitMid(&List, &Preview);
|
||||
List.VSplitRight(15.0f, &List, &Scroll);
|
||||
//int Num = (int)(List.h/17.0f)+1;
|
||||
static int ScrollBar = 0;
|
||||
Scroll.HMargin(5.0f, &Scroll);
|
||||
m_UndoScrollValue = UiDoScrollbarV(&ScrollBar, &Scroll, m_UndoScrollValue);
|
||||
|
||||
float TopY = List.y;
|
||||
float Height = List.h;
|
||||
UI()->ClipEnable(&List);
|
||||
int ClickedIndex = -1;
|
||||
int HoveredIndex = -1;
|
||||
int ScrollNum = m_lUndoSteps.size() - List.h / 17.0f;
|
||||
if (ScrollNum < 0)
|
||||
ScrollNum = 0;
|
||||
List.y -= m_UndoScrollValue*ScrollNum*17.0f;
|
||||
for (int i = 0; i < m_lUndoSteps.size(); i++)
|
||||
{
|
||||
List.HSplitTop(17.0f, &Button, &List);
|
||||
if (List.y < TopY)
|
||||
continue;
|
||||
if (List.y - 17.0f > TopY + Height)
|
||||
break;
|
||||
if(DoButton_Editor(&m_lUndoSteps[i].m_ButtonId, m_lUndoSteps[i].m_aName, 0, &Button, 0, "Undo to this step"))
|
||||
ClickedIndex = i;
|
||||
if (UI()->HotItem() == &m_lUndoSteps[i].m_ButtonId)
|
||||
HoveredIndex = i;
|
||||
}
|
||||
UI()->ClipDisable();
|
||||
if (ClickedIndex != -1)
|
||||
{
|
||||
char aBuffer[1024];
|
||||
str_format(aBuffer, sizeof(aBuffer), "editor/undo_%i", m_lUndoSteps[HoveredIndex].m_FileNum);
|
||||
m_Map.Load(m_pStorage, aBuffer, IStorage::TYPE_SAVE);
|
||||
m_Map.m_UndoModified = 0;
|
||||
m_LastUndoUpdateTime = time_get();
|
||||
}
|
||||
if (HoveredIndex != -1)
|
||||
{
|
||||
if (m_lUndoSteps[HoveredIndex].m_PreviewImage == 0)
|
||||
{
|
||||
char aBuffer[1024];
|
||||
str_format(aBuffer, sizeof(aBuffer), "editor/undo_%i.png", m_lUndoSteps[HoveredIndex].m_FileNum);
|
||||
m_lUndoSteps[HoveredIndex].m_PreviewImage = Graphics()->LoadTexture(aBuffer, IStorage::TYPE_SAVE, CImageInfo::FORMAT_RGB, IGraphics::TEXLOAD_NORESAMPLE);
|
||||
}
|
||||
if (m_lUndoSteps[HoveredIndex].m_PreviewImage)
|
||||
{
|
||||
Graphics()->TextureSet(m_lUndoSteps[HoveredIndex].m_PreviewImage);
|
||||
Graphics()->BlendNormal();
|
||||
Graphics()->QuadsBegin();
|
||||
IGraphics::CQuadItem QuadItem(Preview.x, Preview.y, Preview.w, Preview.h);
|
||||
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
||||
Graphics()->QuadsEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CEditor::RenderEnvelopeEditor(CUIRect View)
|
||||
{
|
||||
if(m_SelectedEnvelope < 0) m_SelectedEnvelope = 0;
|
||||
|
@ -3225,6 +3306,7 @@ void CEditor::RenderEnvelopeEditor(CUIRect View)
|
|||
if(DoButton_Editor(&s_New4dButton, "Color+", 0, &Button, 0, "Creates a new color envelope"))
|
||||
{
|
||||
m_Map.m_Modified = true;
|
||||
m_Map.m_UndoModified++;
|
||||
pNewEnv = m_Map.NewEnvelope(4);
|
||||
}
|
||||
|
||||
|
@ -3234,6 +3316,7 @@ void CEditor::RenderEnvelopeEditor(CUIRect View)
|
|||
if(DoButton_Editor(&s_New2dButton, "Pos.+", 0, &Button, 0, "Creates a new pos envelope"))
|
||||
{
|
||||
m_Map.m_Modified = true;
|
||||
m_Map.m_UndoModified++;
|
||||
pNewEnv = m_Map.NewEnvelope(3);
|
||||
}
|
||||
|
||||
|
@ -3246,6 +3329,7 @@ void CEditor::RenderEnvelopeEditor(CUIRect View)
|
|||
if(DoButton_Editor(&s_DelButton, "Delete", 0, &Button, 0, "Delete this envelope"))
|
||||
{
|
||||
m_Map.m_Modified = true;
|
||||
m_Map.m_UndoModified++;
|
||||
m_Map.DeleteEnvelope(m_SelectedEnvelope);
|
||||
if(m_SelectedEnvelope >= m_Map.m_lEnvelopes.size())
|
||||
m_SelectedEnvelope = m_Map.m_lEnvelopes.size()-1;
|
||||
|
@ -3294,7 +3378,10 @@ void CEditor::RenderEnvelopeEditor(CUIRect View)
|
|||
|
||||
static float s_NameBox = 0;
|
||||
if(DoEditBox(&s_NameBox, &Button, pEnvelope->m_aName, sizeof(pEnvelope->m_aName), 10.0f, &s_NameBox))
|
||||
{
|
||||
m_Map.m_Modified = true;
|
||||
m_Map.m_UndoModified++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3394,6 +3481,7 @@ void CEditor::RenderEnvelopeEditor(CUIRect View)
|
|||
f2fx(aChannels[0]), f2fx(aChannels[1]),
|
||||
f2fx(aChannels[2]), f2fx(aChannels[3]));
|
||||
m_Map.m_Modified = true;
|
||||
m_Map.m_UndoModified++;
|
||||
}
|
||||
|
||||
m_ShowEnvelopePreview = 1;
|
||||
|
@ -3568,6 +3656,7 @@ void CEditor::RenderEnvelopeEditor(CUIRect View)
|
|||
m_ShowEnvelopePreview = 1;
|
||||
m_SelectedEnvelopePoint = i;
|
||||
m_Map.m_Modified = true;
|
||||
m_Map.m_UndoModified++;
|
||||
}
|
||||
|
||||
ColorMod = 100.0f;
|
||||
|
@ -3587,6 +3676,7 @@ void CEditor::RenderEnvelopeEditor(CUIRect View)
|
|||
{
|
||||
pEnvelope->m_lPoints.remove_index(i);
|
||||
m_Map.m_Modified = true;
|
||||
m_Map.m_UndoModified++;
|
||||
}
|
||||
|
||||
m_ShowEnvelopePreview = 1;
|
||||
|
@ -3757,7 +3847,7 @@ void CEditor::Render()
|
|||
// render checker
|
||||
RenderBackground(View, ms_CheckerTexture, 32.0f, 1.0f);
|
||||
|
||||
CUIRect MenuBar, CModeBar, ToolBar, StatusBar, EnvelopeEditor, ToolBox;
|
||||
CUIRect MenuBar, CModeBar, ToolBar, StatusBar, EnvelopeEditor, UndoList, ToolBox;
|
||||
m_ShowPicker = Input()->KeyPressed(KEY_SPACE) != 0 && m_Dialog == DIALOG_NONE;
|
||||
|
||||
if(m_GuiActive)
|
||||
|
@ -3777,6 +3867,10 @@ void CEditor::Render()
|
|||
size *= 3.0f;
|
||||
View.HSplitBottom(size, &View, &EnvelopeEditor);
|
||||
}
|
||||
if (m_ShowUndo && !m_ShowPicker)
|
||||
{
|
||||
View.HSplitBottom(250.0f, &View, &UndoList);
|
||||
}
|
||||
}
|
||||
|
||||
// a little hack for now
|
||||
|
@ -3830,6 +3924,11 @@ void CEditor::Render()
|
|||
RenderBackground(EnvelopeEditor, ms_BackgroundTexture, 128.0f, Brightness);
|
||||
EnvelopeEditor.Margin(2.0f, &EnvelopeEditor);
|
||||
}
|
||||
if(m_ShowUndo)
|
||||
{
|
||||
RenderBackground(UndoList, ms_BackgroundTexture, 128.0f, Brightness);
|
||||
UndoList.Margin(2.0f, &UndoList);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -3847,6 +3946,8 @@ void CEditor::Render()
|
|||
RenderModebar(CModeBar);
|
||||
if(m_ShowEnvelopeEditor)
|
||||
RenderEnvelopeEditor(EnvelopeEditor);
|
||||
if(m_ShowUndo)
|
||||
RenderUndoList(UndoList);
|
||||
}
|
||||
|
||||
if(m_Dialog == DIALOG_FILE)
|
||||
|
@ -3905,10 +4006,29 @@ void CEditor::Render()
|
|||
}
|
||||
}
|
||||
|
||||
static int UndoStepsListdirCallback(const char *pName, int IsDir, int StorageType, void *pUser)
|
||||
{
|
||||
IStorage *pStorage = (IStorage *)pUser;
|
||||
if (str_comp_nocase_num(pName, "undo_", 0) == 0)
|
||||
{
|
||||
char aBuffer[1024];
|
||||
pStorage->GetCompletePath(IStorage::TYPE_SAVE, "editor/", aBuffer, sizeof(aBuffer));
|
||||
str_append(aBuffer, pName, sizeof(aBuffer));
|
||||
fs_remove(aBuffer);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CEditor::Reset(bool CreateDefault)
|
||||
{
|
||||
m_Map.Clean();
|
||||
|
||||
//delete undo file
|
||||
char aBuffer[1024];
|
||||
m_pStorage->GetCompletePath(IStorage::TYPE_SAVE, "editor/", aBuffer, sizeof(aBuffer));
|
||||
fs_listdir(aBuffer, UndoStepsListdirCallback, 0, m_pStorage);
|
||||
m_lUndoSteps.clear();
|
||||
|
||||
// create default layers
|
||||
if(CreateDefault)
|
||||
m_Map.CreateDefault(ms_EntitiesTexture);
|
||||
|
@ -3938,6 +4058,8 @@ void CEditor::Reset(bool CreateDefault)
|
|||
m_MouseDeltaWy = 0;
|
||||
|
||||
m_Map.m_Modified = false;
|
||||
m_Map.m_UndoModified = 0;
|
||||
m_LastUndoUpdateTime = time_get();
|
||||
|
||||
m_ShowEnvelopePreview = 0;
|
||||
}
|
||||
|
@ -3966,6 +4088,7 @@ void CEditorMap::DeleteEnvelope(int Index)
|
|||
return;
|
||||
|
||||
m_Modified = true;
|
||||
m_UndoModified++;
|
||||
|
||||
// fix links between envelopes and quads
|
||||
for(int i = 0; i < m_lGroups.size(); ++i)
|
||||
|
@ -4097,6 +4220,8 @@ void CEditor::Init()
|
|||
|
||||
Reset();
|
||||
m_Map.m_Modified = false;
|
||||
m_Map.m_UndoModified = 0;
|
||||
m_LastUndoUpdateTime = time_get();
|
||||
}
|
||||
|
||||
void CEditor::DoMapBorder()
|
||||
|
@ -4116,6 +4241,36 @@ void CEditor::DoMapBorder()
|
|||
pT->m_pTiles[i].m_Index = 1;
|
||||
}
|
||||
|
||||
void CEditor::CreateUndoStep()
|
||||
{
|
||||
void *CreateThread = thread_create(CreateUndoStepThread, this);
|
||||
#if defined(CONF_FAMILY_UNIX)
|
||||
pthread_detach((pthread_t)CreateThread);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CEditor::CreateUndoStepThread(void *pUser)
|
||||
{
|
||||
CEditor *pEditor = (CEditor *)pUser;
|
||||
|
||||
CUndo NewStep;
|
||||
str_timestamp(NewStep.m_aName, sizeof(NewStep.m_aName));
|
||||
if (pEditor->m_lUndoSteps.size())
|
||||
NewStep.m_FileNum = pEditor->m_lUndoSteps[pEditor->m_lUndoSteps.size() - 1].m_FileNum + 1;
|
||||
else
|
||||
NewStep.m_FileNum = 0;
|
||||
NewStep.m_PreviewImage = 0;
|
||||
|
||||
char aBuffer[1024];
|
||||
str_format(aBuffer, sizeof(aBuffer), "editor/undo_%i.png", NewStep.m_FileNum);
|
||||
pEditor->Graphics()->TakeCustomScreenshot(aBuffer);
|
||||
|
||||
str_format(aBuffer, sizeof(aBuffer), "editor/undo_%i", NewStep.m_FileNum);
|
||||
pEditor->Save(aBuffer);
|
||||
|
||||
pEditor->m_lUndoSteps.add(NewStep);
|
||||
}
|
||||
|
||||
void CEditor::UpdateAndRender()
|
||||
{
|
||||
static float s_MouseX = 0.0f;
|
||||
|
@ -4182,6 +4337,12 @@ void CEditor::UpdateAndRender()
|
|||
if(Input()->KeyDown(KEY_F10))
|
||||
m_ShowMousePointer = false;
|
||||
|
||||
if ((m_LastUndoUpdateTime + time_freq() * 60 < time_get() && m_Map.m_UndoModified) || m_Map.m_UndoModified >= 10)
|
||||
{
|
||||
m_Map.m_UndoModified = 0;
|
||||
m_LastUndoUpdateTime = time_get();
|
||||
CreateUndoStep();
|
||||
}
|
||||
Render();
|
||||
|
||||
if(Input()->KeyDown(KEY_F10))
|
||||
|
|
|
@ -266,6 +266,7 @@ class CEditorMap
|
|||
public:
|
||||
CEditor *m_pEditor;
|
||||
bool m_Modified;
|
||||
int m_UndoModified;
|
||||
|
||||
CEditorMap()
|
||||
{
|
||||
|
@ -310,6 +311,7 @@ public:
|
|||
CEnvelope *NewEnvelope(int Channels)
|
||||
{
|
||||
m_Modified = true;
|
||||
m_UndoModified++;
|
||||
CEnvelope *e = new CEnvelope(Channels);
|
||||
m_lEnvelopes.add(e);
|
||||
return e;
|
||||
|
@ -320,6 +322,7 @@ public:
|
|||
CLayerGroup *NewGroup()
|
||||
{
|
||||
m_Modified = true;
|
||||
m_UndoModified++;
|
||||
CLayerGroup *g = new CLayerGroup;
|
||||
g->m_pMap = this;
|
||||
m_lGroups.add(g);
|
||||
|
@ -332,6 +335,7 @@ public:
|
|||
if(Index1 < 0 || Index1 >= m_lGroups.size()) return Index0;
|
||||
if(Index0 == Index1) return Index0;
|
||||
m_Modified = true;
|
||||
m_UndoModified++;
|
||||
swap(m_lGroups[Index0], m_lGroups[Index1]);
|
||||
return Index1;
|
||||
}
|
||||
|
@ -340,6 +344,7 @@ public:
|
|||
{
|
||||
if(Index < 0 || Index >= m_lGroups.size()) return;
|
||||
m_Modified = true;
|
||||
m_UndoModified++;
|
||||
delete m_lGroups[Index];
|
||||
m_lGroups.remove_index(Index);
|
||||
}
|
||||
|
@ -347,6 +352,7 @@ public:
|
|||
void ModifyImageIndex(INDEX_MODIFY_FUNC pfnFunc)
|
||||
{
|
||||
m_Modified = true;
|
||||
m_UndoModified++;
|
||||
for(int i = 0; i < m_lGroups.size(); i++)
|
||||
m_lGroups[i]->ModifyImageIndex(pfnFunc);
|
||||
}
|
||||
|
@ -354,6 +360,7 @@ public:
|
|||
void ModifyEnvelopeIndex(INDEX_MODIFY_FUNC pfnFunc)
|
||||
{
|
||||
m_Modified = true;
|
||||
m_UndoModified++;
|
||||
for(int i = 0; i < m_lGroups.size(); i++)
|
||||
m_lGroups[i]->ModifyEnvelopeIndex(pfnFunc);
|
||||
}
|
||||
|
@ -578,6 +585,8 @@ public:
|
|||
m_AnimateSpeed = 1;
|
||||
|
||||
m_ShowEnvelopeEditor = 0;
|
||||
m_ShowUndo = 0;
|
||||
m_UndoScrollValue = 0.0f;
|
||||
|
||||
m_ShowEnvelopePreview = 0;
|
||||
m_SelectedQuadEnvelope = -1;
|
||||
|
@ -608,6 +617,21 @@ public:
|
|||
virtual void UpdateAndRender();
|
||||
virtual bool HasUnsavedData() { return m_Map.m_Modified; }
|
||||
|
||||
int64 m_LastUndoUpdateTime;
|
||||
void CreateUndoStep();
|
||||
static void CreateUndoStepThread(void *pUser);
|
||||
int UndoStep();
|
||||
struct CUndo
|
||||
{
|
||||
int m_FileNum;
|
||||
int m_ButtonId;
|
||||
char m_aName[128];
|
||||
int m_PreviewImage;
|
||||
};
|
||||
array<CUndo> m_lUndoSteps;
|
||||
bool m_Undo;
|
||||
int m_ShowUndo;
|
||||
float m_UndoScrollValue;
|
||||
void FilelistPopulate(int StorageType);
|
||||
void InvokeFileDialog(int StorageType, int FileType, const char *pTitle, const char *pButtonText,
|
||||
const char *pBasepath, const char *pDefaultName,
|
||||
|
@ -811,6 +835,7 @@ public:
|
|||
void RenderModebar(CUIRect View);
|
||||
void RenderStatusbar(CUIRect View);
|
||||
void RenderEnvelopeEditor(CUIRect View);
|
||||
void RenderUndoList(CUIRect View);
|
||||
|
||||
void RenderMenubar(CUIRect Menubar);
|
||||
void RenderFileDialog();
|
||||
|
|
Loading…
Reference in a new issue