/platform/osx/objc/window.m

http://github.com/wilkie/djehuty · Objective C · 398 lines · 228 code · 103 blank · 67 comment · 7 complexity · 6ead61631cd29a077bee858c0f90cf67 MD5 · raw file

  1. #include <Cocoa/Cocoa.h>
  2. #include <Foundation/Foundation.h>
  3. #include "OSXView.h"
  4. enum OSXEvents
  5. {
  6. // Window Events
  7. EventResize, // parameters: (width, height) of window
  8. // Mouse Events, params are (x, y) coordinates
  9. EventPrimaryDown,
  10. EventSecondaryDown,
  11. EventTertiaryDown,
  12. EventPrimaryUp,
  13. EventSecondaryUp,
  14. EventTertiaryUp,
  15. EventMouseMove,
  16. EventMouseExit,
  17. EventMouseEnter,
  18. EventWindowClose,
  19. EventOtherDown = 0xff,
  20. EventOtherUp = 0xffff,
  21. };
  22. void OSXEventRoutine(void* window, int event, int p1, int p2);
  23. void _D_OSXInitView(void* windPtr, struct _OSXViewPlatformVars* viewVars);
  24. @interface _OSXWindow : NSWindow {
  25. @public
  26. void* window;
  27. struct _OSXWindowPlatformVars* window_info;
  28. }
  29. @end
  30. @interface _OSXView : NSView <NSWindowDelegate> {
  31. @public
  32. void* window;
  33. struct _OSXWindowPlatformVars* window_info;
  34. bool acceptMouse;
  35. }
  36. - (void)tick:(NSTimer*)timer;
  37. - (void)OSX_HandleEvent:(NSEvent*)event;
  38. @end
  39. @implementation _OSXWindow
  40. - (void)drawRect:(NSRect)rect {
  41. window_info->viewVars->nsRect = [ window_info->viewVars->viewRef bounds ];
  42. [ window_info->viewVars->viewRef setNeedsDisplay:YES ];
  43. OSXEventRoutine(window_info->windowClassRef, EventResize, window_info->viewVars->nsRect.size.width, window_info->viewVars->nsRect.size.height);
  44. }
  45. -(BOOL)isFlipped {
  46. return YES;
  47. }
  48. - (BOOL)acceptsMouseMovedEvents {
  49. return YES;
  50. }
  51. @end
  52. @implementation _OSXView
  53. -(BOOL)isFlipped {
  54. return YES;
  55. }
  56. -(void)windowWillClose:(NSNotification *)notification {
  57. OSXEventRoutine(window_info->windowClassRef, EventWindowClose, 0, 0);
  58. }
  59. - (BOOL)acceptsFirstResponder {
  60. return YES;
  61. }
  62. - (BOOL)acceptsMouseMovedEvents {
  63. return YES;
  64. }
  65. /*
  66. -(void)windowDidExpose:(NSNotification*)aNotification {
  67. printf("OBJ-C: done with windowDidExpose\n");
  68. }
  69. -(void)windowDidUpdate:(NSNotification*)aNotification {
  70. window_info->viewVars->nsRect = [ window_info->viewVars->viewRef bounds ];
  71. [ window_info->viewVars->viewRef setNeedsDisplay:YES ];
  72. OSXEventRoutine(window_info->windowClassRef, EventResize, window_info->viewVars->nsRect.size.width, window_info->viewVars->nsRect.size.height);
  73. printf("OBJ-C: done with windowDidUpdate\n");
  74. }
  75. -(void)windowDidResize:(NSNotification*)aNotification {
  76. printf("OBJ-C: done with windowDidResize\n");
  77. }
  78. */
  79. - (void)drawRect:(NSRect)rect {
  80. window_info->viewVars->nsRect = [ window_info->viewVars->viewRef bounds ];
  81. [ window_info->viewVars->viewRef setNeedsDisplay:YES ];
  82. OSXEventRoutine(window_info->windowClassRef, EventResize, window_info->viewVars->nsRect.size.width, window_info->viewVars->nsRect.size.height);
  83. // printf("OBJ-C: done with drawRect\n");
  84. }
  85. - (void)mouseExited:(NSEvent*)event {
  86. acceptMouse = false;
  87. [ self OSX_HandleEvent:event ];
  88. }
  89. - (void)mouseEntered:(NSEvent*)event {
  90. acceptMouse = true;
  91. [ self OSX_HandleEvent:event ];
  92. }
  93. - (void)mouseDown:(NSEvent*)event {
  94. [ self OSX_HandleEvent:event ];
  95. }
  96. - (void)rightMouseDown:(NSEvent*)event {
  97. [ self OSX_HandleEvent:event ];
  98. }
  99. - (void)otherMouseDown:(NSEvent*)event {
  100. [ self OSX_HandleEvent:event ];
  101. }
  102. - (void)mouseUp:(NSEvent*)event {
  103. [ self OSX_HandleEvent:event ];
  104. }
  105. - (void)rightMouseUp:(NSEvent*)event {
  106. [ self OSX_HandleEvent:event ];
  107. }
  108. - (void)otherMouseUp:(NSEvent*)event {
  109. [ self OSX_HandleEvent:event ];
  110. }
  111. - (void)mouseMoved:(NSEvent*)event {
  112. if (acceptMouse) {
  113. [ self OSX_HandleEvent:event ];
  114. }
  115. }
  116. - (void)mouseDragged:(NSEvent*)event {
  117. [ self OSX_HandleEvent:event ];
  118. }
  119. - (void)OSX_HandleEvent:(NSEvent*)event {
  120. NSPoint coord;
  121. switch ( [ event type ] ) {
  122. case NSMouseExited:
  123. OSXEventRoutine(window_info->windowClassRef, EventMouseExit, 0, 0);
  124. break;
  125. case NSMouseEntered:
  126. OSXEventRoutine(window_info->windowClassRef, EventMouseEnter, 0, 0);
  127. break;
  128. case NSLeftMouseDown:
  129. case NSRightMouseDown:
  130. case NSOtherMouseDown:
  131. coord = [ window_info->viewVars->viewRef convertPoint:[ event locationInWindow ] fromView: nil ];
  132. int xysend;
  133. xysend = coord.x;
  134. xysend |= ((int)coord.y << 16);
  135. switch ( [ event buttonNumber ] ) {
  136. case 0:
  137. OSXEventRoutine(window_info->windowClassRef, EventPrimaryDown, xysend, [ event clickCount ] );
  138. break;
  139. case 1:
  140. OSXEventRoutine(window_info->windowClassRef, EventSecondaryDown, xysend, [ event clickCount ] );
  141. break;
  142. case 2:
  143. OSXEventRoutine(window_info->windowClassRef, EventTertiaryDown, xysend, [ event clickCount ] );
  144. break;
  145. default:
  146. OSXEventRoutine(window_info->windowClassRef, EventOtherDown + ( [ event buttonNumber ] - 3 ), xysend, [ event clickCount ] );
  147. break;
  148. }
  149. break;
  150. case NSLeftMouseUp:
  151. case NSRightMouseUp:
  152. case NSOtherMouseUp:
  153. coord = [ window_info->viewVars->viewRef convertPoint:[ event locationInWindow ] fromView: nil ];
  154. int xysendup;
  155. xysendup = coord.x;
  156. xysendup |= ((int)coord.y << 16);
  157. switch ( [ event buttonNumber ] ) {
  158. case 0:
  159. OSXEventRoutine(window_info->windowClassRef, EventPrimaryUp, xysendup, [ event clickCount ] );
  160. break;
  161. case 1:
  162. OSXEventRoutine(window_info->windowClassRef, EventSecondaryUp, xysendup, [ event clickCount ] );
  163. break;
  164. case 2:
  165. OSXEventRoutine(window_info->windowClassRef, EventTertiaryUp, xysendup, [ event clickCount ] );
  166. break;
  167. default:
  168. OSXEventRoutine(window_info->windowClassRef, EventOtherUp + ( [ event buttonNumber ] - 3 ), xysendup, [ event clickCount ] );
  169. break;
  170. }
  171. break;
  172. case NSMouseMoved:
  173. case NSLeftMouseDragged:
  174. case NSRightMouseDragged:
  175. case NSOtherMouseDragged:
  176. coord = [ window_info->viewVars->viewRef convertPoint:[ event locationInWindow ] fromView: nil ];
  177. int xysendmove;
  178. xysendmove = coord.x;
  179. xysendmove |= ((int)coord.y << 16);
  180. OSXEventRoutine(window_info->windowClassRef, EventMouseMove, xysendmove, [ event clickCount ] );
  181. break;
  182. }
  183. }
  184. // FOCUS //
  185. //- (void)windowDidBecomeKey:(NSNotification *)notification {
  186. /*// control receives focus due to window
  187. //fire event
  188. FIRE_WINDOW_EVENT(window, EventGotFocus, 0, 0);
  189. //currently focused control will regain focus
  190. //all controls receive message ???
  191. _internal_file_event_GotFocus(window);*/
  192. //return;
  193. //}
  194. - (void)windowDidResignKey:(NSNotification *)notification {
  195. /*// control loses focus due to window
  196. //fire event
  197. FIRE_WINDOW_EVENT(window, EventLostFocus, 0, 0);
  198. //currently focused control will regain focus
  199. //all controls receive message ???
  200. _internal_file_event_LostFocus(window);*/
  201. }
  202. // ACTION MESSAGES //
  203. -(void)_osx_redraw {
  204. //Scaffold.RequestRedraw(window_info);
  205. }
  206. // TIMERS //
  207. - (void)tick:(NSTimer*)timer {
  208. /*NSValue* val = (NSValue*)[ timer userInfo ];
  209. void* ptr_val = [ val pointerValue ];
  210. _internal_timer_info* tmr_info = (_internal_timer_info*)ptr_val;
  211. _internal_file_event_Timer(window, tmr_info);*/
  212. }
  213. @end
  214. void _OSXWindowShow(struct _OSXWindowPlatformVars* window, int bShow) {
  215. NSWindow* wnd = window->windowRef;
  216. if (bShow) {
  217. [ wnd makeKeyAndOrderFront: nil ]; // displays
  218. } else {
  219. [ wnd orderOut: nil ]; // hides
  220. }
  221. }
  222. void _OSXWindowSetTitle(struct _OSXWindowPlatformVars* window, char* str) {
  223. NSString* nss = [[NSString alloc] initWithUTF8String: str];
  224. [window->windowRef setTitle: nss];
  225. }
  226. struct _OSXViewPlatformVars* _OSXWindowCreate(void* windowRef, struct _OSXWindowPlatformVars* parent, struct _OSXWindowPlatformVars** window, char* initTitle, int initX, int initY, int initW, int initH) {
  227. // initialize the rectangle variable
  228. NSRect graphicsRect = NSMakeRect(initX,initY,initW,initH); //window->_initial_x,window->_initial_y,window->_initial_width,window->_initial_height);
  229. (*window) = malloc( sizeof( struct _OSXWindowPlatformVars ) );
  230. (*window)->viewVars = malloc( sizeof( struct _OSXViewPlatformVars) );
  231. (*window)->windowClassRef = windowRef;
  232. (*window)->viewVars->layout = [[NSLayoutManager alloc] init];
  233. (*window)->viewVars->container = [[NSTextContainer alloc] init];
  234. [ (*window)->viewVars->layout addTextContainer: (*window)->viewVars->container ];
  235. (*window)->viewVars->cur_font = [ [ NSMutableDictionary alloc ] init ];
  236. (*window)->viewVars->txtstore = [ [ NSTextStorage alloc ] init ];
  237. [ (*window)->viewVars->txtstore addLayoutManager:(*window)->viewVars->layout ];
  238. (*window)->viewVars->viewRef = [[[_OSXView alloc] initWithFrame:graphicsRect] autorelease];
  239. NSTrackingArea* tarea = [[ NSTrackingArea alloc ] initWithRect:graphicsRect options:(NSTrackingMouseMoved | NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways | NSTrackingInVisibleRect) owner:(*window)->viewVars->viewRef userInfo:nil ];
  240. [ (*window)->viewVars->viewRef addTrackingArea:tarea ];
  241. (*window)->viewVars->viewRef->window_info = *window;
  242. // the view is responsible for the rest of the setup
  243. (*window)->windowRef = (*window)->viewVars->viewRef->window = [ [_OSXWindow alloc] // create the window
  244. initWithContentRect: graphicsRect
  245. styleMask:NSTitledWindowMask
  246. |NSClosableWindowMask
  247. |NSMiniaturizableWindowMask
  248. backing:NSBackingStoreBuffered
  249. defer:YES ];
  250. _OSXWindowSetTitle(*window, initTitle);
  251. [ (*window)->windowRef setContentView:(NSView*)(*window)->viewVars->viewRef ]; // set window's view
  252. [ (*window)->windowRef setDelegate: (*window)->viewVars->viewRef ];
  253. [ (*window)->windowRef makeFirstResponder: (*window)->viewVars->viewRef ];
  254. [ (*window)->windowRef setAcceptsMouseMovedEvents:NO ];
  255. [ (*window)->windowRef setAcceptsMouseMovedEvents:YES ];
  256. return (*window)->viewVars;
  257. }
  258. void _OSXWindowStartDraw(struct _OSXWindowPlatformVars* windVars, struct _OSXViewPlatformVars* viewVars, int isSysColorWindow, double r, double g, double b) {
  259. // This stops it from painting upside down (for some reason)
  260. [ viewVars->viewRef setNeedsDisplay:YES ];
  261. // StartDraw
  262. // printf("start draw (OBJ-C)\n");
  263. //Fill the background of the window with the window color
  264. if (!isSysColorWindow) {
  265. NSColor* clr;
  266. clr = [ NSColor colorWithDeviceRed:r green:g blue:b alpha:1.0f ];
  267. [ clr set ];
  268. NSRectFill(viewVars->nsRect);
  269. }
  270. // printf("start draw (OBJ-C)\n");
  271. [ [ NSGraphicsContext currentContext ] setShouldAntialias:YES ];
  272. // printf("start draw (OBJ-C)\n");
  273. //Get the CGContextRef
  274. viewVars->cgContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
  275. // printf("start draw (OBJ-C)\n");
  276. //Set default colors
  277. [ [ NSColor blackColor ] setStroke ];
  278. // printf("start draw (OBJ-C)\n");
  279. [ [ NSColor whiteColor ] setFill ];
  280. // printf("start draw done\n");
  281. }