Add delete option to File browser

This commit is contained in:
elasota
2021-05-09 22:48:23 -04:00
parent 222927d56f
commit d54ad576bc
10 changed files with 134 additions and 18 deletions

View File

@@ -262,6 +262,11 @@ bool GpSystemServices_Win32::IsFullscreenOnStartup() const
return false; return false;
} }
bool GpSystemServices_Win32::HasNativeFileManager() const
{
return false;
}
unsigned int GpSystemServices_Win32::GetCPUCount() const unsigned int GpSystemServices_Win32::GetCPUCount() const
{ {
SYSTEM_INFO sysInfo; SYSTEM_INFO sysInfo;

View File

@@ -34,6 +34,7 @@ public:
bool IsTextInputObstructive() const override; bool IsTextInputObstructive() const override;
bool IsFullscreenPreferred() const override; bool IsFullscreenPreferred() const override;
bool IsFullscreenOnStartup() const override; bool IsFullscreenOnStartup() const override;
bool HasNativeFileManager() const override;
unsigned int GetCPUCount() const override; unsigned int GetCPUCount() const override;
void SetTextInputEnabled(bool isEnabled) override; void SetTextInputEnabled(bool isEnabled) override;
bool IsTextInputEnabled() const override; bool IsTextInputEnabled() const override;

View File

@@ -0,0 +1,61 @@
{
"items" :
[
{
"name" : "Okay",
"itemType" : "Button",
"pos" : [ 376, 240 ],
"size" : [ 58, 20 ],
"id" : 1,
"enabled" : true
},
{
"name" : "Cancel",
"itemType" : "Button",
"pos" : [ 302, 240 ],
"size" : [ 58, 20 ],
"id" : 2,
"enabled" : true
},
{
"name" : "",
"itemType" : "CustomControl",
"pos" : [ 17, 33 ],
"size" : [ 401, 186 ],
"id" : 2,
"enabled" : true
},
{
"name" : "",
"itemType" : "CustomControl",
"pos" : [ 418, 32 ],
"size" : [ 16, 188 ],
"id" : 3,
"enabled" : true
},
{
"name" : "",
"itemType" : "EditBox",
"pos" : [ 16, 240 ],
"size" : [ 196, 16 ],
"id" : 4,
"enabled" : true
},
{
"name" : "^0",
"itemType" : "Label",
"pos" : [ 16, 16 ],
"size" : [ 418, 16 ],
"id" : 10,
"enabled" : true
},
{
"name" : "Delete",
"itemType" : "Button",
"pos" : [ 228, 240 ],
"size" : [ 58, 20 ],
"id" : 2,
"enabled" : false
}
]
}

View File

@@ -12,6 +12,7 @@
"DITL/2006.json" : "ApplicationResourcePatches/DITL/2006.json", "DITL/2006.json" : "ApplicationResourcePatches/DITL/2006.json",
"DITL/2007.json" : "ApplicationResourcePatches/DITL/2007.json", "DITL/2007.json" : "ApplicationResourcePatches/DITL/2007.json",
"DITL/2008.json" : "ApplicationResourcePatches/DITL/2008.json", "DITL/2008.json" : "ApplicationResourcePatches/DITL/2008.json",
"DITL/2009.json" : "ApplicationResourcePatches/DITL/2009.json",
"PICT/1300.bmp" : "ApplicationResourcePatches/PICT/1300.bmp", "PICT/1300.bmp" : "ApplicationResourcePatches/PICT/1300.bmp",
"PICT/1301.bmp" : "ApplicationResourcePatches/PICT/1301.bmp", "PICT/1301.bmp" : "ApplicationResourcePatches/PICT/1301.bmp",
"PICT/1971.bmp" : "ApplicationResourcePatches/PICT/1971.bmp", "PICT/1971.bmp" : "ApplicationResourcePatches/PICT/1971.bmp",

View File

@@ -76,6 +76,14 @@ static bool FBUI_House_FilterFile(PortabilityLayer::VirtualDirectory_t dirID, co
return PortabilityLayer::ResTypeIDCodec::Decode(cfile->GetProperties().m_fileType) == 'gliH'; return PortabilityLayer::ResTypeIDCodec::Decode(cfile->GetProperties().m_fileType) == 'gliH';
} }
static bool FBUI_House_IsDeleteValid(PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename)
{
if (dirID != PortabilityLayer::VirtualDirectories::kUserData)
return false;
return !StrCmp::EqualCaseInsensitive(thisHouseName, filename);
}
static PortabilityLayer::FileBrowserUI_DetailsCallbackAPI GetHouseDetailsAPI() static PortabilityLayer::FileBrowserUI_DetailsCallbackAPI GetHouseDetailsAPI()
{ {
PortabilityLayer::FileBrowserUI_DetailsCallbackAPI api; PortabilityLayer::FileBrowserUI_DetailsCallbackAPI api;
@@ -85,6 +93,7 @@ static PortabilityLayer::FileBrowserUI_DetailsCallbackAPI GetHouseDetailsAPI()
api.m_loadFileDetailsCallback = FBUI_House_LoadFileDetails; api.m_loadFileDetailsCallback = FBUI_House_LoadFileDetails;
api.m_freeFileDetailsCallback = FBUI_House_FreeFileDetails; api.m_freeFileDetailsCallback = FBUI_House_FreeFileDetails;
api.m_filterFileCallback = FBUI_House_FilterFile; api.m_filterFileCallback = FBUI_House_FilterFile;
api.m_isDeleteValidCallback = FBUI_House_IsDeleteValid;
return api; return api;
} }

View File

@@ -107,6 +107,11 @@ static bool FBUI_Save_FilterFile(PortabilityLayer::VirtualDirectory_t dirID, con
return true; return true;
} }
static bool FBUI_Save_IsDeleteValid(PortabilityLayer::VirtualDirectory_t dirID, const PLPasStr &filename)
{
return true;
}
static PortabilityLayer::FileBrowserUI_DetailsCallbackAPI GetSavedGameDetailsAPI() static PortabilityLayer::FileBrowserUI_DetailsCallbackAPI GetSavedGameDetailsAPI()
{ {
PortabilityLayer::FileBrowserUI_DetailsCallbackAPI api; PortabilityLayer::FileBrowserUI_DetailsCallbackAPI api;
@@ -116,6 +121,7 @@ static PortabilityLayer::FileBrowserUI_DetailsCallbackAPI GetSavedGameDetailsAPI
api.m_loadFileDetailsCallback = FBUI_Save_LoadFileDetails; api.m_loadFileDetailsCallback = FBUI_Save_LoadFileDetails;
api.m_freeFileDetailsCallback = FBUI_Save_FreeFileDetails; api.m_freeFileDetailsCallback = FBUI_Save_FreeFileDetails;
api.m_filterFileCallback = FBUI_Save_FilterFile; api.m_filterFileCallback = FBUI_Save_FilterFile;
api.m_isDeleteValidCallback = FBUI_Save_IsDeleteValid;
return api; return api;
} }

