Logo ROOT   6.10/09
Reference Guide
ROOTOpenGLView.mm
Go to the documentation of this file.
1 // @(#)root/graf2d:$Id$
2 // Author: Timur Pocheptsov 26/04/2012
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2012, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include <cassert>
13 
14 #include "ROOTOpenGLView.h"
15 #include "X11Events.h"
16 #include "TGCocoa.h"
17 
18 namespace ROOT {
19 namespace MacOSX {
20 namespace OpenGL {
21 
22 //______________________________________________________________________________
24 {
25  assert(glView != nil && "GLViewIsValid, glView parameter is nil");
26 
27  if ([glView isHiddenOrHasHiddenAncestor]) {
28  //This will result in "invalid drawable" message
29  //from -setView:.
30  return false;
31  }
32 
33  const NSRect visibleRect = [glView visibleRect];
34  if (visibleRect.size.width < 1. || visibleRect.size.height < 1.) {
35  //Another reason for "invalid drawable" message.
36  return false;
37  }
38 
39  return true;
40 }
41 
42 }
43 }
44 }
45 
46 @implementation ROOTOpenGLView
47 
48 @synthesize fOpenGLContext;
49 @synthesize fUpdateContext;
50 
51 //______________________________________________________________________________
52 - (id) initWithFrame : (NSRect) frameRect pixelFormat : (NSOpenGLPixelFormat *) format
53 {
54  if (self = [super initWithFrame : frameRect windowAttributes : 0]) {
55  [self setHidden : YES];//Not sure.
56  fIsOverlapped = NO;
57  fPixelFormat = [format retain];
58 
59  if ([[NSScreen mainScreen] backingScaleFactor] > 1.)
60  [self setWantsBestResolutionOpenGLSurface : YES];
61  }
62 
63  return self;
64 }
65 
66 //______________________________________________________________________________
68 {
69  if (fOpenGLContext && [fOpenGLContext view] == self)
70  [fOpenGLContext clearDrawable];
71 
72  self.fOpenGLContext = nil;
73  [fPixelFormat release];
74  //View does not own context.
75  [super dealloc];
76 }
77 
78 //______________________________________________________________________________
79 - (NSOpenGLPixelFormat *) pixelFormat
80 {
81  return fPixelFormat;
82 }
83 
84 //______________________________________________________________________________
85 - (void) setPixelFormat : (NSOpenGLPixelFormat *) pixelFormat
86 {
87  if (fPixelFormat != pixelFormat) {
88  [fPixelFormat release];
89  fPixelFormat = [pixelFormat retain];
90  }
91 }
92 
93 //X11Drawable protocol.
94 
95 //______________________________________________________________________________
97 {
98  return YES;
99 }
100 
101 //______________________________________________________________________________
103 {
104  //GL-view does not have/need any "back buffer".
105  return nil;
106 }
107 
108 //______________________________________________________________________________
109 - (void) setFBackBuffer : (QuartzPixmap *) notUsed
110 {
111  //GL-view does not have/need any "back buffer".
112 #pragma unused(notUsed)
113 }
114 
115 //______________________________________________________________________________
117 {
118  [self setHidden : NO];
119 }
120 
121 //______________________________________________________________________________
123 {
124  //GL-view can not have any subwindows.
125  assert([[self subviews] count] == 0 && "mapSubwindows, GL-view has children");
126 }
127 
128 //______________________________________________________________________________
130 {
131  //The only node in the tree is 'self'.
132  if (self.fMapState == kIsViewable) {
133  if (self.fEventMask & kStructureNotifyMask) {
134  assert(dynamic_cast<TGCocoa *>(gVirtualX) &&
135  "configureNotifyTree, gVirtualX is either null or has type different from TGCocoa");
136  TGCocoa * const vx = static_cast<TGCocoa *>(gVirtualX);
137  vx->GetEventTranslator()->GenerateConfigureNotifyEvent(self, self.frame);
138  }
139  }
140 }
141 
142 //______________________________________________________________________________
144 {
145  return fIsOverlapped;
146 }
147 
148 //______________________________________________________________________________
149 - (void) setOverlapped : (BOOL) overlap
150 {
151  //If GL-view is overlapped by another view,
152  //it must be hidden (overwise it will be always on top,
153  //producing some strange-looking buggy GUI).
154 
155  fIsOverlapped = overlap;
156  [self setHidden : fIsOverlapped];
157 
158  if (!overlap) {
159  assert(dynamic_cast<TGCocoa *>(gVirtualX) != 0 &&
160  "setFrameSize:, gVirtualX is either null or has a type, different from TGCocoa");
161  [fOpenGLContext update];
162  //View becomes visible, geometry can be changed at this point,
163  //notify ROOT's GL code about this changes.
164  TGCocoa * const vx = static_cast<TGCocoa *>(gVirtualX);
165  vx->GetEventTranslator()->GenerateConfigureNotifyEvent(self, self.frame);
166  vx->GetEventTranslator()->GenerateExposeEvent(self, self.frame);
167  }
168 }
169 
170 //______________________________________________________________________________
171 - (BOOL) isFlipped
172 {
173  return YES;
174 }
175 
176 //______________________________________________________________________________
177 - (void) setFrame : (NSRect) newFrame
178 {
179  //In case of TBrowser, setFrame started infinite recursion:
180  //HandleConfigure for embedded main frame emits signal, slot
181  //calls layout, layout calls setFrame -> HandleConfigure and etc. etc.
182  if (NSEqualRects(newFrame, self.frame))
183  return;
184 
185  [super setFrame : newFrame];
186 }
187 
188 //______________________________________________________________________________
189 - (void) setFrameSize : (NSSize) newSize
190 {
191  //Check, if setFrameSize calls setFrame.
192 
193  [super setFrameSize : newSize];
194 
195  if (![self isHiddenOrHasHiddenAncestor] && !fIsOverlapped)
196  [fOpenGLContext update];
197  else
198  fUpdateContext = YES;
199 
200  if ((self.fEventMask & kStructureNotifyMask) && (self.fMapState == kIsViewable || fIsOverlapped == YES)) {
201  assert(dynamic_cast<TGCocoa *>(gVirtualX) != 0 &&
202  "setFrameSize:, gVirtualX is either null or has a type, different from TGCocoa");
203  TGCocoa * const vx = static_cast<TGCocoa *>(gVirtualX);
204  vx->GetEventTranslator()->GenerateConfigureNotifyEvent(self, self.frame);
205  vx->GetEventTranslator()->GenerateExposeEvent(self, self.frame);
206  }
207 }
208 
209 //______________________________________________________________________________
210 - (void) drawRect : (NSRect) dirtyRect
211 {
212 #pragma unused(dirtyRect)
213 }
214 
215 @end
QuartzPixmap * fBackBuffer
void GenerateConfigureNotifyEvent(NSView< X11Window > *view, const NSRect &newFrame)
Definition: X11Events.mm:1149
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
bool GLViewIsValidDrawable(ROOTOpenGLView *glView)
NSOpenGLPixelFormat * fPixelFormat
NSOpenGLPixelFormat * pixelFormat()
void GenerateExposeEvent(NSView< X11Window > *view, const NSRect &exposedRect)
Definition: X11Events.mm:1176
long fEventMask
Definition: QuartzWindow.h:155
#define gVirtualX
Definition: TVirtualX.h:350
const Mask_t kStructureNotifyMask
Definition: GuiTypes.h:165
NSOpenGLContext * fOpenGLContext
typedef void((*Func_t)())
This class implements TVirtualX interface for MacOS X, using Cocoa and Quartz 2D. ...
Definition: TGCocoa.h:58
ROOT::MacOSX::X11::EventTranslator * GetEventTranslator() const
Definition: TGCocoa.mm:4387