]> git.saurik.com Git - wxWidgets.git/blob - src/osx/iphone/window.mm
fix memory leak while testing for correct Clone() implementation (closes #10304)
[wxWidgets.git] / src / osx / iphone / window.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/iphone/window.mm
3 // Purpose: widgets (non tlw) for iphone
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 2008-06-20
7 // RCS-ID: $Id: window.mm 48805 2007-09-19 14:52:25Z SC $
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13
14 #include "wx/osx/private.h"
15
16 #include "wx/event.h"
17 #include "wx/nonownedwnd.h"
18 #include "wx/frame.h"
19
20 @interface wxUIView : UIView
21 {
22 wxWidgetImpl* ;
23 }
24
25 - (void)drawRect: (CGRect) rect;
26
27 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
28 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
29 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
30 - (void)handleTouchEvent:(NSSet *)touches withEvent:(UIEvent *)event;
31
32 - (void)setImplementation: (wxWidgetImpl *) theImplementation;
33 - (wxWidgetImpl*) implementation;
34 - (BOOL) isFlipped;
35 - (BOOL) becomeFirstResponder;
36 - (BOOL) resignFirstResponder;
37
38 @end // wxUIView
39
40 @interface wxUIContentView : wxUIView
41 {
42 }
43
44 @end
45
46 @interface wxUIContentViewController : UIViewController
47 {
48 }
49
50 @end
51
52 //
53 //
54 //
55
56 void SetupMouseEvent( wxMouseEvent &wxevent , NSSet* touches, UIEvent * nsEvent )
57 {
58 UInt32 modifiers = 0 ;
59 UITouch *touch = [touches anyObject];
60
61 // these parameters are not given for all events
62 UInt32 button = 0; // no secondary button
63 UInt32 clickCount = [touch tapCount];
64 UInt32 mouseChord = 0; // TODO does this exist for cocoa
65
66 // will be overridden
67 wxevent.m_x = 0;
68 wxevent.m_y = 0;
69 wxevent.m_shiftDown = 0;
70 wxevent.m_controlDown = 0;
71 wxevent.m_altDown = 0;
72 wxevent.m_metaDown = 0;
73 wxevent.m_clickCount = clickCount;
74 wxevent.SetTimestamp( [touch timestamp] ) ;
75 /*
76 // a control click is interpreted as a right click
77 bool thisButtonIsFakeRight = false ;
78 if ( button == kEventMouseButtonPrimary && (modifiers & controlKey) )
79 {
80 button = kEventMouseButtonSecondary ;
81 thisButtonIsFakeRight = true ;
82 }
83
84 // otherwise we report double clicks by connecting a left click with a ctrl-left click
85 if ( clickCount > 1 && button != g_lastButton )
86 clickCount = 1 ;
87 // we must make sure that our synthetic 'right' button corresponds in
88 // mouse down, moved and mouse up, and does not deliver a right down and left up
89
90 if ( cEvent.GetKind() == kEventMouseDown )
91 {
92 g_lastButton = button ;
93 g_lastButtonWasFakeRight = thisButtonIsFakeRight ;
94 }
95
96 if ( button == 0 )
97 {
98 g_lastButton = 0 ;
99 g_lastButtonWasFakeRight = false ;
100 }
101 else if ( g_lastButton == kEventMouseButtonSecondary && g_lastButtonWasFakeRight )
102 button = g_lastButton ;
103
104 // Adjust the chord mask to remove the primary button and add the
105 // secondary button. It is possible that the secondary button is
106 // already pressed, e.g. on a mouse connected to a laptop, but this
107 // possibility is ignored here:
108 if( thisButtonIsFakeRight && ( mouseChord & 1U ) )
109 mouseChord = ((mouseChord & ~1U) | 2U);
110
111 if(mouseChord & 1U)
112 wxevent.m_leftDown = true ;
113 if(mouseChord & 2U)
114 wxevent.m_rightDown = true ;
115 if(mouseChord & 4U)
116 wxevent.m_middleDown = true ;
117
118 */
119 // translate into wx types
120 int eventType = [touch phase];
121 switch (eventType)
122 {
123 case UITouchPhaseBegan :
124 switch ( button )
125 {
126 case 0 :
127 wxevent.SetEventType( clickCount > 1 ? wxEVT_LEFT_DCLICK : wxEVT_LEFT_DOWN ) ;
128 break ;
129
130 default:
131 break ;
132 }
133 break ;
134
135 case UITouchPhaseEnded :
136 switch ( button )
137 {
138 case 0 :
139 wxevent.SetEventType( wxEVT_LEFT_UP ) ;
140 break ;
141
142 default:
143 break ;
144 }
145 break ;
146
147 case UITouchPhaseMoved :
148 wxevent.SetEventType( wxEVT_MOTION ) ;
149 break;
150 default :
151 break ;
152 }
153 }
154
155 @implementation wxUIView
156
157 - (id) initWithFrame: (CGRect) frame
158 {
159 if ( self = [super initWithFrame:frame])
160 {
161 // additional inits
162 }
163 return self;
164 }
165
166 - (void) dealloc
167 {
168 // additional deallocs
169 [super dealloc];
170 }
171
172 - (void)drawRect: (CGRect) rect
173 {
174 if ( )
175 {
176 CGContextRef context = (CGContextRef) UIGraphicsGetCurrentContext();
177 CGContextSaveGState( context );
178 // draw background
179
180 CGContextSetFillColorWithColor( context, ->GetWXPeer()->GetBackgroundColour().GetCGColor());
181 CGContextFillRect(context, rect );
182
183 if ( [ self isFlipped ] == NO )
184 {
185 CGContextTranslateCTM( context, 0, [self bounds].size.height );
186 CGContextScaleCTM( context, 1, -1 );
187 }
188
189 ->GetWXPeer()->MacSetCGContextRef( context );
190
191 ->GetWXPeer()->GetUpdateRegion() =
192 wxRegion(rect.origin.x,rect.origin.y,rect.size.width,rect.size.height) ;
193
194 wxPaintEvent event;
195 event.SetTimestamp(0); // todo
196 event.SetEventObject(->GetWXPeer());
197 ->GetWXPeer()->HandleWindowEvent(event);
198
199 CGContextRestoreGState( context );
200 }
201
202 }
203
204 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
205 {
206 [self handleTouchEvent:touches withEvent:event];
207 }
208
209 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
210 {
211 [self handleTouchEvent:touches withEvent:event];
212 }
213
214 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
215 {
216 [self handleTouchEvent:touches withEvent:event];
217 }
218
219 -(void)handleTouchEvent:(NSSet *)touches withEvent:(UIEvent *)event
220 {
221 CGPoint clickLocation;
222 UITouch *touch = [touches anyObject];
223 clickLocation = [touch locationInView:self];
224
225 wxMouseEvent wxevent(wxEVT_LEFT_DOWN);
226 SetupMouseEvent( wxevent , touches, event ) ;
227 wxevent.m_x = clickLocation.x;
228 wxevent.m_y = clickLocation.y;
229 wxevent.SetEventObject( ->GetWXPeer() ) ;
230 wxevent.SetId( ->GetWXPeer()->GetId() ) ;
231 ->GetWXPeer()->HandleWindowEvent(wxevent);
232 }
233
234 - (void)setImplementation: (wxWidgetImpl *) theImplementation
235 {
236 = theImplementation;
237 }
238
239 - (wxWidgetImpl*) implementation
240 {
241 return ;
242 }
243
244 - (BOOL) isFlipped
245 {
246 return YES;
247 }
248
249 - (BOOL) becomeFirstResponder
250 {
251 BOOL r = [super becomeFirstResponder];
252 if ( r )
253 {
254 }
255 return r;
256 }
257
258 - (BOOL) resignFirstResponder
259 {
260 BOOL r = [super resignFirstResponder];
261 if ( r )
262 {
263 }
264 return r;
265 }
266
267
268 @end // wxUIView
269
270 @implementation wxUIContentView
271
272 @end
273
274 @implementation wxUIContentViewController
275
276 - (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation
277 {
278 return YES;
279 }
280
281 - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
282 {
283 CGRect fr = [self.view frame];
284 // CGRect cv = [[self.view superview] frame];
285 // CGRect bounds = CGRectMake( 0,0,fr.size.width, fr.size.height);
286 // [[self.view superview] setFrame: fr ];
287 // [self.view setFrame: bounds];
288 // [self.view setNeedsDisplayInRect:bounds];
289 }
290
291 @end
292
293
294 IMPLEMENT_DYNAMIC_CLASS( wxWidgetIPhoneImpl , wxWidgetImpl )
295
296 wxWidgetIPhoneImpl::wxWidgetIPhoneImpl( wxWindowMac* peer , WXWidget w, bool isRootControl ) :
297 wxWidgetImpl( peer, isRootControl ), m_osxView(w)
298 {
299 }
300
301 wxWidgetIPhoneImpl::wxWidgetIPhoneImpl()
302 {
303 }
304
305 void wxWidgetIPhoneImpl::Init()
306 {
307 m_osxView = NULL;
308 }
309
310 wxWidgetIPhoneImpl::~wxWidgetIPhoneImpl()
311 {
312 [m_osxView setImplementation:NULL];
313 [m_osxView release];
314 }
315
316 bool wxWidgetIPhoneImpl::IsVisible() const
317 {
318 // TODO Superviews
319 return [m_osxView isHidden] == NO;
320 }
321
322 void wxWidgetIPhoneImpl::SetVisibility( bool visible )
323 {
324 [m_osxView setHidden:(visible ? NO:YES)];
325 }
326
327 void wxWidgetIPhoneImpl::Raise()
328 {
329 [[m_osxView superview] bringSubviewToFront:m_osxView];
330 }
331
332 void wxWidgetIPhoneImpl::Lower()
333 {
334 [[m_osxView superview] sendSubviewToBack:m_osxView];
335 }
336
337 void wxWidgetIPhoneImpl::ScrollRect( const wxRect *rect, int dx, int dy )
338 {
339 }
340
341 void wxWidgetIPhoneImpl::Move(int x, int y, int width, int height)
342 {
343 CGRect r = CGRectMake( x, y, width, height) ;
344 [m_osxView setFrame:r];
345 }
346
347 void wxWidgetIPhoneImpl::GetPosition( int &x, int &y ) const
348 {
349 CGRect r = [m_osxView frame];
350 x = r.origin.x;
351 y = r.origin.y;
352 }
353
354 void wxWidgetIPhoneImpl::GetSize( int &width, int &height ) const
355 {
356 CGRect rect = [m_osxView frame];
357 width = rect.size.width;
358 height = rect.size.height;
359 }
360
361 void wxWidgetIPhoneImpl::GetContentArea( int&left, int &top, int &width, int &height ) const
362 {
363 left = top = 0;
364 GetSize( width, height );
365 }
366
367 void wxWidgetIPhoneImpl::SetNeedsDisplay( const wxRect* where )
368 {
369 if ( where )
370 {
371 CGRect r = CGRectMake( where->x, where->y, where->width, where->height) ;
372 [m_osxView setNeedsDisplayInRect:r];
373 }
374 else
375 [m_osxView setNeedsDisplay];
376 }
377
378 bool wxWidgetIPhoneImpl::GetNeedsDisplay() const
379 {
380 return false;
381 // return [m_osxView needsDisplay];
382 }
383
384 bool wxWidgetIPhoneImpl::CanFocus() const
385 {
386 return [m_osxView canBecomeFirstResponder] == YES;
387 // ? return [m_osxView isUserInteractionEnabled] == YES;
388 }
389
390 bool wxWidgetIPhoneImpl::HasFocus() const
391 {
392 return [m_osxView isFirstResponder] == YES;
393 }
394
395 bool wxWidgetIPhoneImpl::SetFocus()
396 {
397 // [m_osxView makeKeyWindow] ;
398 // TODO
399 return false;
400 }
401
402
403 void wxWidgetIPhoneImpl::RemoveFromParent()
404 {
405 [m_osxView removeFromSuperview];
406 }
407
408 void wxWidgetIPhoneImpl::Embed( wxWidgetImpl *parent )
409 {
410 UIView* container = parent->GetWXWidget() ;
411 wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ;
412 [container addSubview:m_osxView];
413 }
414
415 void wxWidgetImpl::Convert( wxPoint *pt , wxWidgetImpl *from , wxWidgetImpl *to )
416 {
417 CGPoint p = CGPointMake( pt->x , pt->y );
418 p = [from->GetWXWidget() convertPoint:p toView:to->GetWXWidget() ];
419 pt->x = (int)p.x;
420 pt->y = (int)p.y;
421 }
422
423 void wxWidgetIPhoneImpl::SetBackgroundColour( const wxColour &col )
424 {
425 // m_osxView.backgroundColor = [[UIColor alloc] initWithCGColor:col.GetCGColor()];
426 }
427
428 //
429 // Factory methods
430 //
431
432 wxWidgetImpl* wxWidgetImpl::CreateUserPane( wxWindowMac* wxpeer, const wxPoint& pos, const wxSize& size,
433 long style, long extraStyle)
434 {
435 UIView* sv = (wxpeer->GetParent()->GetHandle() );
436
437 CGRect r = CGRectMake( pos.x, pos.y, size.x, size.y) ;
438 // Rect bounds = wxMacGetBoundsForControl( wxpeer, pos , size ) ;
439 wxUIView* v = [[wxUIView alloc] initWithFrame:r];
440 sv.clipsToBounds = YES;
441 sv.contentMode = UIViewContentModeRedraw;
442 sv.clearsContextBeforeDrawing = NO;
443 // sv.backgroundColor = [[UIColor alloc] initWithCGColor:wxpeer->GetBackgroundColour().GetCGColor()];
444 [sv addSubview:v];
445 wxWidgetIPhoneImpl* c = new wxWidgetIPhoneImpl( wxpeer, v );
446 [v setImplementation:c];
447 return c;
448 }
449
450 wxWidgetImpl* wxWidgetImpl::CreateContentView( wxNonOwnedWindow* now )
451 {
452 UIWindow* toplevelwindow = now->GetWXWindow();
453
454 wxUIContentView* contentview = [[wxUIContentView alloc] initWithFrame:[toplevelwindow bounds]];
455 contentview.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
456 wxUIContentViewController* controller = [[wxUIContentViewController alloc] init];
457 controller.view = contentview;
458 /*
459 UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
460 // left orientation not yet implemented !
461 if (orientation == UIInterfaceOrientationLandscapeRight )
462 {
463 CGAffineTransform transform = v.transform;
464
465 // Use the status bar frame to determine the center point of the window's content area.
466 CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
467 CGRect bounds = CGRectMake(0, 0, statusBarFrame.size.height, statusBarFrame.origin.x);
468 CGPoint center = CGPointMake(bounds.size.height / 2.0, bounds.size.width / 2.0);
469
470 // Set the center point of the view to the center point of the window's content area.
471 v.center = center;
472
473 // Rotate the view 90 degrees around its new center point.
474 transform = CGAffineTransformRotate(transform, ( M_PI / 2.0));
475 v.transform = transform;
476 }
477 */
478 wxWidgetIPhoneImpl* impl = new wxWidgetIPhoneImpl( now, contentview, true );
479 [contentview setImplementation:impl];
480 [toplevelwindow addSubview:contentview];
481 return impl;
482 }
483