mirror of https://github.com/bsnes-emu/bsnes.git
Update to v092r04 release.
byuu says: This is the first release with full support for OS X, although it's certainly still very buggy. Known issues: - window status bars are still unsupported (they just don't show up) - you get the bad keypress chime when you use the keyboard - window geometry and font metrics aren't perfect (bit of clipping here and there) - list view headers that aren't auto-sized are sometimes too short (file browser) - input assignment is really rough (assigning a key also moves around in the list or beeps at you) Custom OS X integration support so far: - 512x512 ICNS application icon: will look razor-sharp even on a retina display - basic Info.plist added to application bundle - program menu about, preferences, quit all connected - Settings->Configuration removed (use higan->Preferences instead) - global menubar To compile and use this, you'll need: - Xz Utils (to extract .tar.xz) - Xcode 4.6 - Lion 10.7.4 or newer mkdir higan_v092r04 tar -xJf higan_v092r04.tar.xz -C higan_v092r04 cd higan_v092r04 make -j 2 ananke is missing, and I haven't updated purify yet, so you'll have to move game folders from Windows or Linux over, or make them by hand (a not so enjoyable experience, to say the least.)
This commit is contained in:
parent
b7c212de7e
commit
fdd3ea490e
|
@ -14,8 +14,8 @@ target := ethos
|
|||
# console := true
|
||||
|
||||
# compiler
|
||||
flags := -I. -O3 -fomit-frame-pointer
|
||||
link := -s
|
||||
flags += -I. -O3 -fomit-frame-pointer
|
||||
link +=
|
||||
objects := libco
|
||||
|
||||
# profile-guided optimization mode
|
||||
|
@ -32,7 +32,9 @@ endif
|
|||
# platform
|
||||
ifeq ($(platform),x)
|
||||
flags += -march=native
|
||||
link += -Wl,-export-dynamic -ldl -lX11 -lXext
|
||||
link += -s -Wl,-export-dynamic -ldl -lX11 -lXext
|
||||
else ifeq ($(platform),osx)
|
||||
flags += -march=native
|
||||
else ifeq ($(platform),win)
|
||||
ifeq ($(arch),win32)
|
||||
flags += -m32
|
||||
|
@ -43,7 +45,7 @@ else ifeq ($(platform),win)
|
|||
else
|
||||
link += -mwindows
|
||||
endif
|
||||
link += -mthreads -luuid -lkernel32 -luser32 -lgdi32 -lcomctl32 -lcomdlg32 -lshell32 -lole32 -lws2_32
|
||||
link += -s -mthreads -luuid -lkernel32 -luser32 -lgdi32 -lcomctl32 -lcomdlg32 -lshell32 -lole32 -lws2_32
|
||||
link += -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc
|
||||
else
|
||||
$(error unsupported platform.)
|
||||
|
@ -55,9 +57,9 @@ ui := target-$(target)
|
|||
compile = \
|
||||
$(strip \
|
||||
$(if $(filter %.c,$<), \
|
||||
$(c) $(flags) $1 -c $< -o $@, \
|
||||
$(compiler) $(cflags) $(flags) $1 -c $< -o $@, \
|
||||
$(if $(filter %.cpp,$<), \
|
||||
$(cpp) $(flags) $1 -c $< -o $@ \
|
||||
$(compiler) $(cppflags) $(flags) $1 -c $< -o $@ \
|
||||
) \
|
||||
) \
|
||||
)
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>higan</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>higan.icns</string>
|
||||
</dict>
|
||||
</plist>
|
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
|
@ -3,9 +3,10 @@
|
|||
|
||||
namespace Emulator {
|
||||
static const char Name[] = "higan";
|
||||
static const char Version[] = "092.03";
|
||||
static const char Version[] = "092.04";
|
||||
static const char Author[] = "byuu";
|
||||
static const char License[] = "GPLv3";
|
||||
static const char Website[] = "http://byuu.org/";
|
||||
}
|
||||
|
||||
#include <nall/platform.hpp>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <fc/fc.hpp>
|
||||
#include <cmath>
|
||||
|
||||
#define VIDEO_CPP
|
||||
namespace Famicom {
|
||||
|
|
|
@ -37,19 +37,27 @@ endif
|
|||
ifeq ($(compiler),)
|
||||
ifeq ($(platform),win)
|
||||
compiler := g++
|
||||
flags :=
|
||||
link :=
|
||||
else ifeq ($(platform),osx)
|
||||
compiler := clang
|
||||
flags := -w -stdlib=libc++
|
||||
link := -lc++ -lobjc
|
||||
else
|
||||
compiler := g++-4.7
|
||||
flags :=
|
||||
link :=
|
||||
endif
|
||||
|
||||
cflags := -x c -std=gnu99
|
||||
objcflags := -x objective-c -std=gnu99
|
||||
cppflags := -x c++ -std=gnu++11
|
||||
objcppflags := -x objective-c++ -std=gnu++11
|
||||
endif
|
||||
|
||||
c := $(compiler) -x c -std=gnu99
|
||||
cpp := $(compiler) -std=gnu++11
|
||||
|
||||
ifeq ($(arch),x86)
|
||||
c := $(c) -m32
|
||||
cpp := $(cpp) -m32
|
||||
flags := -m32 $(flags)
|
||||
link := -m32 $(link)
|
||||
endif
|
||||
|
||||
ifeq ($(prefix),)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifdef NALL_DSP_INTERNAL_HPP
|
||||
|
||||
#include <math.h>
|
||||
#include <vector>
|
||||
#include <nall/stdint.hpp>
|
||||
|
||||
namespace nall {
|
||||
|
|
|
@ -4,18 +4,21 @@ ifeq ($(platform),x)
|
|||
endif
|
||||
|
||||
ifeq ($(phoenix),gtk)
|
||||
phoenixflags := -DPHOENIX_GTK `pkg-config --cflags gtk+-2.0`
|
||||
phoenixlink := `pkg-config --libs gtk+-2.0`
|
||||
phoenixflags = $(cppflags) $(flags) -DPHOENIX_GTK `pkg-config --cflags gtk+-2.0`
|
||||
phoenixlink = `pkg-config --libs gtk+-2.0`
|
||||
endif
|
||||
|
||||
ifeq ($(phoenix),qt)
|
||||
phoenixflags := -DPHOENIX_QT `pkg-config --cflags QtCore QtGui`
|
||||
phoenixlink := `pkg-config --libs QtCore QtGui`
|
||||
phoenixflags = $(cppflags) $(flags) -DPHOENIX_QT `pkg-config --cflags QtCore QtGui`
|
||||
phoenixlink = `pkg-config --libs QtCore QtGui`
|
||||
endif
|
||||
else ifeq ($(platform),osx)
|
||||
phoenixflags = $(objcppflags) $(flags) -DPHOENIX_COCOA
|
||||
phoenixlink = -framework Cocoa -framework Carbon
|
||||
else ifeq ($(platform),win)
|
||||
phoenixflags := -DPHOENIX_WINDOWS
|
||||
phoenixlink := -lkernel32 -luser32 -lgdi32 -ladvapi32 -lole32 -lcomctl32 -lcomdlg32 -lshlwapi
|
||||
phoenixflags = $(cppflags) $(flags) -DPHOENIX_WINDOWS
|
||||
phoenixlink = -lkernel32 -luser32 -lgdi32 -ladvapi32 -lole32 -lcomctl32 -lcomdlg32 -lshlwapi
|
||||
else
|
||||
phoenixflags := -DPHOENIX_REFERENCE
|
||||
phoenixlink :=
|
||||
phoenixflags = $(cppflags) $(flags) -DPHOENIX_REFERENCE
|
||||
phoenixlink =
|
||||
endif
|
||||
|
|
|
@ -1,19 +1,8 @@
|
|||
@implementation CocoaSeparator : NSMenuItem
|
||||
|
||||
-(id) initWith :(phoenix::Separator&)separatorReference {
|
||||
if(self = [super separatorItem]) {
|
||||
separator = &separatorReference;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
void pSeparator::constructor() {
|
||||
@autoreleasepool {
|
||||
cocoaAction = cocoaSeparator = [[CocoaSeparator alloc] initWith:separator];
|
||||
cocoaAction = cocoaSeparator = [[NSMenuItem separatorItem] retain];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,8 @@
|
|||
@interface CocoaSeparator : NSMenuItem {
|
||||
@public
|
||||
phoenix::Separator *separator;
|
||||
}
|
||||
-(id) initWith :(phoenix::Separator&)separator;
|
||||
@end
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
struct pSeparator : public pAction {
|
||||
Separator &separator;
|
||||
CocoaSeparator *cocoaSeparator;
|
||||
NSMenuItem *cocoaSeparator;
|
||||
|
||||
pSeparator(Separator &separator) : pAction(separator), separator(separator) {}
|
||||
void constructor();
|
||||
|
|
|
@ -1,22 +1,41 @@
|
|||
namespace phoenix {
|
||||
|
||||
string pDialogWindow::fileOpen(Window &parent, const string &path, const lstring &filter) {
|
||||
string pBrowserWindow::directory(BrowserWindow::State &state) {
|
||||
string result;
|
||||
|
||||
@autoreleasepool {
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
if(state.title) [panel setTitle:[NSString stringWithUTF8String:state.title]];
|
||||
[panel setCanChooseDirectories:YES];
|
||||
[panel setCanChooseFiles:NO];
|
||||
if([panel runModalForDirectory:[NSString stringWithUTF8String:state.path] file:nil] == NSOKButton) {
|
||||
NSArray *names = [panel filenames];
|
||||
const char *name = [[names objectAtIndex:0] UTF8String];
|
||||
if(name) result = name;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
string pBrowserWindow::open(BrowserWindow::State &state) {
|
||||
string result;
|
||||
|
||||
@autoreleasepool {
|
||||
NSMutableArray *filters = [[NSMutableArray alloc] init];
|
||||
for(auto &rule : filter) {
|
||||
for(auto &rule : state.filters) {
|
||||
string pattern = rule.split<1>("(")(1).rtrim<1>(")");
|
||||
if(!pattern.empty()) [filters addObject:[NSString stringWithUTF8String:pattern]];
|
||||
}
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
if(state.title) [panel setTitle:[NSString stringWithUTF8String:state.title]];
|
||||
[panel setCanChooseDirectories:NO];
|
||||
[panel setCanChooseFiles:YES];
|
||||
[panel setAllowedFileTypes:filters];
|
||||
if([panel runModalForDirectory:[NSString stringWithUTF8String:path] file:nil] == NSOKButton) {
|
||||
NSArray *filenames = [panel filenames];
|
||||
const char *filename = [[filenames objectAtIndex:0] UTF8String];
|
||||
if(filename) result = filename;
|
||||
if([panel runModalForDirectory:[NSString stringWithUTF8String:state.path] file:nil] == NSOKButton) {
|
||||
NSArray *names = [panel filenames];
|
||||
const char *name = [[names objectAtIndex:0] UTF8String];
|
||||
if(name) result = name;
|
||||
}
|
||||
[filters release];
|
||||
}
|
||||
|
@ -24,21 +43,22 @@ string pDialogWindow::fileOpen(Window &parent, const string &path, const lstring
|
|||
return result;
|
||||
}
|
||||
|
||||
string pDialogWindow::fileSave(Window &parent, const string &path, const lstring &filter) {
|
||||
string pBrowserWindow::save(BrowserWindow::State &state) {
|
||||
string result;
|
||||
|
||||
@autoreleasepool {
|
||||
NSMutableArray *filters = [[NSMutableArray alloc] init];
|
||||
for(auto &rule : filter) {
|
||||
for(auto &rule : state.filters) {
|
||||
string pattern = rule.split<1>("(")(1).rtrim<1>(")");
|
||||
if(!pattern.empty()) [filters addObjects:[NSString stringWithUTF8String:pattern]];
|
||||
}
|
||||
NSSavePanel *panel = [NSSavePanel savePanel];
|
||||
if(state.title) [panel setTitle:[NSString stringWithUTF8String:state.title]];
|
||||
[panel setAllowedFileTypes:filters];
|
||||
if([panel runModalForDirectory:[NSString stringWithUTF8String:path] file:nil] == NSOKButton) {
|
||||
NSArray *filenames = [panel filenames];
|
||||
const char *filename = [[filenames objectAtIndex:0] UTF8String];
|
||||
if(filename) result = filename;
|
||||
if([panel runModalForDirectory:[NSString stringWithUTF8String:state.path] file:nil] == NSOKButton) {
|
||||
NSArray *names = [panel filenames];
|
||||
const char *name = [[names objectAtIndex:0] UTF8String];
|
||||
if(name) result = name;
|
||||
}
|
||||
[filters release];
|
||||
}
|
||||
|
@ -46,21 +66,4 @@ string pDialogWindow::fileSave(Window &parent, const string &path, const lstring
|
|||
return result;
|
||||
}
|
||||
|
||||
string pDialogWindow::folderSelect(Window &parent, const string &path) {
|
||||
string result;
|
||||
|
||||
@autoreleasepool {
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
[panel setCanChooseDirectories:YES];
|
||||
[panel setCanChooseFiles:NO];
|
||||
if([panel runModalForDirectory:[NSString stringWithUTF8String:path] file:nil] == NSOKButton) {
|
||||
NSArray *filenames = [panel filenames];
|
||||
const char *filename = [[filenames objectAtIndex:0] UTF8String];
|
||||
if(filename) result = filename;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
namespace phoenix {
|
||||
|
||||
struct pBrowserWindow {
|
||||
static string directory(BrowserWindow::State &state);
|
||||
static string open(BrowserWindow::State &state);
|
||||
static string save(BrowserWindow::State &state);
|
||||
};
|
||||
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
namespace phoenix {
|
||||
|
||||
struct pDialogWindow {
|
||||
static string fileOpen(Window &parent, const string &path, const lstring &filter);
|
||||
static string fileSave(Window &parent, const string &path, const lstring &filter);
|
||||
static string folderSelect(Window &parent, const string &path);
|
||||
};
|
||||
|
||||
}
|
|
@ -1,27 +1,14 @@
|
|||
namespace phoenix {
|
||||
|
||||
MessageWindow::Response pMessageWindow::information(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
return message(parent, text, buttons, Type::Information);
|
||||
}
|
||||
enum class MessageWindowType : unsigned { Error, Information, Question, Warning };
|
||||
|
||||
MessageWindow::Response pMessageWindow::question(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
return message(parent, text, buttons, Type::Question);
|
||||
}
|
||||
|
||||
MessageWindow::Response pMessageWindow::warning(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
return message(parent, text, buttons, Type::Warning);
|
||||
}
|
||||
|
||||
MessageWindow::Response pMessageWindow::critical(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
return message(parent, text, buttons, Type::Critical);
|
||||
}
|
||||
|
||||
MessageWindow::Response pMessageWindow::message(Window &parent, const string &text, MessageWindow::Buttons buttons, Type type) {
|
||||
MessageWindow::Response MessageWindow_dialog(MessageWindow::State &state, MessageWindowType type) {
|
||||
@autoreleasepool {
|
||||
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
|
||||
[alert setMessageText:[NSString stringWithUTF8String:text]];
|
||||
if(state.title) [alert setMessageText:[NSString stringWithUTF8String:state.title]];
|
||||
[alert setInformativeText:[NSString stringWithUTF8String:state.text]];
|
||||
|
||||
switch(buttons) {
|
||||
switch(state.buttons) {
|
||||
case MessageWindow::Buttons::Ok:
|
||||
[alert addButtonWithTitle:@"Ok"];
|
||||
break;
|
||||
|
@ -41,16 +28,16 @@ MessageWindow::Response pMessageWindow::message(Window &parent, const string &te
|
|||
}
|
||||
|
||||
switch(type) {
|
||||
case Type::Information: [alert setAlertStyle:NSInformationalAlertStyle]; break;
|
||||
case Type::Question: [alert setAlertStyle:NSInformationalAlertStyle]; break;
|
||||
case Type::Warning: [alert setAlertStyle:NSWarningAlertStyle]; break;
|
||||
case Type::Critical: [alert setAlertStyle:NSCriticalAlertStyle]; break;
|
||||
case MessageWindowType::Error: [alert setAlertStyle:NSCriticalAlertStyle]; break;
|
||||
case MessageWindowType::Information: [alert setAlertStyle:NSInformationalAlertStyle]; break;
|
||||
case MessageWindowType::Question: [alert setAlertStyle:NSInformationalAlertStyle]; break;
|
||||
case MessageWindowType::Warning: [alert setAlertStyle:NSWarningAlertStyle]; break;
|
||||
}
|
||||
|
||||
NSInteger response = [alert runModal];
|
||||
//[alert beginSheetModalForWindow:parent.p.cocoaWindow modalDelegate:self didEndSelector:@selector(...) contextInfo:nil];
|
||||
|
||||
switch(buttons) {
|
||||
switch(state.buttons) {
|
||||
case MessageWindow::Buttons::Ok:
|
||||
if(response == NSAlertFirstButtonReturn) return MessageWindow::Response::Ok;
|
||||
break;
|
||||
|
@ -70,7 +57,23 @@ MessageWindow::Response pMessageWindow::message(Window &parent, const string &te
|
|||
}
|
||||
}
|
||||
|
||||
return MessageWindow::Response::Ok;
|
||||
throw;
|
||||
}
|
||||
|
||||
MessageWindow::Response pMessageWindow::error(MessageWindow::State &state) {
|
||||
return MessageWindow_dialog(state, MessageWindowType::Error);
|
||||
}
|
||||
|
||||
MessageWindow::Response pMessageWindow::information(MessageWindow::State &state) {
|
||||
return MessageWindow_dialog(state, MessageWindowType::Information);
|
||||
}
|
||||
|
||||
MessageWindow::Response pMessageWindow::question(MessageWindow::State &state) {
|
||||
return MessageWindow_dialog(state, MessageWindowType::Question);
|
||||
}
|
||||
|
||||
MessageWindow::Response pMessageWindow::warning(MessageWindow::State &state) {
|
||||
return MessageWindow_dialog(state, MessageWindowType::Warning);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
namespace phoenix {
|
||||
|
||||
struct pMessageWindow {
|
||||
static MessageWindow::Response information(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||
static MessageWindow::Response question(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||
static MessageWindow::Response warning(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||
static MessageWindow::Response critical(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||
|
||||
enum class Type : unsigned { Information, Question, Warning, Critical };
|
||||
static MessageWindow::Response message(Window &parent, const string &text, MessageWindow::Buttons buttons, Type type);
|
||||
static MessageWindow::Response error(MessageWindow::State &state);
|
||||
static MessageWindow::Response information(MessageWindow::State &state);
|
||||
static MessageWindow::Response question(MessageWindow::State &state);
|
||||
static MessageWindow::Response warning(MessageWindow::State &state);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "desktop.cpp"
|
||||
#include "keyboard.cpp"
|
||||
#include "mouse.cpp"
|
||||
#include "dialog-window.cpp"
|
||||
#include "browser-window.cpp"
|
||||
#include "message-window.cpp"
|
||||
#include "font.cpp"
|
||||
#include "timer.cpp"
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace phoenix {
|
|||
#include "desktop.hpp"
|
||||
#include "keyboard.hpp"
|
||||
#include "mouse.hpp"
|
||||
#include "dialog-window.hpp"
|
||||
#include "browser-window.hpp"
|
||||
#include "message-window.hpp"
|
||||
#include "object.hpp"
|
||||
#include "timer.hpp"
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
@implementation CocoaHexEdit : NSScrollView
|
||||
|
||||
-(id) initWith :(phoenix::HexEdit&)hexEditReference {
|
||||
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
|
||||
hexEdit = &hexEditReference;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
void pHexEdit::setColumns(unsigned columns) {
|
||||
|
@ -16,6 +27,15 @@ void pHexEdit::update() {
|
|||
}
|
||||
|
||||
void pHexEdit::constructor() {
|
||||
@autoreleasepool {
|
||||
cocoaView = cocoaHexEdit = [[CocoaHexEdit alloc] initWith:hexEdit];
|
||||
}
|
||||
}
|
||||
|
||||
void pHexEdit::destructor() {
|
||||
@autoreleasepool {
|
||||
[cocoaView release];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
@interface CocoaHexEdit : NSScrollView {
|
||||
@public
|
||||
phoenix::HexEdit *hexEdit;
|
||||
}
|
||||
-(id) initWith :(phoenix::HexEdit&)hexEdit;
|
||||
@end
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
struct pHexEdit : public pWidget {
|
||||
HexEdit &hexEdit;
|
||||
CocoaHexEdit *cocoaHexEdit;
|
||||
|
||||
void setColumns(unsigned columns);
|
||||
void setLength(unsigned length);
|
||||
|
@ -11,6 +19,7 @@ struct pHexEdit : public pWidget {
|
|||
|
||||
pHexEdit(HexEdit &hexEdit) : pWidget(hexEdit), hexEdit(hexEdit) {}
|
||||
void constructor();
|
||||
void destructor();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,10 +1,36 @@
|
|||
@implementation CocoaViewport : NSView
|
||||
|
||||
-(id) initWith :(phoenix::Viewport&)viewportReference {
|
||||
if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) {
|
||||
viewport = &viewportReference;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void) drawRect :(NSRect)rect {
|
||||
NSColor *background = [NSColor blackColor];
|
||||
[background set];
|
||||
NSRectFill([self bounds]);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
uintptr_t pViewport::handle() {
|
||||
return 0;
|
||||
return (uintptr_t)cocoaViewport;
|
||||
}
|
||||
|
||||
void pViewport::constructor() {
|
||||
@autoreleasepool {
|
||||
cocoaView = cocoaViewport = [[CocoaViewport alloc] initWith:viewport];
|
||||
}
|
||||
}
|
||||
|
||||
void pViewport::destructor() {
|
||||
@autoreleasepool {
|
||||
[cocoaView release];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,12 +1,22 @@
|
|||
@interface CocoaViewport : NSView {
|
||||
@public
|
||||
phoenix::Viewport *viewport;
|
||||
}
|
||||
-(id) initWith :(phoenix::Viewport&)viewport;
|
||||
-(void) drawRect :(NSRect)rect;
|
||||
@end
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
struct pViewport : public pWidget {
|
||||
Viewport &viewport;
|
||||
CocoaViewport *cocoaViewport;
|
||||
|
||||
uintptr_t handle();
|
||||
|
||||
pViewport(Viewport &viewport) : pWidget(viewport), viewport(viewport) {}
|
||||
void constructor();
|
||||
void destructor();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -13,8 +13,7 @@
|
|||
[self setLevel:NSFloatingWindowLevel]; //when launched from a terminal, this places the window above it
|
||||
[self setTitle:@""];
|
||||
|
||||
menu = [[NSMenu alloc] init];
|
||||
[menu retain];
|
||||
menuBar = [[NSMenu alloc] init];
|
||||
|
||||
NSMenuItem *item;
|
||||
string text;
|
||||
|
@ -22,9 +21,9 @@
|
|||
rootMenu = [[NSMenu alloc] init];
|
||||
item = [[[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""] autorelease];
|
||||
[item setSubmenu:rootMenu];
|
||||
[menu addItem:item];
|
||||
[menuBar addItem:item];
|
||||
|
||||
text = {"About ", phoenix::applicationState.name, "..."};
|
||||
text = {"About ", phoenix::applicationState.name, " ..."};
|
||||
item = [[[NSMenuItem alloc] initWithTitle:[NSString stringWithUTF8String:text] action:@selector(menuAbout) keyEquivalent:@""] autorelease];
|
||||
[rootMenu addItem:item];
|
||||
[rootMenu addItem:[NSMenuItem separatorItem]];
|
||||
|
@ -51,7 +50,7 @@
|
|||
|
||||
-(void) windowDidBecomeMain :(NSNotification*)notification {
|
||||
if(window->state.menu.size() > 0) {
|
||||
[NSApp setMainMenu:menu];
|
||||
[NSApp setMainMenu:menuBar];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,8 +69,8 @@
|
|||
return NO;
|
||||
}
|
||||
|
||||
-(NSMenu*) menu {
|
||||
return menu;
|
||||
-(NSMenu*) menuBar {
|
||||
return menuBar;
|
||||
}
|
||||
|
||||
-(void) menuAbout {
|
||||
|
@ -107,7 +106,7 @@ void pWindow::append(Layout &layout) {
|
|||
|
||||
void pWindow::append(Menu &menu) {
|
||||
@autoreleasepool {
|
||||
[[cocoaWindow menu] addItem:menu.p.cocoaAction];
|
||||
[[cocoaWindow menuBar] addItem:menu.p.cocoaAction];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,7 +163,7 @@ void pWindow::remove(Layout &layout) {
|
|||
|
||||
void pWindow::remove(Menu &menu) {
|
||||
@autoreleasepool {
|
||||
[[cocoaWindow menu] removeItem:menu.p.cocoaAction];
|
||||
[[cocoaWindow menuBar] removeItem:menu.p.cocoaAction];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,7 +195,6 @@ void pWindow::setFocused() {
|
|||
|
||||
void pWindow::setFullScreen(bool fullScreen) {
|
||||
@autoreleasepool {
|
||||
[cocoaWindow setLevel:NSNormalWindowLevel];
|
||||
if(fullScreen == true) {
|
||||
[NSApp setPresentationOptions:NSApplicationPresentationFullScreen];
|
||||
[cocoaWindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
|
||||
|
@ -273,8 +271,12 @@ void pWindow::setTitle(const string &text) {
|
|||
|
||||
void pWindow::setVisible(bool visible) {
|
||||
@autoreleasepool {
|
||||
if(visible) [cocoaWindow makeKeyAndOrderFront:nil];
|
||||
else [cocoaWindow orderOut:nil];
|
||||
if(visible) {
|
||||
[cocoaWindow makeKeyAndOrderFront:nil];
|
||||
[cocoaWindow setLevel:NSNormalWindowLevel];
|
||||
} else {
|
||||
[cocoaWindow orderOut:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
@interface CocoaWindow : NSWindow <NSWindowDelegate> {
|
||||
@public
|
||||
phoenix::Window *window;
|
||||
NSMenu *menu;
|
||||
NSMenu *menuBar;
|
||||
NSMenu *rootMenu;
|
||||
}
|
||||
-(id) initWith :(phoenix::Window&)window;
|
||||
|
@ -11,7 +11,7 @@
|
|||
-(void) windowDidMove :(NSNotification*)notification;
|
||||
-(void) windowDidResize :(NSNotification*)notification;
|
||||
-(BOOL) windowShouldClose :(id)sender;
|
||||
-(NSMenu*) menu;
|
||||
-(NSMenu*) menuBar;
|
||||
-(void) menuAbout;
|
||||
-(void) menuPreferences;
|
||||
-(void) menuQuit;
|
||||
|
|
|
@ -166,42 +166,94 @@ bool Mouse::released(Mouse::Button button) {
|
|||
return !pressed(button);
|
||||
}
|
||||
|
||||
//DialogWindow
|
||||
//============
|
||||
//BrowserWindow
|
||||
//=============
|
||||
|
||||
string DialogWindow::fileOpen_(Window &parent, const string &path, const lstring &filter_) {
|
||||
auto filter = filter_;
|
||||
if(filter.size() == 0) filter.append("All files (*)");
|
||||
return pDialogWindow::fileOpen(parent, path, filter);
|
||||
string BrowserWindow::directory() {
|
||||
return pBrowserWindow::directory(state);
|
||||
}
|
||||
|
||||
string DialogWindow::fileSave_(Window &parent, const string &path, const lstring &filter_) {
|
||||
auto filter = filter_;
|
||||
if(filter.size() == 0) filter.append("All files (*)");
|
||||
return pDialogWindow::fileSave(parent, path, filter);
|
||||
string BrowserWindow::open() {
|
||||
return pBrowserWindow::open(state);
|
||||
}
|
||||
|
||||
string DialogWindow::folderSelect(Window &parent, const string &path) {
|
||||
return pDialogWindow::folderSelect(parent, path);
|
||||
string BrowserWindow::save() {
|
||||
return pBrowserWindow::save(state);
|
||||
}
|
||||
|
||||
BrowserWindow& BrowserWindow::setFilters_(const lstring &filters) {
|
||||
state.filters = filters;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BrowserWindow& BrowserWindow::setParent(Window &parent) {
|
||||
state.parent = &parent;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BrowserWindow& BrowserWindow::setPath(const string &path) {
|
||||
state.path = path;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BrowserWindow& BrowserWindow::setTitle(const string &title) {
|
||||
state.title = title;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BrowserWindow::BrowserWindow():
|
||||
state(*new State) {
|
||||
}
|
||||
|
||||
BrowserWindow::~BrowserWindow() {
|
||||
delete &state;
|
||||
}
|
||||
|
||||
//MessageWindow
|
||||
//=============
|
||||
|
||||
MessageWindow::Response MessageWindow::information(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
return pMessageWindow::information(parent, text, buttons);
|
||||
MessageWindow::Response MessageWindow::error(MessageWindow::Buttons buttons) {
|
||||
state.buttons = buttons;
|
||||
return pMessageWindow::error(state);
|
||||
}
|
||||
|
||||
MessageWindow::Response MessageWindow::question(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
return pMessageWindow::question(parent, text, buttons);
|
||||
MessageWindow::Response MessageWindow::information(MessageWindow::Buttons buttons) {
|
||||
state.buttons = buttons;
|
||||
return pMessageWindow::information(state);
|
||||
}
|
||||
|
||||
MessageWindow::Response MessageWindow::warning(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
return pMessageWindow::warning(parent, text, buttons);
|
||||
MessageWindow::Response MessageWindow::question(MessageWindow::Buttons buttons) {
|
||||
state.buttons = buttons;
|
||||
return pMessageWindow::question(state);
|
||||
}
|
||||
|
||||
MessageWindow::Response MessageWindow::critical(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
return pMessageWindow::critical(parent, text, buttons);
|
||||
MessageWindow& MessageWindow::setParent(Window &parent) {
|
||||
state.parent = &parent;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MessageWindow& MessageWindow::setText(const string &text) {
|
||||
state.text = text;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MessageWindow& MessageWindow::setTitle(const string &title) {
|
||||
state.title = title;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MessageWindow::Response MessageWindow::warning(MessageWindow::Buttons buttons) {
|
||||
state.buttons = buttons;
|
||||
return pMessageWindow::warning(state);
|
||||
}
|
||||
|
||||
MessageWindow::MessageWindow(const string &text):
|
||||
state(*new State) {
|
||||
state.text = text;
|
||||
}
|
||||
|
||||
MessageWindow::~MessageWindow() {
|
||||
delete &state;
|
||||
}
|
||||
|
||||
//Object
|
||||
|
|
|
@ -141,15 +141,21 @@ struct Mouse {
|
|||
Mouse() = delete;
|
||||
};
|
||||
|
||||
struct DialogWindow {
|
||||
template<typename... Args> static nall::string fileOpen(Window &parent, const nall::string &path, const Args&... args) { return fileOpen_(parent, path, { args... }); }
|
||||
template<typename... Args> static nall::string fileSave(Window &parent, const nall::string &path, const Args&... args) { return fileSave_(parent, path, { args... }); }
|
||||
static nall::string folderSelect(Window &parent, const nall::string &path);
|
||||
DialogWindow() = delete;
|
||||
struct BrowserWindow {
|
||||
template<typename... Args> BrowserWindow& setFilters(const Args&... args) { return setFilters_({args...}); }
|
||||
|
||||
private:
|
||||
static nall::string fileOpen_(Window &parent, const nall::string &path, const nall::lstring& filter);
|
||||
static nall::string fileSave_(Window &parent, const nall::string &path, const nall::lstring& filter);
|
||||
nall::string directory();
|
||||
nall::string open();
|
||||
nall::string save();
|
||||
BrowserWindow& setFilters_(const nall::lstring& filters);
|
||||
BrowserWindow& setParent(Window &parent);
|
||||
BrowserWindow& setPath(const nall::string &path);
|
||||
BrowserWindow& setTitle(const nall::string &title);
|
||||
|
||||
BrowserWindow();
|
||||
~BrowserWindow();
|
||||
struct State;
|
||||
State &state;
|
||||
};
|
||||
|
||||
struct MessageWindow {
|
||||
|
@ -167,11 +173,18 @@ struct MessageWindow {
|
|||
No,
|
||||
};
|
||||
|
||||
static Response information(Window &parent, const nall::string &text, Buttons = Buttons::Ok);
|
||||
static Response question(Window &parent, const nall::string &text, Buttons = Buttons::YesNo);
|
||||
static Response warning(Window &parent, const nall::string &text, Buttons = Buttons::Ok);
|
||||
static Response critical(Window &parent, const nall::string &text, Buttons = Buttons::Ok);
|
||||
MessageWindow() = delete;
|
||||
Response error(Buttons = Buttons::Ok);
|
||||
Response information(Buttons = Buttons::Ok);
|
||||
Response question(Buttons = Buttons::YesNo);
|
||||
MessageWindow& setParent(Window &parent);
|
||||
MessageWindow& setText(const nall::string &text);
|
||||
MessageWindow& setTitle(const nall::string &title);
|
||||
Response warning(Buttons = Buttons::Ok);
|
||||
|
||||
MessageWindow(const nall::string &text = "");
|
||||
~MessageWindow();
|
||||
struct State;
|
||||
State &state;
|
||||
};
|
||||
|
||||
struct Object {
|
||||
|
|
|
@ -8,6 +8,20 @@ struct Timer::State {
|
|||
unsigned milliseconds = 0;
|
||||
};
|
||||
|
||||
struct BrowserWindow::State {
|
||||
lstring filters;
|
||||
Window *parent = nullptr;
|
||||
string path;
|
||||
string title;
|
||||
};
|
||||
|
||||
struct MessageWindow::State {
|
||||
MessageWindow::Buttons buttons = MessageWindow::Buttons::Ok;
|
||||
Window *parent = nullptr;
|
||||
string text;
|
||||
string title;
|
||||
};
|
||||
|
||||
struct Window::State {
|
||||
bool backgroundColorOverride = false;
|
||||
Color backgroundColor = {0, 0, 0, 255};
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
namespace phoenix {
|
||||
|
||||
static void BrowserWindow_addFilters(GtkWidget *dialog, lstring filters) {
|
||||
for(auto &filter : filters) {
|
||||
GtkFileFilter *gtkFilter = gtk_file_filter_new();
|
||||
gtk_file_filter_set_name(gtkFilter, filter);
|
||||
lstring patterns = filter.split<1>("(")(1).rtrim<1>(")").split(",");
|
||||
for(auto &pattern : patterns) gtk_file_filter_add_pattern(gtkFilter, pattern.strip());
|
||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), gtkFilter);
|
||||
}
|
||||
}
|
||||
|
||||
string pBrowserWindow::directory(BrowserWindow::State &state) {
|
||||
string name;
|
||||
|
||||
GtkWidget *dialog = gtk_file_chooser_dialog_new(
|
||||
state.title ? state.title : "Select Directory",
|
||||
state.parent ? GTK_WINDOW(state.parent->p.widget) : (GtkWindow*)nullptr,
|
||||
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
|
||||
(const gchar*)nullptr
|
||||
);
|
||||
|
||||
if(state.path) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), state.path);
|
||||
|
||||
if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||
char *temp = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||
name = temp;
|
||||
g_free(temp);
|
||||
}
|
||||
|
||||
gtk_widget_destroy(dialog);
|
||||
if(name && !name.endswith("/")) name.append("/");
|
||||
return name;
|
||||
}
|
||||
|
||||
string pBrowserWindow::open(BrowserWindow::State &state) {
|
||||
string name;
|
||||
|
||||
GtkWidget *dialog = gtk_file_chooser_dialog_new(
|
||||
state.title ? state.title : "Open File",
|
||||
state.parent ? GTK_WINDOW(state.parent->p.widget) : (GtkWindow*)nullptr,
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
|
||||
(const gchar*)nullptr
|
||||
);
|
||||
|
||||
if(state.path) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), state.path);
|
||||
BrowserWindow_addFilters(dialog, state.filters);
|
||||
|
||||
if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||
char *temp = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||
name = temp;
|
||||
g_free(temp);
|
||||
}
|
||||
|
||||
gtk_widget_destroy(dialog);
|
||||
return name;
|
||||
}
|
||||
|
||||
string pBrowserWindow::save(BrowserWindow::State &state) {
|
||||
string name;
|
||||
|
||||
GtkWidget *dialog = gtk_file_chooser_dialog_new(
|
||||
state.title ? state.title : "Save File",
|
||||
state.parent ? GTK_WINDOW(state.parent->p.widget) : (GtkWindow*)nullptr,
|
||||
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
|
||||
(const gchar*)nullptr
|
||||
);
|
||||
|
||||
if(state.path) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), state.path);
|
||||
BrowserWindow_addFilters(dialog, state.filters);
|
||||
|
||||
if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||
char *temp = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||
name = temp;
|
||||
g_free(temp);
|
||||
}
|
||||
|
||||
gtk_widget_destroy(dialog);
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
namespace phoenix {
|
||||
|
||||
static string FileDialog(bool save, Window &parent, const string &path, const lstring &filter) {
|
||||
string name;
|
||||
|
||||
GtkWidget *dialog = gtk_file_chooser_dialog_new(
|
||||
save == 0 ? "Load File" : "Save File",
|
||||
&parent != &Window::none() ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)nullptr,
|
||||
save == 0 ? GTK_FILE_CHOOSER_ACTION_OPEN : GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
|
||||
(const gchar*)nullptr
|
||||
);
|
||||
|
||||
if(path) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path);
|
||||
|
||||
for(auto &filterItem : filter) {
|
||||
GtkFileFilter *gtkFilter = gtk_file_filter_new();
|
||||
gtk_file_filter_set_name(gtkFilter, filterItem);
|
||||
lstring part;
|
||||
part.split("(", filterItem);
|
||||
part[1].rtrim<1>(")");
|
||||
lstring list;
|
||||
list.split(",", part[1]);
|
||||
for(auto &pattern : list) gtk_file_filter_add_pattern(gtkFilter, pattern);
|
||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), gtkFilter);
|
||||
}
|
||||
|
||||
if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||
char *temp = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||
name = temp;
|
||||
g_free(temp);
|
||||
}
|
||||
|
||||
gtk_widget_destroy(dialog);
|
||||
return name;
|
||||
}
|
||||
|
||||
string pDialogWindow::fileOpen(Window &parent, const string &path, const lstring &filter) {
|
||||
return FileDialog(0, parent, path, filter);
|
||||
}
|
||||
|
||||
string pDialogWindow::fileSave(Window &parent, const string &path, const lstring &filter) {
|
||||
return FileDialog(1, parent, path, filter);
|
||||
}
|
||||
|
||||
string pDialogWindow::folderSelect(Window &parent, const string &path) {
|
||||
string name;
|
||||
|
||||
GtkWidget *dialog = gtk_file_chooser_dialog_new(
|
||||
"Select Folder",
|
||||
&parent != &Window::none() ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)nullptr,
|
||||
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
|
||||
(const gchar*)nullptr
|
||||
);
|
||||
|
||||
if(path) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path);
|
||||
|
||||
if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||
char *temp = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||
name = temp;
|
||||
g_free(temp);
|
||||
}
|
||||
|
||||
gtk_widget_destroy(dialog);
|
||||
if(name == "") return "";
|
||||
if(name.endswith("/") == false) name.append("/");
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,65 +1,60 @@
|
|||
namespace phoenix {
|
||||
|
||||
static MessageWindow::Response MessageWindow_response(MessageWindow::Buttons buttons, gint response) {
|
||||
static MessageWindow::Response Message(MessageWindow::State &state, GtkMessageType messageStyle) {
|
||||
GtkWidget *dialog = gtk_message_dialog_new(
|
||||
state.parent ? GTK_WINDOW(state.parent->p.widget) : (GtkWindow*)nullptr,
|
||||
GTK_DIALOG_MODAL, messageStyle, GTK_BUTTONS_NONE, "%s", (const char*)state.text
|
||||
);
|
||||
|
||||
if(state.title) gtk_window_set_title(GTK_WINDOW(dialog), state.title);
|
||||
else if(applicationState.name) gtk_window_set_title(GTK_WINDOW(dialog), applicationState.name);
|
||||
|
||||
switch(state.buttons) {
|
||||
case MessageWindow::Buttons::Ok:
|
||||
gtk_dialog_add_buttons(GTK_DIALOG(dialog), "Ok", GTK_RESPONSE_OK, nullptr);
|
||||
break;
|
||||
case MessageWindow::Buttons::OkCancel:
|
||||
gtk_dialog_add_buttons(GTK_DIALOG(dialog), "Ok", GTK_RESPONSE_OK, "Cancel", GTK_RESPONSE_CANCEL, nullptr);
|
||||
break;
|
||||
case MessageWindow::Buttons::YesNo:
|
||||
gtk_dialog_add_buttons(GTK_DIALOG(dialog), "Yes", GTK_RESPONSE_YES, "No", GTK_RESPONSE_NO, nullptr);
|
||||
break;
|
||||
case MessageWindow::Buttons::YesNoCancel:
|
||||
gtk_dialog_add_buttons(GTK_DIALOG(dialog), "Yes", GTK_RESPONSE_YES, "No", GTK_RESPONSE_NO, "Cancel", GTK_RESPONSE_CANCEL, nullptr);
|
||||
break;
|
||||
}
|
||||
|
||||
auto response = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
|
||||
if(response == GTK_RESPONSE_OK) return MessageWindow::Response::Ok;
|
||||
if(response == GTK_RESPONSE_CANCEL) return MessageWindow::Response::Cancel;
|
||||
if(response == GTK_RESPONSE_YES) return MessageWindow::Response::Yes;
|
||||
if(response == GTK_RESPONSE_NO) return MessageWindow::Response::No;
|
||||
if(buttons == MessageWindow::Buttons::OkCancel) return MessageWindow::Response::Cancel;
|
||||
if(buttons == MessageWindow::Buttons::YesNo) return MessageWindow::Response::No;
|
||||
return MessageWindow::Response::Ok;
|
||||
|
||||
//if dialog was closed without choosing a button, choose the most appropriate response
|
||||
if(state.buttons == MessageWindow::Buttons::Ok) return MessageWindow::Response::Ok;
|
||||
if(state.buttons == MessageWindow::Buttons::OkCancel) return MessageWindow::Response::Cancel;
|
||||
if(state.buttons == MessageWindow::Buttons::YesNo) return MessageWindow::Response::No;
|
||||
if(state.buttons == MessageWindow::Buttons::YesNoCancel) return MessageWindow::Response::Cancel;
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
MessageWindow::Response pMessageWindow::information(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
GtkButtonsType buttonsType = GTK_BUTTONS_OK;
|
||||
if(buttons == MessageWindow::Buttons::OkCancel) buttonsType = GTK_BUTTONS_OK_CANCEL;
|
||||
if(buttons == MessageWindow::Buttons::YesNo) buttonsType = GTK_BUTTONS_YES_NO;
|
||||
GtkWidget *dialog = gtk_message_dialog_new(
|
||||
&parent != &Window::none() ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)nullptr,
|
||||
GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, buttonsType, "%s", (const char*)text
|
||||
);
|
||||
gint response = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
return MessageWindow_response(buttons, response);
|
||||
MessageWindow::Response pMessageWindow::error(MessageWindow::State &state) {
|
||||
return Message(state, GTK_MESSAGE_ERROR);
|
||||
}
|
||||
|
||||
MessageWindow::Response pMessageWindow::question(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
GtkButtonsType buttonsType = GTK_BUTTONS_OK;
|
||||
if(buttons == MessageWindow::Buttons::OkCancel) buttonsType = GTK_BUTTONS_OK_CANCEL;
|
||||
if(buttons == MessageWindow::Buttons::YesNo) buttonsType = GTK_BUTTONS_YES_NO;
|
||||
GtkWidget *dialog = gtk_message_dialog_new(
|
||||
&parent != &Window::none() ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)nullptr,
|
||||
GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, buttonsType, "%s", (const char*)text
|
||||
);
|
||||
gint response = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
return MessageWindow_response(buttons, response);
|
||||
MessageWindow::Response pMessageWindow::information(MessageWindow::State &state) {
|
||||
return Message(state, GTK_MESSAGE_INFO);
|
||||
}
|
||||
|
||||
MessageWindow::Response pMessageWindow::warning(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
GtkButtonsType buttonsType = GTK_BUTTONS_OK;
|
||||
if(buttons == MessageWindow::Buttons::OkCancel) buttonsType = GTK_BUTTONS_OK_CANCEL;
|
||||
if(buttons == MessageWindow::Buttons::YesNo) buttonsType = GTK_BUTTONS_YES_NO;
|
||||
GtkWidget *dialog = gtk_message_dialog_new(
|
||||
&parent != &Window::none() ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)nullptr,
|
||||
GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, buttonsType, "%s", (const char*)text
|
||||
);
|
||||
gint response = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
return MessageWindow_response(buttons, response);
|
||||
MessageWindow::Response pMessageWindow::question(MessageWindow::State &state) {
|
||||
return Message(state, GTK_MESSAGE_QUESTION);
|
||||
}
|
||||
|
||||
MessageWindow::Response pMessageWindow::critical(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
GtkButtonsType buttonsType = GTK_BUTTONS_OK;
|
||||
if(buttons == MessageWindow::Buttons::OkCancel) buttonsType = GTK_BUTTONS_OK_CANCEL;
|
||||
if(buttons == MessageWindow::Buttons::YesNo) buttonsType = GTK_BUTTONS_YES_NO;
|
||||
GtkWidget *dialog = gtk_message_dialog_new(
|
||||
&parent != &Window::none() ? GTK_WINDOW(parent.p.widget) : (GtkWindow*)nullptr,
|
||||
GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, buttonsType, "%s", (const char*)text
|
||||
);
|
||||
gint response = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
return MessageWindow_response(buttons, response);
|
||||
MessageWindow::Response pMessageWindow::warning(MessageWindow::State &state) {
|
||||
return Message(state, GTK_MESSAGE_WARNING);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "desktop.cpp"
|
||||
#include "keyboard.cpp"
|
||||
#include "mouse.cpp"
|
||||
#include "dialog-window.cpp"
|
||||
#include "browser-window.cpp"
|
||||
#include "message-window.cpp"
|
||||
#include "font.cpp"
|
||||
#include "timer.cpp"
|
||||
|
|
|
@ -62,17 +62,17 @@ struct pMouse {
|
|||
static bool pressed(Mouse::Button button);
|
||||
};
|
||||
|
||||
struct pDialogWindow {
|
||||
static string fileOpen(Window &parent, const string &path, const lstring &filter);
|
||||
static string fileSave(Window &parent, const string &path, const lstring &filter);
|
||||
static string folderSelect(Window &parent, const string &path);
|
||||
struct pBrowserWindow {
|
||||
static string directory(BrowserWindow::State &state);
|
||||
static string open(BrowserWindow::State &state);
|
||||
static string save(BrowserWindow::State &state);
|
||||
};
|
||||
|
||||
struct pMessageWindow {
|
||||
static MessageWindow::Response information(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||
static MessageWindow::Response question(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||
static MessageWindow::Response warning(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||
static MessageWindow::Response critical(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||
static MessageWindow::Response error(MessageWindow::State &state);
|
||||
static MessageWindow::Response information(MessageWindow::State &state);
|
||||
static MessageWindow::Response question(MessageWindow::State &state);
|
||||
static MessageWindow::Response warning(MessageWindow::State &state);
|
||||
};
|
||||
|
||||
struct pObject {
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
namespace phoenix {
|
||||
|
||||
string pBrowserWindow::directory(BrowserWindow::State &state) {
|
||||
QString directory = QFileDialog::getExistingDirectory(
|
||||
state.parent ? state.parent->p.qtWindow : nullptr,
|
||||
state.title ? state.title : "Select Directory",
|
||||
QString::fromUtf8(state.path), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks
|
||||
);
|
||||
string name = directory.toUtf8().constData();
|
||||
if(name && name.endswith("/") == false) name.append("/");
|
||||
return name;
|
||||
}
|
||||
|
||||
string pBrowserWindow::open(BrowserWindow::State &state) {
|
||||
string filters = state.filters.concatenate(";;");
|
||||
|
||||
//convert filter list from phoenix to Qt format, example:
|
||||
//"Text, XML files (*.txt,*.xml)" -> "Text, XML files (*.txt *.xml)"
|
||||
signed parentheses = 0;
|
||||
for(auto &n : filters) {
|
||||
if(n == '(') parentheses++;
|
||||
if(n == ')') parentheses--;
|
||||
if(n == ',' && parentheses) n = ' ';
|
||||
}
|
||||
|
||||
QString filename = QFileDialog::getOpenFileName(
|
||||
state.parent ? state.parent->p.qtWindow : nullptr,
|
||||
state.title ? state.title : "Open File",
|
||||
QString::fromUtf8(state.path), QString::fromUtf8(filters)
|
||||
);
|
||||
return filename.toUtf8().constData();
|
||||
}
|
||||
|
||||
string pBrowserWindow::save(BrowserWindow::State &state) {
|
||||
string filters = state.filters.concatenate(";;");
|
||||
|
||||
//convert filter list from phoenix to Qt format, example:
|
||||
//"Text, XML files (*.txt,*.xml)" -> "Text, XML files (*.txt *.xml)"
|
||||
signed parentheses = 0;
|
||||
for(auto &n : filters) {
|
||||
if(n == '(') parentheses++;
|
||||
if(n == ')') parentheses--;
|
||||
if(n == ',' && parentheses) n = ' ';
|
||||
}
|
||||
|
||||
QString filename = QFileDialog::getSaveFileName(
|
||||
state.parent ? state.parent->p.qtWindow : nullptr,
|
||||
state.title ? state.title : "Save File",
|
||||
QString::fromUtf8(state.path), QString::fromUtf8(filters)
|
||||
);
|
||||
return filename.toUtf8().constData();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
namespace phoenix {
|
||||
|
||||
string pDialogWindow::fileOpen(Window &parent, const string &path, const lstring &filter) {
|
||||
string filterList;
|
||||
for(auto &item : filter) {
|
||||
filterList.append(item);
|
||||
filterList.append(";;");
|
||||
}
|
||||
filterList.rtrim<1>(";;");
|
||||
|
||||
//convert filter list from phoenix to Qt format, example:
|
||||
//"Text, XML files (*.txt,*.xml)" -> "Text, XML files (*.txt *.xml)"
|
||||
signed parenthesis = 0;
|
||||
for(auto &n : filterList) {
|
||||
if(n == '(') parenthesis++;
|
||||
if(n == ')') parenthesis--;
|
||||
if(n == ',' && parenthesis) n = ' ';
|
||||
}
|
||||
|
||||
QString filename = QFileDialog::getOpenFileName(
|
||||
&parent != &Window::none() ? parent.p.qtWindow : nullptr, "Open File",
|
||||
QString::fromUtf8(path), QString::fromUtf8(filterList)
|
||||
);
|
||||
return filename.toUtf8().constData();
|
||||
}
|
||||
|
||||
string pDialogWindow::fileSave(Window &parent, const string &path, const lstring &filter) {
|
||||
string filterList;
|
||||
for(auto &item : filter) {
|
||||
filterList.append(item);
|
||||
filterList.append(";;");
|
||||
}
|
||||
filterList.rtrim<1>(";;");
|
||||
|
||||
//convert filter list from phoenix to Qt format, example:
|
||||
//"Text, XML files (*.txt,*.xml)" -> "Text, XML files (*.txt *.xml)"
|
||||
signed parenthesis = 0;
|
||||
for(auto &n : filterList) {
|
||||
if(n == '(') parenthesis++;
|
||||
if(n == ')') parenthesis--;
|
||||
if(n == ',' && parenthesis) n = ' ';
|
||||
}
|
||||
|
||||
QString filename = QFileDialog::getSaveFileName(
|
||||
&parent != &Window::none() ? parent.p.qtWindow : nullptr, "Save File",
|
||||
QString::fromUtf8(path), QString::fromUtf8(filterList)
|
||||
);
|
||||
return filename.toUtf8().constData();
|
||||
}
|
||||
|
||||
string pDialogWindow::folderSelect(Window &parent, const string &path) {
|
||||
QString directory = QFileDialog::getExistingDirectory(
|
||||
&parent != &Window::none() ? parent.p.qtWindow : nullptr, "Select Directory",
|
||||
QString::fromUtf8(path), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks
|
||||
);
|
||||
string name = directory.toUtf8().constData();
|
||||
if(name != "" && name.endswith("/") == false) name.append("/");
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
|
@ -5,6 +5,7 @@ static QMessageBox::StandardButtons MessageWindow_buttons(MessageWindow::Buttons
|
|||
if(buttons == MessageWindow::Buttons::Ok) standardButtons = QMessageBox::Ok;
|
||||
if(buttons == MessageWindow::Buttons::OkCancel) standardButtons = QMessageBox::Ok | QMessageBox::Cancel;
|
||||
if(buttons == MessageWindow::Buttons::YesNo) standardButtons = QMessageBox::Yes | QMessageBox::No;
|
||||
if(buttons == MessageWindow::Buttons::YesNoCancel) standardButtons = QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel;
|
||||
return standardButtons;
|
||||
}
|
||||
|
||||
|
@ -15,36 +16,39 @@ static MessageWindow::Response MessageWindow_response(MessageWindow::Buttons but
|
|||
if(response == QMessageBox::No) return MessageWindow::Response::No;
|
||||
|
||||
//MessageWindow was closed via window manager, rather than by a button; assume a cancel/no response
|
||||
if(buttons == MessageWindow::Buttons::Ok) return MessageWindow::Response::Ok;
|
||||
if(buttons == MessageWindow::Buttons::OkCancel) return MessageWindow::Response::Cancel;
|
||||
if(buttons == MessageWindow::Buttons::YesNo) return MessageWindow::Response::No;
|
||||
return MessageWindow::Response::Ok;
|
||||
if(buttons == MessageWindow::Buttons::YesNoCancel) return MessageWindow::Response::Cancel;
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
MessageWindow::Response pMessageWindow::information(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
MessageWindow::Response pMessageWindow::error(MessageWindow::State &state) {
|
||||
return MessageWindow_response(
|
||||
buttons, QMessageBox::information(&parent != &Window::none() ? parent.p.qtWindow : nullptr, " ",
|
||||
QString::fromUtf8(text), MessageWindow_buttons(buttons))
|
||||
state.buttons, QMessageBox::critical(state.parent ? state.parent->p.qtWindow : nullptr, state.title ? state.title : " ",
|
||||
QString::fromUtf8(state.text), MessageWindow_buttons(state.buttons))
|
||||
);
|
||||
}
|
||||
|
||||
MessageWindow::Response pMessageWindow::question(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
MessageWindow::Response pMessageWindow::information(MessageWindow::State &state) {
|
||||
return MessageWindow_response(
|
||||
buttons, QMessageBox::question(&parent != &Window::none() ? parent.p.qtWindow : nullptr, " ",
|
||||
QString::fromUtf8(text), MessageWindow_buttons(buttons))
|
||||
state.buttons, QMessageBox::information(state.parent ? state.parent->p.qtWindow : nullptr, state.title ? state.title : " ",
|
||||
QString::fromUtf8(state.text), MessageWindow_buttons(state.buttons))
|
||||
);
|
||||
}
|
||||
|
||||
MessageWindow::Response pMessageWindow::warning(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
MessageWindow::Response pMessageWindow::question(MessageWindow::State &state) {
|
||||
return MessageWindow_response(
|
||||
buttons, QMessageBox::warning(&parent != &Window::none() ? parent.p.qtWindow : nullptr, " ",
|
||||
QString::fromUtf8(text), MessageWindow_buttons(buttons))
|
||||
state.buttons, QMessageBox::question(state.parent ? state.parent->p.qtWindow : nullptr, state.title ? state.title : " ",
|
||||
QString::fromUtf8(state.text), MessageWindow_buttons(state.buttons))
|
||||
);
|
||||
}
|
||||
|
||||
MessageWindow::Response pMessageWindow::critical(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
MessageWindow::Response pMessageWindow::warning(MessageWindow::State &state) {
|
||||
return MessageWindow_response(
|
||||
buttons, QMessageBox::critical(&parent != &Window::none() ? parent.p.qtWindow : nullptr, " ",
|
||||
QString::fromUtf8(text), MessageWindow_buttons(buttons))
|
||||
state.buttons, QMessageBox::warning(state.parent ? state.parent->p.qtWindow : nullptr, state.title ? state.title : " ",
|
||||
QString::fromUtf8(state.text), MessageWindow_buttons(state.buttons))
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "desktop.cpp"
|
||||
#include "keyboard.cpp"
|
||||
#include "mouse.cpp"
|
||||
#include "dialog-window.cpp"
|
||||
#include "browser-window.cpp"
|
||||
#include "message-window.cpp"
|
||||
#include "font.cpp"
|
||||
#include "timer.cpp"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
** Meta object code from reading C++ file 'platform.moc.hpp'
|
||||
**
|
||||
** Created: Thu Mar 14 08:12:31 2013
|
||||
** Created: Sat Mar 16 11:52:02 2013
|
||||
** by: The Qt Meta Object Compiler version 62 (Qt 4.6.3)
|
||||
**
|
||||
** WARNING! All changes made in this file will be lost!
|
||||
|
|
|
@ -61,17 +61,17 @@ struct pMouse {
|
|||
static bool pressed(Mouse::Button button);
|
||||
};
|
||||
|
||||
struct pDialogWindow {
|
||||
static string fileOpen(Window &parent, const string &path, const lstring &filter);
|
||||
static string fileSave(Window &parent, const string &path, const lstring &filter);
|
||||
static string folderSelect(Window &parent, const string &path);
|
||||
struct pBrowserWindow {
|
||||
static string directory(BrowserWindow::State &state);
|
||||
static string open(BrowserWindow::State &state);
|
||||
static string save(BrowserWindow::State &state);
|
||||
};
|
||||
|
||||
struct pMessageWindow {
|
||||
static MessageWindow::Response information(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||
static MessageWindow::Response question(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||
static MessageWindow::Response warning(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||
static MessageWindow::Response critical(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||
static MessageWindow::Response error(MessageWindow::State &state);
|
||||
static MessageWindow::Response information(MessageWindow::State &state);
|
||||
static MessageWindow::Response question(MessageWindow::State &state);
|
||||
static MessageWindow::Response warning(MessageWindow::State &state);
|
||||
};
|
||||
|
||||
struct pObject {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
namespace phoenix {
|
||||
|
||||
string pBrowserWindow::directory(BrowserWindow::State &state) {
|
||||
return "";
|
||||
}
|
||||
|
||||
string pBrowserWindow::open(BrowserWindow::State &state) {
|
||||
return "";
|
||||
}
|
||||
|
||||
string pBrowserWindow::save(BrowserWindow::State &state) {
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
namespace phoenix {
|
||||
|
||||
struct pBrowserWindow {
|
||||
static string directory(BrowserWindow::State &state);
|
||||
static string open(BrowserWindow::State &state);
|
||||
static string save(BrowserWindow::State &state);
|
||||
};
|
||||
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
namespace phoenix {
|
||||
|
||||
string pDialogWindow::fileOpen(Window &parent, const string &path, const lstring &filter) {
|
||||
return "";
|
||||
}
|
||||
|
||||
string pDialogWindow::fileSave(Window &parent, const string &path, const lstring &filter) {
|
||||
return "";
|
||||
}
|
||||
|
||||
string pDialogWindow::folderSelect(Window &parent, const string &path) {
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
namespace phoenix {
|
||||
|
||||
struct pDialogWindow {
|
||||
static string fileOpen(Window &parent, const string &path, const lstring &filter);
|
||||
static string fileSave(Window &parent, const string &path, const lstring &filter);
|
||||
static string folderSelect(Window &parent, const string &path);
|
||||
};
|
||||
|
||||
}
|
|
@ -1,18 +1,18 @@
|
|||
namespace phoenix {
|
||||
|
||||
MessageWindow::Response pMessageWindow::information(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
MessageWindow::Response pMessageWindow::error(MessageWindow::State &state) {
|
||||
return MessageWindow::Response::Ok;
|
||||
}
|
||||
|
||||
MessageWindow::Response pMessageWindow::question(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
MessageWindow::Response pMessageWindow::information(MessageWindow::State &state) {
|
||||
return MessageWindow::Response::Ok;
|
||||
}
|
||||
|
||||
MessageWindow::Response pMessageWindow::warning(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
MessageWindow::Response pMessageWindow::question(MessageWindow::State &state) {
|
||||
return MessageWindow::Response::Ok;
|
||||
}
|
||||
|
||||
MessageWindow::Response pMessageWindow::critical(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
MessageWindow::Response pMessageWindow::warning(MessageWindow::State &state) {
|
||||
return MessageWindow::Response::Ok;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
namespace phoenix {
|
||||
|
||||
struct pMessageWindow {
|
||||
static MessageWindow::Response information(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||
static MessageWindow::Response question(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||
static MessageWindow::Response warning(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||
static MessageWindow::Response critical(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||
static MessageWindow::Response error(MessageWindow::State &state);
|
||||
static MessageWindow::Response information(MessageWindow::State &state);
|
||||
static MessageWindow::Response question(MessageWindow::State &state);
|
||||
static MessageWindow::Response warning(MessageWindow::State &state);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "desktop.cpp"
|
||||
#include "keyboard.cpp"
|
||||
#include "mouse.cpp"
|
||||
#include "dialog-window.cpp"
|
||||
#include "browser-window.cpp"
|
||||
#include "message-window.cpp"
|
||||
#include "font.cpp"
|
||||
#include "timer.cpp"
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace phoenix {
|
|||
#include "desktop.hpp"
|
||||
#include "keyboard.hpp"
|
||||
#include "mouse.hpp"
|
||||
#include "dialog-window.hpp"
|
||||
#include "browser-window.hpp"
|
||||
#include "message-window.hpp"
|
||||
#include "object.hpp"
|
||||
#include "timer.hpp"
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
namespace phoenix {
|
||||
|
||||
static int CALLBACK BrowserWindowCallbackProc(HWND hwnd, UINT msg, LPARAM lparam, LPARAM lpdata) {
|
||||
if(msg == BFFM_INITIALIZED) {
|
||||
if(lpdata) {
|
||||
auto state = (BrowserWindow::State*)lpdata;
|
||||
utf16_t wpath(string{state->path}.transform("/", "\\"));
|
||||
if(state->title) SetWindowText(hwnd, utf16_t(state->title));
|
||||
SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)(wchar_t*)wpath);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static string BrowserWindow_fileDialog(bool save, BrowserWindow::State &state) {
|
||||
string path = string{path}.replace("/", "\\");
|
||||
|
||||
string filters;
|
||||
for(auto &filter : state.filters) {
|
||||
lstring part = filter.split("(");
|
||||
if(part.size() != 2) continue;
|
||||
part[1].rtrim<1>(")");
|
||||
part[1].replace(" ", "");
|
||||
part[1].transform(",", ";");
|
||||
filters.append(filter, "\t", part[1], "\t");
|
||||
}
|
||||
|
||||
utf16_t wfilters(filters);
|
||||
wchar_t wname[PATH_MAX + 1] = L"";
|
||||
utf16_t wpath(path);
|
||||
utf16_t wtitle(state.title);
|
||||
|
||||
wchar_t *p = wfilters;
|
||||
while(*p != L'\0') {
|
||||
if(*p == L'\t') *p = L'\0';
|
||||
p++;
|
||||
}
|
||||
|
||||
if(path.empty() == false) {
|
||||
//clear COMDLG32 MRU (most recently used) file list
|
||||
//this is required in order for lpstrInitialDir to be honored in Windows 7 and above
|
||||
registry::remove("HKCU/Software/Microsoft/Windows/CurrentVersion/Explorer/ComDlg32/LastVisitedPidlMRU/");
|
||||
registry::remove("HKCU/Software/Microsoft/Windows/CurrentVersion/Explorer/ComDlg32/OpenSavePidlMRU/");
|
||||
}
|
||||
|
||||
OPENFILENAME ofn;
|
||||
memset(&ofn, 0, sizeof(OPENFILENAME));
|
||||
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||
ofn.hwndOwner = state.parent ? state.parent->p.hwnd : 0;
|
||||
ofn.lpstrFilter = wfilters;
|
||||
ofn.lpstrInitialDir = wpath;
|
||||
ofn.lpstrFile = wname;
|
||||
ofn.lpstrTitle = wtitle;
|
||||
ofn.nMaxFile = PATH_MAX;
|
||||
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
|
||||
ofn.lpstrDefExt = L"";
|
||||
|
||||
bool result = (save == false ? GetOpenFileName(&ofn) : GetSaveFileName(&ofn));
|
||||
if(result == false) return "";
|
||||
string name = (const char*)utf8_t(wname);
|
||||
name.transform("\\", "/");
|
||||
return name;
|
||||
}
|
||||
|
||||
string pBrowserWindow::directory(BrowserWindow::State &state) {
|
||||
wchar_t wname[PATH_MAX + 1] = L"";
|
||||
|
||||
BROWSEINFO bi;
|
||||
bi.hwndOwner = state.parent ? state.parent->p.hwnd : 0;
|
||||
bi.pidlRoot = NULL;
|
||||
bi.pszDisplayName = wname;
|
||||
bi.lpszTitle = L"\nChoose a directory:";
|
||||
bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS;
|
||||
bi.lpfn = BrowserWindowCallbackProc;
|
||||
bi.lParam = (LPARAM)&state;
|
||||
bi.iImage = 0;
|
||||
bool result = false;
|
||||
LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
|
||||
if(pidl) {
|
||||
if(SHGetPathFromIDList(pidl, wname)) {
|
||||
result = true;
|
||||
IMalloc *imalloc = 0;
|
||||
if(SUCCEEDED(SHGetMalloc(&imalloc))) {
|
||||
imalloc->Free(pidl);
|
||||
imalloc->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
if(result == false) return "";
|
||||
string name = (const char*)utf8_t(wname);
|
||||
if(!name) return "";
|
||||
name.transform("\\", "/");
|
||||
if(name.endswith("/") == false) name.append("/");
|
||||
return name;
|
||||
}
|
||||
|
||||
string pBrowserWindow::open(BrowserWindow::State &state) {
|
||||
return BrowserWindow_fileDialog(0, state);
|
||||
}
|
||||
|
||||
string pBrowserWindow::save(BrowserWindow::State &state) {
|
||||
return BrowserWindow_fileDialog(1, state);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,102 +0,0 @@
|
|||
namespace phoenix {
|
||||
|
||||
static string FileDialog(bool save, Window &parent, const string &path, const lstring &filter) {
|
||||
string dir = path;
|
||||
dir.replace("/", "\\");
|
||||
|
||||
string filterList;
|
||||
for(auto &filterItem : filter) {
|
||||
lstring part;
|
||||
part.split("(", filterItem);
|
||||
if(part.size() != 2) continue;
|
||||
part[1].rtrim<1>(")");
|
||||
part[1].replace(" ", "");
|
||||
part[1].transform(",", ";");
|
||||
filterList.append(string(filterItem, "\t", part[1], "\t"));
|
||||
}
|
||||
|
||||
utf16_t wfilter(filterList);
|
||||
utf16_t wdir(dir);
|
||||
wchar_t wfilename[PATH_MAX + 1] = L"";
|
||||
|
||||
wchar_t *p = wfilter;
|
||||
while(*p != L'\0') {
|
||||
if(*p == L'\t') *p = L'\0';
|
||||
p++;
|
||||
}
|
||||
|
||||
if(path.empty() == false) {
|
||||
//clear COMDLG32 MRU (most recently used) file list
|
||||
//this is required in order for lpstrInitialDir to be honored in Windows 7 and above
|
||||
registry::remove("HKCU/Software/Microsoft/Windows/CurrentVersion/Explorer/ComDlg32/LastVisitedPidlMRU/");
|
||||
registry::remove("HKCU/Software/Microsoft/Windows/CurrentVersion/Explorer/ComDlg32/OpenSavePidlMRU/");
|
||||
}
|
||||
|
||||
OPENFILENAME ofn;
|
||||
memset(&ofn, 0, sizeof(OPENFILENAME));
|
||||
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||
ofn.hwndOwner = &parent != &Window::none() ? parent.p.hwnd : 0;
|
||||
ofn.lpstrFilter = wfilter;
|
||||
ofn.lpstrInitialDir = wdir;
|
||||
ofn.lpstrFile = wfilename;
|
||||
ofn.nMaxFile = PATH_MAX;
|
||||
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
|
||||
ofn.lpstrDefExt = L"";
|
||||
|
||||
bool result = (save == false ? GetOpenFileName(&ofn) : GetSaveFileName(&ofn));
|
||||
if(result == false) return "";
|
||||
string name = (const char*)utf8_t(wfilename);
|
||||
name.transform("\\", "/");
|
||||
return name;
|
||||
}
|
||||
|
||||
string pDialogWindow::fileOpen(Window &parent, const string &path, const lstring &filter) {
|
||||
return FileDialog(false, parent, path, filter);
|
||||
}
|
||||
|
||||
string pDialogWindow::fileSave(Window &parent, const string &path, const lstring &filter) {
|
||||
return FileDialog(true, parent, path, filter);
|
||||
}
|
||||
|
||||
static int CALLBACK BrowseCallbackProc(HWND hwnd, UINT msg, LPARAM lparam, LPARAM lpdata) {
|
||||
if(msg == BFFM_INITIALIZED) {
|
||||
if(lpdata) SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpdata);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
string pDialogWindow::folderSelect(Window &parent, const string &path) {
|
||||
wchar_t wfilename[PATH_MAX + 1] = L"";
|
||||
utf16_t wpath(string{path}.transform("/", "\\"));
|
||||
|
||||
BROWSEINFO bi;
|
||||
bi.hwndOwner = &parent != &Window::none() ? parent.p.hwnd : 0;
|
||||
bi.pidlRoot = NULL;
|
||||
bi.pszDisplayName = wfilename;
|
||||
bi.lpszTitle = L"";
|
||||
bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS;
|
||||
bi.lpfn = BrowseCallbackProc;
|
||||
bi.lParam = (LPARAM)(wchar_t*)wpath;
|
||||
bi.iImage = 0;
|
||||
bool result = false;
|
||||
LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
|
||||
if(pidl) {
|
||||
if(SHGetPathFromIDList(pidl, wfilename)) {
|
||||
result = true;
|
||||
IMalloc *imalloc = 0;
|
||||
if(SUCCEEDED(SHGetMalloc(&imalloc))) {
|
||||
imalloc->Free(pidl);
|
||||
imalloc->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
if(result == false) return "";
|
||||
string name = (const char*)utf8_t(wfilename);
|
||||
if(name == "") return "";
|
||||
name.transform("\\", "/");
|
||||
if(name.endswith("/") == false) name.append("/");
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
|
@ -5,41 +5,50 @@ static MessageWindow::Response MessageWindow_response(MessageWindow::Buttons but
|
|||
if(response == IDCANCEL) return MessageWindow::Response::Cancel;
|
||||
if(response == IDYES) return MessageWindow::Response::Yes;
|
||||
if(response == IDNO) return MessageWindow::Response::No;
|
||||
|
||||
//default responses if window was closed without a button selected
|
||||
if(buttons == MessageWindow::Buttons::Ok) return MessageWindow::Response::Ok;
|
||||
if(buttons == MessageWindow::Buttons::OkCancel) return MessageWindow::Response::Cancel;
|
||||
if(buttons == MessageWindow::Buttons::YesNo) return MessageWindow::Response::No;
|
||||
return MessageWindow::Response::Ok;
|
||||
if(buttons == MessageWindow::Buttons::YesNoCancel) return MessageWindow::Response::Cancel;
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
MessageWindow::Response pMessageWindow::information(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
UINT flags = MB_ICONINFORMATION;
|
||||
if(buttons == MessageWindow::Buttons::Ok) flags |= MB_OK;
|
||||
if(buttons == MessageWindow::Buttons::OkCancel) flags |= MB_OKCANCEL;
|
||||
if(buttons == MessageWindow::Buttons::YesNo) flags |= MB_YESNO;
|
||||
return MessageWindow_response(buttons, MessageBox(&parent != &Window::none() ? parent.p.hwnd : 0, utf16_t(text), L"", flags));
|
||||
static UINT MessageWindow_buttons(MessageWindow::Buttons buttons) {
|
||||
if(buttons == MessageWindow::Buttons::Ok) return MB_OK;
|
||||
if(buttons == MessageWindow::Buttons::OkCancel) return MB_OKCANCEL;
|
||||
if(buttons == MessageWindow::Buttons::YesNo) return MB_YESNO;
|
||||
if(buttons == MessageWindow::Buttons::YesNoCancel) return MB_YESNOCANCEL;
|
||||
throw;
|
||||
}
|
||||
|
||||
MessageWindow::Response pMessageWindow::question(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
UINT flags = MB_ICONQUESTION;
|
||||
if(buttons == MessageWindow::Buttons::Ok) flags |= MB_OK;
|
||||
if(buttons == MessageWindow::Buttons::OkCancel) flags |= MB_OKCANCEL;
|
||||
if(buttons == MessageWindow::Buttons::YesNo) flags |= MB_YESNO;
|
||||
return MessageWindow_response(buttons, MessageBox(&parent != &Window::none() ? parent.p.hwnd : 0, utf16_t(text), L"", flags));
|
||||
MessageWindow::Response pMessageWindow::error(MessageWindow::State &state) {
|
||||
UINT flags = MB_ICONERROR | MessageWindow_buttons(state.buttons);
|
||||
return MessageWindow_response(state.buttons, MessageBox(
|
||||
state.parent ? state.parent->p.hwnd : 0, utf16_t(state.text), utf16_t(state.title), flags
|
||||
));
|
||||
}
|
||||
|
||||
MessageWindow::Response pMessageWindow::warning(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
UINT flags = MB_ICONWARNING;
|
||||
if(buttons == MessageWindow::Buttons::Ok) flags |= MB_OK;
|
||||
if(buttons == MessageWindow::Buttons::OkCancel) flags |= MB_OKCANCEL;
|
||||
if(buttons == MessageWindow::Buttons::YesNo) flags |= MB_YESNO;
|
||||
return MessageWindow_response(buttons, MessageBox(&parent != &Window::none() ? parent.p.hwnd : 0, utf16_t(text), L"", flags));
|
||||
MessageWindow::Response pMessageWindow::information(MessageWindow::State &state) {
|
||||
UINT flags = MB_ICONINFORMATION | MessageWindow_buttons(state.buttons);
|
||||
return MessageWindow_response(state.buttons, MessageBox(
|
||||
state.parent ? state.parent->p.hwnd : 0, utf16_t(state.text), utf16_t(state.title), flags
|
||||
));
|
||||
}
|
||||
|
||||
MessageWindow::Response pMessageWindow::critical(Window &parent, const string &text, MessageWindow::Buttons buttons) {
|
||||
UINT flags = MB_ICONERROR;
|
||||
if(buttons == MessageWindow::Buttons::Ok) flags |= MB_OK;
|
||||
if(buttons == MessageWindow::Buttons::OkCancel) flags |= MB_OKCANCEL;
|
||||
if(buttons == MessageWindow::Buttons::YesNo) flags |= MB_YESNO;
|
||||
return MessageWindow_response(buttons, MessageBox(&parent != &Window::none() ? parent.p.hwnd : 0, utf16_t(text), L"", flags));
|
||||
MessageWindow::Response pMessageWindow::question(MessageWindow::State &state) {
|
||||
UINT flags = MB_ICONQUESTION | MessageWindow_buttons(state.buttons);
|
||||
return MessageWindow_response(state.buttons, MessageBox(
|
||||
state.parent ? state.parent->p.hwnd : 0, utf16_t(state.text), utf16_t(state.title), flags
|
||||
));
|
||||
}
|
||||
|
||||
MessageWindow::Response pMessageWindow::warning(MessageWindow::State &state) {
|
||||
UINT flags = MB_ICONWARNING | MessageWindow_buttons(state.buttons);
|
||||
return MessageWindow_response(state.buttons, MessageBox(
|
||||
state.parent ? state.parent->p.hwnd : 0, utf16_t(state.text), utf16_t(state.title), flags
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "desktop.cpp"
|
||||
#include "keyboard.cpp"
|
||||
#include "mouse.cpp"
|
||||
#include "dialog-window.cpp"
|
||||
#include "browser-window.cpp"
|
||||
#include "message-window.cpp"
|
||||
#include "object.cpp"
|
||||
#include "font.cpp"
|
||||
|
|
|
@ -48,17 +48,17 @@ struct pMouse {
|
|||
static bool pressed(Mouse::Button button);
|
||||
};
|
||||
|
||||
struct pDialogWindow {
|
||||
static string fileOpen(Window &parent, const string &path, const lstring &filter);
|
||||
static string fileSave(Window &parent, const string &path, const lstring &filter);
|
||||
static string folderSelect(Window &parent, const string &path);
|
||||
struct pBrowserWindow {
|
||||
static string directory(BrowserWindow::State &state);
|
||||
static string open(BrowserWindow::State &state);
|
||||
static string save(BrowserWindow::State &state);
|
||||
};
|
||||
|
||||
struct pMessageWindow {
|
||||
static MessageWindow::Response information(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||
static MessageWindow::Response question(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||
static MessageWindow::Response warning(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||
static MessageWindow::Response critical(Window &parent, const string &text, MessageWindow::Buttons buttons);
|
||||
static MessageWindow::Response error(MessageWindow::State &state);
|
||||
static MessageWindow::Response information(MessageWindow::State &state);
|
||||
static MessageWindow::Response question(MessageWindow::State &state);
|
||||
static MessageWindow::Response warning(MessageWindow::State &state);
|
||||
};
|
||||
|
||||
struct pObject {
|
||||
|
|
|
@ -1,22 +1,33 @@
|
|||
rubyflags := $(foreach c,$(subst .,_,$(call strupper,$(ruby))),-D$c)
|
||||
ifeq ($(platform),osx)
|
||||
rubyflags = $(objcppflags) $(flags)
|
||||
else
|
||||
rubyflags = $(cppflags) $(flags)
|
||||
endif
|
||||
|
||||
rubyflags += $(foreach c,$(subst .,_,$(call strupper,$(ruby))),-D$c)
|
||||
rubyflags += $(if $(finstring .sdl,$(ruby)),`sdl-config --cflags`)
|
||||
|
||||
rubylink :=
|
||||
rubylink += $(if $(findstring .sdl,$(ruby)),`sdl-config --libs`)
|
||||
rubylink =
|
||||
|
||||
rubylink += $(if $(findstring video.cgl,$(ruby)),-framework OpenGL)
|
||||
rubylink += $(if $(findstring video.direct3d,$(ruby)),-ld3d9)
|
||||
rubylink += $(if $(findstring video.directdraw,$(ruby)),-lddraw)
|
||||
rubylink += $(if $(findstring video.glx,$(ruby)),-lGL)
|
||||
rubylink += $(if $(findstring video.wgl,$(ruby)),-lopengl32)
|
||||
rubylink += $(if $(findstring video.xv,$(ruby)),-lXv)
|
||||
|
||||
rubylink += $(if $(findstring audio.alsa,$(ruby)),-lasound)
|
||||
rubylink += $(if $(findstring audio.ao,$(ruby)),-lao)
|
||||
rubylink += $(if $(findstring audio.directsound,$(ruby)),-ldsound)
|
||||
rubylink += $(if $(findstring audio.pulseaudio,$(ruby)),-lpulse)
|
||||
rubylink += $(if $(findstring audio.pulseaudiosimple,$(ruby)),-lpulse-simple)
|
||||
rubylink += $(if $(findstring audio.xaudio2,$(ruby)),-lole32)
|
||||
|
||||
rubylink += $(if $(findstring input.directinput,$(ruby)),-ldinput8 -ldxguid)
|
||||
rubylink += $(if $(findstring input.rawinput,$(ruby)),-ldinput8 -ldxguid)
|
||||
|
||||
rubylink += $(if $(findstring .sdl,$(ruby)),`sdl-config --libs`)
|
||||
|
||||
ifeq ($(platform),x)
|
||||
rubylink += $(if $(findstring audio.openal,$(ruby)),-lopenal)
|
||||
else ifeq ($(platform),osx)
|
||||
|
|
|
@ -27,6 +27,10 @@ void VideoInterface::driver(const char *driver) {
|
|||
|
||||
if(0);
|
||||
|
||||
#ifdef VIDEO_CGL
|
||||
else if(!strcmp(driver, "OpenGL")) p = new VideoCGL();
|
||||
#endif
|
||||
|
||||
#ifdef VIDEO_DIRECT3D
|
||||
else if(!strcmp(driver, "Direct3D")) p = new VideoD3D();
|
||||
#endif
|
||||
|
@ -80,6 +84,8 @@ const char* VideoInterface::default_driver() {
|
|||
return "DirectDraw";
|
||||
#elif defined(VIDEO_GDI)
|
||||
return "GDI";
|
||||
#elif defined(VIDEO_CGL)
|
||||
return "OpenGL";
|
||||
#elif defined(VIDEO_XSHM)
|
||||
return "XShm";
|
||||
#elif defined(VIDEO_QTOPENGL)
|
||||
|
@ -119,6 +125,12 @@ const char* VideoInterface::driver_list() {
|
|||
"GDI;"
|
||||
#endif
|
||||
|
||||
//OS X
|
||||
|
||||
#if defined(VIDEO_CGL)
|
||||
"OpenGL;"
|
||||
#endif
|
||||
|
||||
//Linux
|
||||
|
||||
#if defined(VIDEO_GLX)
|
||||
|
@ -327,6 +339,10 @@ void InputInterface::driver(const char *driver) {
|
|||
else if(!strcmp(driver, "RawInput")) p = new InputRaw();
|
||||
#endif
|
||||
|
||||
#ifdef INPUT_CARBON
|
||||
else if(!strcmp(driver, "Carbon")) p = new InputCarbon();
|
||||
#endif
|
||||
|
||||
#ifdef INPUT_SDL
|
||||
else if(!strcmp(driver, "SDL")) p = new InputSDL();
|
||||
#endif
|
||||
|
@ -335,10 +351,6 @@ void InputInterface::driver(const char *driver) {
|
|||
else if(!strcmp(driver, "X-Windows")) p = new InputX();
|
||||
#endif
|
||||
|
||||
#ifdef INPUT_CARBON
|
||||
else if(!strcmp(driver, "Carbon")) p = new InputCarbon();
|
||||
#endif
|
||||
|
||||
else p = new Input();
|
||||
}
|
||||
|
||||
|
@ -348,12 +360,12 @@ const char* InputInterface::default_driver() {
|
|||
return "RawInput";
|
||||
#elif defined(INPUT_DIRECTINPUT)
|
||||
return "DirectInput";
|
||||
#elif defined(INPUT_CARBON)
|
||||
return "Carbon";
|
||||
#elif defined(INPUT_SDL)
|
||||
return "SDL";
|
||||
#elif defined(INPUT_X)
|
||||
return "X-Windows";
|
||||
#elif defined(INPUT_CARBON)
|
||||
return "Carbon";
|
||||
#else
|
||||
return "none";
|
||||
#endif
|
||||
|
@ -372,6 +384,12 @@ const char* InputInterface::driver_list() {
|
|||
"DirectInput;"
|
||||
#endif
|
||||
|
||||
//OS X
|
||||
|
||||
#if defined(INPUT_CARBON)
|
||||
"Carbon;"
|
||||
#endif
|
||||
|
||||
//Linux
|
||||
|
||||
#if defined(INPUT_SDL)
|
||||
|
@ -382,12 +400,6 @@ const char* InputInterface::driver_list() {
|
|||
"X-Windows;"
|
||||
#endif
|
||||
|
||||
//OS X
|
||||
|
||||
#if defined(INPUT_CARBON)
|
||||
"Carbon;"
|
||||
#endif
|
||||
|
||||
"None";
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <X11/Xatom.h>
|
||||
#elif defined(PLATFORM_OSX)
|
||||
#define __INTEL_COMPILER
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include <Carbon/Carbon.h>
|
||||
#elif defined(PLATFORM_WINDOWS)
|
||||
#define _WIN32_WINNT 0x0501
|
||||
|
@ -50,6 +51,10 @@ using namespace nall;
|
|||
pVideo##Name &p; \
|
||||
};
|
||||
|
||||
#ifdef VIDEO_CGL
|
||||
#include <ruby/video/cgl.cpp>
|
||||
#endif
|
||||
|
||||
#ifdef VIDEO_DIRECT3D
|
||||
#include <ruby/video/direct3d.cpp>
|
||||
#endif
|
||||
|
@ -175,6 +180,10 @@ using namespace nall;
|
|||
#include <ruby/input/rawinput.cpp>
|
||||
#endif
|
||||
|
||||
#ifdef INPUT_CARBON
|
||||
#include <ruby/input/carbon.cpp>
|
||||
#endif
|
||||
|
||||
#ifdef INPUT_SDL
|
||||
#include <ruby/input/sdl.cpp>
|
||||
#endif
|
||||
|
@ -182,7 +191,3 @@ using namespace nall;
|
|||
#ifdef INPUT_X
|
||||
#include <ruby/input/x.cpp>
|
||||
#endif
|
||||
|
||||
#ifdef INPUT_CARBON
|
||||
#include <ruby/input/carbon.cpp>
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
#include "opengl.hpp"
|
||||
|
||||
namespace ruby {
|
||||
|
||||
class pVideoCGL : public OpenGL {
|
||||
public:
|
||||
NSOpenGLView *view;
|
||||
|
||||
struct {
|
||||
NSView *handle;
|
||||
|
||||
bool synchronize;
|
||||
unsigned filter;
|
||||
string shader;
|
||||
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
} settings;
|
||||
|
||||
bool cap(const string &name) {
|
||||
if(name == Video::Handle) return true;
|
||||
if(name == Video::Synchronize) return true;
|
||||
if(name == Video::Filter) return true;
|
||||
if(name == Video::Shader) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
any get(const string &name) {
|
||||
if(name == Video::Handle) return (uintptr_t)settings.handle;
|
||||
if(name == Video::Synchronize) return settings.synchronize;
|
||||
if(name == Video::Filter) return settings.filter;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool set(const string &name, const any &value) {
|
||||
if(name == Video::Handle) {
|
||||
settings.handle = (NSView*)any_cast<uintptr_t>(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(name == Video::Synchronize) {
|
||||
if(settings.synchronize != any_cast<bool>(value)) {
|
||||
settings.synchronize = any_cast<bool>(value);
|
||||
|
||||
if(view) {
|
||||
@autoreleasepool {
|
||||
[[view openGLContext] makeCurrentContext];
|
||||
init();
|
||||
OpenGL::set_shader(settings.shader);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if(name == Video::Filter) {
|
||||
settings.filter = any_cast<unsigned>(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(name == Video::Shader) {
|
||||
settings.shader = any_cast<const char*>(value);
|
||||
|
||||
@autoreleasepool {
|
||||
[[view openGLContext] makeCurrentContext];
|
||||
OpenGL::set_shader(settings.shader);
|
||||
settings.filter = OpenGL::fragmentfilter;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool lock(uint32_t *&data, unsigned &pitch, unsigned width, unsigned height) {
|
||||
resize(width, height);
|
||||
settings.width = width;
|
||||
settings.height = height;
|
||||
return OpenGL::lock(data, pitch);
|
||||
}
|
||||
|
||||
void unlock() {
|
||||
}
|
||||
|
||||
void clear() {
|
||||
@autoreleasepool {
|
||||
[view lockFocus];
|
||||
OpenGL::clear();
|
||||
[[view openGLContext] flushBuffer];
|
||||
[view unlockFocus];
|
||||
}
|
||||
}
|
||||
|
||||
void refresh() {
|
||||
@autoreleasepool {
|
||||
if([view lockFocusIfCanDraw]) {
|
||||
auto area = [view frame];
|
||||
OpenGL::refresh(
|
||||
settings.filter == Video::FilterLinear,
|
||||
settings.width, settings.height,
|
||||
area.size.width, area.size.height
|
||||
);
|
||||
[[view openGLContext] flushBuffer];
|
||||
[view unlockFocus];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool init() {
|
||||
term();
|
||||
|
||||
@autoreleasepool {
|
||||
NSOpenGLPixelFormatAttribute attributes[] = {
|
||||
NSOpenGLPFAColorSize, 24,
|
||||
NSOpenGLPFAAccelerated,
|
||||
NSOpenGLPFADoubleBuffer,
|
||||
NSOpenGLPFAWindow,
|
||||
0
|
||||
};
|
||||
|
||||
auto size = [settings.handle frame].size;
|
||||
auto format = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes] autorelease];
|
||||
view = [[NSOpenGLView alloc] initWithFrame:NSMakeRect(0, 0, 0, 0) pixelFormat:format];
|
||||
|
||||
[view setFrame:NSMakeRect(0, 0, size.width, size.height)];
|
||||
[view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
||||
[settings.handle addSubview:view];
|
||||
|
||||
[view lockFocus];
|
||||
|
||||
OpenGL::init();
|
||||
settings.width = 256;
|
||||
settings.height = 256;
|
||||
|
||||
auto context = (CGLContextObj)[[view openGLContext] CGLContextObj];
|
||||
int synchronize = settings.synchronize;
|
||||
CGLSetParameter(context, kCGLCPSwapInterval, &synchronize);
|
||||
|
||||
[view unlockFocus];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void term() {
|
||||
OpenGL::term();
|
||||
|
||||
@autoreleasepool {
|
||||
[view removeFromSuperview];
|
||||
[view release];
|
||||
view = nil;
|
||||
}
|
||||
}
|
||||
|
||||
pVideoCGL() {
|
||||
view = nil;
|
||||
|
||||
settings.handle = nil;
|
||||
settings.synchronize = false;
|
||||
settings.filter = 0;
|
||||
|
||||
iformat = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
ibpp = 4;
|
||||
}
|
||||
|
||||
~pVideoCGL() {
|
||||
term();
|
||||
}
|
||||
};
|
||||
|
||||
DeclareVideo(CGL)
|
||||
|
||||
}
|
|
@ -1,28 +1,32 @@
|
|||
#include <GL/gl.h>
|
||||
|
||||
#if defined(PLATFORM_X)
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
#define glGetProcAddress(name) (*glXGetProcAddress)((const GLubyte*)(name))
|
||||
#elif defined(PLATFORM_OSX)
|
||||
#include <OpenGL/gl.h>
|
||||
#elif defined(PLATFORM_WIN)
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#define glGetProcAddress(name) wglGetProcAddress(name)
|
||||
#else
|
||||
#error "ruby::OpenGL: unsupported platform"
|
||||
#endif
|
||||
|
||||
PFNGLCREATEPROGRAMPROC glCreateProgram = 0;
|
||||
PFNGLUSEPROGRAMPROC glUseProgram = 0;
|
||||
PFNGLCREATESHADERPROC glCreateShader = 0;
|
||||
PFNGLDELETESHADERPROC glDeleteShader = 0;
|
||||
PFNGLSHADERSOURCEPROC glShaderSource = 0;
|
||||
PFNGLCOMPILESHADERPROC glCompileShader = 0;
|
||||
PFNGLATTACHSHADERPROC glAttachShader = 0;
|
||||
PFNGLDETACHSHADERPROC glDetachShader = 0;
|
||||
PFNGLLINKPROGRAMPROC glLinkProgram = 0;
|
||||
PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = 0;
|
||||
PFNGLUNIFORM1IPROC glUniform1i = 0;
|
||||
PFNGLUNIFORM2FVPROC glUniform2fv = 0;
|
||||
PFNGLUNIFORM4FVPROC glUniform4fv = 0;
|
||||
#if !defined(PLATFORM_OSX)
|
||||
PFNGLCREATEPROGRAMPROC glCreateProgram = nullptr;
|
||||
PFNGLUSEPROGRAMPROC glUseProgram = nullptr;
|
||||
PFNGLCREATESHADERPROC glCreateShader = nullptr;
|
||||
PFNGLDELETESHADERPROC glDeleteShader = nullptr;
|
||||
PFNGLSHADERSOURCEPROC glShaderSource = nullptr;
|
||||
PFNGLCOMPILESHADERPROC glCompileShader = nullptr;
|
||||
PFNGLATTACHSHADERPROC glAttachShader = nullptr;
|
||||
PFNGLDETACHSHADERPROC glDetachShader = nullptr;
|
||||
PFNGLLINKPROGRAMPROC glLinkProgram = nullptr;
|
||||
PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = nullptr;
|
||||
PFNGLUNIFORM1IPROC glUniform1i = nullptr;
|
||||
PFNGLUNIFORM2FVPROC glUniform2fv = nullptr;
|
||||
PFNGLUNIFORM4FVPROC glUniform4fv = nullptr;
|
||||
#endif
|
||||
|
||||
class OpenGL {
|
||||
public:
|
||||
|
@ -177,6 +181,9 @@ public:
|
|||
glEnable(GL_DITHER);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
#if defined(PLATFORM_OSX)
|
||||
shader_support = true;
|
||||
#else
|
||||
//bind shader functions
|
||||
glCreateProgram = (PFNGLCREATEPROGRAMPROC)glGetProcAddress("glCreateProgram");
|
||||
glUseProgram = (PFNGLUSEPROGRAMPROC)glGetProcAddress("glUseProgram");
|
||||
|
@ -196,6 +203,7 @@ public:
|
|||
&& glDeleteShader && glShaderSource && glCompileShader && glAttachShader
|
||||
&& glDetachShader && glLinkProgram && glGetUniformLocation
|
||||
&& glUniform1i && glUniform2fv && glUniform4fv;
|
||||
#endif
|
||||
|
||||
if(shader_support) glprogram = glCreateProgram();
|
||||
|
||||
|
@ -211,7 +219,7 @@ public:
|
|||
|
||||
if(buffer) {
|
||||
delete[] buffer;
|
||||
buffer = 0;
|
||||
buffer = nullptr;
|
||||
iwidth = 0;
|
||||
iheight = 0;
|
||||
}
|
||||
|
@ -224,7 +232,7 @@ public:
|
|||
fragmentfilter = 0;
|
||||
vertexshader = 0;
|
||||
|
||||
buffer = 0;
|
||||
buffer = nullptr;
|
||||
iwidth = 0;
|
||||
iheight = 0;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ ifeq ($(platform),x)
|
|||
ruby += audio.alsa audio.openal audio.oss audio.pulseaudio audio.pulseaudiosimple audio.ao
|
||||
ruby += input.sdl input.x
|
||||
else ifeq ($(platform),osx)
|
||||
ruby :=
|
||||
ruby := video.cgl
|
||||
ruby += audio.openal
|
||||
ruby += input.carbon
|
||||
else ifeq ($(platform),win)
|
||||
|
@ -52,10 +52,10 @@ obj/ui-settings.o: $(ui)/settings/settings.cpp $(call rwildcard,$(ui)/)
|
|||
obj/ui-tools.o: $(ui)/tools/tools.cpp $(call rwildcard,$(ui)/)
|
||||
|
||||
obj/ruby.o: ruby/ruby.cpp $(call rwildcard,ruby/*)
|
||||
$(call compile,$(rubyflags))
|
||||
$(compiler) $(rubyflags) -c $< -o $@
|
||||
|
||||
obj/phoenix.o: phoenix/phoenix.cpp $(call rwildcard,phoenix/*)
|
||||
$(call compile,$(phoenixflags))
|
||||
$(compiler) $(phoenixflags) -c $< -o $@
|
||||
|
||||
obj/resource.o: $(ui)/resource.rc
|
||||
ifeq ($(arch),win32)
|
||||
|
@ -67,13 +67,19 @@ endif
|
|||
# targets
|
||||
build: $(objects)
|
||||
ifeq ($(platform),x)
|
||||
$(strip $(cpp) -o out/$(name) $(objects) $(link))
|
||||
else ifeq ($(platform),win)
|
||||
$(strip $(cpp) -shared -o out/phoenix.dll obj/phoenix.o $(phoenixlink))
|
||||
$(strip $(cpp) -o out/$(name) $(subst obj/phoenix.o,,$(objects)) $(link) -Lout -lphoenix)
|
||||
$(strip $(compiler) -o out/$(name) $(objects) $(link))
|
||||
else ifeq ($(platform),osx)
|
||||
test -d ../$(name).app || mkdir -p ../$(name).app/Contents/MacOS
|
||||
$(strip $(cpp) -o ../$(name).app/Contents/MacOS/$(name) $(objects) $(link))
|
||||
if [ -d out/$(name).app ]; then rm -r out/$(name).app; fi
|
||||
mkdir out/$(name).app
|
||||
mkdir out/$(name).app/Contents
|
||||
mkdir out/$(name).app/Contents/MacOS
|
||||
mkdir out/$(name).app/Contents/Resources
|
||||
cp data/Info.plist out/$(name).app/Contents/Info.plist
|
||||
sips -s format icns data/higan512.png --out out/$(name).app/Contents/Resources/higan.icns
|
||||
$(strip $(compiler) -o out/$(name).app/Contents/MacOS/$(name) $(objects) $(link))
|
||||
else ifeq ($(platform),win)
|
||||
$(strip $(compiler) -shared -o out/phoenix.dll obj/phoenix.o $(phoenixlink))
|
||||
$(strip $(compiler) -o out/$(name) $(subst obj/phoenix.o,,$(objects)) $(link) -Lout -lphoenix)
|
||||
endif
|
||||
|
||||
resource:
|
||||
|
|
|
@ -54,7 +54,7 @@ Program::Program(int argc, char **argv) {
|
|||
if(Intrinsics::platform() == Intrinsics::Platform::OSX) {
|
||||
normalFont = Font::sans(12);
|
||||
boldFont = Font::sans(12, "Bold");
|
||||
titleFont = Font::sans(24, "Bold");
|
||||
titleFont = Font::sans(20, "Bold");
|
||||
monospaceFont = Font::monospace(8);
|
||||
} else {
|
||||
normalFont = Font::sans(8);
|
||||
|
@ -130,7 +130,24 @@ int main(int argc, char **argv) {
|
|||
#endif
|
||||
|
||||
Application::setName("higan");
|
||||
|
||||
Application::Cocoa::onQuit = &Application::quit;
|
||||
Application::Cocoa::onPreferences = [&] {
|
||||
settings->setVisible();
|
||||
settings->panelList.setFocused();
|
||||
};
|
||||
Application::Cocoa::onAbout = [&] {
|
||||
MessageWindow()
|
||||
.setTitle({"About ", Emulator::Name})
|
||||
.setText({
|
||||
Emulator::Name, " v", Emulator::Version, "\n",
|
||||
"Author: ", Emulator::Author, "\n",
|
||||
"License: ", Emulator::License, "\n",
|
||||
"Website: ", Emulator::Website
|
||||
})
|
||||
.information();
|
||||
};
|
||||
|
||||
new Program(argc, argv);
|
||||
delete program;
|
||||
return 0;
|
||||
|
|
|
@ -98,8 +98,10 @@ Presentation::Presentation() : active(nullptr) {
|
|||
for(auto &shader : shaderList) shaderMenu.append(*shader);
|
||||
settingsMenu.append(*new Separator);
|
||||
settingsMenu.append(synchronizeVideo, synchronizeAudio, muteAudio);
|
||||
settingsMenu.append(*new Separator);
|
||||
settingsMenu.append(configurationSettings);
|
||||
if(Intrinsics::platform() != Intrinsics::Platform::OSX) {
|
||||
settingsMenu.append(*new Separator);
|
||||
settingsMenu.append(configurationSettings);
|
||||
}
|
||||
append(toolsMenu);
|
||||
toolsMenu.append(saveStateMenu);
|
||||
for(unsigned n = 0; n < 5; n++) saveStateMenu.append(saveStateItem[n]);
|
||||
|
|
|
@ -124,5 +124,5 @@ string Interface::server() {
|
|||
}
|
||||
|
||||
void Interface::notify(const string &text) {
|
||||
MessageWindow::information(*presentation, text);
|
||||
MessageWindow().setParent(*presentation).setText(text).information();
|
||||
}
|
||||
|
|
|
@ -27,9 +27,9 @@ AdvancedSettings::AdvancedSettings() {
|
|||
infoLabel.setText({
|
||||
Emulator::Name, " v", Emulator::Version, "\n",
|
||||
" ", profile, " Profile\n",
|
||||
" Author: byuu\n",
|
||||
" Website: http://byuu.org/\n",
|
||||
" License: GPLv3"
|
||||
" Author: ", Emulator::Author, "\n",
|
||||
" License: ", Emulator::License, "\n",
|
||||
" Website: ", Emulator::Website
|
||||
});
|
||||
|
||||
lstring list;
|
||||
|
@ -65,15 +65,17 @@ AdvancedSettings::AdvancedSettings() {
|
|||
libraryLayout.append(libraryLabel, {0, 0}, 5);
|
||||
libraryLayout.append(libraryPath, {~0, 0}, 5);
|
||||
libraryLayout.append(libraryBrowse, {80, 0});
|
||||
append(spacer, {~0, ~0});
|
||||
append(infoLabel, {~0, 0});
|
||||
if(Intrinsics::platform() != Intrinsics::Platform::OSX) {
|
||||
append(spacer, {~0, ~0});
|
||||
append(infoLabel, {~0, 0});
|
||||
}
|
||||
|
||||
videoDriver.onChange = [&] { config->video.driver = videoDriver.text(); };
|
||||
audioDriver.onChange = [&] { config->audio.driver = audioDriver.text(); };
|
||||
inputDriver.onChange = [&] { config->input.driver = inputDriver.text(); };
|
||||
|
||||
libraryBrowse.onActivate = [&] {
|
||||
string path = DialogWindow::folderSelect(Window::none(), userpath());
|
||||
string path = BrowserWindow().setParent(*settings).setPath(userpath()).directory();
|
||||
if(path.empty()) return;
|
||||
file::write({configpath(), "higan/library.cfg"}, path);
|
||||
libraryPath.setText(path);
|
||||
|
|
|
@ -134,8 +134,8 @@ void InputSettings::inputChanged() {
|
|||
}
|
||||
|
||||
void InputSettings::resetInput() {
|
||||
if(MessageWindow::question(*settings, "All inputs will be erased. Are you sure you want to do this?")
|
||||
== MessageWindow::Response::No) return;
|
||||
if(MessageWindow().setParent(*settings).setText("All inputs will be erased. Are you sure you want to do this?")
|
||||
.question() == MessageWindow::Response::No) return;
|
||||
|
||||
auto &device = activeDevice();
|
||||
unsigned length = device.input.size();
|
||||
|
|
|
@ -50,14 +50,14 @@ void CheatDatabase::findCodes() {
|
|||
return;
|
||||
}
|
||||
|
||||
MessageWindow::information(*cheatEditor, "Sorry, no cheat codes were found.");
|
||||
MessageWindow().setParent(*cheatEditor).setText("Sorry, no cheat codes were found.").information();
|
||||
}
|
||||
|
||||
void CheatDatabase::addCodes() {
|
||||
for(unsigned n = 0; n < cheat.size(); n++) {
|
||||
if(cheatList.checked(n) == false) continue;
|
||||
if(cheatEditor->import(cheat[n].code, cheat[n].desc) == false) {
|
||||
MessageWindow::warning(*this, "Ran out of empty slots for cheat codes.\nNot all cheat codes were added.");
|
||||
MessageWindow().setParent(*this).setText("Ran out of empty slots for cheat codes.\nNot all cheat codes were added.").warning();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,8 +40,8 @@ CheatEditor::CheatEditor() {
|
|||
descEdit.onChange = {&CheatEditor::updateDesc, this};
|
||||
findButton.onActivate = {&CheatDatabase::findCodes, cheatDatabase};
|
||||
resetButton.onActivate = [&] {
|
||||
if(MessageWindow::question(*this, "All codes will be erased. Are you sure you want to do this?")
|
||||
== MessageWindow::Response::Yes) reset();
|
||||
if(MessageWindow().setParent(*this).setText("All codes will be erased. Are you sure you want to do this?")
|
||||
.question() == MessageWindow::Response::Yes) reset();
|
||||
};
|
||||
eraseButton.onActivate = {&CheatEditor::erase, this};
|
||||
|
||||
|
|
|
@ -34,8 +34,8 @@ StateManager::StateManager() {
|
|||
saveButton.onActivate = {&StateManager::slotSave, this};
|
||||
loadButton.onActivate = {&StateManager::slotLoad, this};
|
||||
resetButton.onActivate = [&] {
|
||||
if(MessageWindow::question(*this, "All states will be erased. Are you sure you want to do this?")
|
||||
== MessageWindow::Response::Yes) reset();
|
||||
if(MessageWindow().setParent(*this).setText("All states will be erased. Are you sure you want to do this?")
|
||||
.question() == MessageWindow::Response::Yes) reset();
|
||||
};
|
||||
eraseButton.onActivate = {&StateManager::slotErase, this};
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ void Utility::loadMedia(string pathname) {
|
|||
}
|
||||
}
|
||||
|
||||
MessageWindow::warning(Window::none(), "Unable to determine media type.");
|
||||
MessageWindow().setText("Unable to determine media type.").warning();
|
||||
}
|
||||
|
||||
//load menu option selected
|
||||
|
|
Loading…
Reference in New Issue