0023243: Adapt OpenGL viewer for using in Cocoa applications on Mac OS X
[occt.git] / src / Cocoa / Cocoa_Window.mm
CommitLineData
4fe56619 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
31IMPLEMENT_STANDARD_HANDLE (Cocoa_Window, Aspect_Window)
32IMPLEMENT_STANDARD_RTTIEXT(Cocoa_Window, Aspect_Window)
33
34//! Dummy device class implementation
35class Cocoa_GraphicDevice : public Aspect_GraphicDevice
36{
37
38public:
39
40 virtual Handle_Aspect_GraphicDriver GraphicDriver() const
41 {
42 return NULL;
43 }
44
45 DEFINE_STANDARD_RTTI(Cocoa_GraphicDevice)
46
47};
48
49DEFINE_STANDARD_HANDLE(Cocoa_GraphicDevice, Aspect_GraphicDevice)
50
51IMPLEMENT_STANDARD_HANDLE (Cocoa_GraphicDevice, Aspect_GraphicDevice)
52IMPLEMENT_STANDARD_RTTIEXT(Cocoa_GraphicDevice, Aspect_GraphicDevice)
53
54static 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// =======================================================================
81Cocoa_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// =======================================================================
133Cocoa_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// =======================================================================
149void 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// =======================================================================
169NSView* Cocoa_Window::HView() const
170{
171 return myHView;
172}
173
174// =======================================================================
175// function : SetHView
176// purpose :
177// =======================================================================
178void 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// =======================================================================
196Standard_Boolean Cocoa_Window::DoubleBuffer() const
197{
198 return Standard_True;
199}
200
201// =======================================================================
202// function : SetBackground
203// purpose :
204// =======================================================================
205void Cocoa_Window::SetBackground (const Aspect_Background& theBackground)
206{
207 SetBackground (theBackground.Color());
208}
209
210// =======================================================================
211// function : SetBackground
212// purpose :
213// =======================================================================
214void Cocoa_Window::SetBackground (const Quantity_NameOfColor theBackColor)
215{
216 SetBackground (Quantity_Color (theBackColor));
217}
218
219// =======================================================================
220// function : SetBackground
221// purpose :
222// =======================================================================
223void Cocoa_Window::SetBackground (const Aspect_Handle theBackPixmap)
224{
225 //
226}
227
228// =======================================================================
229// function : SetBackground
230// purpose :
231// =======================================================================
232Standard_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// =======================================================================
242void Cocoa_Window::SetBackground (const Quantity_Color& theColor)
243{
244 //
245}
246
247// =======================================================================
248// function : SetBackground
249// purpose :
250// =======================================================================
251void 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// =======================================================================
262void 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// =======================================================================
273void Cocoa_Window::SetDoubleBuffer (const Standard_Boolean )
274{
275 //
276}
277
278// =======================================================================
279// function : Flush
280// purpose :
281// =======================================================================
282void Cocoa_Window::Flush() const
283{
284 Restore();
285}
286
287// =======================================================================
288// function : IsMapped
289// purpose :
290// =======================================================================
291Standard_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// =======================================================================
305void 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// =======================================================================
322void 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// =======================================================================
334Aspect_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// =======================================================================
374Standard_Boolean Cocoa_Window::DoMapping() const
375{
376 return Standard_True;
377}
378
379// =======================================================================
380// function : Clear
381// purpose :
382// =======================================================================
383void Cocoa_Window::Clear() const
384{
385 //
386}
387
388// =======================================================================
389// function : ClearArea
390// purpose :
391// =======================================================================
392void 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// =======================================================================
404void Cocoa_Window::Restore() const
405{
406 //
407}
408
409// =======================================================================
410// function : RestoreArea
411// purpose :
412// =======================================================================
413void 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// =======================================================================
425Standard_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// =======================================================================
445Standard_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// =======================================================================
468Standard_Boolean Cocoa_Window::Load (const Standard_CString theFilename) const
469{
470 return Standard_False;
471}
472
473// =======================================================================
474// function : LoadArea
475// purpose :
476// =======================================================================
477Standard_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// =======================================================================
490Standard_Boolean Cocoa_Window::BackingStore() const
491{
492 return Standard_False;
493}
494
495// =======================================================================
496// function : Ratio
497// purpose :
498// =======================================================================
499Quantity_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// =======================================================================
514void 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// =======================================================================
524void 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// =======================================================================
534void Cocoa_Window::Size (Quantity_Parameter& theWidth,
535 Quantity_Parameter& theHeight) const
536{
537 //
538}
539
540// =======================================================================
541// function : Size
542// purpose :
543// =======================================================================
544void 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// =======================================================================
561void Cocoa_Window::MMSize (Standard_Real& theWidth,
562 Standard_Real& theHeight) const
563{
564 //
565}
566
567// =======================================================================
568// function : Convert
569// purpose :
570// =======================================================================
571Quantity_Parameter Cocoa_Window::Convert (const Standard_Integer PV) const
572{
573 return 0.0; ///
574}
575
576// =======================================================================
577// function : Convert
578// purpose :
579// =======================================================================
580Standard_Integer Cocoa_Window::Convert (const Quantity_Parameter DV) const
581{
582 return 0; ////
583}
584
585// =======================================================================
586// function : Convert
587// purpose :
588// =======================================================================
589void 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// =======================================================================
601void Cocoa_Window::Convert (const Quantity_Parameter DX,
602 const Quantity_Parameter DY,
603 Standard_Integer& PX,
604 Standard_Integer& PY) const
605{
606 //
607}