View File

@@ -32,6 +32,7 @@ public:
virtual bool IsFullscreenPreferred() const = 0; virtual bool IsFullscreenPreferred() const = 0;
virtual bool IsFullscreenOnStartup() const = 0; virtual bool IsFullscreenOnStartup() const = 0;
virtual bool IsTextInputObstructive() const = 0; virtual bool IsTextInputObstructive() const = 0;
virtual bool HasNativeFileManager() const = 0;
virtual unsigned int GetCPUCount() const = 0; virtual unsigned int GetCPUCount() const = 0;
virtual void SetTextInputEnabled(bool isEnabled) = 0; virtual void SetTextInputEnabled(bool isEnabled) = 0;
virtual bool IsTextInputEnabled() const = 0; virtual bool IsTextInputEnabled() const = 0;

View File

@@ -40,13 +40,15 @@ static const int kCancelButton = 2;
static const int kFileList = 3; static const int kFileList = 3;
static const int kFileListScrollBar = 4; static const int kFileListScrollBar = 4;
static const int kFileNameEditBox = 5; static const int kFileNameEditBox = 5;
static const int kDeleteButton = 5; static const int kOpenDeleteButton = 5;
static const int kSaveDeleteButton = 7;
static const int kFileBrowserUIOpenDialogTemplateID = 2001; static const int kFileBrowserUIOpenDialogTemplateID = 2001;
static const int kFileBrowserUISaveDialogTemplateID = 2002; static const int kFileBrowserUISaveDialogTemplateID = 2002;
static const int kFileBrowserUIOverwriteDialogTemplateID = 2003; static const int kFileBrowserUIOverwriteDialogTemplateID = 2003;
static const int kFileBrowserUIBadNameDialogTemplateID = 2004; static const int kFileBrowserUIBadNameDialogTemplateID = 2004;
static const int kFileBrowserUISaveDialogUnobstructiveTemplateID = 2007; static const int kFileBrowserUISaveDialogUnobstructiveTemplateID = 2007;
static const int kFileBrowserUIDeleteDialogTemplateID = 2008; static const int kFileBrowserUIDeleteDialogTemplateID = 2008;
static const int kFileBrowserUISaveDialogWithDeleteButtonTemplateID = 2009;
static const int kOverwriteNoButton = 1; static const int kOverwriteNoButton = 1;
@@ -57,7 +59,7 @@ namespace PortabilityLayer
class FileBrowserUIImpl class FileBrowserUIImpl
{ {
public: public:
explicit FileBrowserUIImpl(const FileBrowserUI_DetailsCallbackAPI &callbackAPI); FileBrowserUIImpl(VirtualDirectory_t dir, const FileBrowserUI_DetailsCallbackAPI &callbackAPI);
~FileBrowserUIImpl(); ~FileBrowserUIImpl();
static void PubScrollBarCallback(void *captureContext, Widget *control, int part); static void PubScrollBarCallback(void *captureContext, Widget *control, int part);
@@ -111,6 +113,8 @@ namespace PortabilityLayer
uint32_t m_doubleClickTime; uint32_t m_doubleClickTime;
bool m_haveFirstClick; bool m_haveFirstClick;
VirtualDirectory_t m_dir;
const FileBrowserUI_DetailsCallbackAPI m_api; const FileBrowserUI_DetailsCallbackAPI m_api;
}; };
} }
@@ -128,7 +132,7 @@ static int16_t FileBrowserUIImpl_PopUpAlertUIFilter(void *context, Dialog *dialo
namespace PortabilityLayer namespace PortabilityLayer
{ {
FileBrowserUIImpl::FileBrowserUIImpl(const FileBrowserUI_DetailsCallbackAPI &callbackAPI) FileBrowserUIImpl::FileBrowserUIImpl(VirtualDirectory_t dir, const FileBrowserUI_DetailsCallbackAPI &callbackAPI)
: m_offset(0) : m_offset(0)
, m_surface(nullptr) , m_surface(nullptr)
, m_window(nullptr) , m_window(nullptr)
@@ -142,6 +146,7 @@ namespace PortabilityLayer
, m_doubleClickTime(0) , m_doubleClickTime(0)
, m_haveFirstClick(false) , m_haveFirstClick(false)
, m_api(callbackAPI) , m_api(callbackAPI)
, m_dir(dir)
{ {
} }
@@ -439,8 +444,19 @@ namespace PortabilityLayer
dialog->GetItems()[kOkayButton - 1].GetWidget()->SetEnabled(selection >= 0); dialog->GetItems()[kOkayButton - 1].GetWidget()->SetEnabled(selection >= 0);
bool isDeleteValid = (selection >= 0);
if (isDeleteValid)
{
const FileBrowserUIImpl::FileEntry &entry = (*m_entries)[selection];
isDeleteValid = m_api.m_isDeleteValidCallback(m_dir, entry.m_nameStr.ToShortStr());
}
if (gs_currentFileBrowserUIMode == FileBrowserUI::Mode_Open) if (gs_currentFileBrowserUIMode == FileBrowserUI::Mode_Open)
dialog->GetItems()[kDeleteButton - 1].GetWidget()->SetEnabled(selection >= 0); dialog->GetItems()[kOpenDeleteButton - 1].GetWidget()->SetEnabled(isDeleteValid);
else if (gs_currentFileBrowserUIMode == FileBrowserUI::Mode_SaveWithDelete)
dialog->GetItems()[kSaveDeleteButton - 1].GetWidget()->SetEnabled(isDeleteValid);
DrawFileList(); DrawFileList();
} }
@@ -585,24 +601,30 @@ namespace PortabilityLayer
int windowHeight = 272; int windowHeight = 272;
if (mode == Mode_Open) if (mode == Mode_Open)
dialogID = kFileBrowserUIOpenDialogTemplateID; dialogID = kFileBrowserUIOpenDialogTemplateID;
else if (mode == Mode_Save) else if (mode == Mode_SaveWithDelete || mode == Mode_SaveNoDelete)
{ {
if (PLDrivers::GetSystemServices()->IsTextInputObstructive()) if (PLDrivers::GetSystemServices()->IsTextInputObstructive())
{ {
dialogID = kFileBrowserUISaveDialogUnobstructiveTemplateID; dialogID = kFileBrowserUISaveDialogUnobstructiveTemplateID;
windowHeight = 208; windowHeight = 208;
isObstructive = true; isObstructive = true;
mode = Mode_SaveNoDelete; // HACK HACK HACK
} }
else
{
if (mode == Mode_SaveWithDelete)
dialogID = kFileBrowserUISaveDialogWithDeleteButtonTemplateID;
else else
dialogID = kFileBrowserUISaveDialogTemplateID; dialogID = kFileBrowserUISaveDialogTemplateID;
} }
}
else else
{ {
assert(false); assert(false);
return false; return false;
} }
FileBrowserUIImpl uiImpl(callbackAPI); FileBrowserUIImpl uiImpl(dirID, callbackAPI);
// Enumerate files // Enumerate files
IGpFileSystem *fs = PLDrivers::GetFileSystem(); IGpFileSystem *fs = PLDrivers::GetFileSystem();
@@ -674,7 +696,7 @@ namespace PortabilityLayer
const Rect scrollBarRect = dialog->GetItems()[kFileListScrollBar - 1].GetWidget()->GetRect(); const Rect scrollBarRect = dialog->GetItems()[kFileListScrollBar - 1].GetWidget()->GetRect();
EditboxWidget *editbox = nullptr; EditboxWidget *editbox = nullptr;
if (mode == Mode_Save) if (mode == Mode_SaveWithDelete || mode == Mode_SaveNoDelete)
{ {
editbox = static_cast<EditboxWidget*>(dialog->GetItems()[kFileNameEditBox - 1].GetWidget()); editbox = static_cast<EditboxWidget*>(dialog->GetItems()[kFileNameEditBox - 1].GetWidget());
editbox->SetCharacterFilter(&uiImpl, FileBrowserUIImpl::PubEditBoxCharFilter); editbox->SetCharacterFilter(&uiImpl, FileBrowserUIImpl::PubEditBoxCharFilter);
@@ -725,7 +747,7 @@ namespace PortabilityLayer
if (hit == kFileListScrollBar) if (hit == kFileListScrollBar)
uiImpl.SetScrollOffset(scrollBar->GetState()); uiImpl.SetScrollOffset(scrollBar->GetState());
if (hit == kOkayButton && mode == Mode_Save) if (hit == kOkayButton && (mode == Mode_SaveWithDelete || mode == Mode_SaveNoDelete))
{ {
IGpFileSystem *fs = PLDrivers::GetFileSystem(); IGpFileSystem *fs = PLDrivers::GetFileSystem();
@@ -759,7 +781,7 @@ namespace PortabilityLayer
} }
} }
if (mode == Mode_Open && hit == kDeleteButton) if ((mode == Mode_Open && hit == kOpenDeleteButton) || (mode == Mode_SaveWithDelete && hit == kSaveDeleteButton))
{ {
PLDrivers::GetSystemServices()->Beep(); PLDrivers::GetSystemServices()->Beep();
int16_t subHit = FileBrowserUIImpl::PopUpAlert(Rect::Create(0, 0, 135, 327), kFileBrowserUIDeleteDialogTemplateID, &substitutions); int16_t subHit = FileBrowserUIImpl::PopUpAlert(Rect::Create(0, 0, 135, 327), kFileBrowserUIDeleteDialogTemplateID, &substitutions);
@@ -768,14 +790,18 @@ namespace PortabilityLayer
{ {
PLPasStr uiFileName = uiImpl.GetSelectedFileName(); PLPasStr uiFileName = uiImpl.GetSelectedFileName();
bool deleted = false;
if (composites) if (composites)
PortabilityLayer::FileManager::GetInstance()->DeleteCompositeFile(dirID, uiFileName); deleted = PortabilityLayer::FileManager::GetInstance()->DeleteCompositeFile(dirID, uiFileName);
else else
PortabilityLayer::FileManager::GetInstance()->DeleteNonCompositeFile(dirID, uiFileName, extension); deleted = PortabilityLayer::FileManager::GetInstance()->DeleteNonCompositeFile(dirID, uiFileName, extension);
uiImpl.RemoveSelectedFile(); uiImpl.RemoveSelectedFile();
dialog->GetItems()[kOkayButton - 1].GetWidget()->SetEnabled(false); dialog->GetItems()[kOkayButton - 1].GetWidget()->SetEnabled(false);
dialog->GetItems()[kDeleteButton - 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; hit = -1;
} }
@@ -793,7 +819,7 @@ namespace PortabilityLayer
uiFileName = uiImpl.GetSelectedFileName(); uiFileName = uiImpl.GetSelectedFileName();
confirmed = true; confirmed = true;
} }
else if (mode == Mode_Save) else if (mode == Mode_SaveWithDelete || mode == Mode_SaveNoDelete)
{ {
uiFileName = editbox->GetString(); uiFileName = editbox->GetString();
confirmed = true; confirmed = true;

View File

@@ -20,8 +20,9 @@ namespace PortabilityLayer
void(*m_drawFileDetailsCallback)(DrawSurface *surface, const Point &basePoint, const Rect &constraintRect, void *fileDetails); void(*m_drawFileDetailsCallback)(DrawSurface *surface, const Point &basePoint, const Rect &constraintRect, void *fileDetails);
void *(*m_loadFileDetailsCallback)(VirtualDirectory_t dirID, const PLPasStr &filename); void *(*m_loadFileDetailsCallback)(VirtualDirectory_t dirID, const PLPasStr &filename);
void(*m_freeFileDetailsCallback)(void *fileDetails); void (*m_freeFileDetailsCallback)(void *fileDetails);
bool(*m_filterFileCallback)(VirtualDirectory_t dirID, const PLPasStr &filename); bool (*m_filterFileCallback)(VirtualDirectory_t dirID, const PLPasStr &filename);
bool (*m_isDeleteValidCallback)(VirtualDirectory_t dirID, const PLPasStr &filename);
}; };
class FileBrowserUI class FileBrowserUI
@@ -30,7 +31,8 @@ namespace PortabilityLayer
enum Mode enum Mode
{ {
Mode_Save, Mode_SaveNoDelete,
Mode_SaveWithDelete,
Mode_Open, Mode_Open,
}; };

View File

@@ -282,7 +282,11 @@ namespace PortabilityLayer
if (!FileManagerTools::ConstructFilename(extFN, initialFileName, "")) if (!FileManagerTools::ConstructFilename(extFN, initialFileName, ""))
return false; return false;
return FileBrowserUI::Prompt(FileBrowserUI::Mode_Save, dirID, extension, path, outPathLength, pathCapacity, initialFileName, promptText, composites, detailsAPI); FileBrowserUI::Mode mode = FileBrowserUI::Mode_SaveNoDelete;
if (!PLDrivers::GetSystemServices()->HasNativeFileManager())
mode = FileBrowserUI::Mode_SaveWithDelete;
return FileBrowserUI::Prompt(mode, dirID, extension, path, outPathLength, pathCapacity, initialFileName, promptText, composites, detailsAPI);
} }
bool FileManagerImpl::PromptOpenFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &detailsAPI) bool FileManagerImpl::PromptOpenFile(VirtualDirectory_t dirID, const char *extension, char *path, size_t &outPathLength, size_t pathCapacity, const PLPasStr &promptText, bool composites, const FileBrowserUI_DetailsCallbackAPI &detailsAPI)