mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-12 12:09:15 +00:00
690b88f982
svn-id: r35668
257 lines
6.7 KiB
C++
257 lines
6.7 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* $URL$
|
|
* $Id$
|
|
*/
|
|
|
|
#include "gui/browser.h"
|
|
#include "gui/GuiManager.h"
|
|
#include "gui/ListWidget.h"
|
|
|
|
#include "common/config-manager.h"
|
|
#include "common/system.h"
|
|
#include "common/algorithm.h"
|
|
|
|
namespace GUI {
|
|
|
|
enum {
|
|
kChooseCmd = 'Chos',
|
|
kGoUpCmd = 'GoUp'
|
|
};
|
|
|
|
#ifdef MACOSX
|
|
/* On Mac OS X, use the native file selector dialog. We could do the same for
|
|
* other operating systems.
|
|
*/
|
|
|
|
BrowserDialog::BrowserDialog(const char *title, bool dirBrowser)
|
|
: Dialog("browser") {
|
|
_titleRef = CFStringCreateWithCString(0, title, CFStringGetSystemEncoding());
|
|
_isDirBrowser = dirBrowser;
|
|
}
|
|
|
|
BrowserDialog::~BrowserDialog() {
|
|
CFRelease(_titleRef);
|
|
}
|
|
|
|
int BrowserDialog::runModal() {
|
|
NavDialogRef dialogRef;
|
|
WindowRef windowRef = 0;
|
|
NavDialogCreationOptions options;
|
|
NavUserAction result;
|
|
NavReplyRecord reply;
|
|
OSStatus err;
|
|
bool choiceMade = false;
|
|
|
|
// If in fullscreen mode, switch to windowed mode
|
|
bool wasFullscreen = g_system->getFeatureState(OSystem::kFeatureFullscreenMode);
|
|
if (wasFullscreen)
|
|
g_system->setFeatureState(OSystem::kFeatureFullscreenMode, false);
|
|
|
|
// Temporarily show the real mouse
|
|
CGDisplayShowCursor(kCGDirectMainDisplay);
|
|
|
|
err = NavGetDefaultDialogCreationOptions(&options);
|
|
assert(err == noErr);
|
|
options.windowTitle = _titleRef;
|
|
// options.message = CFSTR("Select your game directory");
|
|
options.modality = kWindowModalityAppModal;
|
|
|
|
if (_isDirBrowser)
|
|
err = NavCreateChooseFolderDialog(&options, 0, 0, 0, &dialogRef);
|
|
else
|
|
err = NavCreateChooseFileDialog(&options, 0, 0, 0, 0, 0, &dialogRef);
|
|
assert(err == noErr);
|
|
|
|
windowRef = NavDialogGetWindow(dialogRef);
|
|
|
|
err = NavDialogRun(dialogRef);
|
|
assert(err == noErr);
|
|
|
|
CGDisplayHideCursor(kCGDirectMainDisplay);
|
|
|
|
result = NavDialogGetUserAction(dialogRef);
|
|
|
|
if (result == kNavUserActionChoose) {
|
|
err = NavDialogGetReply(dialogRef, &reply);
|
|
assert(err == noErr);
|
|
|
|
if (reply.validRecord && err == noErr) {
|
|
SInt32 theCount;
|
|
AECountItems(&reply.selection, &theCount);
|
|
assert(theCount == 1);
|
|
|
|
AEKeyword keyword;
|
|
FSRef ref;
|
|
char buf[4096];
|
|
err = AEGetNthPtr(&reply.selection, 1, typeFSRef, &keyword, NULL, &ref, sizeof(ref), NULL);
|
|
assert(err == noErr);
|
|
err = FSRefMakePath(&ref, (UInt8*)buf, sizeof(buf)-1);
|
|
assert(err == noErr);
|
|
|
|
_choice = Common::FSNode(buf);
|
|
choiceMade = true;
|
|
}
|
|
|
|
err = NavDisposeReply(&reply);
|
|
assert(err == noErr);
|
|
}
|
|
|
|
NavDialogDispose(dialogRef);
|
|
|
|
// If we were in fullscreen mode, switch back
|
|
if (wasFullscreen)
|
|
g_system->setFeatureState(OSystem::kFeatureFullscreenMode, true);
|
|
|
|
return choiceMade;
|
|
}
|
|
|
|
#else
|
|
|
|
/* We want to use this as a general directory selector at some point... possible uses
|
|
* - to select the data dir for a game
|
|
* - to select the place where save games are stored
|
|
* - others???
|
|
*/
|
|
|
|
BrowserDialog::BrowserDialog(const char *title, bool dirBrowser)
|
|
: Dialog("Browser") {
|
|
|
|
_isDirBrowser = dirBrowser;
|
|
_fileList = NULL;
|
|
_currentPath = NULL;
|
|
|
|
// Headline - TODO: should be customizable during creation time
|
|
new StaticTextWidget(this, "Browser.Headline", title);
|
|
|
|
// Current path - TODO: handle long paths ?
|
|
_currentPath = new StaticTextWidget(this, "Browser.Path", "DUMMY");
|
|
|
|
// Add file list
|
|
_fileList = new ListWidget(this, "Browser.List");
|
|
_fileList->setNumberingMode(kListNumberingOff);
|
|
_fileList->setEditable(false);
|
|
|
|
_backgroundType = GUI::ThemeEngine::kDialogBackgroundPlain;
|
|
|
|
// Buttons
|
|
new ButtonWidget(this, "Browser.Up", "Go up", kGoUpCmd, 0);
|
|
new ButtonWidget(this, "Browser.Cancel", "Cancel", kCloseCmd, 0);
|
|
new ButtonWidget(this, "Browser.Choose", "Choose", kChooseCmd, 0);
|
|
}
|
|
|
|
void BrowserDialog::open() {
|
|
if (ConfMan.hasKey("browser_lastpath"))
|
|
_node = Common::FSNode(ConfMan.get("browser_lastpath"));
|
|
if (!_node.isDirectory())
|
|
_node = Common::FSNode(".");
|
|
|
|
// Alway refresh file list
|
|
updateListing();
|
|
|
|
// Call super implementation
|
|
Dialog::open();
|
|
}
|
|
|
|
void BrowserDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
|
|
switch (cmd) {
|
|
case kChooseCmd:
|
|
if (_isDirBrowser) {
|
|
// If nothing is selected in the list widget, choose the current dir.
|
|
// Else, choose the dir that is selected.
|
|
int selection = _fileList->getSelected();
|
|
if (selection >= 0) {
|
|
_choice = _nodeContent[selection];
|
|
} else {
|
|
_choice = _node;
|
|
}
|
|
setResult(1);
|
|
close();
|
|
} else {
|
|
int selection = _fileList->getSelected();
|
|
if (selection < 0)
|
|
break;
|
|
if (_nodeContent[selection].isDirectory()) {
|
|
_node = _nodeContent[selection];
|
|
updateListing();
|
|
} else {
|
|
_choice = _nodeContent[selection];
|
|
setResult(1);
|
|
close();
|
|
}
|
|
}
|
|
break;
|
|
case kGoUpCmd:
|
|
_node = _node.getParent();
|
|
updateListing();
|
|
break;
|
|
case kListItemActivatedCmd:
|
|
case kListItemDoubleClickedCmd:
|
|
if (_nodeContent[data].isDirectory()) {
|
|
_node = _nodeContent[data];
|
|
updateListing();
|
|
} else {
|
|
_choice = _nodeContent[data];
|
|
setResult(1);
|
|
close();
|
|
}
|
|
break;
|
|
default:
|
|
Dialog::handleCommand(sender, cmd, data);
|
|
}
|
|
}
|
|
|
|
void BrowserDialog::updateListing() {
|
|
// Update the path display
|
|
_currentPath->setLabel(_node.getPath());
|
|
|
|
// We memorize the last visited path.
|
|
ConfMan.set("browser_lastpath", _node.getPath());
|
|
|
|
// Read in the data from the file system
|
|
Common::FSNode::ListMode listMode =
|
|
_isDirBrowser ? Common::FSNode::kListDirectoriesOnly
|
|
: Common::FSNode::kListAll;
|
|
if (!_node.getChildren(_nodeContent, listMode)) {
|
|
_nodeContent.clear();
|
|
} else {
|
|
Common::sort(_nodeContent.begin(), _nodeContent.end());
|
|
}
|
|
|
|
// Populate the ListWidget
|
|
Common::StringList list;
|
|
for (Common::FSList::iterator i = _nodeContent.begin(); i != _nodeContent.end(); ++i) {
|
|
if (!_isDirBrowser && i->isDirectory())
|
|
list.push_back(i->getDisplayName() + "/");
|
|
else
|
|
list.push_back(i->getDisplayName());
|
|
}
|
|
_fileList->setList(list);
|
|
_fileList->scrollTo(0);
|
|
|
|
// Finally, redraw
|
|
draw();
|
|
}
|
|
|
|
#endif // MACOSX
|
|
|
|
} // End of namespace GUI
|