0028110: Configuration - specify Unicode charset instead of multibyte in project...
[occt.git] / src / Draw / Draw_Window_1.mm
CommitLineData
d5f74e42 1// Copyright (c) 2013-2014 OPEN CASCADE SAS
67d97f0e 2//
973c2be1 3// This file is part of Open CASCADE Technology software library.
67d97f0e 4//
d5f74e42 5// This library is free software; you can redistribute it and/or modify it under
6// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 7// by the Free Software Foundation, with special exception defined in the file
8// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9// distribution for complete text of the license and disclaimer of any warranty.
67d97f0e 10//
973c2be1 11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
67d97f0e 13
14#if defined(__APPLE__) && !defined(MACOSX_USE_GLX)
15
16#import <Cocoa/Cocoa.h>
17
18#include <Draw_Window.hxx>
19#include <Cocoa_LocalPool.hxx>
20
21@interface Draw_CocoaView : NSView
22{
23 NSImage* myImage;
24}
25
26- (void )setImage: (NSImage* )theImage;
27- (void )redraw;
28@end
29
30@implementation Draw_CocoaView
31
32- (void )setImage: (NSImage* )theImage
33{
34 [theImage retain];
35 [myImage release];
36 myImage = theImage;
37}
38
39- (BOOL )isFlipped
40{
41 return YES; // for drawing image from left-top corner
42}
43
44- (void )redraw
45{
46 [self setNeedsDisplay: YES];
47}
48
49- (void )drawRect: (NSRect )theRect
50{
5ef127d0 51 (void )theRect;
67d97f0e 52 NSRect aBounds = NSMakeRect (0.0, 0.0, myImage.size.width, myImage.size.height);
53
54 [myImage drawInRect: aBounds
55 fromRect: NSZeroRect
56 operation: NSCompositeSourceOver
57 fraction: 1
58 respectFlipped: YES
59 hints: nil];
60}
61
62- (void )dealloc
63{
64 [myImage release];
65 [super dealloc];
66}
67@end
68
69static Standard_Integer getScreenBottom()
70{
71 NSRect aRect = [[[NSScreen screens] objectAtIndex:0] frame];
72 Standard_Integer aScreenBottom = Standard_Integer(aRect.size.height + aRect.origin.y);
73 return aScreenBottom;
74}
75
76extern Standard_Boolean Draw_VirtualWindows;
77static Standard_Boolean Draw_IsInZoomingMode = Standard_False;
78
79Standard_Real Draw_RGBColorsArray[MAXCOLOR][3] = {{1.0, 1.0, 1.0},
80 {1.0, 0.0, 0.0},
81 {0.0, 1.0, 0.0},
82 {0.0, 0.0, 1.0},
83 {0.0, 1.0, 1.0},
84 {1.0, 0.84, 0.0},
85 {1.0, 0.0, 1.0},
86 {1.0, 0.2, 0.7},
87 {1.0, 0.65, 0.0},
88 {1.0, 0.89, 0.88},
89 {1.0, 0.63, 0.48},
90 {0.78, 0.08, 0.52},
91 {1.0, 1.0, 0.0},
92 {0.94, 0.9, 0.55},
93 {1.0, 0.5, 0.31}};
94
95//=======================================================================
96//function : Draw_Window
97//purpose :
98//=======================================================================
99Draw_Window::Draw_Window() :
100 myWindow (NULL),
101 myView (NULL),
102 myImageBuffer (NULL),
103 myUseBuffer (Standard_False),
104 nextWindow (firstWindow),
105 previousWindow (NULL)
106{
107 if (firstWindow != NULL) firstWindow->previousWindow = this;
108 firstWindow = this;
109}
110
111//=======================================================================
112//function : Draw_Window
113//purpose :
114//=======================================================================
115Draw_Window::Draw_Window (Standard_CString theTitle,
116 const Standard_Integer& theXLeft, const Standard_Integer& theYTop,
117 const Standard_Integer& theWidth, const Standard_Integer& theHeight):
118 myWindow (NULL),
119 myView (NULL),
120 myImageBuffer (NULL),
121 myUseBuffer (Standard_False),
122 nextWindow (firstWindow),
123 previousWindow (NULL)
124{
125 if (firstWindow != NULL) firstWindow->previousWindow = this;
126 firstWindow = this;
127 Init (theXLeft, theYTop, theWidth, theHeight);
128 SetTitle (theTitle);
129}
130
131Draw_Window::Draw_Window (NSWindow* theWindow, Standard_CString theTitle,
132 const Standard_Integer& theXLeft, const Standard_Integer& theYTop,
133 const Standard_Integer& theWidth, const Standard_Integer& theHeight):
134 myWindow (NULL),
135 myView (NULL),
136 myImageBuffer (NULL),
137 myUseBuffer (Standard_False),
138 nextWindow (firstWindow),
139 previousWindow (NULL)
140{
141 myWindow = [theWindow retain];
142 if (firstWindow != NULL) firstWindow->previousWindow = this;
143 firstWindow = this;
144 Init (theXLeft, theYTop, theWidth, theHeight);
145 SetTitle (theTitle);
146}
147
148//=======================================================================
149//function : ~Draw_Window
150//purpose :
151//=======================================================================
152Draw_Window::~Draw_Window()
153{
154 if (previousWindow != NULL)
155 {
156 previousWindow->nextWindow = nextWindow;
157 }
158 else
159 {
160 firstWindow = nextWindow;
161 }
162
163 if (nextWindow != NULL)
164 {
165 nextWindow->previousWindow = previousWindow;
166 }
167
168 if (myWindow != NULL)
169 {
170 [myWindow release];
171 myWindow = NULL;
172 }
173
174 if (myView != NULL)
175 {
176 [myView release];
177 myView = NULL;
178 }
179
180 if (myImageBuffer != NULL)
181 {
182 [myImageBuffer release];
183 myImageBuffer = NULL;
184 }
185}
186
187//=======================================================================
188//function : Init
189//purpose :
190//=======================================================================
191void Draw_Window::Init (const Standard_Integer& theXLeft, const Standard_Integer& theYTop,
192 const Standard_Integer& theWidth, const Standard_Integer& theHeight)
193{
194 Cocoa_LocalPool aLocalPool;
195
196 // converting left-bottom coordinate to left-top coordinate
197 Standard_Integer anYTop = getScreenBottom() - theYTop - theHeight;
198
199 if (myWindow == NULL)
200 {
201 NSRect aRectNs = NSMakeRect (theXLeft, anYTop, theWidth, theHeight);
202 NSUInteger aWinStyle = NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask;
203
204 myWindow = [[NSWindow alloc] initWithContentRect: aRectNs
205 styleMask: aWinStyle
206 backing: NSBackingStoreBuffered
207 defer: NO];
208 }
209
210 if (myView == NULL)
211 {
212 NSRect aBounds = [[myWindow contentView] bounds];
213
214 myView = [[Draw_CocoaView alloc] initWithFrame: aBounds];
215 [myWindow setContentView: myView];
216 }
217
218 if (myImageBuffer == NULL)
219 {
220 NSRect aRectNs = [myView bounds];
221 myImageBuffer = [[NSImage alloc] initWithSize: aRectNs.size];
222 }
223
224 [myView setImage: myImageBuffer];
225
226 myUseBuffer = Draw_VirtualWindows;
227
228 myCurrentColor = 3;
229
230 [myWindow setBackgroundColor: NSColor.blackColor];
231 [myWindow setReleasedWhenClosed: NO];
232}
233
234//=======================================================================
235//function : InitBuffer
236//purpose :
237//=======================================================================
238void Draw_Window::InitBuffer()
239{
240 //
241}
242
243//=======================================================================
244//function : SetPosition
245//purpose :
246//=======================================================================
247void Draw_Window::SetPosition (const Standard_Integer& theNewXpos,
248 const Standard_Integer& theNewYpos)
249{
250 NSPoint aNewPosition = NSMakePoint (theNewXpos, theNewYpos);
251 [myWindow setFrameTopLeftPoint: aNewPosition];
252}
253
254//=======================================================================
255//function : SetDimension
256//purpose :
257//=======================================================================
258void Draw_Window::SetDimension (const Standard_Integer& theNewWidth,
259 const Standard_Integer& theNewHeight)
260{
261 NSRect aWindowRect = [myWindow frame];
262 Standard_Integer aNewY = aWindowRect.origin.y + aWindowRect.size.height - theNewHeight;
263 NSRect aNewContentRect = NSMakeRect (aWindowRect.origin.x, aNewY,
264 theNewWidth, theNewHeight);
265 [myWindow setFrame: aNewContentRect display: YES];
266}
267
268//=======================================================================
269//function : GetPosition
270//purpose :
271//=======================================================================
272void Draw_Window::GetPosition (Standard_Integer &thePosX,
273 Standard_Integer &thePosY)
274{
275 NSRect aWindowRect = [myWindow frame];
276 thePosX = aWindowRect.origin.x;
277 thePosY = getScreenBottom() - aWindowRect.origin.y - aWindowRect.size.height;
278}
279
280//=======================================================================
281//function : HeightWin
282//purpose :
283//=======================================================================
284Standard_Integer Draw_Window::HeightWin() const
285{
286 NSRect aViewBounds = [myView bounds];
287 return aViewBounds.size.height;
288}
289
290//=======================================================================
291//function : WidthWin
292//purpose :
293//=======================================================================
294Standard_Integer Draw_Window::WidthWin() const
295{
296 NSRect aViewBounds = [myView bounds];
297 return aViewBounds.size.width;
298}
299
300//=======================================================================
301//function : SetTitle
302//purpose :
303//=======================================================================
ad03c234 304void Draw_Window::SetTitle (const TCollection_AsciiString& theTitle)
67d97f0e 305{
ad03c234 306 NSString* aTitleNs = [[NSString alloc] initWithUTF8String: theTitle.ToCString()];
67d97f0e 307 [myWindow setTitle: aTitleNs];
308 [aTitleNs release];
309}
310
311//=======================================================================
312//function : GetTitle
313//purpose :
314//=======================================================================
ad03c234 315TCollection_AsciiString Draw_Window::GetTitle() const
67d97f0e 316{
317 Standard_CString aTitle = [[myWindow title] UTF8String];
ad03c234 318 return TCollection_AsciiString (aTitle);
67d97f0e 319}
320
321//=======================================================================
322//function :DefineColor
323//purpose :
324//=======================================================================
325Standard_Boolean Draw_Window::DefineColor (const Standard_Integer&, Standard_CString)
326{
327 return Standard_True; // unused
328}
329
330//=======================================================================
331//function : DisplayWindow
332//purpose :
333//=======================================================================
334void Draw_Window::DisplayWindow()
335{
336 if (Draw_VirtualWindows)
337 {
338 return;
339 }
340
341 if (myWindow != NULL)
342 {
343 [myWindow orderFront: NULL];
344 }
345}
346
347//=======================================================================
348//function : Hide
349//purpose :
350//=======================================================================
351void Draw_Window::Hide()
352{
353 if (myWindow != NULL)
354 {
355 [myWindow orderOut: NULL];
356 }
357}
358
359//=======================================================================
360//function : Destroy
361//purpose :
362//=======================================================================
363void Draw_Window::Destroy()
364{
365 if (myWindow != NULL)
366 {
367 [myWindow release];
368 myWindow = NULL;
369 }
370
371 if (myView != NULL)
372 {
373 [myView release];
374 myView = NULL;
375 }
376
377 if (myImageBuffer != NULL)
378 {
379 [myImageBuffer release];
380 myImageBuffer = NULL;
381 }
382}
383
384//=======================================================================
385//function : Clear
386//purpose :
387//=======================================================================
388void Draw_Window::Clear()
389{
390 [myImageBuffer lockFocus];
391 [[NSColor blackColor] set];
392 NSRect anImageBounds = NSMakeRect (0.0, 0.0, myImageBuffer.size.width, myImageBuffer.size.height);
393 NSRectFill (anImageBounds);
394 [myImageBuffer unlockFocus];
395
396 if (!myUseBuffer)
397 {
398 [myView redraw];
399 }
400}
401
402//=======================================================================
403//function : Flush
404//purpose :
405//=======================================================================
406void Draw_Window::Flush()
407{
408 //
409}
410
411//=======================================================================
412//function : DrawString
413//purpose :
414//=======================================================================
415void Draw_Window::DrawString (const Standard_Integer& theXLeft, const Standard_Integer& theYTop, char* theText)
416{
417 Cocoa_LocalPool aLocalPool;
418
419 NSString* aTextNs = [[[NSString alloc] initWithUTF8String: theText] autorelease];
420 NSColor* aColor = [NSColor colorWithDeviceRed: Draw_RGBColorsArray[myCurrentColor][0]
421 green: Draw_RGBColorsArray[myCurrentColor][1]
422 blue: Draw_RGBColorsArray[myCurrentColor][2]
423 alpha: 1.0f];
424 NSDictionary* anAttributes = [[[NSDictionary alloc] initWithObjectsAndKeys: aColor, NSForegroundColorAttributeName, nil] autorelease];
425
426 [myImageBuffer lockFocus];
427 [aTextNs drawAtPoint: NSMakePoint (theXLeft, myImageBuffer.size.height - theYTop) withAttributes: anAttributes];
428 [myImageBuffer unlockFocus];
429
430 if (!myUseBuffer)
431 {
432 [myView redraw];
433 }
434}
435
436//=======================================================================
437//function : DrawSegments
438//purpose :
439//=======================================================================
440void Draw_Window::DrawSegments (Segment *theSegment, const Standard_Integer& theNumberOfElements)
441{
442 Cocoa_LocalPool aLocalPool;
443
444 NSBezierPath* aPath = [[[NSBezierPath alloc] init] autorelease];
445
446 NSImage* anImage;
447 Standard_Integer anIter = 0;
448
449 if (Draw_IsInZoomingMode)
450 {
451 // workaround for rectangle drawing when zooming
452 anImage = [[myImageBuffer copy] autorelease];
453 anIter = 4;
454 }
455 else
456 {
457 anImage = myImageBuffer;
458 }
459
460
461 for (; anIter < theNumberOfElements; anIter++)
462 {
463 NSPoint aPoint = NSMakePoint (theSegment[anIter].myXStart, myImageBuffer.size.height - theSegment[anIter].myYStart);
464 [aPath moveToPoint: aPoint];
465 aPoint = NSMakePoint (theSegment[anIter].myXEnd, myImageBuffer.size.height - theSegment[anIter].myYEnd);
466 [aPath lineToPoint: aPoint];
467 }
468
469 [anImage lockFocus];
470 NSColor* aColor = [NSColor colorWithDeviceRed: Draw_RGBColorsArray[myCurrentColor][0]
471 green: Draw_RGBColorsArray[myCurrentColor][1]
472 blue: Draw_RGBColorsArray[myCurrentColor][2]
473 alpha: 1.0f];
474 [aColor set];
475 [aPath stroke];
476 [anImage unlockFocus];
477
478 if (!myUseBuffer)
479 {
480 [myView setImage: anImage];
481 [myView redraw];
482 }
483
484 Draw_IsInZoomingMode = Standard_False;
485}
486
487//=======================================================================
488//function : Redraw
489//purpose :
490//=======================================================================
491void Draw_Window::Redraw()
492{
493 if (myUseBuffer)
494 {
495 [myView redraw];
496 }
497}
498
499//=======================================================================
500//function : SetColor
501//purpose :
502//=======================================================================
503void Draw_Window::SetColor (const Standard_Integer& theColor)
504{
505 myCurrentColor = theColor;
506}
507
508//=======================================================================
509//function : SetMode
510//purpose :
511//=======================================================================
512void Draw_Window::SetMode (const Standard_Integer& theMode)
513{
5ef127d0 514 // unsupported
515 (void )theMode;
67d97f0e 516}
517
518//=======================================================================
519//function : Save
520//purpose :
521//=======================================================================
522Standard_Boolean Draw_Window::Save (Standard_CString theFileName) const
523{
524 Cocoa_LocalPool aLocalPool;
525
526 NSString* aFileName = [[[NSString alloc] initWithUTF8String: theFileName] autorelease];
527 NSString* aFileExtension = [[aFileName pathExtension] lowercaseString];
528
529 NSDictionary* aFileTypeDict = [NSDictionary dictionaryWithObjectsAndKeys:
530 [NSNumber numberWithInt: NSPNGFileType], @"png",
531 [NSNumber numberWithInt: NSBMPFileType], @"bmp",
532 [NSNumber numberWithInt: NSJPEGFileType], @"jpg",
533 [NSNumber numberWithInt: NSGIFFileType], @"gif",
534 nil];
52f7e0d0 535 if ([aFileTypeDict valueForKey: aFileExtension] == NULL)
67d97f0e 536 {
537 return Standard_False; // unsupported image extension
538 }
539
52f7e0d0 540 NSBitmapImageFileType aFileType = (NSBitmapImageFileType )[[aFileTypeDict valueForKey: aFileExtension] intValue];
67d97f0e 541 NSBitmapImageRep* anImageRep = [NSBitmapImageRep imageRepWithData: [myImageBuffer TIFFRepresentation]];
542
5ef127d0 543 NSDictionary* anImgProps = [NSDictionary dictionaryWithObject: [NSNumber numberWithFloat: 0.8]
544 forKey: NSImageCompressionFactor];
545
67d97f0e 546 NSData* aData = [anImageRep representationUsingType: aFileType
5ef127d0 547 properties: anImgProps];
67d97f0e 548
549 Standard_Boolean isSuccess = [aData writeToFile: aFileName
550 atomically: NO];
551
552 return isSuccess;
553}
554
555Standard_Boolean Draw_Window::IsEqualWindows (const Standard_Integer& theWindowNumber)
556{
557 return ([myWindow windowNumber] == theWindowNumber);
558}
559
560void GetNextEvent (Standard_Boolean theWait,
561 Standard_Integer& theWindowNumber,
562 Standard_Integer& theX,
563 Standard_Integer& theY,
564 Standard_Integer& theButton)
565{
566 Cocoa_LocalPool aLocalPool;
567
568 unsigned int anEventMatchMask = NSLeftMouseDownMask | NSRightMouseDownMask;
569
570 if (!theWait)
571 {
572 anEventMatchMask = anEventMatchMask | NSMouseMovedMask | NSLeftMouseDraggedMask;
573 Draw_IsInZoomingMode = Standard_True;
574 }
575
576 NSEvent* anEvent = [NSApp nextEventMatchingMask: anEventMatchMask
577 untilDate: [NSDate distantFuture]
578 inMode: NSEventTrackingRunLoopMode
579 dequeue: YES];
580
581 NSWindow* aWindow = [anEvent window];
582 NSView* aView = [aWindow contentView];
583 theWindowNumber = [aWindow windowNumber];
584
585 NSPoint aMouseLoc = [aView convertPoint: [anEvent locationInWindow] fromView: nil];
67d97f0e 586
587 theX = Standard_Integer (aMouseLoc.x);
588 theY = Standard_Integer (aMouseLoc.y);
589
590 NSEventType anEventType = [anEvent type];
591
592 if (anEventType == NSLeftMouseDown)
593 {
594 theButton = 1;
595 }
596 else if (anEventType == NSRightMouseDown)
597 {
598 theButton = 3;
599 }
600 else if ((anEventType == NSMouseMoved || anEventType == NSLeftMouseDragged) && !theWait)
601 {
602 theButton = 0;
603 }
604}
605#endif // __APPLE__