mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 15:21:51 +00:00
Enhanced Cocoa version of IWAD picker window
Added ability to specify custom command line parameters Added ability to browse for user files Improved handling of restart console command Improved layout for window
This commit is contained in:
parent
82e8c514e9
commit
18c9caf68d
3 changed files with 239 additions and 18 deletions
|
@ -144,6 +144,8 @@ char* s_argv[ARGC_MAX];
|
||||||
|
|
||||||
TArray<FString> s_argvStorage;
|
TArray<FString> s_argvStorage;
|
||||||
|
|
||||||
|
bool s_restartedFromWADPicker;
|
||||||
|
|
||||||
|
|
||||||
bool s_nativeMouse = true;
|
bool s_nativeMouse = true;
|
||||||
|
|
||||||
|
@ -966,7 +968,9 @@ static ApplicationDelegate* s_applicationDelegate;
|
||||||
{
|
{
|
||||||
ZD_UNUSED(theApplication);
|
ZD_UNUSED(theApplication);
|
||||||
|
|
||||||
if (0 == [filename length] || s_argc + 2 >= ARGC_MAX)
|
if (s_restartedFromWADPicker
|
||||||
|
|| 0 == [filename length]
|
||||||
|
|| s_argc + 2 >= ARGC_MAX)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1724,8 +1728,15 @@ int main(int argc, char** argv)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
s_argvStorage.Push(argument);
|
if (0 == strcmp(argument, "-wad_picker_restart"))
|
||||||
s_argv[s_argc++] = s_argvStorage.Last().LockBuffer();
|
{
|
||||||
|
s_restartedFromWADPicker = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s_argvStorage.Push(argument);
|
||||||
|
s_argv[s_argc++] = s_argvStorage.Last().LockBuffer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
|
@ -71,3 +71,8 @@ bool I_SetCursor(FTexture *cursorpic)
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void I_SetMainWindowVisible(bool visible)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -33,9 +33,17 @@
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "cmdlib.h"
|
||||||
#include "d_main.h"
|
#include "d_main.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
#include "c_cvars.h"
|
||||||
|
#include "m_argv.h"
|
||||||
|
#include "m_misc.h"
|
||||||
|
#include "gameconfigfile.h"
|
||||||
#include <Cocoa/Cocoa.h>
|
#include <Cocoa/Cocoa.h>
|
||||||
|
#include <wordexp.h>
|
||||||
|
|
||||||
|
CVAR(String, osx_additional_parameters, "", CVAR_ARCHIVE | CVAR_NOSET | CVAR_GLOBALCONFIG);
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -107,6 +115,45 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" };
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
static NSDictionary* GetKnownFileTypes()
|
||||||
|
{
|
||||||
|
return [NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
|
@"-file" , @"wad",
|
||||||
|
@"-file" , @"pk3",
|
||||||
|
@"-file" , @"zip",
|
||||||
|
@"-file" , @"pk7",
|
||||||
|
@"-file" , @"7z",
|
||||||
|
@"-deh" , @"deh",
|
||||||
|
@"-bex" , @"bex",
|
||||||
|
@"-exec" , @"cfg",
|
||||||
|
@"-playdemo", @"lmp",
|
||||||
|
nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
static NSArray* GetKnownExtensions()
|
||||||
|
{
|
||||||
|
return [GetKnownFileTypes() allKeys];
|
||||||
|
}
|
||||||
|
|
||||||
|
@interface NSMutableString(AppendKnownFileType)
|
||||||
|
- (void)appendKnownFileType:(NSString *)filePath;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation NSMutableString(AppendKnownFileType)
|
||||||
|
- (void)appendKnownFileType:(NSString *)filePath
|
||||||
|
{
|
||||||
|
NSString* extension = [[filePath pathExtension] lowercaseString];
|
||||||
|
NSString* parameter = [GetKnownFileTypes() objectForKey:extension];
|
||||||
|
|
||||||
|
if (nil == parameter)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[self appendFormat:@"%@ \"%@\" ", parameter, filePath];
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
// So we can listen for button actions and such we need to have an Obj-C class.
|
// So we can listen for button actions and such we need to have an Obj-C class.
|
||||||
@interface IWADPicker : NSObject
|
@interface IWADPicker : NSObject
|
||||||
{
|
{
|
||||||
|
@ -114,13 +161,18 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" };
|
||||||
NSWindow *window;
|
NSWindow *window;
|
||||||
NSButton *okButton;
|
NSButton *okButton;
|
||||||
NSButton *cancelButton;
|
NSButton *cancelButton;
|
||||||
|
NSButton *browseButton;
|
||||||
|
NSTextField *parametersTextField;
|
||||||
bool cancelled;
|
bool cancelled;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)buttonPressed:(id) sender;
|
- (void)buttonPressed:(id) sender;
|
||||||
|
- (void)browseButtonPressed:(id) sender;
|
||||||
- (void)doubleClicked:(id) sender;
|
- (void)doubleClicked:(id) sender;
|
||||||
- (void)makeLabel:(NSTextField *)label withString:(const char*) str;
|
- (void)makeLabel:(NSTextField *)label withString:(const char*) str;
|
||||||
- (int)pickIWad:(WadStuff *)wads num:(int) numwads showWindow:(bool) showwin defaultWad:(int) defaultiwad;
|
- (int)pickIWad:(WadStuff *)wads num:(int) numwads showWindow:(bool) showwin defaultWad:(int) defaultiwad;
|
||||||
|
- (NSString*)commandLineParameters;
|
||||||
|
- (void)menuActionSent:(NSNotification*)notification;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation IWADPicker
|
@implementation IWADPicker
|
||||||
|
@ -134,6 +186,52 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" };
|
||||||
[app stopModal];
|
[app stopModal];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)browseButtonPressed:(id) sender
|
||||||
|
{
|
||||||
|
NSOpenPanel* openPanel = [NSOpenPanel openPanel];
|
||||||
|
[openPanel setAllowsMultipleSelection:YES];
|
||||||
|
[openPanel setCanChooseFiles:YES];
|
||||||
|
[openPanel setCanChooseDirectories:YES];
|
||||||
|
[openPanel setResolvesAliases:YES];
|
||||||
|
[openPanel setAllowedFileTypes:GetKnownExtensions()];
|
||||||
|
|
||||||
|
if (NSOKButton == [openPanel runModal])
|
||||||
|
{
|
||||||
|
NSArray* files = [openPanel URLs];
|
||||||
|
NSMutableString* parameters = [NSMutableString string];
|
||||||
|
|
||||||
|
for (NSUInteger i = 0, ei = [files count]; i < ei; ++i)
|
||||||
|
{
|
||||||
|
NSString* filePath = [[files objectAtIndex:i] path];
|
||||||
|
BOOL isDirectory = false;
|
||||||
|
|
||||||
|
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isDirectory] && isDirectory)
|
||||||
|
{
|
||||||
|
[parameters appendFormat:@"-file \"%@\" ", filePath];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[parameters appendKnownFileType:filePath];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([parameters length] > 0)
|
||||||
|
{
|
||||||
|
NSString* newParameters = [parametersTextField stringValue];
|
||||||
|
|
||||||
|
if ([newParameters length] > 0
|
||||||
|
&& NO == [newParameters hasSuffix:@" "])
|
||||||
|
{
|
||||||
|
newParameters = [newParameters stringByAppendingString:@" "];
|
||||||
|
}
|
||||||
|
|
||||||
|
newParameters = [newParameters stringByAppendingString:parameters];
|
||||||
|
|
||||||
|
[parametersTextField setStringValue: newParameters];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)doubleClicked:(id) sender
|
- (void)doubleClicked:(id) sender
|
||||||
{
|
{
|
||||||
if ([sender clickedRow] >= 0)
|
if ([sender clickedRow] >= 0)
|
||||||
|
@ -159,20 +257,18 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" };
|
||||||
cancelled = false;
|
cancelled = false;
|
||||||
|
|
||||||
app = [NSApplication sharedApplication];
|
app = [NSApplication sharedApplication];
|
||||||
id windowTitle = [NSString stringWithFormat:@GAMESIG " %s: Select an IWAD to use", GetVersionString()];
|
id windowTitle = [NSString stringWithFormat:@"%s %s", GAMENAME, GetVersionString()];
|
||||||
|
|
||||||
NSRect frame = NSMakeRect(0, 0, 440, 450);
|
NSRect frame = NSMakeRect(0, 0, 440, 450);
|
||||||
window = [[NSWindow alloc] initWithContentRect:frame styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:NO];
|
window = [[NSWindow alloc] initWithContentRect:frame styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:NO];
|
||||||
[window setTitle:windowTitle];
|
[window setTitle:windowTitle];
|
||||||
|
|
||||||
NSTextField *description = [[NSTextField alloc] initWithFrame:NSMakeRect(22, 379, 412, 50)];
|
NSTextField *description = [[NSTextField alloc] initWithFrame:NSMakeRect(18, 384, 402, 50)];
|
||||||
[self makeLabel:description withString:"ZDoom found more than one IWAD\nSelect from the list below to determine which one to use:"];
|
[self makeLabel:description withString:GAMENAME " found more than one IWAD\nSelect from the list below to determine which one to use:"];
|
||||||
[[window contentView] addSubview:description];
|
[[window contentView] addSubview:description];
|
||||||
[description release];
|
[description release];
|
||||||
|
|
||||||
// Commented out version would account for an additional parameters box.
|
NSScrollView *iwadScroller = [[NSScrollView alloc] initWithFrame:NSMakeRect(20, 135, 402, 256)];
|
||||||
//NSScrollView *iwadScroller = [[NSScrollView alloc] initWithFrame:NSMakeRect(20, 103, 412, 288)];
|
|
||||||
NSScrollView *iwadScroller = [[NSScrollView alloc] initWithFrame:NSMakeRect(20, 50, 412, 341)];
|
|
||||||
NSTableView *iwadTable = [[NSTableView alloc] initWithFrame:[iwadScroller bounds]];
|
NSTableView *iwadTable = [[NSTableView alloc] initWithFrame:[iwadScroller bounds]];
|
||||||
IWADTableData *tableData = [[IWADTableData alloc] init:wads num:numwads];
|
IWADTableData *tableData = [[IWADTableData alloc] init:wads num:numwads];
|
||||||
for(int i = 0;i < NUM_COLUMNS;i++)
|
for(int i = 0;i < NUM_COLUMNS;i++)
|
||||||
|
@ -200,11 +296,12 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" };
|
||||||
[iwadTable release];
|
[iwadTable release];
|
||||||
[iwadScroller release];
|
[iwadScroller release];
|
||||||
|
|
||||||
/*NSTextField *additionalParametersLabel = [[NSTextField alloc] initWithFrame:NSMakeRect(17, 78, 144, 17)];
|
NSTextField *additionalParametersLabel = [[NSTextField alloc] initWithFrame:NSMakeRect(18, 108, 144, 17)];
|
||||||
[self makeLabel:additionalParametersLabel:"Additional Parameters"];
|
[self makeLabel:additionalParametersLabel withString:"Additional Parameters:"];
|
||||||
[[window contentView] addSubview:additionalParametersLabel];
|
[[window contentView] addSubview:additionalParametersLabel];
|
||||||
NSTextField *additionalParameters = [[NSTextField alloc] initWithFrame:NSMakeRect(20, 48, 360, 22)];
|
parametersTextField = [[NSTextField alloc] initWithFrame:NSMakeRect(20, 48, 402, 54)];
|
||||||
[[window contentView] addSubview:additionalParameters];*/
|
[parametersTextField setStringValue:[NSString stringWithUTF8String:osx_additional_parameters]];
|
||||||
|
[[window contentView] addSubview:parametersTextField];
|
||||||
|
|
||||||
// Doesn't look like the SDL version implements this so lets not show it.
|
// Doesn't look like the SDL version implements this so lets not show it.
|
||||||
/*NSButton *dontAsk = [[NSButton alloc] initWithFrame:NSMakeRect(18, 18, 178, 18)];
|
/*NSButton *dontAsk = [[NSButton alloc] initWithFrame:NSMakeRect(18, 18, 178, 18)];
|
||||||
|
@ -213,39 +310,147 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" };
|
||||||
[dontAsk setState:(showwin ? NSOffState : NSOnState)];
|
[dontAsk setState:(showwin ? NSOffState : NSOnState)];
|
||||||
[[window contentView] addSubview:dontAsk];*/
|
[[window contentView] addSubview:dontAsk];*/
|
||||||
|
|
||||||
okButton = [[NSButton alloc] initWithFrame:NSMakeRect(236, 12, 96, 32)];
|
okButton = [[NSButton alloc] initWithFrame:NSMakeRect(236, 8, 96, 32)];
|
||||||
[okButton setTitle:[NSString stringWithUTF8String:"OK"]];
|
[okButton setTitle:@"OK"];
|
||||||
[okButton setBezelStyle:NSRoundedBezelStyle];
|
[okButton setBezelStyle:NSRoundedBezelStyle];
|
||||||
[okButton setAction:@selector(buttonPressed:)];
|
[okButton setAction:@selector(buttonPressed:)];
|
||||||
[okButton setTarget:self];
|
[okButton setTarget:self];
|
||||||
[okButton setKeyEquivalent:@"\r"];
|
[okButton setKeyEquivalent:@"\r"];
|
||||||
[[window contentView] addSubview:okButton];
|
[[window contentView] addSubview:okButton];
|
||||||
|
|
||||||
cancelButton = [[NSButton alloc] initWithFrame:NSMakeRect(332, 12, 96, 32)];
|
cancelButton = [[NSButton alloc] initWithFrame:NSMakeRect(332, 8, 96, 32)];
|
||||||
[cancelButton setTitle:[NSString stringWithUTF8String:"Cancel"]];
|
[cancelButton setTitle:@"Cancel"];
|
||||||
[cancelButton setBezelStyle:NSRoundedBezelStyle];
|
[cancelButton setBezelStyle:NSRoundedBezelStyle];
|
||||||
[cancelButton setAction:@selector(buttonPressed:)];
|
[cancelButton setAction:@selector(buttonPressed:)];
|
||||||
[cancelButton setTarget:self];
|
[cancelButton setTarget:self];
|
||||||
[cancelButton setKeyEquivalent:@"\033"];
|
[cancelButton setKeyEquivalent:@"\033"];
|
||||||
[[window contentView] addSubview:cancelButton];
|
[[window contentView] addSubview:cancelButton];
|
||||||
|
|
||||||
|
browseButton = [[NSButton alloc] initWithFrame:NSMakeRect(14, 8, 96, 32)];
|
||||||
|
[browseButton setTitle:@"Browse..."];
|
||||||
|
[browseButton setBezelStyle:NSRoundedBezelStyle];
|
||||||
|
[browseButton setAction:@selector(browseButtonPressed:)];
|
||||||
|
[browseButton setTarget:self];
|
||||||
|
[[window contentView] addSubview:browseButton];
|
||||||
|
|
||||||
|
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
|
||||||
|
[center addObserver:self selector:@selector(menuActionSent:) name:NSMenuDidSendActionNotification object:nil];
|
||||||
|
|
||||||
[window center];
|
[window center];
|
||||||
[app runModalForWindow:window];
|
[app runModalForWindow:window];
|
||||||
|
|
||||||
|
[center removeObserver:self name:NSMenuDidSendActionNotification object:nil];
|
||||||
|
|
||||||
[window release];
|
[window release];
|
||||||
[okButton release];
|
[okButton release];
|
||||||
[cancelButton release];
|
[cancelButton release];
|
||||||
|
[browseButton release];
|
||||||
|
|
||||||
return cancelled ? -1 : [iwadTable selectedRow];
|
return cancelled ? -1 : [iwadTable selectedRow];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSString*)commandLineParameters
|
||||||
|
{
|
||||||
|
return [parametersTextField stringValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)menuActionSent:(NSNotification*)notification
|
||||||
|
{
|
||||||
|
NSDictionary* userInfo = [notification userInfo];
|
||||||
|
NSMenuItem* menuItem = [userInfo valueForKey:@"MenuItem"];
|
||||||
|
|
||||||
|
if ( @selector(terminate:) == [menuItem action] )
|
||||||
|
{
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
EXTERN_CVAR(String, defaultiwad)
|
||||||
|
|
||||||
|
static void RestartWithParameters(const char* iwadPath, NSString* parameters)
|
||||||
|
{
|
||||||
|
assert(nil != parameters);
|
||||||
|
|
||||||
|
defaultiwad = ExtractFileBase(iwadPath);
|
||||||
|
|
||||||
|
GameConfig->DoGameSetup("Doom");
|
||||||
|
M_SaveDefaults(NULL);
|
||||||
|
|
||||||
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
|
@try
|
||||||
|
{
|
||||||
|
const int commandLineParametersCount = Args->NumArgs();
|
||||||
|
assert(commandLineParametersCount > 0);
|
||||||
|
|
||||||
|
NSString* executablePath = [NSString stringWithUTF8String:Args->GetArg(0)];
|
||||||
|
|
||||||
|
NSMutableArray* arguments = [NSMutableArray arrayWithCapacity:commandLineParametersCount + 3];
|
||||||
|
[arguments addObject:@"-wad_picker_restart"];
|
||||||
|
[arguments addObject:@"-iwad"];
|
||||||
|
[arguments addObject:[NSString stringWithUTF8String:iwadPath]];
|
||||||
|
|
||||||
|
for (int i = 1; i < commandLineParametersCount; ++i)
|
||||||
|
{
|
||||||
|
NSString* currentParameter = [NSString stringWithUTF8String:Args->GetArg(i)];
|
||||||
|
[arguments addObject:currentParameter];
|
||||||
|
}
|
||||||
|
|
||||||
|
wordexp_t expansion;
|
||||||
|
|
||||||
|
if (0 == wordexp([parameters UTF8String], &expansion, 0))
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < expansion.we_wordc; ++i)
|
||||||
|
{
|
||||||
|
NSString* argumentString = [NSString stringWithCString:expansion.we_wordv[i]
|
||||||
|
encoding:NSUTF8StringEncoding];
|
||||||
|
[arguments addObject:argumentString];
|
||||||
|
}
|
||||||
|
|
||||||
|
wordfree(&expansion);
|
||||||
|
}
|
||||||
|
|
||||||
|
[NSTask launchedTaskWithLaunchPath:executablePath arguments:arguments];
|
||||||
|
|
||||||
|
_exit(0); // to avoid atexit()'s functions
|
||||||
|
}
|
||||||
|
@catch (NSException* e)
|
||||||
|
{
|
||||||
|
NSLog(@"Cannot restart: %@", [e reason]);
|
||||||
|
}
|
||||||
|
|
||||||
|
[pool release];
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_SetMainWindowVisible(bool visible);
|
||||||
|
|
||||||
// Simple wrapper so we can call this from outside.
|
// Simple wrapper so we can call this from outside.
|
||||||
int I_PickIWad_Cocoa (WadStuff *wads, int numwads, bool showwin, int defaultiwad)
|
int I_PickIWad_Cocoa (WadStuff *wads, int numwads, bool showwin, int defaultiwad)
|
||||||
{
|
{
|
||||||
|
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
|
I_SetMainWindowVisible(false);
|
||||||
|
|
||||||
IWADPicker *picker = [IWADPicker alloc];
|
IWADPicker *picker = [IWADPicker alloc];
|
||||||
int ret = [picker pickIWad:wads num:numwads showWindow:showwin defaultWad:defaultiwad];
|
int ret = [picker pickIWad:wads num:numwads showWindow:showwin defaultWad:defaultiwad];
|
||||||
[picker release];
|
|
||||||
|
I_SetMainWindowVisible(true);
|
||||||
|
|
||||||
|
NSString* parametersToAppend = [picker commandLineParameters];
|
||||||
|
osx_additional_parameters = [parametersToAppend UTF8String];
|
||||||
|
|
||||||
|
if (ret >= 0)
|
||||||
|
{
|
||||||
|
if (0 != [parametersToAppend length])
|
||||||
|
{
|
||||||
|
RestartWithParameters(wads[ret].Path, parametersToAppend);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[pool release];
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue