47 NSTouchBarItemIdentifier
key;
58 {
@"openttd.pause", SPR_IMG_PAUSE, MTHK_PAUSE,
@"Pause" },
59 {
@"openttd.fastforward", SPR_IMG_FASTFORWARD, MTHK_FASTFORWARD,
@"Fast Forward" },
60 {
@"openttd.zoom_in", SPR_IMG_ZOOMIN, MTHK_ZOOM_IN,
@"Zoom In" },
61 {
@"openttd.zoom_out", SPR_IMG_ZOOMOUT, MTHK_ZOOM_OUT,
@"Zoom Out" },
62 {
@"openttd.build_rail", SPR_IMG_BUILDRAIL, MTHK_BUILD_RAIL,
@"Rail" },
63 {
@"openttd.build_road", SPR_IMG_BUILDROAD, MTHK_BUILD_ROAD,
@"Road" },
64 {
@"openttd.build_tram", SPR_IMG_BUILDTRAMS, MTHK_BUILD_TRAM,
@"Tram" },
65 {
@"openttd.build_docks", SPR_IMG_BUILDWATER, MTHK_BUILD_DOCKS,
@"Docks" },
66 {
@"openttd.build_airport", SPR_IMG_BUILDAIR, MTHK_BUILD_AIRPORT,
@"Airport" }
71@interface OTTDMain : NSObject <NSApplicationDelegate>
92 i += c < 0x10000 ? 1 : 2;
106 auto it = view.begin();
107 const auto end = view.end();
108 for (NSUInteger i = 0; it != end && i < count; ++it) {
109 i += *it < 0x10000 ? 1 : 2;
111 return it.GetByteOffset();
121 std::vector<char32_t> unicode_str;
124 for (NSUInteger i = 0; i < s.length; i++) {
125 unichar c = [ s characterAtIndex:i ];
132 unicode_str.push_back(c);
145 delete[] (
const uint32_t *)data;
156 if (!SpriteExists(sprite_id))
return nullptr;
161 if (!buffer)
return nullptr;
164 if (!data)
return nullptr;
166 CGBitmapInfo info = kCGImageAlphaFirst | kCGBitmapByteOrder32Host;
168 CFAutoRelease<CGImage> bitmap(CGImageCreate(dim.width, dim.height, 8, 32, dim.width * 4, colour_space.get(), info, data.get(),
nullptr,
false, kCGRenderingIntentDefault));
169 if (!bitmap)
return nullptr;
171 return [ [ [ NSImage alloc ] initWithCGImage:bitmap.get() size:NSZeroSize ] autorelease ];
187 NSEventType type = NSEventTypeApplicationDefined;
188 NSEvent *
event = [ NSEvent otherEventWithType:type location:NSMakePoint(0, 0) modifierFlags:0 timestamp:0.0 windowNumber:0 context:nil subtype:0 data1:0 data2:0 ];
189 [ NSApp postEvent:event atStart:YES ];
195- (void)launchGameEngine: (NSNotification*) note
200 NSEvent *e = [ [ NSEvent alloc ] init ];
201 [ drv->cocoaview cursorUpdate:e ];
208 [
self performSelectorOnMainThread:@selector(stopEngine) withObject:nil waitUntilDone:FALSE ];
214- (void) applicationDidFinishLaunching: (NSNotification*) note
217 [ [ NSNotificationCenter defaultCenter ] addObserver:self selector:@selector(launchGameEngine:) name:OTTDMainLaunchGameEngine object:nil ];
220 [ [ NSNotificationCenter defaultCenter ] postNotificationName:OTTDMainLaunchGameEngine object:nil ];
226- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*) sender
228 HandleExitGameRequest();
230 return NSTerminateCancel;
238 [ [ NSNotificationCenter defaultCenter ] removeObserver:self ];
248- (BOOL)applicationSupportsSecureRestorableState:(NSApplication*) sender
259 NSString *appName =
@"OpenTTD";
260 NSMenu *appleMenu = [ [ NSMenu alloc ] initWithTitle:appName ];
263 NSString *title = [ @"About " stringByAppendingString:appName ];
264 [ appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@"" ];
266 [ appleMenu addItem:[ NSMenuItem separatorItem ] ];
268 title = [ @"Hide " stringByAppendingString:appName ];
269 [ appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h" ];
271 NSMenuItem *menuItem = [ appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h" ];
272 [ menuItem setKeyEquivalentModifierMask:(NSEventModifierFlagOption | NSEventModifierFlagCommand) ];
274 [ appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@"" ];
276 [ appleMenu addItem:[ NSMenuItem separatorItem ] ];
278 title = [ @"Quit " stringByAppendingString:appName ];
279 [ appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q" ];
282 menuItem = [ [ NSMenuItem alloc ] initWithTitle:@"" action:nil keyEquivalent:@"" ];
283 [ menuItem setSubmenu:appleMenu ];
284 [ [ NSApp mainMenu ] addItem:menuItem ];
289 if ([ NSApp respondsToSelector:
@selector(setAppleMenu:) ]) {
290 [ NSApp performSelector:@selector(setAppleMenu:) withObject:appleMenu ];
294 [ appleMenu release ];
295 [ menuItem release ];
303 NSMenu *windowMenu = [ [ NSMenu alloc ] initWithTitle:@"Window" ];
306 [ windowMenu addItemWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m" ];
309 NSMenuItem *menuItem = [ [ NSMenuItem alloc ] initWithTitle:@"Window" action:nil keyEquivalent:@"" ];
310 [ menuItem setSubmenu:windowMenu ];
311 [ [ NSApp mainMenu ] addItem:menuItem ];
314 [ windowMenu addItemWithTitle:@"Fullscreen" action:@selector(toggleFullScreen:) keyEquivalent:@"^f" ];
317 [ NSApp setWindowsMenu:windowMenu ];
320 [ windowMenu release ];
321 [ menuItem release ];
330 ProcessSerialNumber psn = { 0, kCurrentProcess };
333 [ NSApplication sharedApplication ];
336 OSStatus returnCode = TransformProcessType(&psn, kProcessTransformToForegroundApplication);
337 if (returnCode != 0)
Debug(driver, 0,
"Could not change to foreground application. Error {}", (
int)returnCode);
340 if ([ NSWindow respondsToSelector:
@selector(setAllowsAutomaticWindowTabbing:) ]) {
342 [ NSWindow performSelector:@selector(setAllowsAutomaticWindowTabbing:) withObject:nil];
346 [ [ NSApplication sharedApplication ] setActivationPolicy:NSApplicationActivationPolicyRegular ];
347 [ [ NSApplication sharedApplication ] activateIgnoringOtherApps:YES ];
350 [ NSApp setMainMenu:[ [ NSMenu alloc ] init ] ];
356 [ NSApp setDelegate:_ottd_main ];
366 [ _ottd_main unregisterObserver ];
367 [ _ottd_main release ];
379void CocoaDialog(std::string_view title, std::string_view message, std::string_view buttonLabel)
387 fmt::print(stderr,
"{}: {}\n", title, message);
392 NSAlert *alert = [ [ NSAlert alloc ] init ];
393 [ alert setAlertStyle: NSAlertStyleCritical ];
394 [ alert setMessageText:[ [ NSString alloc ] initWithBytes:title.data() length:title.size() encoding:NSUTF8StringEncoding ] ];
395 [ alert setInformativeText:[ [ NSString alloc ] initWithBytes:message.data() length:message.size() encoding:NSUTF8StringEncoding ] ];
396 [ alert addButtonWithTitle: [ [ NSString alloc ] initWithBytes:buttonLabel.data() length:buttonLabel.size() encoding:NSUTF8StringEncoding ] ];
410@implementation NSCursor (OTTD_CocoaCursor)
415+ (NSCursor *) clearCocoaCursor
418 unsigned char clearGIFBytes[] = {
419 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x10, 0x00, 0x10, 0x00, 0x80, 0x00,
420 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xF9, 0x04, 0x01, 0x00,
421 0x00, 0x01, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00,
422 0x00, 0x02, 0x0E, 0x8C, 0x8F, 0xA9, 0xCB, 0xED, 0x0F, 0xA3, 0x9C, 0xB4,
423 0xDA, 0x8B, 0xB3, 0x3E, 0x05, 0x00, 0x3B};
424 NSData *clearGIFData = [ NSData dataWithBytesNoCopy:&clearGIFBytes[0] length:55 freeWhenDone:NO ];
425 NSImage *clearImg = [ [ NSImage alloc ] initWithData:clearGIFData ];
426 return [ [ NSCursor alloc ] initWithImage:clearImg hotSpot:NSMakePoint(0.0,0.0) ];
438- (instancetype)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag driver:(
VideoDriver_Cocoa *)drv
440 if (self = [ super initWithContentRect:contentRect styleMask:styleMask backing:backingType defer:flag ]) {
442 self->touchbar_created =
false;
444 [
self setContentMinSize:NSMakeSize(64.0f, 64.0f) ];
447 NSString *nsscaption = [ [ NSString alloc ] initWithBytes:caption.data() length:caption.size() encoding:NSUTF8StringEncoding ];
448 [
self setTitle:nsscaption ];
449 [
self setMiniwindowTitle:nsscaption ];
450 [ nsscaption release ];
459- (void)setFrame:(NSRect)frameRect display:(BOOL)flag
461 [
super setFrame:frameRect display:flag ];
463 driver->AllocateBackingStore();
466- (void)touchBarButtonAction:(
id)sender
468 NSButton *btn = (NSButton *)sender;
474- (nullable NSTouchBar *)makeTouchBar
477 NSMutableArray<NSTouchBarItemIdentifier> *button_ids = [ [ NSMutableArray alloc ] init ];
479 [ button_ids addObject:button.key ];
481 [ button_ids addObject:NSTouchBarItemIdentifierOtherItemsProxy ];
483 NSTouchBar *bar = [ [ NSTouchBar alloc ] init ];
485 bar.defaultItemIdentifiers = button_ids;
486 [ button_ids release ];
488 self->touchbar_created =
true;
493- (nullable NSTouchBarItem *)touchBar:(NSTouchBar *)touchBar makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier
498 NSButton *button = [ NSButton buttonWithTitle:item->fallback_text target:self action:@selector(touchBarButtonAction:) ];
499 button.identifier = identifier;
500 button.imageScaling = NSImageScaleProportionallyDown;
502 NSCustomTouchBarItem *tb_item = [ [ NSCustomTouchBarItem alloc] initWithIdentifier:identifier ];
503 tb_item.view = button;
507- (void)refreshSystemSprites
509 if (!self->touchbar_created || ![ self respondsToSelector:@selector(touchBar) ] || self.touchBar == nil) return;
512 for (NSTouchBarItemIdentifier ident in self.touchBar.itemIdentifiers) {
516 NSCustomTouchBarItem *tb_item = [
self.touchBar itemForIdentifier:ident ];
517 NSButton *button = tb_item.view;
522 CGFloat max_dim = std::max(image.size.width, image.size.height);
524 CGFloat scale = 22.0 / max_dim;
525 image.size = NSMakeSize(image.size.width * scale, image.size.height * scale);
528 button.image = image;
529 button.imagePosition = NSImageOnly;
532 button.imagePosition = NSNoImage;
540 float _current_magnification;
546- (instancetype)initWithFrame:(NSRect)frameRect
548 if (self = [ super initWithFrame:frameRect ]) {
549 self->_use_hidpi =
_allow_hidpi_window && [
self respondsToSelector:@selector(convertRectToBacking:) ] && [
self respondsToSelector:@selector(convertRectFromBacking:) ];
554- (NSRect)getRealRect:(NSRect)rect
556 return _use_hidpi ? [
self convertRectToBacking:rect ] : rect;
559- (NSRect)getVirtualRect:(NSRect)rect
561 return _use_hidpi ? [
self convertRectFromBacking:rect ] : rect;
564- (CGFloat)getContentsScale
566 return _use_hidpi && self.window != nil ? [
self.window backingScaleFactor ] : 1.0f;
572- (BOOL)acceptsFirstResponder
577- (void)setNeedsDisplayInRect:(NSRect)invalidRect
580 for ( NSView *v in [ self subviews ]) {
581 [ v setNeedsDisplayInRect:[ v convertRect:invalidRect fromView:self ] ];
586- (void)cursorUpdate:(NSEvent *)event
588 [ (_game_mode == GM_BOOTSTRAP ? [ NSCursor arrowCursor ] : [ NSCursor clearCocoaCursor ]) set ];
591- (void)viewWillMoveToWindow:(NSWindow *)win
593 for (NSTrackingArea *a in [ self trackingAreas ]) {
594 [
self removeTrackingArea:a ];
598- (void)viewDidMoveToWindow
601 NSTrackingAreaOptions track_opt = NSTrackingInVisibleRect | NSTrackingActiveInActiveApp | NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingCursorUpdate;
602 NSTrackingArea *track = [ [ NSTrackingArea alloc ] initWithRect:[
self bounds ] options:track_opt owner:self userInfo:nil ];
603 [
self addTrackingArea:track ];
610- (void)mouseEntered:(NSEvent *)theEvent
618- (void)mouseExited:(NSEvent *)theEvent
620 if ([ self window ] != nil) UndrawMouseCursor();
629- (NSPoint)mousePositionFromEvent:(NSEvent *)e
631 NSPoint pt = e.locationInWindow;
632 if ([ e window ] == nil) pt = [
self.window convertRectFromScreen:NSMakeRect(pt.x, pt.y, 0, 0) ].origin;
633 pt = [
self convertPoint:pt fromView:nil ];
635 return [
self getRealRect:NSMakeRect(pt.x, self.bounds.size.height - pt.y, 0, 0) ].origin;
642- (void)internalMouseMoveEvent:(NSEvent *)event
647 NSPoint pt = [
self mousePositionFromEvent:event ];
657- (void)internalMouseButtonEvent
659 bool cur_fix = _cursor.
fix_at;
663 if (cur_fix != _cursor.
fix_at) CGAssociateMouseAndMouseCursorPosition(!_cursor.
fix_at);
671- (BOOL)emulateRightButton:(NSEvent *)event
673 uint32_t keymask = 0;
677 return (event.modifierFlags & keymask) != 0;
684- (void)mouseMoved:(NSEvent *)event
686 [
self internalMouseMoveEvent:event ];
693- (void)mouseDragged:(NSEvent *)event
695 [
self internalMouseMoveEvent:event ];
702- (void)mouseDown:(NSEvent *)event
704 if ([ self emulateRightButton:event ]) {
705 self->_emulated_down =
true;
706 [
self rightMouseDown:event ];
709 [
self internalMouseButtonEvent ];
717- (void)mouseUp:(NSEvent *)event
719 if (self->_emulated_down) {
720 self->_emulated_down =
false;
721 [
self rightMouseUp:event ];
725 [
self internalMouseButtonEvent ];
733- (void)rightMouseDragged:(NSEvent *)event
735 [
self internalMouseMoveEvent:event ];
742- (void)rightMouseDown:(NSEvent *)event
746 [
self internalMouseButtonEvent ];
753- (void)rightMouseUp:(NSEvent *)event
756 [
self internalMouseButtonEvent ];
763- (void)scrollWheel:(NSEvent *)event
765 if ([ event deltaY ] > 0.0) {
767 }
else if ([ event deltaY ] < 0.0) {
776 if ([ event respondsToSelector:@selector(hasPreciseScrollingDeltas) ]) {
778 if (![ event hasPreciseScrollingDeltas ])
return;
780 deltaX = [ event scrollingDeltaX ] * 0.5f;
781 deltaY = [ event scrollingDeltaY ] * 0.5f;
783 deltaX = [ event deltaX ] * 5;
784 deltaY = [ event deltaY ] * 5;
787 _cursor.h_wheel -= static_cast<float>(deltaX *
_settings_client.gui.scrollwheel_multiplier);
788 _cursor.v_wheel -= static_cast<float>(deltaY *
_settings_client.gui.scrollwheel_multiplier);
789 _cursor.wheel_moved =
true;
796- (void)magnifyWithEvent:(NSEvent *)event
799 self->_current_magnification += [ event magnification ] * 5.0f;
801 while (self->_current_magnification >= 1.0f) {
802 self->_current_magnification -= 1.0f;
806 while (self->_current_magnification <= -1.0f) {
807 self->_current_magnification += 1.0f;
817- (void)endGestureWithEvent:(NSEvent *)event
820 self->_current_magnification = 0.0f;
829- (BOOL)internalHandleKeycode:(
unsigned short)keycode unicode:(
char32_t)unicode pressed:(BOOL)down modifiers:(NSUInteger)modifiers
833 case QZ_DOWN:
SB(
_dirkeys, 3, 1, down);
break;
834 case QZ_LEFT:
SB(
_dirkeys, 0, 1, down);
break;
835 case QZ_RIGHT:
SB(
_dirkeys, 2, 1, down);
break;
846 if (down && (modifiers & NSEventModifierFlagCommand)) {
852 if (down &&
EditBoxInGlobalFocus() && (modifiers & (NSEventModifierFlagCommand | NSEventModifierFlagControl))) {
857 if (down &&
EditBoxInGlobalFocus() && (modifiers & (NSEventModifierFlagCommand | NSEventModifierFlagControl))) {
863 BOOL interpret_keys = YES;
866 auto vk = std::ranges::find(_vk_mapping, keycode, &CocoaVkMapping::vk_from);
867 uint32_t pressed_key = vk != std::end(_vk_mapping) ? vk->map_to : 0;
869 if (modifiers & NSEventModifierFlagShift) pressed_key |= WKC_SHIFT;
871 if (modifiers & NSEventModifierFlagOption) pressed_key |= WKC_ALT;
874 static bool console =
false;
877 if (pressed_key == WKC_BACKQUOTE && (console || unicode == 0)) {
893 Debug(driver, 3,
"cocoa_v: QZ_KeyEvent: {:x} ({:x}), down, mapping: {:x}", keycode, (
int)unicode, pressed_key);
895 Debug(driver, 3,
"cocoa_v: QZ_KeyEvent: {:x} ({:x}), up", keycode, (
int)unicode);
898 return interpret_keys;
905- (void)keyDown:(NSEvent *)event
908 switch (event.keyCode) {
912 if (event.modifierFlags & NSEventModifierFlagCommand) {
913 [
self interpretKeyEvents:[ NSArray arrayWithObject:event ] ];
919 std::vector<char32_t> unicode_str =
NSStringToUTF32([ event characters ]);
920 if (unicode_str.empty()) unicode_str.push_back(0);
923 if ([ self internalHandleKeycode:event.keyCode unicode:unicode_str[0] pressed:YES modifiers:event.modifierFlags ]) {
924 [
self interpretKeyEvents:[ NSArray arrayWithObject:event ] ];
927 [
self internalHandleKeycode:event.keyCode unicode:unicode_str[0] pressed:YES modifiers:event.modifierFlags ];
928 for (
size_t i = 1; i < unicode_str.size(); i++) {
929 [
self internalHandleKeycode:0 unicode:unicode_str[i] pressed:YES modifiers:event.modifierFlags ];
938- (void)keyUp:(NSEvent *)event
941 switch (event.keyCode) {
945 if (event.modifierFlags & NSEventModifierFlagCommand) {
946 [ self interpretKeyEvents:[ NSArray arrayWithObject:event ] ];
952 std::vector<char32_t> unicode_str =
NSStringToUTF32([ event characters ]);
953 if (unicode_str.empty()) unicode_str.push_back(0);
955 [
self internalHandleKeycode:event.keyCode unicode:unicode_str[0] pressed:NO modifiers:event.modifierFlags ];
962- (void)flagsChanged:(NSEvent *)event
964 const int mapping[] = { QZ_CAPSLOCK, QZ_LSHIFT, QZ_LCTRL, QZ_LALT, QZ_LMETA };
966 NSUInteger newMods =
event.modifierFlags;
967 if (self->_current_mods == newMods)
return;
970 for (
unsigned int i = 0, bit = NSEventModifierFlagCapsLock; bit <= NSEventModifierFlagCommand; bit <<= 1, ++i) {
971 unsigned int currentMask, newMask;
973 currentMask = self->_current_mods & bit;
974 newMask = newMods & bit;
976 if (currentMask && currentMask != newMask) {
977 [
self internalHandleKeycode:mapping[i] unicode:0 pressed:NO modifiers:newMods ];
978 }
else if (newMask && currentMask != newMask) {
979 [
self internalHandleKeycode:mapping[i] unicode:0 pressed:YES modifiers:newMods ];
988- (void)insertText:(
id)aString replacementRange:(NSRange)replacementRange
992 NSString *s = [ aString isKindOfClass:[ NSAttributedString class ] ] ? [ aString string ] : (NSString *)aString;
994 std::optional<size_t> insert_point;
995 std::optional<size_t> replace_range;
996 if (replacementRange.location != NSNotFound) {
1000 replace_range = *insert_point +
Utf8AdvanceByUtf16Units(focused_text.substr(*insert_point), replacementRange.length);
1004 HandleTextInput([ s UTF8String ],
false, std::nullopt, insert_point, replace_range);
1008- (void)insertText:(
id)aString
1010 [
self insertText:aString replacementRange:NSMakeRange(NSNotFound, 0) ];
1014- (void)setMarkedText:(
id)aString selectedRange:(NSRange)selRange replacementRange:(NSRange)replacementRange
1018 NSString *s = [ aString isKindOfClass:[ NSAttributedString class ] ] ? [ aString string ] : (NSString *)aString;
1020 const char *utf8 = [ s UTF8String ];
1021 if (utf8 !=
nullptr) {
1022 std::optional<size_t> insert_point;
1023 std::optional<size_t> replace_range;
1024 if (replacementRange.location != NSNotFound) {
1026 NSRange marked = [
self markedRange ];
1028 insert_point =
Utf8AdvanceByUtf16Units(focused_text, replacementRange.location + (marked.location != NSNotFound ? marked.location : 0u));
1029 replace_range = *insert_point +
Utf8AdvanceByUtf16Units(focused_text.substr(*insert_point), replacementRange.length);
1040- (void)setMarkedText:(
id)aString selectedRange:(NSRange)selRange
1042 [
self setMarkedText:aString selectedRange:selRange replacementRange:NSMakeRange(NSNotFound, 0) ];
1052- (NSRange)selectedRange
1057 std::string_view text = text_buf->
GetText();
1059 return NSMakeRange(start, 0);
1063- (NSRange)markedRange
1069 std::string_view text = text_buf->
GetText();
1073 return NSMakeRange(start, len);
1076 return NSMakeRange(NSNotFound, 0);
1080- (BOOL)hasMarkedText
1088- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)theRange actualRange:(NSRangePointer)actualRange
1093 NSString *s = [ [ NSString alloc] initWithBytes:text.data() length:text.size() encoding:NSUTF8StringEncoding ];
1094 NSRange valid_range = NSIntersectionRange(NSMakeRange(0, [ s length ]), theRange);
1096 if (actualRange !=
nullptr) *actualRange = valid_range;
1097 if (valid_range.length == 0)
return nil;
1099 return [ [ [ NSAttributedString alloc ] initWithString:[ s substringWithRange:valid_range ] ] autorelease ];
1103- (NSAttributedString *)attributedSubstringFromRange:(NSRange)theRange
1105 return [
self attributedSubstringForProposedRange:theRange actualRange:nil ];
1109- (NSAttributedString *)attributedString
1111 if (!
EditBoxInGlobalFocus())
return [ [ [ NSAttributedString alloc ] initWithString:@"" ] autorelease ];
1114 return [ [ [ NSAttributedString alloc ] initWithString:[ [ NSString alloc ] initWithBytes:text.data() length:text.size() encoding:NSUTF8StringEncoding ] ] autorelease ];
1118- (NSUInteger)characterIndexForPoint:(NSPoint)thePoint
1122 NSPoint view_pt = [
self convertRect:[ [
self window ] convertRectFromScreen:NSMakeRect(thePoint.x, thePoint.y, 0, 0) ] fromView:nil ].origin;
1124 Point pt = { (int)view_pt.
x, (
int)[
self frame ].size.height - (int)view_pt.y };
1127 if (index == -1)
return NSNotFound;
1134- (NSRect)firstRectForCharacterRange:(NSRange)aRange
1145 NSRect view_rect = NSMakeRect(_focused_window->
left + r.left, [ self frame ].size.height - _focused_window->
top - r.bottom, r.right - r.left, r.bottom - r.top);
1147 return [ [
self window ] convertRectToScreen:[
self convertRect:view_rect toView:nil ] ];
1151- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
1153 return [
self firstRectForCharacterRange:aRange ];
1157- (NSArray*)validAttributesForMarkedText
1159 return [ NSArray array ];
1166- (void)deleteBackward:(
id)sender
1175- (void)deleteWordBackward:(
id)sender
1184- (void)deleteForward:(
id)sender
1193- (void)deleteWordForward:(
id)sender
1202- (void)moveLeft:(
id)sender
1211- (void)moveWordLeft:(
id)sender
1220- (void)moveRight:(
id)sender
1229- (void)moveWordRight:(
id)sender
1238- (void)moveUp:(
id)sender
1247- (void)moveDown:(
id)sender
1256- (void)moveUpAndModifySelection:(
id)sender
1265- (void)moveDownAndModifySelection:(
id)sender
1274- (void)moveToBeginningOfLine:(
id)sender
1283- (void)moveToEndOfLine:(
id)sender
1292- (void)scrollPageUp:(
id)sender
1301- (void)scrollPageDown:(
id)sender
1310- (void)pageUpAndModifySelection:(
id)sender
1319- (void)pageDownAndModifySelection:(
id)sender
1328- (void)scrollToBeginningOfDocument:(
id)sender
1331 [
self moveToBeginningOfLine:sender ];
1338- (void)scrollToEndOfDocument:(
id)sender
1341 [
self moveToEndOfLine:sender ];
1348- (void)insertNewline:(
id)sender
1357- (void)cancelOperation:(
id)sender
1366- (void)doCommandBySelector:(
SEL)aSelector
1368 if ([ self respondsToSelector:aSelector ]) [ self performSelector:aSelector ];
1381 if (self = [ super init ]) {
1390- (BOOL)windowShouldClose:(
id)sender
1392 HandleExitGameRequest();
1397- (void)windowDidEnterFullScreen:(NSNotification *)aNotification
1399 NSPoint loc = [ driver->cocoaview convertPoint:[ [ aNotification object ] mouseLocationOutsideOfEventStream ] fromView:nil ];
1400 BOOL inside = ([ driver->cocoaview hitTest:loc ] == driver->cocoaview);
1404 NSEvent *e = [ [ NSEvent alloc ] init ];
1405 [ driver->cocoaview mouseEntered:e ];
1410- (void)windowDidChangeBackingProperties:(NSNotification *)notification
1415 driver->AllocateBackingStore();
1421- (NSApplicationPresentationOptions)window:(NSWindow *)window willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)proposedOptions
1423 return NSApplicationPresentationFullScreen | NSApplicationPresentationHideMenuBar | NSApplicationPresentationHideDock;