8966e59d8d571211d0ad94fdfacb62e907f6016b
[occt.git] / src / Cocoa / Cocoa_Window.mm
1 // Created on: 2012-11-12
2 // Created by: Kirill GAVRILOV
3 // Copyright (c) 2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20 #import <Cocoa/Cocoa.h>
21
22 #include <Cocoa_Window.hxx>
23
24 #include <Cocoa_LocalPool.hxx>
25
26 #include <Image_AlienPixMap.hxx>
27 #include <Aspect_Convert.hxx>
28 #include <Aspect_GraphicDevice.hxx>
29 #include <Aspect_WindowDefinitionError.hxx>
30
31 IMPLEMENT_STANDARD_HANDLE (Cocoa_Window, Aspect_Window)
32 IMPLEMENT_STANDARD_RTTIEXT(Cocoa_Window, Aspect_Window)
33
34 //! Dummy device class implementation
35 class Cocoa_GraphicDevice : public Aspect_GraphicDevice
36 {
37
38 public:
39
40   virtual Handle_Aspect_GraphicDriver GraphicDriver() const
41   {
42     return NULL;
43   }
44
45   DEFINE_STANDARD_RTTI(Cocoa_GraphicDevice)
46
47 };
48
49 DEFINE_STANDARD_HANDLE(Cocoa_GraphicDevice, Aspect_GraphicDevice)
50
51 IMPLEMENT_STANDARD_HANDLE (Cocoa_GraphicDevice, Aspect_GraphicDevice)
52 IMPLEMENT_STANDARD_RTTIEXT(Cocoa_GraphicDevice, Aspect_GraphicDevice)
53
54 static Standard_Integer getScreenBottom()
55 {
56   Cocoa_LocalPool aLocalPool;
57   NSArray* aScreens = [NSScreen screens];
58   if (aScreens == NULL || [aScreens count] == 0)
59   {
60     return 0;
61   }
62
63   NSScreen* aScreen = (NSScreen* )[aScreens objectAtIndex: 0];
64   NSDictionary* aDict = [aScreen deviceDescription];
65   NSNumber* aNumber = [aDict objectForKey: @"NSScreenNumber"];
66   if (aNumber == NULL
67   || [aNumber isKindOfClass: [NSNumber class]] == NO)
68   {
69     return 0;
70   }
71
72   CGDirectDisplayID aDispId = [aNumber unsignedIntValue];
73   CGRect aRect = CGDisplayBounds(aDispId);
74   return Standard_Integer(aRect.origin.y + aRect.size.height);
75 }
76
77 // =======================================================================
78 // function : Cocoa_Window
79 // purpose  :
80 // =======================================================================
81 Cocoa_Window::Cocoa_Window (const Standard_CString theTitle,
82                             const Standard_Integer thePxLeft,
83                             const Standard_Integer thePxTop,
84                             const Standard_Integer thePxWidth,
85                             const Standard_Integer thePxHeight)
86 : Aspect_Window (new Cocoa_GraphicDevice()),
87   myHWindow (NULL),
88   myHView   (NULL),
89   myXLeft   (thePxLeft),
90   myYTop    (thePxTop),
91   myXRight  (thePxLeft + thePxWidth),
92   myYBottom (thePxTop + thePxHeight)
93 {
94   if (thePxWidth <= 0 || thePxHeight <= 0)
95   {
96     Aspect_WindowDefinitionError::Raise ("Coordinate(s) out of range");
97   }
98   else if (NSApp == NULL)
99   {
100     Aspect_WindowDefinitionError::Raise ("Cocoa application should be instantiated before window");
101     return;
102   }
103
104   // convert top-bottom coordinates to bottom-top (Cocoa)
105   myYTop    = getScreenBottom() - myYBottom;
106   myYBottom = myYTop + thePxHeight;
107
108   Cocoa_LocalPool aLocalPool;
109   NSUInteger aWinStyle = NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask;
110   NSRect aRectNs = NSMakeRect (float(myXLeft), float(myYTop), float(thePxWidth), float(thePxHeight));
111   myHWindow = [[NSWindow alloc] initWithContentRect: aRectNs
112                                           styleMask: aWinStyle
113                                             backing: NSBackingStoreBuffered
114                                               defer: NO];
115   if (myHWindow == NULL)
116   {
117     Aspect_WindowDefinitionError::Raise ("Unable to create window");
118   }
119   myHView = [[myHWindow contentView] retain];
120
121   NSString* aTitleNs = [[NSString alloc] initWithUTF8String: theTitle];
122   [myHWindow setTitle: aTitleNs];
123   [aTitleNs release];
124
125   // do not destroy NSWindow on close - we didn't handle it!
126   [myHWindow setReleasedWhenClosed: NO];
127 }
128
129 // =======================================================================
130 // function : Cocoa_Window
131 // purpose  :
132 // =======================================================================
133 Cocoa_Window::Cocoa_Window (NSView* theViewNS)
134 : Aspect_Window (new Cocoa_GraphicDevice()),
135   myHWindow (NULL),
136   myHView   ([theViewNS retain]),
137   myXLeft   (0),
138   myYTop    (0),
139   myXRight  (512),
140   myYBottom (512)
141 {
142   DoResize();
143 }
144
145 // =======================================================================
146 // function : Destroy
147 // purpose  :
148 // =======================================================================
149 void Cocoa_Window::Destroy()
150 {
151   Cocoa_LocalPool aLocalPool;
152   if (myHWindow != NULL)
153   {
154     //[myHWindow close];
155     [myHWindow release];
156     myHWindow = NULL;
157   }
158   if (myHView != NULL)
159   {
160     [myHView release];
161     myHView = NULL;
162   }
163 }
164
165 // =======================================================================
166 // function : HView
167 // purpose  :
168 // =======================================================================
169 NSView* Cocoa_Window::HView() const
170 {
171   return myHView;
172 }
173
174 // =======================================================================
175 // function : SetHView
176 // purpose  :
177 // =======================================================================
178 void Cocoa_Window::SetHView (NSView* theView)
179 {
180   if (myHWindow != NULL)
181   {
182     [myHWindow setContentView: theView];
183   }
184   if (myHView != NULL)
185   {
186     [myHView release];
187     myHView = NULL;
188   }
189   myHView = [theView retain];
190 }
191
192 // =======================================================================
193 // function : DoubleBuffer
194 // purpose  :
195 // =======================================================================
196 Standard_Boolean Cocoa_Window::DoubleBuffer() const
197 {
198   return Standard_True;
199 }
200
201 // =======================================================================
202 // function : SetBackground
203 // purpose  :
204 // =======================================================================
205 void Cocoa_Window::SetBackground (const Aspect_Background& theBackground)
206 {
207   SetBackground (theBackground.Color());
208 }
209
210 // =======================================================================
211 // function : SetBackground
212 // purpose  :
213 // =======================================================================
214 void Cocoa_Window::SetBackground (const Quantity_NameOfColor theBackColor)
215 {
216   SetBackground (Quantity_Color (theBackColor));
217 }
218
219 // =======================================================================
220 // function : SetBackground
221 // purpose  :
222 // =======================================================================
223 void Cocoa_Window::SetBackground (const Aspect_Handle theBackPixmap)
224 {
225   //
226 }
227
228 // =======================================================================
229 // function : SetBackground
230 // purpose  :
231 // =======================================================================
232 Standard_Boolean Cocoa_Window::SetBackground (const Standard_CString  theFileName,
233                                               const Aspect_FillMethod theMethod)
234 {
235   return Standard_False;
236 }
237
238 // =======================================================================
239 // function : SetBackground
240 // purpose  :
241 // =======================================================================
242 void Cocoa_Window::SetBackground (const Quantity_Color& theColor)
243 {
244   //
245 }
246
247 // =======================================================================
248 // function : SetBackground
249 // purpose  :
250 // =======================================================================
251 void Cocoa_Window::SetBackground (const Aspect_GradientBackground& theGrBackground)
252 {
253   Quantity_Color aColor1, aColor2;
254   theGrBackground.Colors (aColor1, aColor2);
255   SetBackground (aColor1, aColor2, theGrBackground.BgGradientFillMethod());
256 }
257
258 // =======================================================================
259 // function : SetBackground
260 // purpose  :
261 // =======================================================================
262 void Cocoa_Window::SetBackground (const Quantity_Color&           theColor1,
263                                   const Quantity_Color&           theColor2,
264                                   const Aspect_GradientFillMethod theMethod)
265 {
266   //
267 }
268
269 // =======================================================================
270 // function : SetDoubleBuffer
271 // purpose  :
272 // =======================================================================
273 void Cocoa_Window::SetDoubleBuffer (const Standard_Boolean )
274 {
275   //
276 }
277
278 // =======================================================================
279 // function : Flush
280 // purpose  :
281 // =======================================================================
282 void Cocoa_Window::Flush() const
283 {
284   Restore();
285 }
286
287 // =======================================================================
288 // function : IsMapped
289 // purpose  :
290 // =======================================================================
291 Standard_Boolean Cocoa_Window::IsMapped() const
292 {
293   if (IsVirtual())
294   {
295     return Standard_True;
296   }
297
298   return (myHView != NULL) &&  [[myHView window] isVisible];
299 }
300
301 // =======================================================================
302 // function : Map
303 // purpose  :
304 // =======================================================================
305 void Cocoa_Window::Map() const
306 {
307   if (IsVirtual())
308   {
309     return;
310   }
311
312   if (myHView != NULL)
313   {
314     [[myHView window] orderFront: NULL];
315   }
316 }
317
318 // =======================================================================
319 // function : Unmap
320 // purpose  :
321 // =======================================================================
322 void Cocoa_Window::Unmap() const
323 {
324   if (myHView != NULL)
325   {
326     [[myHView window] orderOut: NULL];
327   }
328 }
329
330 // =======================================================================
331 // function : DoResize
332 // purpose  :
333 // =======================================================================
334 Aspect_TypeOfResize Cocoa_Window::DoResize() const
335 {
336   if (myHView == NULL)
337   {
338     return Aspect_TOR_UNKNOWN;
339   }
340
341   NSRect aBounds = [myHView bounds];
342   Standard_Integer aMask = 0;
343   Aspect_TypeOfResize aMode = Aspect_TOR_UNKNOWN;
344
345   if (Abs ((Standard_Integer )aBounds.origin.x                         - myXLeft  ) > 2) aMask |= 1;
346   if (Abs ((Standard_Integer )(aBounds.origin.x + aBounds.size.width)  - myXRight ) > 2) aMask |= 2;
347   if (Abs ((Standard_Integer )aBounds.origin.y                         - myYTop   ) > 2) aMask |= 4;
348   if (Abs ((Standard_Integer )(aBounds.origin.y + aBounds.size.height) - myYBottom) > 2) aMask |= 8;
349   switch (aMask)
350   {
351     case 0:  aMode = Aspect_TOR_NO_BORDER;               break;
352     case 1:  aMode = Aspect_TOR_LEFT_BORDER;             break;
353     case 2:  aMode = Aspect_TOR_RIGHT_BORDER;            break;
354     case 4:  aMode = Aspect_TOR_TOP_BORDER;              break;
355     case 5:  aMode = Aspect_TOR_LEFT_AND_TOP_BORDER;     break;
356     case 6:  aMode = Aspect_TOR_TOP_AND_RIGHT_BORDER;    break;
357     case 8:  aMode = Aspect_TOR_BOTTOM_BORDER;           break;
358     case 9:  aMode = Aspect_TOR_BOTTOM_AND_LEFT_BORDER;  break;
359     case 10: aMode = Aspect_TOR_RIGHT_AND_BOTTOM_BORDER; break;
360     default: break;
361   }
362
363   *((Standard_Integer* )&myXLeft   ) = (Standard_Integer )aBounds.origin.x;
364   *((Standard_Integer* )&myXRight  ) = (Standard_Integer )(aBounds.origin.x + aBounds.size.width);
365   *((Standard_Integer* )&myYTop    ) = (Standard_Integer )aBounds.origin.y;
366   *((Standard_Integer* )&myYBottom ) = (Standard_Integer )(aBounds.origin.y + aBounds.size.height);
367   return aMode;
368 }
369
370 // =======================================================================
371 // function : DoMapping
372 // purpose  :
373 // =======================================================================
374 Standard_Boolean Cocoa_Window::DoMapping() const
375 {
376   return Standard_True;
377 }
378
379 // =======================================================================
380 // function : Clear
381 // purpose  :
382 // =======================================================================
383 void Cocoa_Window::Clear() const
384 {
385   //
386 }
387
388 // =======================================================================
389 // function : ClearArea
390 // purpose  :
391 // =======================================================================
392 void Cocoa_Window::ClearArea (const Standard_Integer Xc,
393                               const Standard_Integer Yc,
394                               const Standard_Integer Width,
395                               const Standard_Integer Height) const
396 {
397   //
398 }
399
400 // =======================================================================
401 // function : Restore
402 // purpose  :
403 // =======================================================================
404 void Cocoa_Window::Restore() const
405 {
406   //
407 }
408
409 // =======================================================================
410 // function : RestoreArea
411 // purpose  :
412 // =======================================================================
413 void Cocoa_Window::RestoreArea (const Standard_Integer Xc,
414                                 const Standard_Integer Yc,
415                                 const Standard_Integer Width,
416                                 const Standard_Integer Height) const
417 {
418   //
419 }
420
421 // =======================================================================
422 // function : Dump
423 // purpose  :
424 // =======================================================================
425 Standard_Boolean Cocoa_Window::Dump (const Standard_CString theFilename,
426                                      const Standard_Real    theGammaValue) const
427 {
428   /*Image_AlienPixMap anImg;
429   if (!ToPixMap (anImg) || anImg.IsEmpty())
430   {
431     return Standard_False;
432   }
433   if (Abs (theGammaValue - 1.0) > 0.001)
434   {
435     anImg.AdjustGamma (theGammaValue);
436   }
437   return anImg.Save (theFilename);*/
438   return Standard_False;
439 }
440
441 // =======================================================================
442 // function : DumpArea
443 // purpose  :
444 // =======================================================================
445 Standard_Boolean Cocoa_Window::DumpArea (const Standard_CString theFilename,
446                                          const Standard_Integer theCenterX,
447                                          const Standard_Integer theCenterY,
448                                          const Standard_Integer theWidth,
449                                          const Standard_Integer theHeight,
450                                          const Standard_Real    theGammaValue) const
451 {
452   return Standard_False;
453 }
454
455 // =======================================================================
456 // function : ToPixMap
457 // purpose  :
458 // =======================================================================
459 /*Standard_Boolean Cocoa_Window::ToPixMap (Image_PixMap& thePixMap) const
460 {
461   return Standard_False;
462 }*/
463
464 // =======================================================================
465 // function : Load
466 // purpose  :
467 // =======================================================================
468 Standard_Boolean Cocoa_Window::Load (const Standard_CString theFilename) const
469 {
470   return Standard_False;
471 }
472
473 // =======================================================================
474 // function : LoadArea
475 // purpose  :
476 // =======================================================================
477 Standard_Boolean Cocoa_Window::LoadArea (const Standard_CString theFilename,
478                                          const Standard_Integer theCenterX,
479                                          const Standard_Integer theCenterY,
480                                          const Standard_Integer theWidth,
481                                          const Standard_Integer theHeight) const
482 {
483   return Standard_False;
484 }
485
486 // =======================================================================
487 // function : BackingStore
488 // purpose  :
489 // =======================================================================
490 Standard_Boolean Cocoa_Window::BackingStore() const
491 {
492   return Standard_False;
493 }
494
495 // =======================================================================
496 // function : Ratio
497 // purpose  :
498 // =======================================================================
499 Quantity_Ratio Cocoa_Window::Ratio() const
500 {
501   if (myHView == NULL)
502   {
503     return 1.0;
504   }
505
506   NSRect aBounds = [myHView bounds];
507   return Quantity_Ratio (aBounds.size.width / aBounds.size.height);
508 }
509
510 // =======================================================================
511 // function : Position
512 // purpose  :
513 // =======================================================================
514 void Cocoa_Window::Position (Quantity_Parameter& X1, Quantity_Parameter& Y1,
515                              Quantity_Parameter& X2, Quantity_Parameter& Y2) const
516 {
517   //
518 }
519
520 // =======================================================================
521 // function : Position
522 // purpose  :
523 // =======================================================================
524 void Cocoa_Window::Position (Standard_Integer& X1, Standard_Integer& Y1,
525                              Standard_Integer& X2, Standard_Integer& Y2) const
526 {
527   //
528 }
529
530 // =======================================================================
531 // function : Size
532 // purpose  :
533 // =======================================================================
534 void Cocoa_Window::Size (Quantity_Parameter& theWidth,
535                          Quantity_Parameter& theHeight) const
536 {
537   //
538 }
539
540 // =======================================================================
541 // function : Size
542 // purpose  :
543 // =======================================================================
544 void Cocoa_Window::Size (Standard_Integer& theWidth,
545                          Standard_Integer& theHeight) const
546 {
547   if (myHView == NULL)
548   {
549     return;
550   }
551
552   NSRect aBounds = [myHView bounds];
553   theWidth  = (Standard_Integer )aBounds.size.width;
554   theHeight = (Standard_Integer )aBounds.size.height;
555 }
556
557 // =======================================================================
558 // function : MMSize
559 // purpose  :
560 // =======================================================================
561 void Cocoa_Window::MMSize (Standard_Real& theWidth,
562                            Standard_Real& theHeight) const
563 {
564   //
565 }
566
567 // =======================================================================
568 // function : Convert
569 // purpose  :
570 // =======================================================================
571 Quantity_Parameter Cocoa_Window::Convert (const Standard_Integer PV) const
572 {
573   return 0.0; ///
574 }
575
576 // =======================================================================
577 // function : Convert
578 // purpose  :
579 // =======================================================================
580 Standard_Integer Cocoa_Window::Convert (const Quantity_Parameter DV) const
581 {
582   return 0; ////
583 }
584
585 // =======================================================================
586 // function : Convert
587 // purpose  :
588 // =======================================================================
589 void Cocoa_Window::Convert (const Standard_Integer PX,
590                             const Standard_Integer PY,
591                             Quantity_Parameter&    DX,
592                             Quantity_Parameter&    DY) const
593 {
594   //
595 }
596
597 // =======================================================================
598 // function : Convert
599 // purpose  :
600 // =======================================================================
601 void Cocoa_Window::Convert (const Quantity_Parameter DX,
602                             const Quantity_Parameter DY,
603                             Standard_Integer&        PX,
604                             Standard_Integer&        PY) const
605 {
606   //
607 }