mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Fix image/sound readding broken by error messages
When an image/sound is readded, this reuses the `ReplaceImage/Sound` callback functions. The added error handling to prevent duplicate images/sounds was causing this to not work, as the image/sound being readded was already present. The implementation is separated from the callback functions and an additional parameter is added to toggle the duplicate name check. Previously this was hard to notice, as the error message popup was not shown due to the top-most popup being closed immediately. This will be fixed separately by a larger refactoring, so a popup can close itself immediately after opening another popup without closing the child popup instead. Closes #6500.
This commit is contained in:
parent
b4c114450c
commit
eaa4e19188
|
@ -4045,31 +4045,32 @@ bool CEditor::SelectLayerByTile()
|
|||
return false;
|
||||
}
|
||||
|
||||
bool CEditor::ReplaceImage(const char *pFileName, int StorageType, void *pUser)
|
||||
bool CEditor::ReplaceImage(const char *pFileName, int StorageType, bool CheckDuplicate)
|
||||
{
|
||||
CEditor *pEditor = (CEditor *)pUser;
|
||||
|
||||
// check if we have that image already
|
||||
char aBuf[128];
|
||||
IStorage::StripPathAndExtension(pFileName, aBuf, sizeof(aBuf));
|
||||
for(const auto &pImage : pEditor->m_Map.m_vpImages)
|
||||
if(CheckDuplicate)
|
||||
{
|
||||
if(!str_comp(pImage->m_aName, aBuf))
|
||||
for(const auto &pImage : m_Map.m_vpImages)
|
||||
{
|
||||
pEditor->ShowFileDialogError("Image named '%s' was already added.", pImage->m_aName);
|
||||
return false;
|
||||
if(!str_comp(pImage->m_aName, aBuf))
|
||||
{
|
||||
ShowFileDialogError("Image named '%s' was already added.", pImage->m_aName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CEditorImage ImgInfo(pEditor);
|
||||
if(!pEditor->Graphics()->LoadPNG(&ImgInfo, pFileName, StorageType))
|
||||
CEditorImage ImgInfo(this);
|
||||
if(!Graphics()->LoadPNG(&ImgInfo, pFileName, StorageType))
|
||||
{
|
||||
pEditor->ShowFileDialogError("Failed to load image from file '%s'.", pFileName);
|
||||
ShowFileDialogError("Failed to load image from file '%s'.", pFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
CEditorImage *pImg = pEditor->m_Map.m_vpImages[pEditor->m_SelectedImage];
|
||||
pEditor->Graphics()->UnloadTexture(&(pImg->m_Texture));
|
||||
CEditorImage *pImg = m_Map.m_vpImages[m_SelectedImage];
|
||||
Graphics()->UnloadTexture(&(pImg->m_Texture));
|
||||
free(pImg->m_pData);
|
||||
pImg->m_pData = nullptr;
|
||||
*pImg = ImgInfo;
|
||||
|
@ -4086,21 +4087,26 @@ bool CEditor::ReplaceImage(const char *pFileName, int StorageType, void *pUser)
|
|||
}
|
||||
|
||||
pImg->m_AutoMapper.Load(pImg->m_aName);
|
||||
int TextureLoadFlag = pEditor->Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE;
|
||||
int TextureLoadFlag = Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE;
|
||||
if(ImgInfo.m_Width % 16 != 0 || ImgInfo.m_Height % 16 != 0)
|
||||
TextureLoadFlag = 0;
|
||||
pImg->m_Texture = pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, CImageInfo::FORMAT_AUTO, TextureLoadFlag, pFileName);
|
||||
pImg->m_Texture = Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, CImageInfo::FORMAT_AUTO, TextureLoadFlag, pFileName);
|
||||
ImgInfo.m_pData = nullptr;
|
||||
pEditor->SortImages();
|
||||
for(size_t i = 0; i < pEditor->m_Map.m_vpImages.size(); ++i)
|
||||
SortImages();
|
||||
for(size_t i = 0; i < m_Map.m_vpImages.size(); ++i)
|
||||
{
|
||||
if(!str_comp(pEditor->m_Map.m_vpImages[i]->m_aName, pImg->m_aName))
|
||||
pEditor->m_SelectedImage = i;
|
||||
if(!str_comp(m_Map.m_vpImages[i]->m_aName, pImg->m_aName))
|
||||
m_SelectedImage = i;
|
||||
}
|
||||
pEditor->m_Dialog = DIALOG_NONE;
|
||||
m_Dialog = DIALOG_NONE;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CEditor::ReplaceImageCallback(const char *pFileName, int StorageType, void *pUser)
|
||||
{
|
||||
return static_cast<CEditor *>(pUser)->ReplaceImage(pFileName, StorageType, true);
|
||||
}
|
||||
|
||||
bool CEditor::AddImage(const char *pFileName, int StorageType, void *pUser)
|
||||
{
|
||||
CEditor *pEditor = (CEditor *)pUser;
|
||||
|
@ -4222,44 +4228,45 @@ bool CEditor::AddSound(const char *pFileName, int StorageType, void *pUser)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CEditor::ReplaceSound(const char *pFileName, int StorageType, void *pUser)
|
||||
bool CEditor::ReplaceSound(const char *pFileName, int StorageType, bool CheckDuplicate)
|
||||
{
|
||||
CEditor *pEditor = (CEditor *)pUser;
|
||||
|
||||
// check if we have that sound already
|
||||
char aBuf[128];
|
||||
IStorage::StripPathAndExtension(pFileName, aBuf, sizeof(aBuf));
|
||||
for(const auto &pSound : pEditor->m_Map.m_vpSounds)
|
||||
if(CheckDuplicate)
|
||||
{
|
||||
if(!str_comp(pSound->m_aName, aBuf))
|
||||
for(const auto &pSound : m_Map.m_vpSounds)
|
||||
{
|
||||
pEditor->ShowFileDialogError("Sound named '%s' was already added.", pSound->m_aName);
|
||||
return false;
|
||||
if(!str_comp(pSound->m_aName, aBuf))
|
||||
{
|
||||
ShowFileDialogError("Sound named '%s' was already added.", pSound->m_aName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// load external
|
||||
void *pData;
|
||||
unsigned DataSize;
|
||||
if(!pEditor->Storage()->ReadFile(pFileName, StorageType, &pData, &DataSize))
|
||||
if(!Storage()->ReadFile(pFileName, StorageType, &pData, &DataSize))
|
||||
{
|
||||
pEditor->ShowFileDialogError("Failed to open sound file '%s'.", pFileName);
|
||||
ShowFileDialogError("Failed to open sound file '%s'.", pFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// load sound
|
||||
const int SoundId = pEditor->Sound()->LoadOpusFromMem(pData, DataSize, true);
|
||||
const int SoundId = Sound()->LoadOpusFromMem(pData, DataSize, true);
|
||||
if(SoundId == -1)
|
||||
{
|
||||
free(pData);
|
||||
pEditor->ShowFileDialogError("Failed to load sound from file '%s'.", pFileName);
|
||||
ShowFileDialogError("Failed to load sound from file '%s'.", pFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
CEditorSound *pSound = pEditor->m_Map.m_vpSounds[pEditor->m_SelectedSound];
|
||||
CEditorSound *pSound = m_Map.m_vpSounds[m_SelectedSound];
|
||||
|
||||
// unload sample
|
||||
pEditor->Sound()->UnloadSample(pSound->m_SoundID);
|
||||
Sound()->UnloadSample(pSound->m_SoundID);
|
||||
free(pSound->m_pData);
|
||||
|
||||
// replace sound
|
||||
|
@ -4268,10 +4275,15 @@ bool CEditor::ReplaceSound(const char *pFileName, int StorageType, void *pUser)
|
|||
pSound->m_pData = pData;
|
||||
pSound->m_DataSize = DataSize;
|
||||
|
||||
pEditor->m_Dialog = DIALOG_NONE;
|
||||
m_Dialog = DIALOG_NONE;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CEditor::ReplaceSoundCallback(const char *pFileName, int StorageType, void *pUser)
|
||||
{
|
||||
return static_cast<CEditor *>(pUser)->ReplaceSound(pFileName, StorageType, true);
|
||||
}
|
||||
|
||||
void CEditor::SelectGameLayer()
|
||||
{
|
||||
for(size_t g = 0; g < m_Map.m_vpGroups.size(); g++)
|
||||
|
|
|
@ -1302,8 +1302,10 @@ public:
|
|||
void DoQuad(CQuad *pQuad, int Index);
|
||||
ColorRGBA GetButtonColor(const void *pID, int Checked);
|
||||
|
||||
static bool ReplaceImage(const char *pFilename, int StorageType, void *pUser);
|
||||
static bool ReplaceSound(const char *pFileName, int StorageType, void *pUser);
|
||||
bool ReplaceImage(const char *pFilename, int StorageType, bool CheckDuplicate);
|
||||
static bool ReplaceImageCallback(const char *pFilename, int StorageType, void *pUser);
|
||||
bool ReplaceSound(const char *pFileName, int StorageType, bool CheckDuplicate);
|
||||
static bool ReplaceSoundCallback(const char *pFileName, int StorageType, void *pUser);
|
||||
static bool AddImage(const char *pFilename, int StorageType, void *pUser);
|
||||
static bool AddSound(const char *pFileName, int StorageType, void *pUser);
|
||||
|
||||
|
|
|
@ -1283,17 +1283,17 @@ int CEditor::PopupImage(CEditor *pEditor, CUIRect View, void *pContext)
|
|||
if(s_SelectionPopupContext.m_pSelection != nullptr)
|
||||
{
|
||||
const bool WasExternal = pImg->m_External;
|
||||
ReplaceImage(s_SelectionPopupContext.m_pSelection->c_str(), IStorage::TYPE_ALL, pEditor);
|
||||
const bool Result = pEditor->ReplaceImage(s_SelectionPopupContext.m_pSelection->c_str(), IStorage::TYPE_ALL, false);
|
||||
pImg->m_External = WasExternal;
|
||||
s_SelectionPopupContext.Reset();
|
||||
return 1;
|
||||
return Result ? 1 : 0;
|
||||
}
|
||||
|
||||
View.HSplitTop(5.0f, nullptr, &View);
|
||||
View.HSplitTop(12.0f, &Slot, &View);
|
||||
if(pEditor->DoButton_MenuItem(&s_ReplaceButton, "Replace", 0, &Slot, 0, "Replaces the image with a new one"))
|
||||
{
|
||||
pEditor->InvokeFileDialog(IStorage::TYPE_ALL, FILETYPE_IMG, "Replace Image", "Replace", "mapres", "", ReplaceImage, pEditor);
|
||||
pEditor->InvokeFileDialog(IStorage::TYPE_ALL, FILETYPE_IMG, "Replace Image", "Replace", "mapres", "", ReplaceImageCallback, pEditor);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1344,16 +1344,16 @@ int CEditor::PopupSound(CEditor *pEditor, CUIRect View, void *pContext)
|
|||
}
|
||||
if(s_SelectionPopupContext.m_pSelection != nullptr)
|
||||
{
|
||||
ReplaceSound(s_SelectionPopupContext.m_pSelection->c_str(), IStorage::TYPE_ALL, pEditor);
|
||||
const bool Result = pEditor->ReplaceSound(s_SelectionPopupContext.m_pSelection->c_str(), IStorage::TYPE_ALL, false);
|
||||
s_SelectionPopupContext.Reset();
|
||||
return 1;
|
||||
return Result ? 1 : 0;
|
||||
}
|
||||
|
||||
View.HSplitTop(5.0f, nullptr, &View);
|
||||
View.HSplitTop(12.0f, &Slot, &View);
|
||||
if(pEditor->DoButton_MenuItem(&s_ReplaceButton, "Replace", 0, &Slot, 0, "Replaces the sound with a new one"))
|
||||
{
|
||||
pEditor->InvokeFileDialog(IStorage::TYPE_ALL, FILETYPE_SOUND, "Replace sound", "Replace", "mapres", "", ReplaceSound, pEditor);
|
||||
pEditor->InvokeFileDialog(IStorage::TYPE_ALL, FILETYPE_SOUND, "Replace sound", "Replace", "mapres", "", ReplaceSoundCallback, pEditor);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue