From 5b4bbf5045576cf30bf1cd258120707c4357227a Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Thu, 21 Mar 2013 23:59:01 +1100 Subject: [PATCH] Update to v092r05 release. byuu says: This release should be polished enough for a general release. This release should be polished enough for a general release. Anyone with a real, clean Mac up for posting compiled binaries? Preferably compile with "make profile=balanced" In fact, I'd like it if someone were willing to host a "higan for Mac" page, with binaries of each of the latest releases. Only really needed for major official releases, but it'd be preferable to have the builds updated as soon as possible after I post new builds. Changelog: - no more keyboard chimes when pressing keys - status bar added, fully functional - Label::minimumSize() takes frame into account (but note a few places hard-code raw Font::size(), so a few text labels are still clipped) - resizing the main window looks smooth regardless of whether a game is running or not - currently, resizing the window pauses the emulation. Allowing it to run the main loop was lagging out the window resize process too much to be worth it Additional OS X integration enhancements: - closing the main window unloads the current game, but does not quit the application (quit via the main menu or the dock menu) - clicking the icon in the dock will (re)display the main menu --- higan/emulator/emulator.hpp | 10 ++- higan/phoenix/cocoa/action/action.hpp | 2 +- higan/phoenix/cocoa/action/check-item.cpp | 2 +- higan/phoenix/cocoa/action/check-item.hpp | 4 +- higan/phoenix/cocoa/action/item.cpp | 2 +- higan/phoenix/cocoa/action/item.hpp | 4 +- higan/phoenix/cocoa/action/menu.cpp | 2 +- higan/phoenix/cocoa/action/menu.hpp | 4 +- higan/phoenix/cocoa/action/radio-item.cpp | 2 +- higan/phoenix/cocoa/action/radio-item.hpp | 4 +- higan/phoenix/cocoa/action/separator.hpp | 2 +- higan/phoenix/cocoa/application.cpp | 13 +++- higan/phoenix/cocoa/application.hpp | 5 +- higan/phoenix/cocoa/object.cpp | 9 +++ higan/phoenix/cocoa/object.hpp | 4 +- higan/phoenix/cocoa/platform.cpp | 3 +- higan/phoenix/cocoa/timer.cpp | 4 +- higan/phoenix/cocoa/timer.hpp | 6 +- higan/phoenix/cocoa/widget/button.cpp | 4 +- higan/phoenix/cocoa/widget/button.hpp | 6 +- higan/phoenix/cocoa/widget/canvas.cpp | 26 +++---- higan/phoenix/cocoa/widget/canvas.hpp | 26 +++---- higan/phoenix/cocoa/widget/check-button.cpp | 4 +- higan/phoenix/cocoa/widget/check-button.hpp | 6 +- higan/phoenix/cocoa/widget/combo-button.cpp | 4 +- higan/phoenix/cocoa/widget/combo-button.hpp | 6 +- higan/phoenix/cocoa/widget/hex-edit.cpp | 2 +- higan/phoenix/cocoa/widget/hex-edit.hpp | 4 +- .../cocoa/widget/horizontal-scroller.cpp | 4 +- .../cocoa/widget/horizontal-scroller.hpp | 6 +- .../cocoa/widget/horizontal-slider.cpp | 4 +- .../cocoa/widget/horizontal-slider.hpp | 6 +- higan/phoenix/cocoa/widget/label.cpp | 4 +- higan/phoenix/cocoa/widget/label.hpp | 4 +- higan/phoenix/cocoa/widget/line-edit.cpp | 6 +- higan/phoenix/cocoa/widget/line-edit.hpp | 8 +-- higan/phoenix/cocoa/widget/list-view.cpp | 52 +++++++++----- higan/phoenix/cocoa/widget/list-view.hpp | 25 ++++--- higan/phoenix/cocoa/widget/progress-bar.cpp | 2 +- higan/phoenix/cocoa/widget/progress-bar.hpp | 4 +- higan/phoenix/cocoa/widget/radio-button.cpp | 4 +- higan/phoenix/cocoa/widget/radio-button.hpp | 5 +- higan/phoenix/cocoa/widget/text-edit.cpp | 4 +- higan/phoenix/cocoa/widget/text-edit.hpp | 6 +- .../cocoa/widget/vertical-scroller.cpp | 4 +- .../cocoa/widget/vertical-scroller.hpp | 6 +- .../phoenix/cocoa/widget/vertical-slider.cpp | 4 +- .../phoenix/cocoa/widget/vertical-slider.hpp | 6 +- higan/phoenix/cocoa/widget/viewport.cpp | 19 +++-- higan/phoenix/cocoa/widget/viewport.hpp | 9 ++- higan/phoenix/cocoa/widget/widget.hpp | 2 +- higan/phoenix/cocoa/window.cpp | 71 +++++++++++++++---- higan/phoenix/cocoa/window.hpp | 16 +++-- higan/phoenix/core/core.cpp | 9 +-- higan/phoenix/core/core.hpp | 1 + higan/phoenix/reference/action/action.cpp | 3 + higan/phoenix/reference/action/action.hpp | 1 + higan/phoenix/reference/object.cpp | 9 +++ higan/phoenix/reference/object.hpp | 4 +- higan/phoenix/reference/platform.cpp | 3 +- higan/phoenix/reference/timer.cpp | 3 + higan/phoenix/reference/timer.hpp | 1 + higan/phoenix/reference/widget/button.cpp | 3 + higan/phoenix/reference/widget/button.hpp | 1 + higan/phoenix/reference/widget/canvas.cpp | 3 + higan/phoenix/reference/widget/canvas.hpp | 1 + .../phoenix/reference/widget/check-button.cpp | 3 + .../phoenix/reference/widget/check-button.hpp | 1 + .../phoenix/reference/widget/combo-button.cpp | 3 + .../phoenix/reference/widget/combo-button.hpp | 1 + higan/phoenix/reference/widget/hex-edit.cpp | 3 + higan/phoenix/reference/widget/hex-edit.hpp | 1 + .../reference/widget/horizontal-scroller.cpp | 3 + .../reference/widget/horizontal-scroller.hpp | 1 + .../reference/widget/horizontal-slider.cpp | 3 + .../reference/widget/horizontal-slider.hpp | 1 + higan/phoenix/reference/widget/label.cpp | 3 + higan/phoenix/reference/widget/label.hpp | 1 + higan/phoenix/reference/widget/line-edit.cpp | 3 + higan/phoenix/reference/widget/line-edit.hpp | 1 + higan/phoenix/reference/widget/list-view.cpp | 3 + higan/phoenix/reference/widget/list-view.hpp | 1 + .../phoenix/reference/widget/progress-bar.cpp | 3 + .../phoenix/reference/widget/progress-bar.hpp | 1 + .../phoenix/reference/widget/radio-button.cpp | 3 + .../phoenix/reference/widget/radio-button.hpp | 1 + higan/phoenix/reference/widget/text-edit.cpp | 3 + higan/phoenix/reference/widget/text-edit.hpp | 1 + .../reference/widget/vertical-scroller.cpp | 3 + .../reference/widget/vertical-scroller.hpp | 1 + .../reference/widget/vertical-slider.cpp | 3 + .../reference/widget/vertical-slider.hpp | 1 + higan/phoenix/reference/widget/viewport.cpp | 3 + higan/phoenix/reference/widget/viewport.hpp | 1 + higan/phoenix/reference/widget/widget.cpp | 3 + higan/phoenix/reference/widget/widget.hpp | 1 + higan/phoenix/reference/window.cpp | 3 + higan/phoenix/reference/window.hpp | 1 + higan/ruby/video/cgl.cpp | 32 ++++++++- higan/sfc/profile-accuracy.hpp | 4 -- higan/sfc/profile-balanced.hpp | 4 -- higan/sfc/profile-performance.hpp | 4 -- higan/sfc/system/serialization.cpp | 4 +- higan/target-ethos/ethos.cpp | 18 +++-- higan/target-ethos/general/presentation.cpp | 8 ++- higan/target-ethos/settings/advanced.cpp | 10 +-- higan/target-ethos/utility/utility.cpp | 10 ++- 107 files changed, 441 insertions(+), 210 deletions(-) create mode 100644 higan/phoenix/cocoa/object.cpp create mode 100644 higan/phoenix/reference/object.cpp diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index a31d04ce..427e5333 100755 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -3,10 +3,18 @@ namespace Emulator { static const char Name[] = "higan"; - static const char Version[] = "092.04"; + static const char Version[] = "092.05"; static const char Author[] = "byuu"; static const char License[] = "GPLv3"; static const char Website[] = "http://byuu.org/"; + + #if defined(PROFILE_ACCURACY) + static const char Profile[] = "Accuracy"; + #elif defined(PROFILE_BALANCED) + static const char Profile[] = "Balanced"; + #elif defined(PROFILE_PERFORMANCE) + static const char Profile[] = "Performance"; + #endif } #include diff --git a/higan/phoenix/cocoa/action/action.hpp b/higan/phoenix/cocoa/action/action.hpp index f8a7325c..e7cf5707 100644 --- a/higan/phoenix/cocoa/action/action.hpp +++ b/higan/phoenix/cocoa/action/action.hpp @@ -2,7 +2,7 @@ namespace phoenix { struct pAction : public pObject { Action &action; - NSMenuItem *cocoaAction; + NSMenuItem *cocoaAction = nullptr; void setEnabled(bool enabled); void setVisible(bool visible); diff --git a/higan/phoenix/cocoa/action/check-item.cpp b/higan/phoenix/cocoa/action/check-item.cpp index 57c2ef0f..a35580b7 100644 --- a/higan/phoenix/cocoa/action/check-item.cpp +++ b/higan/phoenix/cocoa/action/check-item.cpp @@ -1,6 +1,6 @@ @implementation CocoaCheckItem : NSMenuItem --(id) initWith :(phoenix::CheckItem&)checkItemReference { +-(id) initWith:(phoenix::CheckItem&)checkItemReference { if(self = [super initWithTitle:@"" action:@selector(activate) keyEquivalent:@""]) { checkItem = &checkItemReference; diff --git a/higan/phoenix/cocoa/action/check-item.hpp b/higan/phoenix/cocoa/action/check-item.hpp index b3db94e5..72d39e5d 100644 --- a/higan/phoenix/cocoa/action/check-item.hpp +++ b/higan/phoenix/cocoa/action/check-item.hpp @@ -2,7 +2,7 @@ @public phoenix::CheckItem *checkItem; } --(id) initWith :(phoenix::CheckItem&)checkItem; +-(id) initWith:(phoenix::CheckItem&)checkItem; -(void) activate; @end @@ -10,7 +10,7 @@ namespace phoenix { struct pCheckItem : public pAction { CheckItem &checkItem; - CocoaCheckItem *cocoaCheckItem; + CocoaCheckItem *cocoaCheckItem = nullptr; bool checked(); void setChecked(bool checked); diff --git a/higan/phoenix/cocoa/action/item.cpp b/higan/phoenix/cocoa/action/item.cpp index 5ceea8ea..85db9ec6 100644 --- a/higan/phoenix/cocoa/action/item.cpp +++ b/higan/phoenix/cocoa/action/item.cpp @@ -1,6 +1,6 @@ @implementation CocoaItem : NSMenuItem --(id) initWith :(phoenix::Item&)itemReference { +-(id) initWith:(phoenix::Item&)itemReference { if(self = [super initWithTitle:@"" action:@selector(activate) keyEquivalent:@""]) { item = &itemReference; diff --git a/higan/phoenix/cocoa/action/item.hpp b/higan/phoenix/cocoa/action/item.hpp index 44ca7727..915d7e9c 100644 --- a/higan/phoenix/cocoa/action/item.hpp +++ b/higan/phoenix/cocoa/action/item.hpp @@ -2,7 +2,7 @@ @public phoenix::Item *item; } --(id) initWith :(phoenix::Item&)item; +-(id) initWith:(phoenix::Item&)item; -(void) activate; @end @@ -10,7 +10,7 @@ namespace phoenix { struct pItem : public pAction { Item &item; - CocoaItem *cocoaItem; + CocoaItem *cocoaItem = nullptr; void setImage(const image &image); void setText(const string &text); diff --git a/higan/phoenix/cocoa/action/menu.cpp b/higan/phoenix/cocoa/action/menu.cpp index 3ce66289..447b0054 100644 --- a/higan/phoenix/cocoa/action/menu.cpp +++ b/higan/phoenix/cocoa/action/menu.cpp @@ -1,6 +1,6 @@ @implementation CocoaMenu : NSMenuItem --(id) initWith :(phoenix::Menu&)menuReference { +-(id) initWith:(phoenix::Menu&)menuReference { if(self = [super initWithTitle:@"" action:nil keyEquivalent:@""]) { menu = &menuReference; diff --git a/higan/phoenix/cocoa/action/menu.hpp b/higan/phoenix/cocoa/action/menu.hpp index 51b3bf63..3d1d5e21 100644 --- a/higan/phoenix/cocoa/action/menu.hpp +++ b/higan/phoenix/cocoa/action/menu.hpp @@ -3,7 +3,7 @@ phoenix::Menu *menu; NSMenu *cocoaMenu; } --(id) initWith :(phoenix::Menu&)menu; +-(id) initWith:(phoenix::Menu&)menu; -(NSMenu*) cocoaMenu; @end @@ -11,7 +11,7 @@ namespace phoenix { struct pMenu : public pAction { Menu &menu; - CocoaMenu *cocoaMenu; + CocoaMenu *cocoaMenu = nullptr; void append(Action &action); void remove(Action &action); diff --git a/higan/phoenix/cocoa/action/radio-item.cpp b/higan/phoenix/cocoa/action/radio-item.cpp index 2fa3f207..7e10f949 100644 --- a/higan/phoenix/cocoa/action/radio-item.cpp +++ b/higan/phoenix/cocoa/action/radio-item.cpp @@ -1,6 +1,6 @@ @implementation CocoaRadioItem : NSMenuItem --(id) initWith :(phoenix::RadioItem&)radioItemReference { +-(id) initWith:(phoenix::RadioItem&)radioItemReference { if(self = [super initWithTitle:@"" action:@selector(activate) keyEquivalent:@""]) { radioItem = &radioItemReference; diff --git a/higan/phoenix/cocoa/action/radio-item.hpp b/higan/phoenix/cocoa/action/radio-item.hpp index 41d16669..4fe52f3b 100644 --- a/higan/phoenix/cocoa/action/radio-item.hpp +++ b/higan/phoenix/cocoa/action/radio-item.hpp @@ -2,7 +2,7 @@ @public phoenix::RadioItem *radioItem; } --(id) initWith :(phoenix::RadioItem&)radioItem; +-(id) initWith:(phoenix::RadioItem&)radioItem; -(void) activate; @end @@ -10,7 +10,7 @@ namespace phoenix { struct pRadioItem : public pAction { RadioItem &radioItem; - CocoaRadioItem *cocoaRadioItem; + CocoaRadioItem *cocoaRadioItem = nullptr; bool checked(); void setChecked(); diff --git a/higan/phoenix/cocoa/action/separator.hpp b/higan/phoenix/cocoa/action/separator.hpp index 9bb2bab4..6e426aba 100644 --- a/higan/phoenix/cocoa/action/separator.hpp +++ b/higan/phoenix/cocoa/action/separator.hpp @@ -2,7 +2,7 @@ namespace phoenix { struct pSeparator : public pAction { Separator &separator; - NSMenuItem *cocoaSeparator; + NSMenuItem *cocoaSeparator = nullptr; pSeparator(Separator &separator) : pAction(separator), separator(separator) {} void constructor(); diff --git a/higan/phoenix/cocoa/application.cpp b/higan/phoenix/cocoa/application.cpp index 0c57c72b..4bce9c9d 100644 --- a/higan/phoenix/cocoa/application.cpp +++ b/higan/phoenix/cocoa/application.cpp @@ -1,13 +1,19 @@ @implementation CocoaDelegate : NSObject --(NSApplicationTerminateReply) applicationShouldTerminate :(NSApplication*)sender { +-(NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication*)sender { using phoenix::Application; if(Application::Cocoa::onQuit) Application::Cocoa::onQuit(); else Application::quit(); return NSTerminateCancel; } --(void) run :(NSTimer*)timer { +-(BOOL) applicationShouldHandleReopen:(NSApplication*)application hasVisibleWindows:(BOOL)flag { + using phoenix::Application; + if(Application::Cocoa::onActivate) Application::Cocoa::onActivate(); + return NO; +} + +-(void) run:(NSTimer*)timer { using phoenix::Application; if(Application::main) Application::main(); } @@ -21,6 +27,9 @@ namespace phoenix { void pApplication::run() { if(Application::main) { NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:cocoaDelegate selector:@selector(run:) userInfo:nil repeats:YES]; + + //below line is needed to run application during window resize; however it has a large performance penalty on the resize smoothness + //[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSEventTrackingRunLoopMode]; } @autoreleasepool { [NSApp run]; diff --git a/higan/phoenix/cocoa/application.hpp b/higan/phoenix/cocoa/application.hpp index 6f34d728..76082727 100644 --- a/higan/phoenix/cocoa/application.hpp +++ b/higan/phoenix/cocoa/application.hpp @@ -1,7 +1,8 @@ @interface CocoaDelegate : NSObject { } --(NSApplicationTerminateReply) applicationShouldTerminate :(NSApplication*)sender; --(void) run :(NSTimer*)timer; +-(NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication*)sender; +-(BOOL) applicationShouldHandleReopen:(NSApplication*)application hasVisibleWindows:(BOOL)flag; +-(void) run:(NSTimer*)timer; @end namespace phoenix { diff --git a/higan/phoenix/cocoa/object.cpp b/higan/phoenix/cocoa/object.cpp new file mode 100644 index 00000000..d1397b10 --- /dev/null +++ b/higan/phoenix/cocoa/object.cpp @@ -0,0 +1,9 @@ +namespace phoenix { + +void pObject::constructor() { +} + +void pObject::destructor() { +} + +} diff --git a/higan/phoenix/cocoa/object.hpp b/higan/phoenix/cocoa/object.hpp index f5102b5b..232a9f84 100644 --- a/higan/phoenix/cocoa/object.hpp +++ b/higan/phoenix/cocoa/object.hpp @@ -7,8 +7,8 @@ struct pObject { pObject(Object &object) : object(object), locked(false) {} virtual ~pObject() {} - void constructor() {} - void destructor() {} + void constructor(); + void destructor(); }; } diff --git a/higan/phoenix/cocoa/platform.cpp b/higan/phoenix/cocoa/platform.cpp index edd588c2..159d3316 100644 --- a/higan/phoenix/cocoa/platform.cpp +++ b/higan/phoenix/cocoa/platform.cpp @@ -1,12 +1,13 @@ #include "platform.hpp" #include "utility.cpp" +#include "font.cpp" #include "desktop.cpp" #include "keyboard.cpp" #include "mouse.cpp" #include "browser-window.cpp" #include "message-window.cpp" -#include "font.cpp" +#include "object.cpp" #include "timer.cpp" #include "window.cpp" diff --git a/higan/phoenix/cocoa/timer.cpp b/higan/phoenix/cocoa/timer.cpp index 1b85bd65..cb132c5d 100644 --- a/higan/phoenix/cocoa/timer.cpp +++ b/higan/phoenix/cocoa/timer.cpp @@ -1,6 +1,6 @@ @implementation CocoaTimer : NSObject --(id) initWith :(phoenix::Timer&)timerReference { +-(id) initWith:(phoenix::Timer&)timerReference { if(self = [super init]) { timer = &timerReference; instance = nil; @@ -24,7 +24,7 @@ ]; } --(void) run :(NSTimer*)instance { +-(void) run:(NSTimer*)instance { if(timer->onActivate) timer->onActivate(); } diff --git a/higan/phoenix/cocoa/timer.hpp b/higan/phoenix/cocoa/timer.hpp index a4874bc0..729328fd 100644 --- a/higan/phoenix/cocoa/timer.hpp +++ b/higan/phoenix/cocoa/timer.hpp @@ -3,17 +3,17 @@ phoenix::Timer *timer; NSTimer *instance; } --(id) initWith :(phoenix::Timer&)timer; +-(id) initWith:(phoenix::Timer&)timer; -(NSTimer*) instance; -(void) update; --(void) run :(NSTimer*)instance; +-(void) run:(NSTimer*)instance; @end namespace phoenix { struct pTimer : public pObject { Timer &timer; - CocoaTimer *cocoaTimer; + CocoaTimer *cocoaTimer = nullptr; void setEnabled(bool enabled); void setInterval(unsigned milliseconds); diff --git a/higan/phoenix/cocoa/widget/button.cpp b/higan/phoenix/cocoa/widget/button.cpp index 24797731..8839bd8a 100644 --- a/higan/phoenix/cocoa/widget/button.cpp +++ b/higan/phoenix/cocoa/widget/button.cpp @@ -1,6 +1,6 @@ @implementation CocoaButton : NSButton --(id) initWith :(phoenix::Button&)buttonReference { +-(id) initWith:(phoenix::Button&)buttonReference { if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) { button = &buttonReference; [self setTarget:self]; @@ -11,7 +11,7 @@ return self; } --(IBAction) activate :(id)sender { +-(IBAction) activate:(id)sender { if(button->onActivate) button->onActivate(); } diff --git a/higan/phoenix/cocoa/widget/button.hpp b/higan/phoenix/cocoa/widget/button.hpp index 367ca19a..b48f46f8 100644 --- a/higan/phoenix/cocoa/widget/button.hpp +++ b/higan/phoenix/cocoa/widget/button.hpp @@ -2,15 +2,15 @@ @public phoenix::Button *button; } --(id) initWith :(phoenix::Button&)button; --(IBAction) activate :(id)sender; +-(id) initWith:(phoenix::Button&)button; +-(IBAction) activate:(id)sender; @end namespace phoenix { struct pButton : public pWidget { Button &button; - CocoaButton *cocoaButton; + CocoaButton *cocoaButton = nullptr; Size minimumSize(); void setImage(const image &image, Orientation orientation); diff --git a/higan/phoenix/cocoa/widget/canvas.cpp b/higan/phoenix/cocoa/widget/canvas.cpp index d7d654c5..fd895bc5 100644 --- a/higan/phoenix/cocoa/widget/canvas.cpp +++ b/higan/phoenix/cocoa/widget/canvas.cpp @@ -1,6 +1,6 @@ @implementation CocoaCanvas : NSImageView --(id) initWith :(phoenix::Canvas&)canvasReference { +-(id) initWith:(phoenix::Canvas&)canvasReference { if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) { canvas = &canvasReference; [self setEditable:NO]; //disable image drag-and-drop functionality @@ -13,7 +13,7 @@ return self; } --(void) mouseButton :(NSEvent*)event down:(BOOL)isDown { +-(void) mouseButton:(NSEvent*)event down:(BOOL)isDown { if(auto &callback = isDown ? canvas->onMousePress : canvas->onMouseRelease) { switch([event buttonNumber]) { case 0: return callback(phoenix::Mouse::Button::Left); @@ -23,49 +23,49 @@ } } --(void) mouseExited :(NSEvent*)event { +-(void) mouseExited:(NSEvent*)event { if(canvas->onMouseLeave) canvas->onMouseLeave(); } --(void) mouseMove :(NSEvent*)event { +-(void) mouseMove:(NSEvent*)event { if([event window] == nil) return; NSPoint location = [self convertPoint:[event locationInWindow] fromView:nil]; if(canvas->onMouseMove) canvas->onMouseMove({location.x, [self frame].size.height - 1 - location.y}); } --(void) mouseDown :(NSEvent*)event { +-(void) mouseDown:(NSEvent*)event { [self mouseButton:event down:YES]; } --(void) mouseUp :(NSEvent*)event { +-(void) mouseUp:(NSEvent*)event { [self mouseButton:event down:NO]; } --(void) mouseDragged :(NSEvent*)event { +-(void) mouseDragged:(NSEvent*)event { [self mouseMove:event]; } --(void) rightMouseDown :(NSEvent*)event { +-(void) rightMouseDown:(NSEvent*)event { [self mouseButton:event down:YES]; } --(void) rightMouseUp :(NSEvent*)event { +-(void) rightMouseUp:(NSEvent*)event { [self mouseButton:event down:NO]; } --(void) rightMouseDragged :(NSEvent*)event { +-(void) rightMouseDragged:(NSEvent*)event { [self mouseMove:event]; } --(void) otherMouseDown :(NSEvent*)event { +-(void) otherMouseDown:(NSEvent*)event { [self mouseButton:event down:YES]; } --(void) otherMouseUp :(NSEvent*)event { +-(void) otherMouseUp:(NSEvent*)event { [self mouseButton:event down:NO]; } --(void) otherMouseDragged :(NSEvent*)event { +-(void) otherMouseDragged:(NSEvent*)event { [self mouseMove:event]; } diff --git a/higan/phoenix/cocoa/widget/canvas.hpp b/higan/phoenix/cocoa/widget/canvas.hpp index d3fb3936..825506ae 100644 --- a/higan/phoenix/cocoa/widget/canvas.hpp +++ b/higan/phoenix/cocoa/widget/canvas.hpp @@ -3,25 +3,25 @@ phoenix::Canvas *canvas; } -(id) initWith:(phoenix::Canvas&)canvas; --(void) mouseButton :(NSEvent*)event down:(BOOL)isDown; --(void) mouseExited :(NSEvent*)event; --(void) mouseMove :(NSEvent*)event; --(void) mouseDown :(NSEvent*)event; --(void) mouseUp :(NSEvent*)event; --(void) mouseDragged :(NSEvent*)event; --(void) rightMouseDown :(NSEvent*)event; --(void) rightMouseUp :(NSEvent*)event; --(void) rightMouseDragged :(NSEvent*)event; --(void) otherMouseDown :(NSEvent*)event; --(void) otherMouseUp :(NSEvent*)event; --(void) otherMouseDragged :(NSEvent*)event; +-(void) mouseButton:(NSEvent*)event down:(BOOL)isDown; +-(void) mouseExited:(NSEvent*)event; +-(void) mouseMove:(NSEvent*)event; +-(void) mouseDown:(NSEvent*)event; +-(void) mouseUp:(NSEvent*)event; +-(void) mouseDragged:(NSEvent*)event; +-(void) rightMouseDown:(NSEvent*)event; +-(void) rightMouseUp:(NSEvent*)event; +-(void) rightMouseDragged:(NSEvent*)event; +-(void) otherMouseDown:(NSEvent*)event; +-(void) otherMouseUp:(NSEvent*)event; +-(void) otherMouseDragged:(NSEvent*)event; @end namespace phoenix { struct pCanvas : public pWidget { Canvas &canvas; - CocoaCanvas *cocoaCanvas; + CocoaCanvas *cocoaCanvas = nullptr; void setSize(const Size &size); void update(); diff --git a/higan/phoenix/cocoa/widget/check-button.cpp b/higan/phoenix/cocoa/widget/check-button.cpp index 68afe838..7ffe66eb 100644 --- a/higan/phoenix/cocoa/widget/check-button.cpp +++ b/higan/phoenix/cocoa/widget/check-button.cpp @@ -1,6 +1,6 @@ @implementation CocoaCheckButton : NSButton --(id) initWith :(phoenix::CheckButton&)checkButtonReference { +-(id) initWith:(phoenix::CheckButton&)checkButtonReference { if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) { checkButton = &checkButtonReference; @@ -11,7 +11,7 @@ return self; } --(IBAction) activate :(id)sender { +-(IBAction) activate:(id)sender { checkButton->state.checked = [self state] != NSOffState; if(checkButton->onToggle) checkButton->onToggle(); } diff --git a/higan/phoenix/cocoa/widget/check-button.hpp b/higan/phoenix/cocoa/widget/check-button.hpp index 52d240e5..c164b6f0 100644 --- a/higan/phoenix/cocoa/widget/check-button.hpp +++ b/higan/phoenix/cocoa/widget/check-button.hpp @@ -2,15 +2,15 @@ @public phoenix::CheckButton *checkButton; } --(id) initWith :(phoenix::CheckButton&)checkButton; --(IBAction) activate :(id)sender; +-(id) initWith:(phoenix::CheckButton&)checkButton; +-(IBAction) activate:(id)sender; @end namespace phoenix { struct pCheckButton : public pWidget { CheckButton &checkButton; - CocoaCheckButton *cocoaCheckButton; + CocoaCheckButton *cocoaCheckButton = nullptr; bool checked(); Size minimumSize(); diff --git a/higan/phoenix/cocoa/widget/combo-button.cpp b/higan/phoenix/cocoa/widget/combo-button.cpp index 72226cdb..2394bf9c 100644 --- a/higan/phoenix/cocoa/widget/combo-button.cpp +++ b/higan/phoenix/cocoa/widget/combo-button.cpp @@ -1,6 +1,6 @@ @implementation CocoaComboButton : NSPopUpButton --(id) initWith :(phoenix::ComboButton&)comboButtonReference { +-(id) initWith:(phoenix::ComboButton&)comboButtonReference { if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0) pullsDown:NO]) { comboButton = &comboButtonReference; @@ -10,7 +10,7 @@ return self; } --(IBAction) activate :(id)sender { +-(IBAction) activate:(id)sender { if(comboButton->onChange) comboButton->onChange(); } diff --git a/higan/phoenix/cocoa/widget/combo-button.hpp b/higan/phoenix/cocoa/widget/combo-button.hpp index 7701155c..a861c3e6 100644 --- a/higan/phoenix/cocoa/widget/combo-button.hpp +++ b/higan/phoenix/cocoa/widget/combo-button.hpp @@ -2,15 +2,15 @@ @public phoenix::ComboButton *comboButton; } --(id) initWith :(phoenix::ComboButton&)comboButton; --(IBAction) activate :(id)sender; +-(id) initWith:(phoenix::ComboButton&)comboButton; +-(IBAction) activate:(id)sender; @end namespace phoenix { struct pComboButton : public pWidget { ComboButton &comboButton; - CocoaComboButton *cocoaComboButton; + CocoaComboButton *cocoaComboButton = nullptr; void append(const string &text); Size minimumSize(); diff --git a/higan/phoenix/cocoa/widget/hex-edit.cpp b/higan/phoenix/cocoa/widget/hex-edit.cpp index 3330dc91..12f11036 100644 --- a/higan/phoenix/cocoa/widget/hex-edit.cpp +++ b/higan/phoenix/cocoa/widget/hex-edit.cpp @@ -1,6 +1,6 @@ @implementation CocoaHexEdit : NSScrollView --(id) initWith :(phoenix::HexEdit&)hexEditReference { +-(id) initWith:(phoenix::HexEdit&)hexEditReference { if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) { hexEdit = &hexEditReference; } diff --git a/higan/phoenix/cocoa/widget/hex-edit.hpp b/higan/phoenix/cocoa/widget/hex-edit.hpp index 0c240c48..707d2185 100644 --- a/higan/phoenix/cocoa/widget/hex-edit.hpp +++ b/higan/phoenix/cocoa/widget/hex-edit.hpp @@ -2,14 +2,14 @@ @public phoenix::HexEdit *hexEdit; } --(id) initWith :(phoenix::HexEdit&)hexEdit; +-(id) initWith:(phoenix::HexEdit&)hexEdit; @end namespace phoenix { struct pHexEdit : public pWidget { HexEdit &hexEdit; - CocoaHexEdit *cocoaHexEdit; + CocoaHexEdit *cocoaHexEdit = nullptr; void setColumns(unsigned columns); void setLength(unsigned length); diff --git a/higan/phoenix/cocoa/widget/horizontal-scroller.cpp b/higan/phoenix/cocoa/widget/horizontal-scroller.cpp index 67b59ffe..990eeecf 100644 --- a/higan/phoenix/cocoa/widget/horizontal-scroller.cpp +++ b/higan/phoenix/cocoa/widget/horizontal-scroller.cpp @@ -1,6 +1,6 @@ @implementation CocoaHorizontalScroller : NSScroller --(id) initWith :(phoenix::HorizontalScroller&)horizontalScrollerReference { +-(id) initWith:(phoenix::HorizontalScroller&)horizontalScrollerReference { if(self = [super initWithFrame:NSMakeRect(0, 0, 1, 0)]) { horizontalScroller = &horizontalScrollerReference; @@ -24,7 +24,7 @@ [self setKnobProportion:d]; } --(IBAction) scroll :(id)sender { +-(IBAction) scroll:(id)sender { auto &state = horizontalScroller->state; switch([self hitPart]) { diff --git a/higan/phoenix/cocoa/widget/horizontal-scroller.hpp b/higan/phoenix/cocoa/widget/horizontal-scroller.hpp index 1756705b..85299d49 100644 --- a/higan/phoenix/cocoa/widget/horizontal-scroller.hpp +++ b/higan/phoenix/cocoa/widget/horizontal-scroller.hpp @@ -2,16 +2,16 @@ @public phoenix::HorizontalScroller *horizontalScroller; } --(id) initWith :(phoenix::HorizontalScroller&)horizontalScroller; +-(id) initWith:(phoenix::HorizontalScroller&)horizontalScroller; -(void) update; --(IBAction) scroll :(id)sender; +-(IBAction) scroll:(id)sender; @end namespace phoenix { struct pHorizontalScroller : public pWidget { HorizontalScroller &horizontalScroller; - CocoaHorizontalScroller *cocoaHorizontalScroller; + CocoaHorizontalScroller *cocoaHorizontalScroller = nullptr; Size minimumSize(); unsigned position(); diff --git a/higan/phoenix/cocoa/widget/horizontal-slider.cpp b/higan/phoenix/cocoa/widget/horizontal-slider.cpp index aa0976ed..2636e95f 100644 --- a/higan/phoenix/cocoa/widget/horizontal-slider.cpp +++ b/higan/phoenix/cocoa/widget/horizontal-slider.cpp @@ -1,6 +1,6 @@ @implementation CocoaHorizontalSlider : NSSlider --(id) initWith :(phoenix::HorizontalSlider&)horizontalSliderReference { +-(id) initWith:(phoenix::HorizontalSlider&)horizontalSliderReference { if(self = [super initWithFrame:NSMakeRect(0, 0, 1, 0)]) { horizontalSlider = &horizontalSliderReference; @@ -11,7 +11,7 @@ return self; } --(IBAction) activate :(id)sender { +-(IBAction) activate:(id)sender { horizontalSlider->state.position = [self doubleValue]; if(horizontalSlider->onChange) horizontalSlider->onChange(); } diff --git a/higan/phoenix/cocoa/widget/horizontal-slider.hpp b/higan/phoenix/cocoa/widget/horizontal-slider.hpp index d60b6a0c..d5c5bf28 100644 --- a/higan/phoenix/cocoa/widget/horizontal-slider.hpp +++ b/higan/phoenix/cocoa/widget/horizontal-slider.hpp @@ -2,15 +2,15 @@ @public phoenix::HorizontalSlider *horizontalSlider; } --(id) initWith :(phoenix::HorizontalSlider&)horizontalSlider; --(IBAction) activate :(id)sender; +-(id) initWith:(phoenix::HorizontalSlider&)horizontalSlider; +-(IBAction) activate:(id)sender; @end namespace phoenix { struct pHorizontalSlider : public pWidget { HorizontalSlider &horizontalSlider; - CocoaHorizontalSlider *cocoaHorizontalSlider; + CocoaHorizontalSlider *cocoaHorizontalSlider = nullptr; Size minimumSize(); unsigned position(); diff --git a/higan/phoenix/cocoa/widget/label.cpp b/higan/phoenix/cocoa/widget/label.cpp index 24eb5e0e..b1794fd1 100644 --- a/higan/phoenix/cocoa/widget/label.cpp +++ b/higan/phoenix/cocoa/widget/label.cpp @@ -1,6 +1,6 @@ @implementation CocoaLabel : NSTextField --(id) initWith :(phoenix::Label&)labelReference { +-(id) initWith:(phoenix::Label&)labelReference { if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) { label = &labelReference; @@ -18,7 +18,7 @@ namespace phoenix { Size pLabel::minimumSize() { Size size = Font::size(label.font(), label.state.text); - return {size.width, size.height}; + return {size.width + 6, size.height}; } void pLabel::setText(const string &text) { diff --git a/higan/phoenix/cocoa/widget/label.hpp b/higan/phoenix/cocoa/widget/label.hpp index 69466ebf..197ca7a2 100644 --- a/higan/phoenix/cocoa/widget/label.hpp +++ b/higan/phoenix/cocoa/widget/label.hpp @@ -2,14 +2,14 @@ @public phoenix::Label *label; } --(id) initWith :(phoenix::Label&)label; +-(id) initWith:(phoenix::Label&)label; @end namespace phoenix { struct pLabel : public pWidget { Label &label; - CocoaLabel *cocoaLabel; + CocoaLabel *cocoaLabel = nullptr; Size minimumSize(); void setText(const string &text); diff --git a/higan/phoenix/cocoa/widget/line-edit.cpp b/higan/phoenix/cocoa/widget/line-edit.cpp index 9e68cfe7..b1befe94 100644 --- a/higan/phoenix/cocoa/widget/line-edit.cpp +++ b/higan/phoenix/cocoa/widget/line-edit.cpp @@ -1,6 +1,6 @@ @implementation CocoaLineEdit : NSTextField --(id) initWith :(phoenix::LineEdit&)lineEditReference { +-(id) initWith:(phoenix::LineEdit&)lineEditReference { if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) { lineEdit = &lineEditReference; @@ -14,11 +14,11 @@ return self; } --(void) textDidChange :(NSNotification*)n { +-(void) textDidChange:(NSNotification*)n { if(lineEdit->onChange) lineEdit->onChange(); } --(IBAction) activate :(id)sender { +-(IBAction) activate:(id)sender { if(lineEdit->onActivate) lineEdit->onActivate(); } diff --git a/higan/phoenix/cocoa/widget/line-edit.hpp b/higan/phoenix/cocoa/widget/line-edit.hpp index 97cfe7c6..25aaf7d3 100644 --- a/higan/phoenix/cocoa/widget/line-edit.hpp +++ b/higan/phoenix/cocoa/widget/line-edit.hpp @@ -2,16 +2,16 @@ @public phoenix::LineEdit *lineEdit; } --(id) initWith :(phoenix::LineEdit&)lineEdit; --(void) textDidChange :(NSNotification*)n; --(IBAction) activate :(id)sender; +-(id) initWith:(phoenix::LineEdit&)lineEdit; +-(void) textDidChange:(NSNotification*)n; +-(IBAction) activate:(id)sender; @end namespace phoenix { struct pLineEdit : public pWidget { LineEdit &lineEdit; - CocoaLineEdit *cocoaLineEdit; + CocoaLineEdit *cocoaLineEdit = nullptr; Size minimumSize(); void setEditable(bool editable); diff --git a/higan/phoenix/cocoa/widget/list-view.cpp b/higan/phoenix/cocoa/widget/list-view.cpp index f8bf1042..98e640eb 100644 --- a/higan/phoenix/cocoa/widget/list-view.cpp +++ b/higan/phoenix/cocoa/widget/list-view.cpp @@ -1,6 +1,6 @@ @implementation CocoaListView : NSScrollView --(id) initWith :(phoenix::ListView&)listViewReference { +-(id) initWith:(phoenix::ListView&)listViewReference { if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) { listView = &listViewReference; content = [[CocoaListViewContent alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)]; @@ -12,14 +12,14 @@ [content setDataSource:self]; [content setDelegate:self]; [content setTarget:self]; - [content setDoubleAction:@selector(activate:)]; + [content setDoubleAction:@selector(doubleAction:)]; [content setAllowsColumnReordering:NO]; [content setAllowsColumnResizing:YES]; [content setAllowsColumnSelection:NO]; [content setAllowsEmptySelection:YES]; [content setAllowsMultipleSelection:NO]; - [content setColumnAutoresizingStyle:NSTableViewNoColumnAutoresizing]; + [content setColumnAutoresizingStyle:NSTableViewLastColumnOnlyAutoresizingStyle]; font = nil; [self setFont:nil]; @@ -41,7 +41,7 @@ return font; } --(void) setFont :(NSFont*)fontPointer { +-(void) setFont:(NSFont*)fontPointer { if(!fontPointer) fontPointer = [NSFont systemFontOfSize:12]; [fontPointer retain]; if(font) [font release]; @@ -94,11 +94,11 @@ } } --(NSInteger) numberOfRowsInTableView :(NSTableView*)table { +-(NSInteger) numberOfRowsInTableView:(NSTableView*)table { return listView->state.text.size(); } --(id) tableView :(NSTableView*)table objectValueForTableColumn :(NSTableColumn*)tableColumn row:(NSInteger)row { +-(id) tableView:(NSTableView*)table objectValueForTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row { if([[tableColumn identifier] isEqualToString:@"check"]) { auto checked = listView->state.checked(row) ? NSOnState : NSOffState; return [NSNumber numberWithInteger:checked]; @@ -114,37 +114,53 @@ return @{ @"text":text }; } --(void) tableView :(NSTableView*)table setObjectValue:(id)object forTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row { +-(BOOL) tableView:(NSTableView*)table shouldShowCellExpansionForTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row { + return NO; +} + +-(NSString*) tableView:(NSTableView*)table toolTipForCell:(NSCell*)cell rect:(NSRectPointer)rect tableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row mouseLocation:(NSPoint)mouseLocation { + return nil; +} + +-(void) tableView:(NSTableView*)table setObjectValue:(id)object forTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row { if([[tableColumn identifier] isEqualToString:@"check"]) { listView->state.checked(row) = [object integerValue] != NSOffState; if(listView->onToggle) listView->onToggle(row); } } --(void) tableView :(NSTableView*)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row { +-(void) tableView:(NSTableView*)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row { [cell setFont:[self font]]; } --(void) tableViewSelectionDidChange :(NSNotification*)notification { +-(void) tableViewSelectionDidChange:(NSNotification*)notification { if(listView->onChange) listView->onChange(); } --(IBAction) activate :(id)sender { - if([content clickedRow] < 0) return; +-(IBAction) activate:(id)sender { if(listView->onActivate) listView->onActivate(); } +-(IBAction) doubleAction:(id)sender { + if([content clickedRow] >= 0) { + [self activate:self]; + } +} + @end @implementation CocoaListViewContent : NSTableView --(void) keyDown :(NSEvent*)event { - [super keyDown:event]; - +-(void) keyDown:(NSEvent*)event { auto character = [[event characters] characterAtIndex:0]; if(character == NSEnterCharacter || character == NSCarriageReturnCharacter) { - [[self delegate] activate:self]; + if([self selectedRow] >= 0) { + [[self delegate] activate:self]; + return; + } } + + [super keyDown:event]; } @end @@ -156,7 +172,7 @@ return [[self objectValue] objectForKey:@"text"]; } --(void) drawWithFrame :(NSRect)frame inView:(NSView*)view { +-(void) drawWithFrame:(NSRect)frame inView:(NSView*)view { NSString *text = [[self objectValue] objectForKey:@"text"]; NSImage *image = [[self objectValue] objectForKey:@"image"]; unsigned textDisplacement = 0; @@ -206,7 +222,7 @@ void pListView::autoSizeColumns() { } unsigned height = [[cocoaView content] rowHeight]; - for(unsigned column = 0; column < listView.state.headerText.size(); column++) { + for(unsigned column = 0; column < max(1u, listView.state.headerText.size()); column++) { NSTableColumn *tableColumn = [[cocoaView content] tableColumnWithIdentifier:[[NSNumber numberWithInteger:column] stringValue]]; unsigned minimumWidth = pFont::size([[tableColumn headerCell] font], listView.state.headerText(column)).width + 4; for(unsigned row = 0; row < listView.state.text.size(); row++) { @@ -216,6 +232,8 @@ void pListView::autoSizeColumns() { } [tableColumn setWidth:minimumWidth]; } + + [[cocoaView content] sizeLastColumnToFit]; } } diff --git a/higan/phoenix/cocoa/widget/list-view.hpp b/higan/phoenix/cocoa/widget/list-view.hpp index 5d794d3b..d60f1d8c 100644 --- a/higan/phoenix/cocoa/widget/list-view.hpp +++ b/higan/phoenix/cocoa/widget/list-view.hpp @@ -6,36 +6,39 @@ CocoaListViewContent *content; NSFont *font; } --(id) initWith :(phoenix::ListView&)listView; +-(id) initWith:(phoenix::ListView&)listView; -(void) dealloc; -(CocoaListViewContent*) content; -(NSFont*) font; --(void) setFont :(NSFont*)font; +-(void) setFont:(NSFont*)font; -(void) reloadColumns; --(NSInteger) numberOfRowsInTableView :(NSTableView*)table; --(id) tableView :(NSTableView*)table objectValueForTableColumn :(NSTableColumn*)tableColumn row:(NSInteger)row; --(void) tableView :(NSTableView*)table setObjectValue:(id)object forTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row; --(void) tableView :(NSTableView*)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row; --(void) tableViewSelectionDidChange :(NSNotification*)notification; --(IBAction) activate :(id)sender; +-(NSInteger) numberOfRowsInTableView:(NSTableView*)table; +-(id) tableView:(NSTableView*)table objectValueForTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row; +-(BOOL) tableView:(NSTableView*)table shouldShowCellExpansionForTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row; +-(NSString*) tableView:(NSTableView*)table toolTipForCell:(NSCell*)cell rect:(NSRectPointer)rect tableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row mouseLocation:(NSPoint)mouseLocation; +-(void) tableView:(NSTableView*)table setObjectValue:(id)object forTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row; +-(void) tableView:(NSTableView*)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row; +-(void) tableViewSelectionDidChange:(NSNotification*)notification; +-(IBAction) activate:(id)sender; +-(IBAction) doubleAction:(id)sender; @end @interface CocoaListViewContent : NSTableView { } --(void) keyDown :(NSEvent*)event; +-(void) keyDown:(NSEvent*)event; @end @interface CocoaListViewCell : NSTextFieldCell { } -(NSString*) stringValue; --(void) drawWithFrame :(NSRect)frame inView:(NSView*)view; +-(void) drawWithFrame:(NSRect)frame inView:(NSView*)view; @end namespace phoenix { struct pListView : public pWidget { ListView &listView; - CocoaListView *cocoaListView; + CocoaListView *cocoaListView = nullptr; void append(const lstring &text); void autoSizeColumns(); diff --git a/higan/phoenix/cocoa/widget/progress-bar.cpp b/higan/phoenix/cocoa/widget/progress-bar.cpp index 6a4cad1e..1144af01 100644 --- a/higan/phoenix/cocoa/widget/progress-bar.cpp +++ b/higan/phoenix/cocoa/widget/progress-bar.cpp @@ -1,6 +1,6 @@ @implementation CocoaProgressBar : NSProgressIndicator --(id) initWith :(phoenix::ProgressBar&)progressBarReference { +-(id) initWith:(phoenix::ProgressBar&)progressBarReference { if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) { progressBar = &progressBarReference; diff --git a/higan/phoenix/cocoa/widget/progress-bar.hpp b/higan/phoenix/cocoa/widget/progress-bar.hpp index 7fd43079..20fa6baa 100644 --- a/higan/phoenix/cocoa/widget/progress-bar.hpp +++ b/higan/phoenix/cocoa/widget/progress-bar.hpp @@ -2,14 +2,14 @@ @public phoenix::ProgressBar *progressBar; } --(id) initWith :(phoenix::ProgressBar&)progressBar; +-(id) initWith:(phoenix::ProgressBar&)progressBar; @end namespace phoenix { struct pProgressBar : public pWidget { ProgressBar &progressBar; - CocoaProgressBar *cocoaProgressBar; + CocoaProgressBar *cocoaProgressBar = nullptr; void setPosition(unsigned position); diff --git a/higan/phoenix/cocoa/widget/radio-button.cpp b/higan/phoenix/cocoa/widget/radio-button.cpp index 77ba67e0..992b8282 100644 --- a/higan/phoenix/cocoa/widget/radio-button.cpp +++ b/higan/phoenix/cocoa/widget/radio-button.cpp @@ -1,6 +1,6 @@ @implementation CocoaRadioButton : NSButton --(id) initWith :(phoenix::RadioButton&)radioButtonReference { +-(id) initWith:(phoenix::RadioButton&)radioButtonReference { if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) { radioButton = &radioButtonReference; @@ -11,7 +11,7 @@ return self; } --(IBAction) activate :(id)sender { +-(IBAction) activate:(id)sender { radioButton->setChecked(); if(radioButton->onActivate) radioButton->onActivate(); } diff --git a/higan/phoenix/cocoa/widget/radio-button.hpp b/higan/phoenix/cocoa/widget/radio-button.hpp index 3c0a6658..63beec59 100644 --- a/higan/phoenix/cocoa/widget/radio-button.hpp +++ b/higan/phoenix/cocoa/widget/radio-button.hpp @@ -2,14 +2,15 @@ @public phoenix::RadioButton *radioButton; } --(id) initWith :(phoenix::RadioButton&)radioButton; +-(id) initWith:(phoenix::RadioButton&)radioButton; +-(IBAction) activate:(id)sender; @end namespace phoenix { struct pRadioButton : public pWidget { RadioButton &radioButton; - CocoaRadioButton *cocoaRadioButton; + CocoaRadioButton *cocoaRadioButton = nullptr; bool checked(); Size minimumSize(); diff --git a/higan/phoenix/cocoa/widget/text-edit.cpp b/higan/phoenix/cocoa/widget/text-edit.cpp index 36dde2a9..9312d139 100644 --- a/higan/phoenix/cocoa/widget/text-edit.cpp +++ b/higan/phoenix/cocoa/widget/text-edit.cpp @@ -1,6 +1,6 @@ @implementation CocoaTextEdit : NSScrollView --(id) initWith :(phoenix::TextEdit&)textEditReference { +-(id) initWith:(phoenix::TextEdit&)textEditReference { if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0)]) { textEdit = &textEditReference; @@ -34,7 +34,7 @@ [self setHasVerticalScroller:YES]; } --(void) textDidChange :(NSNotification*)notification { +-(void) textDidChange:(NSNotification*)notification { textEdit->state.text = [[content string] UTF8String]; if(textEdit->onChange) textEdit->onChange(); } diff --git a/higan/phoenix/cocoa/widget/text-edit.hpp b/higan/phoenix/cocoa/widget/text-edit.hpp index 2b58f62a..45764171 100644 --- a/higan/phoenix/cocoa/widget/text-edit.hpp +++ b/higan/phoenix/cocoa/widget/text-edit.hpp @@ -3,17 +3,17 @@ phoenix::TextEdit *textEdit; NSTextView *content; } --(id) initWith :(phoenix::TextEdit&)textEdit; +-(id) initWith:(phoenix::TextEdit&)textEdit; -(NSTextView*) content; -(void) configure; --(void) textDidChange :(NSNotification*)notification; +-(void) textDidChange:(NSNotification*)notification; @end namespace phoenix { struct pTextEdit : public pWidget { TextEdit &textEdit; - CocoaTextEdit *cocoaTextEdit; + CocoaTextEdit *cocoaTextEdit = nullptr; void setCursorPosition(unsigned position); void setEditable(bool editable); diff --git a/higan/phoenix/cocoa/widget/vertical-scroller.cpp b/higan/phoenix/cocoa/widget/vertical-scroller.cpp index 830eb52b..0783be05 100644 --- a/higan/phoenix/cocoa/widget/vertical-scroller.cpp +++ b/higan/phoenix/cocoa/widget/vertical-scroller.cpp @@ -1,6 +1,6 @@ @implementation CocoaVerticalScroller : NSScroller --(id) initWith :(phoenix::VerticalScroller&)verticalScrollerReference { +-(id) initWith:(phoenix::VerticalScroller&)verticalScrollerReference { if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 1)]) { verticalScroller = &verticalScrollerReference; @@ -24,7 +24,7 @@ [self setKnobProportion:d]; } --(IBAction) scroll :(id)sender { +-(IBAction) scroll:(id)sender { auto &state = verticalScroller->state; switch([self hitPart]) { diff --git a/higan/phoenix/cocoa/widget/vertical-scroller.hpp b/higan/phoenix/cocoa/widget/vertical-scroller.hpp index ad2d87aa..5298ff13 100644 --- a/higan/phoenix/cocoa/widget/vertical-scroller.hpp +++ b/higan/phoenix/cocoa/widget/vertical-scroller.hpp @@ -2,14 +2,16 @@ @public phoenix::VerticalScroller *verticalScroller; } --(id) initWith :(phoenix::VerticalScroller&)verticalScroller; +-(id) initWith:(phoenix::VerticalScroller&)verticalScroller; +-(void) update; +-(IBAction) scroll:(id)sender; @end namespace phoenix { struct pVerticalScroller : public pWidget { VerticalScroller &verticalScroller; - CocoaVerticalScroller *cocoaVerticalScroller; + CocoaVerticalScroller *cocoaVerticalScroller = nullptr; Size minimumSize(); unsigned position(); diff --git a/higan/phoenix/cocoa/widget/vertical-slider.cpp b/higan/phoenix/cocoa/widget/vertical-slider.cpp index dadd07f9..189cc560 100644 --- a/higan/phoenix/cocoa/widget/vertical-slider.cpp +++ b/higan/phoenix/cocoa/widget/vertical-slider.cpp @@ -1,6 +1,6 @@ @implementation CocoaVerticalSlider : NSSlider --(id) initWith :(phoenix::VerticalSlider&)verticalSliderReference { +-(id) initWith:(phoenix::VerticalSlider&)verticalSliderReference { if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 1)]) { verticalSlider = &verticalSliderReference; @@ -11,7 +11,7 @@ return self; } --(IBAction) activate :(id)sender { +-(IBAction) activate:(id)sender { verticalSlider->state.position = [self doubleValue]; if(verticalSlider->onChange) verticalSlider->onChange(); } diff --git a/higan/phoenix/cocoa/widget/vertical-slider.hpp b/higan/phoenix/cocoa/widget/vertical-slider.hpp index dfcb8e69..5f4ef818 100644 --- a/higan/phoenix/cocoa/widget/vertical-slider.hpp +++ b/higan/phoenix/cocoa/widget/vertical-slider.hpp @@ -2,15 +2,15 @@ @public phoenix::VerticalSlider *verticalSlider; } --(id) initWith :(phoenix::VerticalSlider&)verticalSlider; --(IBAction) activate :(id)sender; +-(id) initWith:(phoenix::VerticalSlider&)verticalSlider; +-(IBAction) activate:(id)sender; @end namespace phoenix { struct pVerticalSlider : public pWidget { VerticalSlider &verticalSlider; - CocoaVerticalSlider *cocoaVerticalSlider; + CocoaVerticalSlider *cocoaVerticalSlider = nullptr; Size minimumSize(); unsigned position(); diff --git a/higan/phoenix/cocoa/widget/viewport.cpp b/higan/phoenix/cocoa/widget/viewport.cpp index 14ee816a..5e2a5db4 100644 --- a/higan/phoenix/cocoa/widget/viewport.cpp +++ b/higan/phoenix/cocoa/widget/viewport.cpp @@ -1,16 +1,25 @@ @implementation CocoaViewport : NSView --(id) initWith :(phoenix::Viewport&)viewportReference { +-(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]); +-(void) drawRect:(NSRect)rect { + [[NSColor blackColor] setFill]; + NSRectFillUsingOperation(rect, NSCompositeSourceOver); +} + +-(BOOL) acceptsFirstResponder { + return YES; +} + +-(void) keyDown:(NSEvent*)event { +} + +-(void) keyUp:(NSEvent*)event { } @end diff --git a/higan/phoenix/cocoa/widget/viewport.hpp b/higan/phoenix/cocoa/widget/viewport.hpp index f4eb3306..f38addb7 100644 --- a/higan/phoenix/cocoa/widget/viewport.hpp +++ b/higan/phoenix/cocoa/widget/viewport.hpp @@ -2,15 +2,18 @@ @public phoenix::Viewport *viewport; } --(id) initWith :(phoenix::Viewport&)viewport; --(void) drawRect :(NSRect)rect; +-(id) initWith:(phoenix::Viewport&)viewport; +-(void) drawRect:(NSRect)rect; +-(BOOL) acceptsFirstResponder; +-(void) keyDown:(NSEvent*)event; +-(void) keyUp:(NSEvent*)event; @end namespace phoenix { struct pViewport : public pWidget { Viewport &viewport; - CocoaViewport *cocoaViewport; + CocoaViewport *cocoaViewport = nullptr; uintptr_t handle(); diff --git a/higan/phoenix/cocoa/widget/widget.hpp b/higan/phoenix/cocoa/widget/widget.hpp index d0dc99a2..d3a8bf9d 100644 --- a/higan/phoenix/cocoa/widget/widget.hpp +++ b/higan/phoenix/cocoa/widget/widget.hpp @@ -2,7 +2,7 @@ namespace phoenix { struct pWidget : public pSizable { Widget &widget; - NSView *cocoaView; + NSView *cocoaView = nullptr; bool enabled(); bool focused(); diff --git a/higan/phoenix/cocoa/window.cpp b/higan/phoenix/cocoa/window.cpp index 9647932c..d96fc1d8 100644 --- a/higan/phoenix/cocoa/window.cpp +++ b/higan/phoenix/cocoa/window.cpp @@ -1,6 +1,6 @@ @implementation CocoaWindow : NSWindow --(id) initWith :(phoenix::Window&)windowReference { +-(id) initWith:(phoenix::Window&)windowReference { window = &windowReference; NSUInteger style = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask; @@ -10,7 +10,6 @@ [self setDelegate:self]; [self setReleasedWhenClosed:NO]; [self setAcceptsMouseMovedEvents:YES]; - [self setLevel:NSFloatingWindowLevel]; //when launched from a terminal, this places the window above it [self setTitle:@""]; menuBar = [[NSMenu alloc] init]; @@ -35,6 +34,16 @@ text = {"Quit ", phoenix::applicationState.name}; item = [[[NSMenuItem alloc] initWithTitle:[NSString stringWithUTF8String:text] action:@selector(menuQuit) keyEquivalent:@""] autorelease]; [rootMenu addItem:item]; + + statusBar = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)]; + [statusBar setAlignment:NSLeftTextAlignment]; + [statusBar setBordered:YES]; + [statusBar setBezeled:YES]; + [statusBar setBezelStyle:NSTextFieldSquareBezel]; + [statusBar setEditable:NO]; + [statusBar setHidden:YES]; + + [[self contentView] addSubview:statusBar positioned:NSWindowBelow relativeTo:nil]; } return self; @@ -48,21 +57,21 @@ return YES; } --(void) windowDidBecomeMain :(NSNotification*)notification { +-(void) windowDidBecomeMain:(NSNotification*)notification { if(window->state.menu.size() > 0) { [NSApp setMainMenu:menuBar]; } } --(void) windowDidMove :(NSNotification*)notification { +-(void) windowDidMove:(NSNotification*)notification { window->p.moveEvent(); } --(void) windowDidResize :(NSNotification*)notification { +-(void) windowDidResize:(NSNotification*)notification { window->p.sizeEvent(); } --(BOOL) windowShouldClose :(id)sender { +-(BOOL) windowShouldClose:(id)sender { if(window->onClose) window->onClose(); else window->setVisible(false); if(window->state.modal && !window->visible()) window->setModal(false); @@ -88,6 +97,10 @@ if(Application::Cocoa::onQuit) Application::Cocoa::onQuit(); } +-(NSTextField*) statusBar { + return statusBar; +} + @end namespace phoenix { @@ -102,6 +115,8 @@ void pWindow::append(Layout &layout) { Geometry geometry = window.state.geometry; geometry.x = geometry.y = 0; layout.setGeometry(geometry); + + statusBarReposition(); } void pWindow::append(Menu &menu) { @@ -117,7 +132,7 @@ void pWindow::append(Widget &widget) { @autoreleasepool { [widget.p.cocoaView removeFromSuperview]; - [[cocoaWindow contentView] addSubview:widget.p.cocoaView positioned:NSWindowAbove relativeTo:nil]; + [[cocoaWindow contentView] addSubview:widget.p.cocoaView positioned:NSWindowBelow relativeTo:nil]; widget.p.setGeometry(widget.geometry()); [[cocoaWindow contentView] setNeedsDisplay:YES]; } @@ -151,6 +166,7 @@ Geometry pWindow::frameMargin() { Geometry pWindow::geometry() { @autoreleasepool { NSRect area = [cocoaWindow contentRectForFrameRect:[cocoaWindow frame]]; + area.size.height -= statusBarHeight(); return {area.origin.x, Desktop::size().height - area.origin.y - area.size.height, area.size.width, area.size.height}; } } @@ -213,7 +229,10 @@ void pWindow::setGeometry(const Geometry &geometry) { @autoreleasepool { [cocoaWindow setFrame:[cocoaWindow - frameRectForContentRect:NSMakeRect(geometry.x, Desktop::size().height - geometry.y - geometry.height, geometry.width, geometry.height) + frameRectForContentRect:NSMakeRect( + geometry.x, Desktop::size().height - geometry.y - geometry.height, + geometry.width, geometry.height + statusBarHeight() + ) ] display:YES ]; @@ -223,6 +242,8 @@ void pWindow::setGeometry(const Geometry &geometry) { geometry.x = geometry.y = 0; layout.setGeometry(geometry); } + + statusBarReposition(); } locked = false; @@ -255,12 +276,23 @@ void pWindow::setResizable(bool resizable) { } void pWindow::setStatusFont(const string &font) { + @autoreleasepool { + [[cocoaWindow statusBar] setFont:pFont::cocoaFont(font)]; + } + statusBarReposition(); } void pWindow::setStatusText(const string &text) { + @autoreleasepool { + [[cocoaWindow statusBar] setStringValue:[NSString stringWithUTF8String:text]]; + } } void pWindow::setStatusVisible(bool visible) { + @autoreleasepool { + [[cocoaWindow statusBar] setHidden:!visible]; + setGeometry(geometry()); + } } void pWindow::setTitle(const string &text) { @@ -271,12 +303,8 @@ void pWindow::setTitle(const string &text) { void pWindow::setVisible(bool visible) { @autoreleasepool { - if(visible) { - [cocoaWindow makeKeyAndOrderFront:nil]; - [cocoaWindow setLevel:NSNormalWindowLevel]; - } else { - [cocoaWindow orderOut:nil]; - } + if(visible) [cocoaWindow makeKeyAndOrderFront:nil]; + else [cocoaWindow orderOut:nil]; } } @@ -320,9 +348,24 @@ void pWindow::sizeEvent() { layout.setGeometry(geometry); } + statusBarReposition(); + if(locked == false) { if(window.onSize) window.onSize(); } } +unsigned pWindow::statusBarHeight() { + if(!window.state.statusVisible) return 0; + return Font::size(window.state.statusFont, " ").height + 6; +} + +void pWindow::statusBarReposition() { + @autoreleasepool { + NSRect area = [cocoaWindow contentRectForFrameRect:[cocoaWindow frame]]; + [[cocoaWindow statusBar] setFrame:NSMakeRect(0, 0, area.size.width, statusBarHeight())]; + [[cocoaWindow contentView] setNeedsDisplay:YES]; + } +} + } diff --git a/higan/phoenix/cocoa/window.hpp b/higan/phoenix/cocoa/window.hpp index 59759a2a..ddfc0c15 100644 --- a/higan/phoenix/cocoa/window.hpp +++ b/higan/phoenix/cocoa/window.hpp @@ -3,25 +3,27 @@ phoenix::Window *window; NSMenu *menuBar; NSMenu *rootMenu; + NSTextField *statusBar; } --(id) initWith :(phoenix::Window&)window; +-(id) initWith:(phoenix::Window&)window; -(BOOL) canBecomeKeyWindow; -(BOOL) canBecomeMainWindow; --(void) windowDidBecomeMain :(NSNotification*)notification; --(void) windowDidMove :(NSNotification*)notification; --(void) windowDidResize :(NSNotification*)notification; --(BOOL) windowShouldClose :(id)sender; +-(void) windowDidBecomeMain:(NSNotification*)notification; +-(void) windowDidMove:(NSNotification*)notification; +-(void) windowDidResize:(NSNotification*)notification; +-(BOOL) windowShouldClose:(id)sender; -(NSMenu*) menuBar; -(void) menuAbout; -(void) menuPreferences; -(void) menuQuit; +-(NSTextField*) statusBar; @end namespace phoenix { struct pWindow : public pObject { Window &window; - CocoaWindow *cocoaWindow; + CocoaWindow *cocoaWindow = nullptr; static Window& none(); @@ -55,6 +57,8 @@ struct pWindow : public pObject { void destructor(); void moveEvent(); void sizeEvent(); + unsigned statusBarHeight(); + void statusBarReposition(); }; } diff --git a/higan/phoenix/core/core.cpp b/higan/phoenix/core/core.cpp index ce3da3aa..9c542fd4 100755 --- a/higan/phoenix/core/core.cpp +++ b/higan/phoenix/core/core.cpp @@ -37,11 +37,12 @@ namespace phoenix { //Application //=========== -nall::function Application::main; +function Application::main; -nall::function Application::Cocoa::onAbout; -nall::function Application::Cocoa::onPreferences; -nall::function Application::Cocoa::onQuit; +function Application::Cocoa::onAbout; +function Application::Cocoa::onActivate; +function Application::Cocoa::onPreferences; +function Application::Cocoa::onQuit; void Application::run() { return pApplication::run(); diff --git a/higan/phoenix/core/core.hpp b/higan/phoenix/core/core.hpp index 82d89e9f..018d7295 100755 --- a/higan/phoenix/core/core.hpp +++ b/higan/phoenix/core/core.hpp @@ -65,6 +65,7 @@ struct Application { struct Cocoa { static nall::function onAbout; + static nall::function onActivate; static nall::function onPreferences; static nall::function onQuit; }; diff --git a/higan/phoenix/reference/action/action.cpp b/higan/phoenix/reference/action/action.cpp index 87320a55..320911d3 100755 --- a/higan/phoenix/reference/action/action.cpp +++ b/higan/phoenix/reference/action/action.cpp @@ -9,4 +9,7 @@ void pAction::setVisible(bool visible) { void pAction::constructor() { } +void pAction::destructor() { +} + } diff --git a/higan/phoenix/reference/action/action.hpp b/higan/phoenix/reference/action/action.hpp index 936afae0..c9dbdb0a 100644 --- a/higan/phoenix/reference/action/action.hpp +++ b/higan/phoenix/reference/action/action.hpp @@ -8,6 +8,7 @@ struct pAction : public pObject { pAction(Action &action) : pObject(action), action(action) {} void constructor(); + void destructor(); }; } diff --git a/higan/phoenix/reference/object.cpp b/higan/phoenix/reference/object.cpp new file mode 100644 index 00000000..d1397b10 --- /dev/null +++ b/higan/phoenix/reference/object.cpp @@ -0,0 +1,9 @@ +namespace phoenix { + +void pObject::constructor() { +} + +void pObject::destructor() { +} + +} diff --git a/higan/phoenix/reference/object.hpp b/higan/phoenix/reference/object.hpp index 6958a5fb..cd13fd20 100644 --- a/higan/phoenix/reference/object.hpp +++ b/higan/phoenix/reference/object.hpp @@ -7,8 +7,8 @@ struct pObject { pObject(Object &object) : object(object), locked(locked) {} virtual ~pObject() {} - void constructor() {} - void destructor() {} + void constructor(); + void destructor(); }; } diff --git a/higan/phoenix/reference/platform.cpp b/higan/phoenix/reference/platform.cpp index 06041a67..22e51dd2 100755 --- a/higan/phoenix/reference/platform.cpp +++ b/higan/phoenix/reference/platform.cpp @@ -1,11 +1,12 @@ #include "platform.hpp" +#include "font.cpp" #include "desktop.cpp" #include "keyboard.cpp" #include "mouse.cpp" #include "browser-window.cpp" #include "message-window.cpp" -#include "font.cpp" +#include "object.cpp" #include "timer.cpp" #include "window.cpp" diff --git a/higan/phoenix/reference/timer.cpp b/higan/phoenix/reference/timer.cpp index 66681688..abe06080 100755 --- a/higan/phoenix/reference/timer.cpp +++ b/higan/phoenix/reference/timer.cpp @@ -9,4 +9,7 @@ void pTimer::setInterval(unsigned milliseconds) { void pTimer::constructor() { } +void pTimer::destructor() { +} + } diff --git a/higan/phoenix/reference/timer.hpp b/higan/phoenix/reference/timer.hpp index b4c296bc..d8aac74c 100644 --- a/higan/phoenix/reference/timer.hpp +++ b/higan/phoenix/reference/timer.hpp @@ -8,6 +8,7 @@ struct pTimer : public pObject { pTimer(Timer &timer) : pObject(timer), timer(timer) {} void constructor(); + void destructor(); }; } diff --git a/higan/phoenix/reference/widget/button.cpp b/higan/phoenix/reference/widget/button.cpp index 1a9cdc08..99b9e109 100755 --- a/higan/phoenix/reference/widget/button.cpp +++ b/higan/phoenix/reference/widget/button.cpp @@ -9,4 +9,7 @@ void pButton::setText(const string &text) { void pButton::constructor() { } +void pButton::destructor() { +} + } diff --git a/higan/phoenix/reference/widget/button.hpp b/higan/phoenix/reference/widget/button.hpp index a3ad3277..5343e090 100644 --- a/higan/phoenix/reference/widget/button.hpp +++ b/higan/phoenix/reference/widget/button.hpp @@ -8,6 +8,7 @@ struct pButton : public pWidget { pButton(Button &button) : pWidget(button), button(button) {} void constructor(); + void destructor(); }; } diff --git a/higan/phoenix/reference/widget/canvas.cpp b/higan/phoenix/reference/widget/canvas.cpp index 82b81b7a..3a481e87 100755 --- a/higan/phoenix/reference/widget/canvas.cpp +++ b/higan/phoenix/reference/widget/canvas.cpp @@ -9,4 +9,7 @@ void pCanvas::update() { void pCanvas::constructor() { } +void pCanvas::destructor() { +} + } diff --git a/higan/phoenix/reference/widget/canvas.hpp b/higan/phoenix/reference/widget/canvas.hpp index d8f14cc9..c7b44282 100644 --- a/higan/phoenix/reference/widget/canvas.hpp +++ b/higan/phoenix/reference/widget/canvas.hpp @@ -8,6 +8,7 @@ struct pCanvas : public pWidget { pCanvas(Canvas &canvas) : pWidget(canvas), canvas(canvas) {} void constructor(); + void destructor(); }; } diff --git a/higan/phoenix/reference/widget/check-button.cpp b/higan/phoenix/reference/widget/check-button.cpp index 37564725..3a41a37f 100644 --- a/higan/phoenix/reference/widget/check-button.cpp +++ b/higan/phoenix/reference/widget/check-button.cpp @@ -13,4 +13,7 @@ void pCheckButton::setText(const string &text) { void pCheckButton::constructor() { } +void pCheckButton::destructor() { +} + } diff --git a/higan/phoenix/reference/widget/check-button.hpp b/higan/phoenix/reference/widget/check-button.hpp index 17cd5d71..a2b944d0 100644 --- a/higan/phoenix/reference/widget/check-button.hpp +++ b/higan/phoenix/reference/widget/check-button.hpp @@ -9,6 +9,7 @@ struct pCheckButton : public pWidget { pCheckButton(CheckButton &checkButton) : pWidget(checkButton), checkButton(checkButton) {} void constructor(); + void destructor(); }; } diff --git a/higan/phoenix/reference/widget/combo-button.cpp b/higan/phoenix/reference/widget/combo-button.cpp index 13787999..b67f7a25 100644 --- a/higan/phoenix/reference/widget/combo-button.cpp +++ b/higan/phoenix/reference/widget/combo-button.cpp @@ -22,4 +22,7 @@ void pComboButton::setSelection(unsigned row) { void pComboButton::constructor() { } +void pComboButton::destructor() { +} + } diff --git a/higan/phoenix/reference/widget/combo-button.hpp b/higan/phoenix/reference/widget/combo-button.hpp index 84cc0372..8dbefda8 100644 --- a/higan/phoenix/reference/widget/combo-button.hpp +++ b/higan/phoenix/reference/widget/combo-button.hpp @@ -12,6 +12,7 @@ struct pComboButton : public pWidget { pComboButton(ComboButton &comboButton) : pWidget(comboButton), comboButton(comboButton) {} void constructor(); + void destructor(); }; } diff --git a/higan/phoenix/reference/widget/hex-edit.cpp b/higan/phoenix/reference/widget/hex-edit.cpp index 95d8b72a..4d2ea5e5 100755 --- a/higan/phoenix/reference/widget/hex-edit.cpp +++ b/higan/phoenix/reference/widget/hex-edit.cpp @@ -18,4 +18,7 @@ void pHexEdit::update() { void pHexEdit::constructor() { } +void pHexEdit::destructor() { +} + } diff --git a/higan/phoenix/reference/widget/hex-edit.hpp b/higan/phoenix/reference/widget/hex-edit.hpp index 5819ee4d..923a0f25 100644 --- a/higan/phoenix/reference/widget/hex-edit.hpp +++ b/higan/phoenix/reference/widget/hex-edit.hpp @@ -11,6 +11,7 @@ struct pHexEdit : public pWidget { pHexEdit(HexEdit &hexEdit) : pWidget(hexEdit), hexEdit(hexEdit) {} void constructor(); + void destructor(); }; } diff --git a/higan/phoenix/reference/widget/horizontal-scroller.cpp b/higan/phoenix/reference/widget/horizontal-scroller.cpp index ef66115a..7f60a1bd 100644 --- a/higan/phoenix/reference/widget/horizontal-scroller.cpp +++ b/higan/phoenix/reference/widget/horizontal-scroller.cpp @@ -13,4 +13,7 @@ void pHorizontalScroller::setPosition(unsigned position) { void pHorizontalScroller::constructor() { } +void pHorizontalScroller::destructor() { +} + } diff --git a/higan/phoenix/reference/widget/horizontal-scroller.hpp b/higan/phoenix/reference/widget/horizontal-scroller.hpp index ea915b59..9aea9e14 100644 --- a/higan/phoenix/reference/widget/horizontal-scroller.hpp +++ b/higan/phoenix/reference/widget/horizontal-scroller.hpp @@ -9,6 +9,7 @@ struct pHorizontalScroller : public pWidget { pHorizontalScroller(HorizontalScroller &horizontalScroller) : pWidget(horizontalScroller), horizontalScroller(horizontalScroller) {} void constructor(); + void destructor(); }; } diff --git a/higan/phoenix/reference/widget/horizontal-slider.cpp b/higan/phoenix/reference/widget/horizontal-slider.cpp index 2bc97bab..bb926f04 100755 --- a/higan/phoenix/reference/widget/horizontal-slider.cpp +++ b/higan/phoenix/reference/widget/horizontal-slider.cpp @@ -13,4 +13,7 @@ void pHorizontalSlider::setPosition(unsigned position) { void pHorizontalSlider::constructor() { } +void pHorizontalSlider::destructor() { +} + } diff --git a/higan/phoenix/reference/widget/horizontal-slider.hpp b/higan/phoenix/reference/widget/horizontal-slider.hpp index 3caac46a..c15d6b38 100644 --- a/higan/phoenix/reference/widget/horizontal-slider.hpp +++ b/higan/phoenix/reference/widget/horizontal-slider.hpp @@ -9,6 +9,7 @@ struct pHorizontalSlider : public pWidget { pHorizontalSlider(HorizontalSlider &horizontalSlider) : pWidget(horizontalSlider), horizontalSlider(horizontalSlider) {} void constructor(); + void destructor(); }; } diff --git a/higan/phoenix/reference/widget/label.cpp b/higan/phoenix/reference/widget/label.cpp index 30f0ea63..39249c79 100755 --- a/higan/phoenix/reference/widget/label.cpp +++ b/higan/phoenix/reference/widget/label.cpp @@ -6,4 +6,7 @@ void pLabel::setText(const string &text) { void pLabel::constructor() { } +void pLabel::destructor() { +} + } diff --git a/higan/phoenix/reference/widget/label.hpp b/higan/phoenix/reference/widget/label.hpp index aca53cef..444a58d3 100644 --- a/higan/phoenix/reference/widget/label.hpp +++ b/higan/phoenix/reference/widget/label.hpp @@ -7,6 +7,7 @@ struct pLabel : public pWidget { pLabel(Label &label) : pWidget(label), label(label) {} void constructor(); + void destructor(); }; } diff --git a/higan/phoenix/reference/widget/line-edit.cpp b/higan/phoenix/reference/widget/line-edit.cpp index 6fd26dfe..1f9ff8a2 100755 --- a/higan/phoenix/reference/widget/line-edit.cpp +++ b/higan/phoenix/reference/widget/line-edit.cpp @@ -12,4 +12,7 @@ string pLineEdit::text() { void pLineEdit::constructor() { } +void pLineEdit::destructor() { +} + } diff --git a/higan/phoenix/reference/widget/line-edit.hpp b/higan/phoenix/reference/widget/line-edit.hpp index 1ca8b0ab..fafa9387 100644 --- a/higan/phoenix/reference/widget/line-edit.hpp +++ b/higan/phoenix/reference/widget/line-edit.hpp @@ -9,6 +9,7 @@ struct pLineEdit : public pWidget { pLineEdit(LineEdit &lineEdit) : pWidget(lineEdit), lineEdit(lineEdit) {} void constructor(); + void destructor(); }; } diff --git a/higan/phoenix/reference/widget/list-view.cpp b/higan/phoenix/reference/widget/list-view.cpp index c1cb54cf..0184f455 100755 --- a/higan/phoenix/reference/widget/list-view.cpp +++ b/higan/phoenix/reference/widget/list-view.cpp @@ -50,4 +50,7 @@ void pListView::setSelection(unsigned row) { void pListView::constructor() { } +void pListView::destructor() { +} + } diff --git a/higan/phoenix/reference/widget/list-view.hpp b/higan/phoenix/reference/widget/list-view.hpp index 8f0695c3..9def6058 100644 --- a/higan/phoenix/reference/widget/list-view.hpp +++ b/higan/phoenix/reference/widget/list-view.hpp @@ -21,6 +21,7 @@ struct pListView : public pWidget { pListView(ListView &listView) : pWidget(listView), listView(listView) {} void constructor(); + void destructor(); }; } diff --git a/higan/phoenix/reference/widget/progress-bar.cpp b/higan/phoenix/reference/widget/progress-bar.cpp index 87144b3d..7697f65a 100755 --- a/higan/phoenix/reference/widget/progress-bar.cpp +++ b/higan/phoenix/reference/widget/progress-bar.cpp @@ -6,4 +6,7 @@ void pProgressBar::setPosition(unsigned position) { void pProgressBar::constructor() { } +void pProgressBar::destructor() { +} + } diff --git a/higan/phoenix/reference/widget/progress-bar.hpp b/higan/phoenix/reference/widget/progress-bar.hpp index 06d745c0..a6a4531d 100644 --- a/higan/phoenix/reference/widget/progress-bar.hpp +++ b/higan/phoenix/reference/widget/progress-bar.hpp @@ -7,6 +7,7 @@ struct pProgressBar : public pWidget { pProgressBar(ProgressBar &progressBar) : pWidget(progressBar), progressBar(progressBar) {} void constructor(); + void destructor(); }; } diff --git a/higan/phoenix/reference/widget/radio-button.cpp b/higan/phoenix/reference/widget/radio-button.cpp index 34c82bc6..6fe4d98c 100644 --- a/higan/phoenix/reference/widget/radio-button.cpp +++ b/higan/phoenix/reference/widget/radio-button.cpp @@ -16,4 +16,7 @@ void pRadioButton::setText(const string &text) { void pRadioButton::constructor() { } +void pRadioButton::destructor() { +} + } diff --git a/higan/phoenix/reference/widget/radio-button.hpp b/higan/phoenix/reference/widget/radio-button.hpp index 6c92b52e..b560789c 100644 --- a/higan/phoenix/reference/widget/radio-button.hpp +++ b/higan/phoenix/reference/widget/radio-button.hpp @@ -10,6 +10,7 @@ struct pRadioButton : public pWidget { pRadioButton(RadioButton &radioButton) : pWidget(radioButton), radioButton(radioButton) {} void constructor(); + void destructor(); }; } diff --git a/higan/phoenix/reference/widget/text-edit.cpp b/higan/phoenix/reference/widget/text-edit.cpp index 20f02df6..991cac7a 100755 --- a/higan/phoenix/reference/widget/text-edit.cpp +++ b/higan/phoenix/reference/widget/text-edit.cpp @@ -18,4 +18,7 @@ string pTextEdit::text() { void pTextEdit::constructor() { } +void pTextEdit::destructor() { +} + } diff --git a/higan/phoenix/reference/widget/text-edit.hpp b/higan/phoenix/reference/widget/text-edit.hpp index 46e1a93e..b8a0411b 100644 --- a/higan/phoenix/reference/widget/text-edit.hpp +++ b/higan/phoenix/reference/widget/text-edit.hpp @@ -11,6 +11,7 @@ struct pTextEdit : public pWidget { pTextEdit(TextEdit &textEdit) : pWidget(textEdit), textEdit(textEdit) {} void constructor(); + void destructor(); }; } diff --git a/higan/phoenix/reference/widget/vertical-scroller.cpp b/higan/phoenix/reference/widget/vertical-scroller.cpp index 6b03f2fa..866b0bd9 100644 --- a/higan/phoenix/reference/widget/vertical-scroller.cpp +++ b/higan/phoenix/reference/widget/vertical-scroller.cpp @@ -13,4 +13,7 @@ void pVerticalScroller::setPosition(unsigned position) { void pVerticalScroller::constructor() { } +void pVerticalScroller::destructor() { +} + } diff --git a/higan/phoenix/reference/widget/vertical-scroller.hpp b/higan/phoenix/reference/widget/vertical-scroller.hpp index d1efe1c3..f012ed10 100644 --- a/higan/phoenix/reference/widget/vertical-scroller.hpp +++ b/higan/phoenix/reference/widget/vertical-scroller.hpp @@ -9,6 +9,7 @@ struct pVerticalScroller : public pWidget { pVerticalScroller(VerticalScroller &verticalScroller) : pWidget(verticalScroller), verticalScroller(verticalScroller) {} void constructor(); + void destructor(); }; } diff --git a/higan/phoenix/reference/widget/vertical-slider.cpp b/higan/phoenix/reference/widget/vertical-slider.cpp index 6f48f80a..68ba9426 100755 --- a/higan/phoenix/reference/widget/vertical-slider.cpp +++ b/higan/phoenix/reference/widget/vertical-slider.cpp @@ -13,4 +13,7 @@ void pVerticalSlider::setPosition(unsigned position) { void pVerticalSlider::constructor() { } +void pVerticalSlider::destructor() { +} + } diff --git a/higan/phoenix/reference/widget/vertical-slider.hpp b/higan/phoenix/reference/widget/vertical-slider.hpp index bad27451..feb84b47 100644 --- a/higan/phoenix/reference/widget/vertical-slider.hpp +++ b/higan/phoenix/reference/widget/vertical-slider.hpp @@ -9,6 +9,7 @@ struct pVerticalSlider : public pWidget { pVerticalSlider(VerticalSlider &verticalSlider) : pWidget(verticalSlider), verticalSlider(verticalSlider) {} void constructor(); + void destructor(); }; } diff --git a/higan/phoenix/reference/widget/viewport.cpp b/higan/phoenix/reference/widget/viewport.cpp index 5d088e3d..f4ad01ee 100755 --- a/higan/phoenix/reference/widget/viewport.cpp +++ b/higan/phoenix/reference/widget/viewport.cpp @@ -7,4 +7,7 @@ uintptr_t pViewport::handle() { void pViewport::constructor() { } +void pViewport::destructor() { +} + } diff --git a/higan/phoenix/reference/widget/viewport.hpp b/higan/phoenix/reference/widget/viewport.hpp index 94a6eecb..0b45c212 100644 --- a/higan/phoenix/reference/widget/viewport.hpp +++ b/higan/phoenix/reference/widget/viewport.hpp @@ -7,6 +7,7 @@ struct pViewport : public pWidget { pViewport(Viewport &viewport) : pWidget(viewport), viewport(viewport) {} void constructor(); + void destructor(); }; } diff --git a/higan/phoenix/reference/widget/widget.cpp b/higan/phoenix/reference/widget/widget.cpp index 6533ac62..8fba4a7e 100755 --- a/higan/phoenix/reference/widget/widget.cpp +++ b/higan/phoenix/reference/widget/widget.cpp @@ -30,4 +30,7 @@ void pWidget::setVisible(bool visible) { void pWidget::constructor() { } +void pWidget::destructor() { +} + } diff --git a/higan/phoenix/reference/widget/widget.hpp b/higan/phoenix/reference/widget/widget.hpp index 797fda05..383018d4 100644 --- a/higan/phoenix/reference/widget/widget.hpp +++ b/higan/phoenix/reference/widget/widget.hpp @@ -14,6 +14,7 @@ struct pWidget : public pSizable { pWidget(Widget &widget) : pSizable(widget), widget(widget) {} void constructor(); + void destructor(); }; } diff --git a/higan/phoenix/reference/window.cpp b/higan/phoenix/reference/window.cpp index aa6c4adb..672fea92 100755 --- a/higan/phoenix/reference/window.cpp +++ b/higan/phoenix/reference/window.cpp @@ -85,4 +85,7 @@ void pWindow::setWidgetFont(const string &font) { void pWindow::constructor() { } +void pWindow::destructor() { +} + } diff --git a/higan/phoenix/reference/window.hpp b/higan/phoenix/reference/window.hpp index 12fc6a03..46a070ff 100644 --- a/higan/phoenix/reference/window.hpp +++ b/higan/phoenix/reference/window.hpp @@ -32,6 +32,7 @@ struct pWindow : public pObject { pWindow(Window &window) : pObject(window), window(window) {} void constructor(); + void destructor(); }; } diff --git a/higan/ruby/video/cgl.cpp b/higan/ruby/video/cgl.cpp index 6333d718..ffbdcd5a 100644 --- a/higan/ruby/video/cgl.cpp +++ b/higan/ruby/video/cgl.cpp @@ -1,10 +1,22 @@ #include "opengl.hpp" +namespace ruby { + class pVideoCGL; +} + +@interface RubyVideoCGL : NSOpenGLView { +@public + ruby::pVideoCGL *video; +} +-(id) initWith:(ruby::pVideoCGL*)video pixelFormat:(NSOpenGLPixelFormat*)pixelFormat; +-(void) reshape; +@end + namespace ruby { class pVideoCGL : public OpenGL { public: - NSOpenGLView *view; + RubyVideoCGL *view; struct { NSView *handle; @@ -121,8 +133,8 @@ public: 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 = [[RubyVideoCGL alloc] initWith:this pixelFormat:format]; [view setFrame:NSMakeRect(0, 0, size.width, size.height)]; [view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; [settings.handle addSubview:view]; @@ -140,6 +152,7 @@ public: [view unlockFocus]; } + clear(); return true; } @@ -172,3 +185,18 @@ public: DeclareVideo(CGL) } + +@implementation RubyVideoCGL : NSOpenGLView + +-(id) initWith:(ruby::pVideoCGL*)videoPointer pixelFormat:(NSOpenGLPixelFormat*)pixelFormat { + if(self = [super initWithFrame:NSMakeRect(0, 0, 0, 0) pixelFormat:pixelFormat]) { + video = videoPointer; + } + return self; +} + +-(void) reshape { + video->refresh(); +} + +@end diff --git a/higan/sfc/profile-accuracy.hpp b/higan/sfc/profile-accuracy.hpp index e336c9e3..0d11708a 100755 --- a/higan/sfc/profile-accuracy.hpp +++ b/higan/sfc/profile-accuracy.hpp @@ -1,7 +1,3 @@ -namespace Info { - static const char Profile[] = "Accuracy"; -} - #include #include #include diff --git a/higan/sfc/profile-balanced.hpp b/higan/sfc/profile-balanced.hpp index ed9f7da2..7e09ad9d 100644 --- a/higan/sfc/profile-balanced.hpp +++ b/higan/sfc/profile-balanced.hpp @@ -1,7 +1,3 @@ -namespace Info { - static const char Profile[] = "Balanced"; -} - #include #include #include diff --git a/higan/sfc/profile-performance.hpp b/higan/sfc/profile-performance.hpp index 658bcd46..da48b143 100755 --- a/higan/sfc/profile-performance.hpp +++ b/higan/sfc/profile-performance.hpp @@ -1,7 +1,3 @@ -namespace Info { - static const char Profile[] = "Performance"; -} - #if defined(DEBUGGER) #error "bsnes: debugger not supported with performance profile." #endif diff --git a/higan/sfc/system/serialization.cpp b/higan/sfc/system/serialization.cpp index 1f91b6de..eaf14b61 100755 --- a/higan/sfc/system/serialization.cpp +++ b/higan/sfc/system/serialization.cpp @@ -8,7 +8,7 @@ serializer System::serialize() { memcpy(&hash, (const char*)cartridge.sha256(), 64); memset(&description, 0, sizeof description); memset(&profile, 0, sizeof profile); - strmcpy(profile, Info::Profile, sizeof profile); + strmcpy(profile, Emulator::Profile, sizeof profile); s.integer(signature); s.integer(version); @@ -32,7 +32,7 @@ bool System::unserialize(serializer &s) { if(signature != 0x31545342) return false; if(version != Info::SerializerVersion) return false; - if(strcmp(profile, Info::Profile)) return false; + if(strcmp(profile, Emulator::Profile)) return false; power(); serialize_all(s); diff --git a/higan/target-ethos/ethos.cpp b/higan/target-ethos/ethos.cpp index b60ea77f..04321db9 100755 --- a/higan/target-ethos/ethos.cpp +++ b/higan/target-ethos/ethos.cpp @@ -87,6 +87,7 @@ Program::Program(int argc, char **argv) { stateManager = new StateManager; windowManager->loadGeometry(); presentation->setVisible(); + utility->resize(); video.set(Video::Handle, presentation->viewport.handle()); if(!video.cap(Video::Depth) || !video.set(Video::Depth, depth = 30u)) { @@ -131,16 +132,16 @@ int main(int argc, char **argv) { Application::setName("higan"); - Application::Cocoa::onQuit = &Application::quit; - Application::Cocoa::onPreferences = [&] { - settings->setVisible(); - settings->panelList.setFocused(); + Application::Cocoa::onActivate = [&] { + presentation->setVisible(); }; + Application::Cocoa::onAbout = [&] { MessageWindow() .setTitle({"About ", Emulator::Name}) .setText({ Emulator::Name, " v", Emulator::Version, "\n", + Emulator::Profile, " Profile\n", "Author: ", Emulator::Author, "\n", "License: ", Emulator::License, "\n", "Website: ", Emulator::Website @@ -148,6 +149,15 @@ int main(int argc, char **argv) { .information(); }; + Application::Cocoa::onPreferences = [&] { + settings->setVisible(); + settings->panelList.setFocused(); + }; + + Application::Cocoa::onQuit = [&] { + Application::quit(); + }; + new Program(argc, argv); delete program; return 0; diff --git a/higan/target-ethos/general/presentation.cpp b/higan/target-ethos/general/presentation.cpp index a4eb45f7..2b8884d5 100755 --- a/higan/target-ethos/general/presentation.cpp +++ b/higan/target-ethos/general/presentation.cpp @@ -111,7 +111,7 @@ Presentation::Presentation() : active(nullptr) { toolsMenu.append(resizeWindow, stateManager, cheatEditor, synchronizeTime); append(layout); - layout.append(viewport, {0, 0, 720, 480}); + layout.append(viewport, {0, 0, 1, 1}); onSize = [&] { utility->resize(); @@ -119,7 +119,11 @@ Presentation::Presentation() : active(nullptr) { onClose = [&] { setVisible(false); - Application::quit(); + if(Intrinsics::platform() == Intrinsics::Platform::OSX) { + utility->unload(); + } else { + Application::quit(); + } }; loadImport.onActivate = [&] { diff --git a/higan/target-ethos/settings/advanced.cpp b/higan/target-ethos/settings/advanced.cpp index 175fd8ab..e0bdff6b 100644 --- a/higan/target-ethos/settings/advanced.cpp +++ b/higan/target-ethos/settings/advanced.cpp @@ -16,17 +16,9 @@ AdvancedSettings::AdvancedSettings() { libraryPath.setText(path); libraryBrowse.setText("Browse ..."); infoLabel.setFont(program->boldFont); - string profile; - #if defined(PROFILE_ACCURACY) - profile = "Accuracy"; - #elif defined(PROFILE_BALANCED) - profile = "Balanced"; - #elif defined(PROFILE_PERFORMANCE) - profile = "Performance"; - #endif infoLabel.setText({ Emulator::Name, " v", Emulator::Version, "\n", - " ", profile, " Profile\n", + " ", Emulator::Profile, " Profile\n", " Author: ", Emulator::Author, "\n", " License: ", Emulator::License, "\n", " Website: ", Emulator::Website diff --git a/higan/target-ethos/utility/utility.cpp b/higan/target-ethos/utility/utility.cpp index a4d71855..499837ae 100755 --- a/higan/target-ethos/utility/utility.cpp +++ b/higan/target-ethos/utility/utility.cpp @@ -30,7 +30,7 @@ void Utility::loadMedia(string pathname) { for(auto &media : emulator->media) { if(media.bootable == false) continue; if(type != media.type) continue; - return utility->loadMedia(emulator, media, {pathname, "/"}); + return loadMedia(emulator, media, {pathname, "/"}); } } @@ -56,6 +56,7 @@ void Utility::loadMedia(Emulator::Interface *emulator, Emulator::Interface::Medi system().power(); presentation->setSystemName(media.name); + presentation->setVisible(); load(); } @@ -210,7 +211,12 @@ void Utility::updateShader() { } void Utility::resize(bool resizeWindow) { - if(program->active == nullptr) return; + if(program->active == nullptr) { + auto geometry = presentation->geometry(); + presentation->viewport.setGeometry({0, 0, geometry.width, geometry.height}); + return; + } + Geometry geometry = presentation->geometry(); unsigned width = system().information.width; unsigned height = system().information.height;