diff --git a/GpApp/House.cpp b/GpApp/House.cpp index b07bdea..d5fb26f 100644 --- a/GpApp/House.cpp +++ b/GpApp/House.cpp @@ -51,32 +51,43 @@ extern short numberRooms, mapLeftRoom, mapTopRoom, numStarsRemaining; extern Boolean houseOpen, noRoomAtAll; extern Boolean twoPlayerGame, wardBitSet, phoneBitSet; +struct FBUI_House_Context +{ + FBUI_House_Context(); -static void FBUI_House_DrawLabels(DrawSurface *surface, const Point &basePoint) + bool m_deletedAny; +}; + +FBUI_House_Context::FBUI_House_Context() + : m_deletedAny(false) { } -static void FBUI_House_DrawFileDetails(DrawSurface *surface, const Point &basePoint, const Rect &constraintRect, void *fileDetails) +static void FBUI_House_DrawLabels(void *context, DrawSurface *surface, const Point &basePoint) { } -static void *FBUI_House_LoadFileDetails(PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename) +static void FBUI_House_DrawFileDetails(void *context, DrawSurface *surface, const Point &basePoint, const Rect &constraintRect, void *fileDetails) +{ +} + +static void *FBUI_House_LoadFileDetails(void *context, PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename) { return nullptr; } -static void FBUI_House_FreeFileDetails(void *fileDetails) +static void FBUI_House_FreeFileDetails(void *context, void *fileDetails) { } -static bool FBUI_House_FilterFile(PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename) +static bool FBUI_House_FilterFile(void *context, PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename) { PortabilityLayer::CompositeFile *cfile = PortabilityLayer::FileManager::GetInstance()->OpenCompositeFile(dirID, filename); return PortabilityLayer::ResTypeIDCodec::Decode(cfile->GetProperties().m_fileType) == 'gliH'; } -static bool FBUI_House_IsDeleteValid(PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename) +static bool FBUI_House_IsDeleteValid(void *context, PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename) { if (dirID != PortabilityLayer::VirtualDirectories::kUserData) return false; @@ -84,16 +95,26 @@ static bool FBUI_House_IsDeleteValid(PortabilityLayer::VirtualDirectory_t dirID, return !StrCmp::EqualCaseInsensitive(thisHouseName, filename); } -static PortabilityLayer::FileBrowserUI_DetailsCallbackAPI GetHouseDetailsAPI() +static void FBUI_House_OnDeleted(void *context, PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename) +{ + if (dirID != PortabilityLayer::VirtualDirectories::kUserData) + return; + + static_cast(context)->m_deletedAny = true; +} + +static PortabilityLayer::FileBrowserUI_DetailsCallbackAPI GetHouseDetailsAPI(FBUI_House_Context *context) { PortabilityLayer::FileBrowserUI_DetailsCallbackAPI api; + api.m_context = context; api.m_drawLabelsCallback = FBUI_House_DrawLabels; api.m_drawFileDetailsCallback = FBUI_House_DrawFileDetails; api.m_loadFileDetailsCallback = FBUI_House_LoadFileDetails; api.m_freeFileDetailsCallback = FBUI_House_FreeFileDetails; api.m_filterFileCallback = FBUI_House_FilterFile; api.m_isDeleteValidCallback = FBUI_House_IsDeleteValid; + api.m_onDeletedCallback = FBUI_House_OnDeleted; return api; } @@ -118,8 +139,18 @@ Boolean CreateNewHouse (void) char savePath[sizeof(theSpec.m_name) + 1]; size_t savePathLength = 0; - if (!fm->PromptSaveFile(theSpec.m_dir, ".gpf", savePath, savePathLength, sizeof(theSpec.m_name), PSTR("My House"), PSTR("Create House"), true, GetHouseDetailsAPI())) + FBUI_House_Context fbuiContext; + + if (!fm->PromptSaveFile(theSpec.m_dir, ".gpf", savePath, savePathLength, sizeof(theSpec.m_name), PSTR("My House"), PSTR("Create House"), true, GetHouseDetailsAPI(&fbuiContext))) + { + if (fbuiContext.m_deletedAny) + { + BuildHouseList(); + InitCursor(); + } + return false; + } assert(savePathLength < sizeof(theSpec.m_name) - 1); diff --git a/GpApp/SavedGames.cpp b/GpApp/SavedGames.cpp index a009124..de8e530 100644 --- a/GpApp/SavedGames.cpp +++ b/GpApp/SavedGames.cpp @@ -41,7 +41,11 @@ static const int kStarsOffset = 180; static const int kGlidersOffset = 260; static const int kScoreOffset = 320; -static void FBUI_Save_DrawLabels(DrawSurface *surface, const Point &basePoint) +struct FBUI_Save_Context +{ +}; + +static void FBUI_Save_DrawLabels(void *context, DrawSurface *surface, const Point &basePoint) { PortabilityLayer::ResolveCachingColor blackColor(StdColors::Black()); PortabilityLayer::RenderedFont *rfont = GetFont(PortabilityLayer::FontPresets::kSystem12Bold); @@ -51,7 +55,7 @@ static void FBUI_Save_DrawLabels(DrawSurface *surface, const Point &basePoint) surface->DrawString(basePoint + Point::Create(kScoreOffset, 0), PSTR("Score"), blackColor, rfont); } -static void FBUI_Save_DrawFileDetails(DrawSurface *surface, const Point &basePoint, const Rect &constraintRect, void *fileDetails) +static void FBUI_Save_DrawFileDetails(void *context, DrawSurface *surface, const Point &basePoint, const Rect &constraintRect, void *fileDetails) { PortabilityLayer::ResolveCachingColor blackColor(StdColors::Black()); PortabilityLayer::RenderedFont *rfont = GetFont(PortabilityLayer::FontPresets::kSystem12Bold); @@ -70,7 +74,7 @@ static void FBUI_Save_DrawFileDetails(DrawSurface *surface, const Point &basePoi surface->DrawString(basePoint + Point::Create(kScoreOffset, 0), numStr, blackColor, rfont); } -static void *FBUI_Save_LoadFileDetails(PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename) +static void *FBUI_Save_LoadFileDetails(void *context, PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename) { GpIOStream *stream = nullptr; if (PortabilityLayer::FileManager::GetInstance()->OpenNonCompositeFile(dirID, filename, ".sav", PortabilityLayer::EFilePermission_Read, GpFileCreationDispositions::kOpenExisting, stream) != PLErrors::kNone) @@ -97,31 +101,37 @@ static void *FBUI_Save_LoadFileDetails(PortabilityLayer::VirtualDirectory_t dirI return gameData; } -static void FBUI_Save_FreeFileDetails(void *fileDetails) +static void FBUI_Save_FreeFileDetails(void *context, void *fileDetails) { PortabilityLayer::MemoryManager::GetInstance()->Release(fileDetails); } -static bool FBUI_Save_FilterFile(PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename) +static bool FBUI_Save_FilterFile(void *context, PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename) { return true; } -static bool FBUI_Save_IsDeleteValid(PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename) +static bool FBUI_Save_IsDeleteValid(void *context, PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename) { return true; } -static PortabilityLayer::FileBrowserUI_DetailsCallbackAPI GetSavedGameDetailsAPI() +static void FBUI_Save_OnDeleted(void *context, PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename) +{ +} + +static PortabilityLayer::FileBrowserUI_DetailsCallbackAPI GetSavedGameDetailsAPI(FBUI_Save_Context *context) { PortabilityLayer::FileBrowserUI_DetailsCallbackAPI api; + api.m_context = context; api.m_drawLabelsCallback = FBUI_Save_DrawLabels; api.m_drawFileDetailsCallback = FBUI_Save_DrawFileDetails; api.m_loadFileDetailsCallback = FBUI_Save_LoadFileDetails; api.m_freeFileDetailsCallback = FBUI_Save_FreeFileDetails; api.m_filterFileCallback = FBUI_Save_FilterFile; api.m_isDeleteValidCallback = FBUI_Save_IsDeleteValid; + api.m_onDeletedCallback = FBUI_Save_OnDeleted; return api; } @@ -175,7 +185,8 @@ Boolean SaveGame2 (void) char savePath[sizeof(spec.m_name) + 1]; size_t savePathLength = 0; - if (!fm->PromptSaveFile(spec.m_dir, ".sav", savePath, savePathLength, sizeof(spec.m_name), PLPasStr(gameNameStr), PSTR("Save Game"), false, GetSavedGameDetailsAPI())) + FBUI_Save_Context context; + if (!fm->PromptSaveFile(spec.m_dir, ".sav", savePath, savePathLength, sizeof(spec.m_name), PLPasStr(gameNameStr), PSTR("Save Game"), false, GetSavedGameDetailsAPI(&context))) { mm->Release(savedGame); return false; @@ -272,7 +283,8 @@ Boolean OpenSavedGame (void) char savePath[sizeof(spec.m_name) + 1]; size_t savePathLength = 0; - if (!fm->PromptOpenFile(spec.m_dir, ".sav", savePath, savePathLength, sizeof(spec.m_name), PSTR("Open Saved Game"), false, GetSavedGameDetailsAPI())) + FBUI_Save_Context context; + if (!fm->PromptOpenFile(spec.m_dir, ".sav", savePath, savePathLength, sizeof(spec.m_name), PSTR("Open Saved Game"), false, GetSavedGameDetailsAPI(&context))) return false; assert(savePathLength < sizeof(spec.m_name) - 1); diff --git a/PortabilityLayer/FileBrowserUI.cpp b/PortabilityLayer/FileBrowserUI.cpp index e2a0004..c0bc0e0 100644 --- a/PortabilityLayer/FileBrowserUI.cpp +++ b/PortabilityLayer/FileBrowserUI.cpp @@ -157,7 +157,7 @@ namespace PortabilityLayer { FileEntry *entries = *m_entries; for (size_t i = 0; i < m_numEntries; i++) - m_api.m_freeFileDetailsCallback(entries[i].m_fileDetails); + m_api.m_freeFileDetailsCallback(m_api.m_context, entries[i].m_fileDetails); } m_entries.Dispose(); } @@ -213,7 +213,7 @@ namespace PortabilityLayer ResolveCachingColor blackColor = StdColors::Black(); const Point basePoint = Point::Create(16, 16 + font->GetMetrics().m_ascent); - m_api.m_drawLabelsCallback(m_surface, basePoint); + m_api.m_drawLabelsCallback(m_api.m_context, m_surface, basePoint); } void FileBrowserUIImpl::DrawFileList() @@ -249,7 +249,7 @@ namespace PortabilityLayer Point itemStringPoint = Point::Create(itemRect.left + 2, itemRect.top + glyphOffset); m_surface->DrawStringConstrained(itemStringPoint, (*m_entries)[i].m_nameStr.ToShortStr(), m_rect, blackColor, font); - m_api.m_drawFileDetailsCallback(m_surface, itemStringPoint, m_rect, (*m_entries)[i].m_fileDetails); + m_api.m_drawFileDetailsCallback(m_api.m_context, m_surface, itemStringPoint, m_rect, (*m_entries)[i].m_fileDetails); itemRect.top += spacing; itemRect.bottom += spacing; @@ -300,11 +300,10 @@ namespace PortabilityLayer if (m_selectedIndex < 0) return; - FileEntry *entries = *m_entries; FileEntry &removedEntry = entries[m_selectedIndex]; - m_api.m_freeFileDetailsCallback(removedEntry.m_fileDetails); + m_api.m_freeFileDetailsCallback(m_api.m_context, removedEntry.m_fileDetails); for (size_t i = m_selectedIndex; i < m_numEntries - 1; i++) entries[i] = entries[i + 1]; @@ -450,7 +449,7 @@ namespace PortabilityLayer if (isDeleteValid) { const FileBrowserUIImpl::FileEntry &entry = (*m_entries)[selection]; - isDeleteValid = m_api.m_isDeleteValidCallback(m_dir, entry.m_nameStr.ToShortStr()); + isDeleteValid = m_api.m_isDeleteValidCallback(m_api.m_context, m_dir, entry.m_nameStr.ToShortStr()); } if (gs_currentFileBrowserUIMode == FileBrowserUI::Mode_Open) @@ -647,10 +646,10 @@ namespace PortabilityLayer if (!memcmp(nameExt, extension, extensionLength)) { PLPasStr fnamePStr = PLPasStr(nameLength - extensionLength, fileName); - if (!callbackAPI.m_filterFileCallback(dirID, fnamePStr)) + if (!callbackAPI.m_filterFileCallback(callbackAPI.m_context, dirID, fnamePStr)) continue; - if (!uiImpl.AppendName(fileName, nameLength - extensionLength, callbackAPI.m_loadFileDetailsCallback(dirID, fnamePStr))) + if (!uiImpl.AppendName(fileName, nameLength - extensionLength, callbackAPI.m_loadFileDetailsCallback(callbackAPI.m_context, dirID, fnamePStr))) { dirCursor->Destroy(); return false; @@ -797,12 +796,17 @@ namespace PortabilityLayer else deleted = PortabilityLayer::FileManager::GetInstance()->DeleteNonCompositeFile(dirID, uiFileName, extension); - uiImpl.RemoveSelectedFile(); - dialog->GetItems()[kOkayButton - 1].GetWidget()->SetEnabled(false); - if (mode == Mode_Open) - dialog->GetItems()[kOpenDeleteButton - 1].GetWidget()->SetEnabled(false); - else if (mode == Mode_SaveWithDelete) - dialog->GetItems()[kSaveDeleteButton - 1].GetWidget()->SetEnabled(false); + if (deleted) + { + callbackAPI.m_onDeletedCallback(callbackAPI.m_context, dirID, uiFileName); + + uiImpl.RemoveSelectedFile(); + dialog->GetItems()[kOkayButton - 1].GetWidget()->SetEnabled(false); + if (mode == Mode_Open) + dialog->GetItems()[kOpenDeleteButton - 1].GetWidget()->SetEnabled(false); + else if (mode == Mode_SaveWithDelete) + dialog->GetItems()[kSaveDeleteButton - 1].GetWidget()->SetEnabled(false); + } } hit = -1; } diff --git a/PortabilityLayer/FileBrowserUI.h b/PortabilityLayer/FileBrowserUI.h index e0994b3..a24ab17 100644 --- a/PortabilityLayer/FileBrowserUI.h +++ b/PortabilityLayer/FileBrowserUI.h @@ -16,13 +16,16 @@ namespace PortabilityLayer struct FileBrowserUI_DetailsCallbackAPI { - void(*m_drawLabelsCallback)(DrawSurface *surface, const Point &basePoint); - void(*m_drawFileDetailsCallback)(DrawSurface *surface, const Point &basePoint, const Rect &constraintRect, void *fileDetails); + void *m_context; - void *(*m_loadFileDetailsCallback)(VirtualDirectory_t dirID, const PLPasStr &filename); - void (*m_freeFileDetailsCallback)(void *fileDetails); - bool (*m_filterFileCallback)(VirtualDirectory_t dirID, const PLPasStr &filename); - bool (*m_isDeleteValidCallback)(VirtualDirectory_t dirID, const PLPasStr &filename); + void (*m_drawLabelsCallback)(void *context, DrawSurface *surface, const Point &basePoint); + void (*m_drawFileDetailsCallback)(void *context, DrawSurface *surface, const Point &basePoint, const Rect &constraintRect, void *fileDetails); + + void *(*m_loadFileDetailsCallback)(void *context, VirtualDirectory_t dirID, const PLPasStr &filename); + void (*m_freeFileDetailsCallback)(void *context, void *fileDetails); + bool (*m_filterFileCallback)(void *context, VirtualDirectory_t dirID, const PLPasStr &filename); + bool (*m_isDeleteValidCallback)(void *context, VirtualDirectory_t dirID, const PLPasStr &filename); + void (*m_onDeletedCallback)(void *context, VirtualDirectory_t dirID, const PLPasStr &filename); }; class FileBrowserUI diff --git a/PortabilityLayer/FileManager.cpp b/PortabilityLayer/FileManager.cpp index 303d041..3f869ab 100644 --- a/PortabilityLayer/FileManager.cpp +++ b/PortabilityLayer/FileManager.cpp @@ -513,9 +513,9 @@ namespace PortabilityLayer } #if GP_ASYNCIFY_PARANOID - bool FileManager::PromptSaveFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) + bool FileManager::PromptSaveFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, bool &outDeletedAny, const PLPasStr &initialFileName, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) { - return static_cast(this)->PromptSaveFile(dirID, extension, path, outPathLength, pathCapacity, initialFileName, promptText, composites, callbackAPI); + return static_cast(this)->PromptSaveFile(dirID, extension, path, outPathLength, pathCapacity, outDeletedAny, initialFileName, promptText, composites, callbackAPI); } bool FileManager::PromptOpenFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &callbackAPI)