diff --git a/GpApp/House.cpp b/GpApp/House.cpp index c9296e3..05d8fb0 100644 --- a/GpApp/House.cpp +++ b/GpApp/House.cpp @@ -12,7 +12,9 @@ #include "PLSysCalls.h" #include "DialogUtils.h" #include "Externs.h" +#include "FileBrowserUI.h" #include "FileManager.h" +#include "FontFamily.h" #include "HostFileSystem.h" #include "House.h" #include "PLStandardColors.h" @@ -48,6 +50,35 @@ extern Boolean houseOpen, noRoomAtAll; extern Boolean twoPlayerGame, wardBitSet, phoneBitSet; +static void FBUI_DrawLabels(DrawSurface *surface, const Point &basePoint) +{ +} + +static void FBUI_DrawFileDetails(DrawSurface *surface, const Point &basePoint, const Rect &constraintRect, void *fileDetails) +{ +} + +static void *FBUI_LoadFileDetails(PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename) +{ + return nullptr; +} + +static void FBUI_FreeFileDetails(void *fileDetails) +{ +} + +static PortabilityLayer::FileBrowserUI_DetailsCallbackAPI GetHouseDetailsAPI() +{ + PortabilityLayer::FileBrowserUI_DetailsCallbackAPI api; + + api.m_drawLabelsCallback = FBUI_DrawLabels; + api.m_drawFileDetailsCallback = FBUI_DrawFileDetails; + api.m_loadFileDetailsCallback = FBUI_LoadFileDetails; + api.m_freeFileDetailsCallback = FBUI_FreeFileDetails; + + return api; +} + //============================================================== Functions //-------------------------------------------------------------- CreateNewHouse // Called to create a new house file. @@ -68,7 +99,7 @@ Boolean CreateNewHouse (void) char savePath[sizeof(theSpec.m_name) + 1]; size_t savePathLength = 0; - if (!fm->PromptSaveFile(theSpec.m_dir, savePath, savePathLength, sizeof(theSpec.m_name), PSTR("My House"), PSTR("Create House"))) + if (!fm->PromptSaveFile(theSpec.m_dir, savePath, savePathLength, sizeof(theSpec.m_name), PSTR("My House"), PSTR("Create House"), GetHouseDetailsAPI())) return false; assert(savePathLength < sizeof(theSpec.m_name) - 1); diff --git a/GpApp/SavedGames.cpp b/GpApp/SavedGames.cpp index 811271a..fca7fb9 100644 --- a/GpApp/SavedGames.cpp +++ b/GpApp/SavedGames.cpp @@ -9,16 +9,19 @@ #include "PLStringCompare.h" #include "DialogManager.h" #include "Externs.h" +#include "FileBrowserUI.h" #include "FileManager.h" +#include "FontFamily.h" #include "House.h" #include "GpIOStream.h" #include "InputManager.h" #include "MacFileInfo.h" #include "MemoryManager.h" +#include "PLStandardColors.h" +#include "ResolveCachingColor.h" #include - #define kSavedGameVersion 0x0200 @@ -33,6 +36,84 @@ extern Boolean twoPlayerGame; //============================================================== Functions + +static const int kStarsOffset = 180; +static const int kGlidersOffset = 260; +static const int kScoreOffset = 320; + +static void FBUI_DrawLabels(DrawSurface *surface, const Point &basePoint) +{ + PortabilityLayer::ResolveCachingColor blackColor(StdColors::Black()); + PortabilityLayer::RenderedFont *rfont = GetSystemFont(12, PortabilityLayer::FontFamilyFlag_Bold, true); + + surface->DrawString(basePoint + Point::Create(kStarsOffset, 0), PSTR("Stars Left"), blackColor, rfont); + surface->DrawString(basePoint + Point::Create(kGlidersOffset, 0), PSTR("Gliders"), blackColor, rfont); + surface->DrawString(basePoint + Point::Create(kScoreOffset, 0), PSTR("Score"), blackColor, rfont); +} + +static void FBUI_DrawFileDetails(DrawSurface *surface, const Point &basePoint, const Rect &constraintRect, void *fileDetails) +{ + PortabilityLayer::ResolveCachingColor blackColor(StdColors::Black()); + PortabilityLayer::RenderedFont *rfont = GetApplicationFont(12, PortabilityLayer::FontFamilyFlag_Bold, true); + + const game2Type *gameData = static_cast(fileDetails); + + Str255 numStr; + + NumToString(gameData->wasStarsLeft, numStr); + surface->DrawString(basePoint + Point::Create(kStarsOffset, 0), numStr, blackColor, rfont); + + NumToString(gameData->numGliders, numStr); + surface->DrawString(basePoint + Point::Create(kGlidersOffset, 0), numStr, blackColor, rfont); + + NumToString(gameData->score, numStr); + surface->DrawString(basePoint + Point::Create(kScoreOffset, 0), numStr, blackColor, rfont); +} + +static void *FBUI_LoadFileDetails(PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename) +{ + GpIOStream *stream = nullptr; + if (PortabilityLayer::FileManager::GetInstance()->OpenFileData(dirID, filename, PortabilityLayer::EFilePermission_Read, stream) != PLErrors::kNone) + return nullptr; + + const size_t kPrefixSize = sizeof(game2Type) - sizeof(savedRoom); + + game2Type *gameData = static_cast(PortabilityLayer::MemoryManager::GetInstance()->Alloc(kPrefixSize)); + if (!gameData) + { + stream->Close(); + return nullptr; + } + + if (stream->Read(gameData, kPrefixSize) != kPrefixSize) + { + PortabilityLayer::MemoryManager::GetInstance()->Release(gameData); + stream->Close(); + return nullptr; + } + + stream->Close(); + + return gameData; +} + +static void FBUI_FreeFileDetails(void *fileDetails) +{ + PortabilityLayer::MemoryManager::GetInstance()->Release(fileDetails); +} + +static PortabilityLayer::FileBrowserUI_DetailsCallbackAPI GetSavedGameDetailsAPI() +{ + PortabilityLayer::FileBrowserUI_DetailsCallbackAPI api; + + api.m_drawLabelsCallback = FBUI_DrawLabels; + api.m_drawFileDetailsCallback = FBUI_DrawFileDetails; + api.m_loadFileDetailsCallback = FBUI_LoadFileDetails; + api.m_freeFileDetailsCallback = FBUI_FreeFileDetails; + + return api; +} + //-------------------------------------------------------------- SaveGame2 void SaveGame2 (void) @@ -82,7 +163,7 @@ void SaveGame2 (void) char savePath[sizeof(spec.m_name) + 1]; size_t savePathLength = 0; - if (!fm->PromptSaveFile(spec.m_dir, savePath, savePathLength, sizeof(spec.m_name), PLPasStr(gameNameStr), PSTR("Save Game"))) + if (!fm->PromptSaveFile(spec.m_dir, savePath, savePathLength, sizeof(spec.m_name), PLPasStr(gameNameStr), PSTR("Save Game"), GetSavedGameDetailsAPI())) { mm->Release(savedGame); return; @@ -191,7 +272,7 @@ Boolean OpenSavedGame (void) char savePath[sizeof(spec.m_name) + 1]; size_t savePathLength = 0; - if (!fm->PromptOpenFile(spec.m_dir, savePath, savePathLength, sizeof(spec.m_name), PSTR("Open Saved Game"))) + if (!fm->PromptOpenFile(spec.m_dir, savePath, savePathLength, sizeof(spec.m_name), PSTR("Open Saved Game"), GetSavedGameDetailsAPI())) return false; assert(savePathLength < sizeof(spec.m_name) - 1); diff --git a/PortabilityLayer/FileBrowserUI.cpp b/PortabilityLayer/FileBrowserUI.cpp index 3a074f3..e03eff5 100644 --- a/PortabilityLayer/FileBrowserUI.cpp +++ b/PortabilityLayer/FileBrowserUI.cpp @@ -54,7 +54,7 @@ namespace PortabilityLayer class FileBrowserUIImpl { public: - FileBrowserUIImpl(); + explicit FileBrowserUIImpl(const FileBrowserUI_DetailsCallbackAPI &callbackAPI); ~FileBrowserUIImpl(); static void PubScrollBarCallback(void *captureContext, Widget *control, int part); @@ -62,8 +62,9 @@ namespace PortabilityLayer static int16_t PubFileBrowserUIFilter(void *context, Dialog *dialog, const TimeTaggedVOSEvent *evt); static int16_t PubPopUpAlertUIFilter(void *context, Dialog *dialog, const TimeTaggedVOSEvent *evt); - bool AppendName(const char *name, size_t nameLength); + bool AppendName(const char *name, size_t nameLength, void *details); void SortNames(); + void DrawHeaders(); void DrawFileList(); void CaptureFileListDrag(); @@ -80,18 +81,25 @@ namespace PortabilityLayer private: typedef PascalStr<255> NameStr_t; + + struct FileEntry + { + NameStr_t m_nameStr; + void *m_fileDetails; + }; + void ScrollBarCallback(Widget *control, int part); int16_t FileBrowserUIFilter(Dialog *dialog, const TimeTaggedVOSEvent *evt); int16_t PopUpAlertUIFilter(Dialog *dialog, const TimeTaggedVOSEvent *evt); - static bool NameSortPred(const NameStr_t &a, const NameStr_t &b); + static bool FileEntrySortPred(const FileEntry &a, const FileEntry &b); int m_offset; int m_selectedIndex; int32_t m_scrollOffset; int32_t m_fontSpacing; - THandle m_names; - size_t m_numNames; + THandle m_entries; + size_t m_numEntries; DrawSurface *m_surface; Window *m_window; EditboxWidget *m_editBox; @@ -100,9 +108,11 @@ namespace PortabilityLayer Point m_doubleClickPos; uint32_t m_doubleClickTime; bool m_haveFirstClick; + + const FileBrowserUI_DetailsCallbackAPI m_api; }; - FileBrowserUIImpl::FileBrowserUIImpl() + FileBrowserUIImpl::FileBrowserUIImpl(const FileBrowserUI_DetailsCallbackAPI &callbackAPI) : m_offset(0) , m_surface(nullptr) , m_window(nullptr) @@ -111,16 +121,23 @@ namespace PortabilityLayer , m_selectedIndex(-1) , m_scrollOffset(0) , m_fontSpacing(1) - , m_numNames(0) + , m_numEntries(0) , m_doubleClickPos(Point::Create(0, 0)) , m_doubleClickTime(0) , m_haveFirstClick(false) + , m_api(callbackAPI) { } FileBrowserUIImpl::~FileBrowserUIImpl() { - m_names.Dispose(); + if (m_entries) + { + FileEntry *entries = *m_entries; + for (size_t i = 0; i < m_numEntries; i++) + m_api.m_freeFileDetailsCallback(entries[i].m_fileDetails); + } + m_entries.Dispose(); } void FileBrowserUIImpl::PubScrollBarCallback(void *captureContext, Widget *control, int part) @@ -145,39 +162,51 @@ namespace PortabilityLayer return HostFileSystem::GetInstance()->ValidateFilePathUnicodeChar(unicodeChar); } - bool FileBrowserUIImpl::AppendName(const char *name, size_t nameLen) + bool FileBrowserUIImpl::AppendName(const char *name, size_t nameLen, void *details) { MemoryManager *mm = MemoryManager::GetInstance(); - if (!m_names) + if (!m_entries) { - m_names = THandle(mm->AllocHandle(0)); - if (!m_names) + m_entries = THandle(mm->AllocHandle(0)); + if (!m_entries) return false; } - size_t oldSize = m_names.MMBlock()->m_size; + size_t oldSize = m_entries.MMBlock()->m_size; - if (!mm->ResizeHandle(m_names.MMBlock(), oldSize + sizeof(NameStr_t))) - return false; + if (!mm->ResizeHandle(m_entries.MMBlock(), oldSize + sizeof(FileEntry))) + return false; - (*m_names)[m_numNames++] = NameStr_t(nameLen, name); + FileEntry &entry = (*m_entries)[m_numEntries++]; + entry.m_nameStr = NameStr_t(nameLen, name); + entry.m_fileDetails = details; return true; } void FileBrowserUIImpl::SortNames() { - if (!m_names) + if (!m_entries) return; - NameStr_t *names = *m_names; + FileEntry *entries = *m_entries; - std::sort(names, names + m_numNames, NameSortPred); + std::sort(entries, entries + m_numEntries, FileEntrySortPred); + } + + void FileBrowserUIImpl::DrawHeaders() + { + PortabilityLayer::RenderedFont *font = GetApplicationFont(12, PortabilityLayer::FontFamilyFlags::FontFamilyFlag_Bold, true); + + ResolveCachingColor blackColor = StdColors::Black(); + + const Point basePoint = Point::Create(16, 16 + font->GetMetrics().m_ascent); + m_api.m_drawLabelsCallback(m_surface, basePoint); } void FileBrowserUIImpl::DrawFileList() { - if (!m_names.MMBlock()) + if (!m_entries.MMBlock()) return; PortabilityLayer::RenderedFont *font = GetApplicationFont(12, PortabilityLayer::FontFamilyFlags::FontFamilyFlag_Bold, true); @@ -196,7 +225,7 @@ namespace PortabilityLayer m_surface->FillRect(m_rect, whiteColor); - for (size_t i = 0; i < m_numNames; i++) + for (size_t i = 0; i < m_numEntries; i++) { if (m_selectedIndex >= 0 && static_cast(m_selectedIndex) == i) { @@ -206,7 +235,9 @@ namespace PortabilityLayer } Point itemStringPoint = Point::Create(itemRect.left + 2, itemRect.top + glyphOffset); - m_surface->DrawStringConstrained(itemStringPoint, (*m_names)[i].ToShortStr(), m_rect, blackColor, font); + 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); itemRect.top += spacing; itemRect.bottom += spacing; @@ -228,7 +259,7 @@ namespace PortabilityLayer uint16_t FileBrowserUIImpl::GetScrollCapacity() const { int32_t boxHeight = m_rect.Height(); - int32_t overCapacity = (static_cast(m_numNames) * m_fontSpacing - boxHeight); + int32_t overCapacity = (static_cast(m_numEntries) * m_fontSpacing - boxHeight); if (overCapacity < 0) return 0; @@ -249,7 +280,7 @@ namespace PortabilityLayer if (m_selectedIndex < 0) return PSTR(""); else - return (*m_names)[m_selectedIndex].ToShortStr(); + return (*m_entries)[m_selectedIndex].m_nameStr.ToShortStr(); } void FileBrowserUIImpl::RemoveSelectedFile() @@ -257,12 +288,17 @@ namespace PortabilityLayer if (m_selectedIndex < 0) return; - NameStr_t *names = *m_names; - for (size_t i = m_selectedIndex; i < m_numNames - 1; i++) - names[i] = names[i + 1]; - m_numNames--; - PortabilityLayer::MemoryManager::GetInstance()->ResizeHandle(m_names.MMBlock(), sizeof(NameStr_t) * m_numNames); + FileEntry *entries = *m_entries; + + FileEntry &removedEntry = entries[m_selectedIndex]; + m_api.m_freeFileDetailsCallback(removedEntry.m_fileDetails); + + for (size_t i = m_selectedIndex; i < m_numEntries - 1; i++) + entries[i] = entries[i + 1]; + + m_numEntries--; + PortabilityLayer::MemoryManager::GetInstance()->ResizeHandle(m_entries.MMBlock(), sizeof(FileEntry) * m_numEntries); m_selectedIndex = -1; DrawFileList(); @@ -384,7 +420,7 @@ namespace PortabilityLayer { int32_t selection = (mousePt.v - m_rect.top + m_scrollOffset) / m_fontSpacing; - if (selection < 0 || static_cast(selection) >= m_numNames) + if (selection < 0 || static_cast(selection) >= m_numEntries) selection = -1; if (selection >= 0) @@ -403,7 +439,7 @@ namespace PortabilityLayer if (m_editBox) { - PLPasStr nameStr = (*m_names)[m_selectedIndex].ToShortStr(); + PLPasStr nameStr = (*m_entries)[m_selectedIndex].m_nameStr.ToShortStr(); m_editBox->SetString(nameStr); m_editBox->SetSelection(0, nameStr.Length()); } @@ -480,14 +516,14 @@ namespace PortabilityLayer return hit; } - bool FileBrowserUIImpl::NameSortPred(const NameStr_t &a, const NameStr_t &b) + bool FileBrowserUIImpl::FileEntrySortPred(const FileEntry &a, const FileEntry &b) { - const size_t lenA = a.Length(); - const size_t lenB = b.Length(); + const size_t lenA = a.m_nameStr.Length(); + const size_t lenB = b.m_nameStr.Length(); const size_t shorterLength = std::min(lenA, lenB); - int comparison = memcmp(a.UnsafeCharPtr(), b.UnsafeCharPtr(), shorterLength); + int comparison = memcmp(a.m_nameStr.UnsafeCharPtr(), b.m_nameStr.UnsafeCharPtr(), shorterLength); if (comparison > 0) return false; @@ -526,7 +562,7 @@ namespace PortabilityLayer return hit; } - bool FileBrowserUI::Prompt(Mode mode, VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText) + bool FileBrowserUI::Prompt(Mode mode, VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) { int dialogID = 0; bool isObstructive = false; @@ -550,7 +586,7 @@ namespace PortabilityLayer return false; } - FileBrowserUIImpl uiImpl; + FileBrowserUIImpl uiImpl(callbackAPI); // Enumerate files PortabilityLayer::HostFileSystem *fs = PortabilityLayer::HostFileSystem::GetInstance(); @@ -571,7 +607,7 @@ namespace PortabilityLayer if (!memcmp(nameExt, ".gpf", 4)) { - if (!uiImpl.AppendName(fileName, nameLength - 4)) + if (!uiImpl.AppendName(fileName, nameLength - 4, callbackAPI.m_loadFileDetailsCallback(dirID, PLPasStr(nameLength - 4, fileName)))) { dirCursor->Destroy(); return false; @@ -652,6 +688,8 @@ namespace PortabilityLayer window->DrawControls(); + uiImpl.DrawHeaders(); + int16_t hit = 0; Window *exclWindow = dialog->GetWindow(); @@ -741,7 +779,7 @@ namespace PortabilityLayer outPathLength = uiFileName.Length(); } - dialog->Destroy(); + dialog->Destroy(); return confirmed; } diff --git a/PortabilityLayer/FileBrowserUI.h b/PortabilityLayer/FileBrowserUI.h index e92a63e..fd5eaed 100644 --- a/PortabilityLayer/FileBrowserUI.h +++ b/PortabilityLayer/FileBrowserUI.h @@ -5,18 +5,31 @@ #include "VirtualDirectory.h" class PLPasStr; +struct DrawSurface; +struct Point; +struct Rect; 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_loadFileDetailsCallback)(VirtualDirectory_t dirID, const PLPasStr &filename); + void(*m_freeFileDetailsCallback)(void *fileDetails); + }; + class FileBrowserUI { public: + enum Mode { Mode_Save, Mode_Open, }; - static bool Prompt(Mode mode, VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText); + static bool Prompt(Mode mode, VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText, const FileBrowserUI_DetailsCallbackAPI &callbackAPI); }; } diff --git a/PortabilityLayer/FileManager.cpp b/PortabilityLayer/FileManager.cpp index 35c9be7..1293dde 100644 --- a/PortabilityLayer/FileManager.cpp +++ b/PortabilityLayer/FileManager.cpp @@ -35,8 +35,8 @@ namespace PortabilityLayer PLError_t RawOpenFileData(VirtualDirectory_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, GpFileCreationDisposition_t creationDisposition, GpIOStream *&outStream) override; PLError_t RawOpenFileResources(VirtualDirectory_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, GpFileCreationDisposition_t creationDisposition, GpIOStream *&outStream) override; - bool PromptSaveFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText) override; - bool PromptOpenFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &promptText) override; + bool PromptSaveFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) override; + bool PromptOpenFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &promptText, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) override; static FileManagerImpl *GetInstance(); @@ -176,18 +176,18 @@ namespace PortabilityLayer return RawOpenFileFork(dirID, filename, ".gpa", permission, ignoreMeta, createDisposition, outStream); } - bool FileManagerImpl::PromptSaveFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText) + bool FileManagerImpl::PromptSaveFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText, const FileBrowserUI_DetailsCallbackAPI &detailsAPI) { ExtendedFileName_t extFN; if (!ConstructFilename(extFN, initialFileName, "")) return false; - return FileBrowserUI::Prompt(FileBrowserUI::Mode_Save, dirID, path, outPathLength, pathCapacity, initialFileName, promptText); + return FileBrowserUI::Prompt(FileBrowserUI::Mode_Save, dirID, path, outPathLength, pathCapacity, initialFileName, promptText, detailsAPI); } - bool FileManagerImpl::PromptOpenFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &promptText) + bool FileManagerImpl::PromptOpenFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &promptText, const FileBrowserUI_DetailsCallbackAPI &detailsAPI) { - return FileBrowserUI::Prompt(FileBrowserUI::Mode_Open, dirID, path, outPathLength, pathCapacity, PSTR(""), promptText); + return FileBrowserUI::Prompt(FileBrowserUI::Mode_Open, dirID, path, outPathLength, pathCapacity, PSTR(""), promptText, detailsAPI); } FileManagerImpl *FileManagerImpl::GetInstance() diff --git a/PortabilityLayer/FileManager.h b/PortabilityLayer/FileManager.h index eaf4d8a..94b1111 100644 --- a/PortabilityLayer/FileManager.h +++ b/PortabilityLayer/FileManager.h @@ -16,6 +16,7 @@ namespace PortabilityLayer { class ResTypeID; struct MacFileProperties; + struct FileBrowserUI_DetailsCallbackAPI; class FileManager { @@ -35,8 +36,8 @@ namespace PortabilityLayer virtual PLError_t RawOpenFileData(VirtualDirectory_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, GpFileCreationDisposition_t createDisposition, GpIOStream *&outStream) = 0; virtual PLError_t RawOpenFileResources(VirtualDirectory_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, GpFileCreationDisposition_t createDisposition, GpIOStream *&outStream) = 0; - virtual bool PromptSaveFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText) = 0; - virtual bool PromptOpenFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &promptText) = 0; + virtual bool PromptSaveFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &initialFileName, const PLPasStr &promptText, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) = 0; + virtual bool PromptOpenFile(VirtualDirectory_t dirID, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &promptText, const FileBrowserUI_DetailsCallbackAPI &callbackAPI) = 0; static FileManager *GetInstance(); };