mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-12 03:56:20 +00:00
76fb3ba5c7
svn-id: r12823
277 lines
7.0 KiB
C++
277 lines
7.0 KiB
C++
/* ScummVM - Scumm Interpreter
|
|
* Copyright (C) 2002-2004 The ScummVM project
|
|
*
|
|
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
* $Header$
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include "gui/browser.h"
|
|
#include "gui/newgui.h"
|
|
#include "gui/ListWidget.h"
|
|
|
|
#include "backends/fs/fs.h"
|
|
|
|
namespace GUI {
|
|
|
|
#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)
|
|
: Dialog(20, 10, 320 -2 * 20, 200 - 2 * 10) {
|
|
_choice = NULL;
|
|
_titleRef = CFStringCreateWithCString(0, title, CFStringGetSystemEncoding());
|
|
}
|
|
|
|
BrowserDialog::~BrowserDialog() {
|
|
delete _choice;
|
|
CFRelease(_titleRef);
|
|
}
|
|
|
|
static void myNavEventProc(NavEventCallbackMessage message, NavCBRecPtr callBackParms, void * callBackUD) {
|
|
switch (message) {
|
|
case kNavCBStart: {
|
|
// Force the window to be in the shielding window level -- this way
|
|
// it's visible even in fullscreen mode.
|
|
// Some glitches remain:
|
|
// - Need to center the nav dialog over the game window
|
|
// - In fullscreen mode, the game window won't be redrawn while the nav
|
|
// dialog is up, since our event loop won't run.
|
|
// - It will not work well if you try to use it in 320x200 fullscreen mode.
|
|
// Not that I have found any machine which actually supports that :-).
|
|
WindowGroupRef group;
|
|
OSStatus err;
|
|
err = CreateWindowGroup(0, &group);
|
|
SetWindowGroupLevel(group, CGShieldingWindowLevel());
|
|
err = SetWindowGroup(callBackParms->window, group);
|
|
break; }
|
|
case kNavCBTerminate: {
|
|
WindowGroupRef group;
|
|
OSStatus err;
|
|
|
|
group = GetWindowGroup(callBackParms->window);
|
|
err = ReleaseWindowGroup(group);
|
|
break; }
|
|
case kNavCBEvent: {
|
|
// TODO: here we could try to redraw the ScummVM window.
|
|
// This will probably require direct interfacing with the (SDL) backend
|
|
// and/or with Cocoa.
|
|
break; }
|
|
}
|
|
|
|
}
|
|
|
|
static NavEventUPP myNavEventUPP = NewNavEventUPP((NavEventProcPtr)myNavEventProc);
|
|
|
|
int BrowserDialog::runModal() {
|
|
NavDialogRef dialogRef;
|
|
WindowRef windowRef = 0;
|
|
NavDialogCreationOptions options;
|
|
NavUserAction result;
|
|
NavReplyRecord reply;
|
|
OSStatus err;
|
|
|
|
delete _choice;
|
|
_choice = 0;
|
|
|
|
// Temporarily show the real mouse
|
|
ShowCursor();
|
|
|
|
err = NavGetDefaultDialogCreationOptions(&options);
|
|
assert(err == noErr);
|
|
options.windowTitle = _titleRef;
|
|
// options.message = CFSTR("Select your game directory");
|
|
options.modality = kWindowModalityAppModal;
|
|
|
|
err = NavCreateChooseFolderDialog(&options, myNavEventUPP, 0, g_system, &dialogRef);
|
|
assert(err == noErr);
|
|
|
|
windowRef = NavDialogGetWindow(dialogRef);
|
|
|
|
err = NavDialogRun(dialogRef);
|
|
assert(err == noErr);
|
|
|
|
HideCursor();
|
|
|
|
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 = FilesystemNode::getNodeForPath(buf);
|
|
}
|
|
|
|
err = NavDisposeReply(&reply);
|
|
assert(err == noErr);
|
|
}
|
|
|
|
NavDialogDispose(dialogRef);
|
|
|
|
return (_choice != 0);
|
|
}
|
|
|
|
#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???
|
|
*/
|
|
|
|
enum {
|
|
kChooseCmd = 'Chos',
|
|
kGoUpCmd = 'GoUp'
|
|
};
|
|
|
|
BrowserDialog::BrowserDialog(const char *title)
|
|
: Dialog(20, 10, 320 -2 * 20, 200 - 2 * 10),
|
|
_node(0), _nodeContent(0) {
|
|
|
|
_fileList = NULL;
|
|
_currentPath = NULL;
|
|
_node = NULL;
|
|
_nodeContent = NULL;
|
|
_choice = NULL;
|
|
|
|
// Headline - TODO: should be customizable during creation time
|
|
new StaticTextWidget(this, 10, 8, _w - 2 * 10, kLineHeight, title, kTextAlignCenter);
|
|
|
|
// Current path - TODO: handle long paths ?
|
|
_currentPath = new StaticTextWidget(this, 10, 20, _w - 2 * 10, kLineHeight,
|
|
"DUMMY", kTextAlignLeft);
|
|
|
|
// Add file list
|
|
_fileList = new ListWidget(this, 10, 34, _w - 2 * 10, _h - 34 - 24 - 10);
|
|
_fileList->setNumberingMode(kListNumberingOff);
|
|
|
|
// Buttons
|
|
addButton(10, _h - 24, "Go up", kGoUpCmd, 0);
|
|
addButton(_w - 2 * (kButtonWidth + 10), _h - 24, "Cancel", kCloseCmd, 0);
|
|
addButton(_w - (kButtonWidth+10), _h - 24, "Choose", kChooseCmd, 0);
|
|
}
|
|
|
|
BrowserDialog::~BrowserDialog() {
|
|
delete _node;
|
|
delete _nodeContent;
|
|
delete _choice;
|
|
}
|
|
|
|
void BrowserDialog::open() {
|
|
// If no node has been set, or the last used one is now invalid,
|
|
// go back to the root/default dir.
|
|
if (_node == NULL || !_node->isValid()) {
|
|
delete _node;
|
|
_node = FilesystemNode::getRoot();
|
|
assert(_node != NULL);
|
|
}
|
|
|
|
// Alway refresh file list
|
|
updateListing();
|
|
|
|
// Nothing chosen by default
|
|
delete _choice;
|
|
_choice = 0;
|
|
|
|
// Call super implementation
|
|
Dialog::open();
|
|
}
|
|
|
|
void BrowserDialog::close() {
|
|
delete _nodeContent;
|
|
_nodeContent = 0;
|
|
|
|
// Call super implementation
|
|
Dialog::close();
|
|
}
|
|
|
|
void BrowserDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
|
|
FilesystemNode *tmp;
|
|
|
|
switch (cmd) {
|
|
case kChooseCmd: {
|
|
// 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].clone();
|
|
} else {
|
|
_choice = _node->clone();
|
|
}
|
|
setResult(1);
|
|
close();
|
|
}
|
|
break;
|
|
case kGoUpCmd:
|
|
tmp = _node->parent();
|
|
delete _node;
|
|
_node = tmp;
|
|
updateListing();
|
|
break;
|
|
case kListItemDoubleClickedCmd:
|
|
tmp = (*_nodeContent)[data].clone();
|
|
delete _node;
|
|
_node = tmp;
|
|
updateListing();
|
|
break;
|
|
default:
|
|
Dialog::handleCommand(sender, cmd, data);
|
|
}
|
|
}
|
|
|
|
void BrowserDialog::updateListing() {
|
|
assert(_node != NULL);
|
|
|
|
// Update the path display
|
|
_currentPath->setLabel(_node->path());
|
|
|
|
// Read in the data from the file system
|
|
delete _nodeContent;
|
|
_nodeContent = _node->listDir();
|
|
assert(_nodeContent != NULL);
|
|
|
|
// Populate the ListWidget
|
|
Common::StringList list;
|
|
int size = _nodeContent->size();
|
|
for (int i = 0; i < size; i++) {
|
|
list.push_back((*_nodeContent)[i].displayName());
|
|
}
|
|
_fileList->setList(list);
|
|
_fileList->scrollTo(0);
|
|
|
|
// Finally, redraw
|
|
draw();
|
|
}
|
|
|
|
#endif // MACOSX
|
|
|
|
} // End of namespace GUI
|