1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-05-01 10:26:12 +03:00
occt/src/Draw/Draw_Window_1.mm
dbv 67d97f0eec 0023682: Implement Draw_Window with Cocoa framework
Implemented most Draw_Window functions with Cocoa. Still should be implemented: drawing rectangle when zooming, window screenshot function in QAxwd
Added workaround for drawing rectangle when zooming
Added small fixes
2013-01-18 15:04:50 +04:00

613 lines
18 KiB
Plaintext

// Copyright 2012 OPEN CASCADE SAS
//
// The content of this file is subject to the Open CASCADE Technology Public
// License Version 6.5 (the "License"). You may not use the content of this file
// except in compliance with the License. Please obtain a copy of the License
// at http://www.opencascade.org and read it completely before using this file.
//
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
//
// The Original Code and all software distributed under the License is
// distributed on an "AS IS" basis, without warranty of any kind, and the
// Initial Developer hereby disclaims all such warranties, including without
// limitation, any warranties of merchantability, fitness for a particular
// purpose or non-infringement. Please see the License for the specific terms
// and conditions governing the rights and limitations under the License.
#if defined(__APPLE__) && !defined(MACOSX_USE_GLX)
#import <Cocoa/Cocoa.h>
#include <Draw_Window.hxx>
#include <Cocoa_LocalPool.hxx>
@interface Draw_CocoaView : NSView
{
NSImage* myImage;
}
- (void )setImage: (NSImage* )theImage;
- (void )redraw;
@end
@implementation Draw_CocoaView
- (void )setImage: (NSImage* )theImage
{
[theImage retain];
[myImage release];
myImage = theImage;
}
- (BOOL )isFlipped
{
return YES; // for drawing image from left-top corner
}
- (void )redraw
{
[self setNeedsDisplay: YES];
}
- (void )drawRect: (NSRect )theRect
{
NSRect aBounds = NSMakeRect (0.0, 0.0, myImage.size.width, myImage.size.height);
[myImage drawInRect: aBounds
fromRect: NSZeroRect
operation: NSCompositeSourceOver
fraction: 1
respectFlipped: YES
hints: nil];
}
- (void )dealloc
{
[myImage release];
[super dealloc];
}
@end
static Standard_Integer getScreenBottom()
{
NSRect aRect = [[[NSScreen screens] objectAtIndex:0] frame];
Standard_Integer aScreenBottom = Standard_Integer(aRect.size.height + aRect.origin.y);
return aScreenBottom;
}
extern Standard_Boolean Draw_VirtualWindows;
static Standard_Boolean Draw_IsInZoomingMode = Standard_False;
Standard_Real Draw_RGBColorsArray[MAXCOLOR][3] = {{1.0, 1.0, 1.0},
{1.0, 0.0, 0.0},
{0.0, 1.0, 0.0},
{0.0, 0.0, 1.0},
{0.0, 1.0, 1.0},
{1.0, 0.84, 0.0},
{1.0, 0.0, 1.0},
{1.0, 0.2, 0.7},
{1.0, 0.65, 0.0},
{1.0, 0.89, 0.88},
{1.0, 0.63, 0.48},
{0.78, 0.08, 0.52},
{1.0, 1.0, 0.0},
{0.94, 0.9, 0.55},
{1.0, 0.5, 0.31}};
//=======================================================================
//function : Draw_Window
//purpose :
//=======================================================================
Draw_Window::Draw_Window() :
myWindow (NULL),
myView (NULL),
myImageBuffer (NULL),
myUseBuffer (Standard_False),
nextWindow (firstWindow),
previousWindow (NULL)
{
if (firstWindow != NULL) firstWindow->previousWindow = this;
firstWindow = this;
}
//=======================================================================
//function : Draw_Window
//purpose :
//=======================================================================
Draw_Window::Draw_Window (Standard_CString theTitle,
const Standard_Integer& theXLeft, const Standard_Integer& theYTop,
const Standard_Integer& theWidth, const Standard_Integer& theHeight):
myWindow (NULL),
myView (NULL),
myImageBuffer (NULL),
myUseBuffer (Standard_False),
nextWindow (firstWindow),
previousWindow (NULL)
{
if (firstWindow != NULL) firstWindow->previousWindow = this;
firstWindow = this;
Init (theXLeft, theYTop, theWidth, theHeight);
SetTitle (theTitle);
}
Draw_Window::Draw_Window (NSWindow* theWindow, Standard_CString theTitle,
const Standard_Integer& theXLeft, const Standard_Integer& theYTop,
const Standard_Integer& theWidth, const Standard_Integer& theHeight):
myWindow (NULL),
myView (NULL),
myImageBuffer (NULL),
myUseBuffer (Standard_False),
nextWindow (firstWindow),
previousWindow (NULL)
{
myWindow = [theWindow retain];
if (firstWindow != NULL) firstWindow->previousWindow = this;
firstWindow = this;
Init (theXLeft, theYTop, theWidth, theHeight);
SetTitle (theTitle);
}
//=======================================================================
//function : ~Draw_Window
//purpose :
//=======================================================================
Draw_Window::~Draw_Window()
{
if (previousWindow != NULL)
{
previousWindow->nextWindow = nextWindow;
}
else
{
firstWindow = nextWindow;
}
if (nextWindow != NULL)
{
nextWindow->previousWindow = previousWindow;
}
if (myWindow != NULL)
{
[myWindow release];
myWindow = NULL;
}
if (myView != NULL)
{
[myView release];
myView = NULL;
}
if (myImageBuffer != NULL)
{
[myImageBuffer release];
myImageBuffer = NULL;
}
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void Draw_Window::Init (const Standard_Integer& theXLeft, const Standard_Integer& theYTop,
const Standard_Integer& theWidth, const Standard_Integer& theHeight)
{
Cocoa_LocalPool aLocalPool;
// converting left-bottom coordinate to left-top coordinate
Standard_Integer anYTop = getScreenBottom() - theYTop - theHeight;
if (myWindow == NULL)
{
NSRect aRectNs = NSMakeRect (theXLeft, anYTop, theWidth, theHeight);
NSUInteger aWinStyle = NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask;
myWindow = [[NSWindow alloc] initWithContentRect: aRectNs
styleMask: aWinStyle
backing: NSBackingStoreBuffered
defer: NO];
}
if (myView == NULL)
{
NSRect aBounds = [[myWindow contentView] bounds];
myView = [[Draw_CocoaView alloc] initWithFrame: aBounds];
[myWindow setContentView: myView];
}
if (myImageBuffer == NULL)
{
NSRect aRectNs = [myView bounds];
myImageBuffer = [[NSImage alloc] initWithSize: aRectNs.size];
}
[myView setImage: myImageBuffer];
myUseBuffer = Draw_VirtualWindows;
myCurrentColor = 3;
[myWindow setBackgroundColor: NSColor.blackColor];
[myWindow setReleasedWhenClosed: NO];
}
//=======================================================================
//function : InitBuffer
//purpose :
//=======================================================================
void Draw_Window::InitBuffer()
{
//
}
//=======================================================================
//function : SetPosition
//purpose :
//=======================================================================
void Draw_Window::SetPosition (const Standard_Integer& theNewXpos,
const Standard_Integer& theNewYpos)
{
NSPoint aNewPosition = NSMakePoint (theNewXpos, theNewYpos);
[myWindow setFrameTopLeftPoint: aNewPosition];
}
//=======================================================================
//function : SetDimension
//purpose :
//=======================================================================
void Draw_Window::SetDimension (const Standard_Integer& theNewWidth,
const Standard_Integer& theNewHeight)
{
NSRect aWindowRect = [myWindow frame];
Standard_Integer aNewY = aWindowRect.origin.y + aWindowRect.size.height - theNewHeight;
NSRect aNewContentRect = NSMakeRect (aWindowRect.origin.x, aNewY,
theNewWidth, theNewHeight);
[myWindow setFrame: aNewContentRect display: YES];
}
//=======================================================================
//function : GetPosition
//purpose :
//=======================================================================
void Draw_Window::GetPosition (Standard_Integer &thePosX,
Standard_Integer &thePosY)
{
NSRect aWindowRect = [myWindow frame];
thePosX = aWindowRect.origin.x;
thePosY = getScreenBottom() - aWindowRect.origin.y - aWindowRect.size.height;
}
//=======================================================================
//function : HeightWin
//purpose :
//=======================================================================
Standard_Integer Draw_Window::HeightWin() const
{
NSRect aViewBounds = [myView bounds];
return aViewBounds.size.height;
}
//=======================================================================
//function : WidthWin
//purpose :
//=======================================================================
Standard_Integer Draw_Window::WidthWin() const
{
NSRect aViewBounds = [myView bounds];
return aViewBounds.size.width;
}
//=======================================================================
//function : SetTitle
//purpose :
//=======================================================================
void Draw_Window::SetTitle (Standard_CString theTitle)
{
NSString* aTitleNs = [[NSString alloc] initWithUTF8String: theTitle];
[myWindow setTitle: aTitleNs];
[aTitleNs release];
}
//=======================================================================
//function : GetTitle
//purpose :
//=======================================================================
Standard_CString Draw_Window::GetTitle()
{
Standard_CString aTitle = [[myWindow title] UTF8String];
return aTitle;
}
//=======================================================================
//function :DefineColor
//purpose :
//=======================================================================
Standard_Boolean Draw_Window::DefineColor (const Standard_Integer&, Standard_CString)
{
return Standard_True; // unused
}
//=======================================================================
//function : DisplayWindow
//purpose :
//=======================================================================
void Draw_Window::DisplayWindow()
{
if (Draw_VirtualWindows)
{
return;
}
if (myWindow != NULL)
{
[myWindow orderFront: NULL];
}
}
//=======================================================================
//function : Hide
//purpose :
//=======================================================================
void Draw_Window::Hide()
{
if (myWindow != NULL)
{
[myWindow orderOut: NULL];
}
}
//=======================================================================
//function : Destroy
//purpose :
//=======================================================================
void Draw_Window::Destroy()
{
if (myWindow != NULL)
{
[myWindow release];
myWindow = NULL;
}
if (myView != NULL)
{
[myView release];
myView = NULL;
}
if (myImageBuffer != NULL)
{
[myImageBuffer release];
myImageBuffer = NULL;
}
}
//=======================================================================
//function : Clear
//purpose :
//=======================================================================
void Draw_Window::Clear()
{
[myImageBuffer lockFocus];
[[NSColor blackColor] set];
NSRect anImageBounds = NSMakeRect (0.0, 0.0, myImageBuffer.size.width, myImageBuffer.size.height);
NSRectFill (anImageBounds);
[myImageBuffer unlockFocus];
if (!myUseBuffer)
{
[myView redraw];
}
}
//=======================================================================
//function : Flush
//purpose :
//=======================================================================
void Draw_Window::Flush()
{
//
}
//=======================================================================
//function : DrawString
//purpose :
//=======================================================================
void Draw_Window::DrawString (const Standard_Integer& theXLeft, const Standard_Integer& theYTop, char* theText)
{
Cocoa_LocalPool aLocalPool;
NSString* aTextNs = [[[NSString alloc] initWithUTF8String: theText] autorelease];
NSColor* aColor = [NSColor colorWithDeviceRed: Draw_RGBColorsArray[myCurrentColor][0]
green: Draw_RGBColorsArray[myCurrentColor][1]
blue: Draw_RGBColorsArray[myCurrentColor][2]
alpha: 1.0f];
NSDictionary* anAttributes = [[[NSDictionary alloc] initWithObjectsAndKeys: aColor, NSForegroundColorAttributeName, nil] autorelease];
[myImageBuffer lockFocus];
[aTextNs drawAtPoint: NSMakePoint (theXLeft, myImageBuffer.size.height - theYTop) withAttributes: anAttributes];
[myImageBuffer unlockFocus];
if (!myUseBuffer)
{
[myView redraw];
}
}
//=======================================================================
//function : DrawSegments
//purpose :
//=======================================================================
void Draw_Window::DrawSegments (Segment *theSegment, const Standard_Integer& theNumberOfElements)
{
Cocoa_LocalPool aLocalPool;
NSBezierPath* aPath = [[[NSBezierPath alloc] init] autorelease];
NSImage* anImage;
Standard_Integer anIter = 0;
if (Draw_IsInZoomingMode)
{
// workaround for rectangle drawing when zooming
anImage = [[myImageBuffer copy] autorelease];
anIter = 4;
}
else
{
anImage = myImageBuffer;
}
for (; anIter < theNumberOfElements; anIter++)
{
NSPoint aPoint = NSMakePoint (theSegment[anIter].myXStart, myImageBuffer.size.height - theSegment[anIter].myYStart);
[aPath moveToPoint: aPoint];
aPoint = NSMakePoint (theSegment[anIter].myXEnd, myImageBuffer.size.height - theSegment[anIter].myYEnd);
[aPath lineToPoint: aPoint];
}
[anImage lockFocus];
NSColor* aColor = [NSColor colorWithDeviceRed: Draw_RGBColorsArray[myCurrentColor][0]
green: Draw_RGBColorsArray[myCurrentColor][1]
blue: Draw_RGBColorsArray[myCurrentColor][2]
alpha: 1.0f];
[aColor set];
[aPath stroke];
[anImage unlockFocus];
if (!myUseBuffer)
{
[myView setImage: anImage];
[myView redraw];
}
Draw_IsInZoomingMode = Standard_False;
}
//=======================================================================
//function : Redraw
//purpose :
//=======================================================================
void Draw_Window::Redraw()
{
if (myUseBuffer)
{
[myView redraw];
}
}
//=======================================================================
//function : SetColor
//purpose :
//=======================================================================
void Draw_Window::SetColor (const Standard_Integer& theColor)
{
myCurrentColor = theColor;
}
//=======================================================================
//function : SetMode
//purpose :
//=======================================================================
void Draw_Window::SetMode (const Standard_Integer& theMode)
{
//
}
//=======================================================================
//function : Save
//purpose :
//=======================================================================
Standard_Boolean Draw_Window::Save (Standard_CString theFileName) const
{
Cocoa_LocalPool aLocalPool;
NSString* aFileName = [[[NSString alloc] initWithUTF8String: theFileName] autorelease];
NSString* aFileExtension = [[aFileName pathExtension] lowercaseString];
NSDictionary* aFileTypeDict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt: NSPNGFileType], @"png",
[NSNumber numberWithInt: NSBMPFileType], @"bmp",
[NSNumber numberWithInt: NSJPEGFileType], @"jpg",
[NSNumber numberWithInt: NSGIFFileType], @"gif",
nil];
NSBitmapImageFileType aFileType;
if ([aFileTypeDict valueForKey: aFileExtension] != nil)
{
aFileType = [[aFileTypeDict valueForKey: aFileExtension] intValue];
}
else
{
return Standard_False; // unsupported image extension
}
NSBitmapImageRep* anImageRep = [NSBitmapImageRep imageRepWithData: [myImageBuffer TIFFRepresentation]];
NSData* aData = [anImageRep representationUsingType: aFileType
properties: nil];
Standard_Boolean isSuccess = [aData writeToFile: aFileName
atomically: NO];
return isSuccess;
}
Standard_Boolean Draw_Window::IsEqualWindows (const Standard_Integer& theWindowNumber)
{
return ([myWindow windowNumber] == theWindowNumber);
}
void GetNextEvent (Standard_Boolean theWait,
Standard_Integer& theWindowNumber,
Standard_Integer& theX,
Standard_Integer& theY,
Standard_Integer& theButton)
{
Cocoa_LocalPool aLocalPool;
unsigned int anEventMatchMask = NSLeftMouseDownMask | NSRightMouseDownMask;
if (!theWait)
{
anEventMatchMask = anEventMatchMask | NSMouseMovedMask | NSLeftMouseDraggedMask;
Draw_IsInZoomingMode = Standard_True;
}
NSEvent* anEvent = [NSApp nextEventMatchingMask: anEventMatchMask
untilDate: [NSDate distantFuture]
inMode: NSEventTrackingRunLoopMode
dequeue: YES];
NSWindow* aWindow = [anEvent window];
NSView* aView = [aWindow contentView];
theWindowNumber = [aWindow windowNumber];
NSPoint aMouseLoc = [aView convertPoint: [anEvent locationInWindow] fromView: nil];
NSRect aBounds = [aView bounds];
theX = Standard_Integer (aMouseLoc.x);
theY = Standard_Integer (aMouseLoc.y);
NSEventType anEventType = [anEvent type];
if (anEventType == NSLeftMouseDown)
{
theButton = 1;
}
else if (anEventType == NSRightMouseDown)
{
theButton = 3;
}
else if ((anEventType == NSMouseMoved || anEventType == NSLeftMouseDragged) && !theWait)
{
theButton = 0;
}
}
#endif // __APPLE__