1/////////////////////////////////////////////////////////////////////////////
2// Name:        src/osx/iphone/nonownedwnd.mm
3// Purpose:     non owned window for iphone
4// Author:      Stefan Csomor
5// Modified by:
6// Created:     2008-06-20
7// Copyright:   (c) Stefan Csomor
8// Licence:     wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11#include "wx/wxprec.h"
12
13#include "wx/osx/private.h"
14
15#include "wx/nonownedwnd.h"
16#include "wx/frame.h"
17#include <algorithm>
18
19CGRect wxToNSRect(UIView* parent, const wxRect& r )
20{
21    CGRect frame = parent ? [parent bounds] : [[UIScreen mainScreen] bounds];
22    int y = r.y;
23    int x = r.x ;
24    return CGRectMake(x, y, r.width , r.height);
25}
26
27wxRect wxFromNSRect( UIView* parent, const CGRect& rect )
28{
29    CGRect frame = parent ? [parent bounds] : [[UIScreen mainScreen] bounds];
30    int y = rect.origin.y;
31    int x = rect.origin.x;
32    return wxRect( x, y, rect.size.width, rect.size.height );
33}
34
35CGPoint wxToNSPoint( UIView* parent, const wxPoint& p )
36{
37    CGRect frame = parent ? [parent bounds] : [[UIScreen mainScreen] bounds];
38    int x = p.x ;
39    int y = p.y;
40    return CGPointMake(x, y);
41}
42
43wxPoint wxFromNSPoint( UIView* parent, const CGPoint& p )
44{
45    CGRect frame = parent ? [parent bounds] : [[UIScreen mainScreen] bounds];
46    int x = p.x;
47    int y = p.y;
48    return wxPoint( x, y);
49}
50
51@interface wxUIContentViewController : UIViewController
52{
53}
54
55@end
56
57@interface wxUIContentView : UIView
58{
59    wxUIContentViewController* _controller;
60}
61
62- (void) setController: (wxUIContentViewController*) controller;
63- (wxUIContentViewController*) controller;
64@end
65
66
67
68//
69// c++ impl
70//
71
72wxIMPLEMENT_DYNAMIC_CLASS(wxNonOwnedWindowIPhoneImpl , wxNonOwnedWindowImpl);
73
74wxNonOwnedWindowIPhoneImpl::wxNonOwnedWindowIPhoneImpl( wxNonOwnedWindow* nonownedwnd) :
75    wxNonOwnedWindowImpl(nonownedwnd)
76{
77    m_macWindow = NULL;
78    m_macFullScreenData = NULL;
79    m_initialShowSent = false;
80}
81
82wxNonOwnedWindowIPhoneImpl::wxNonOwnedWindowIPhoneImpl()
83{
84    m_macWindow = NULL;
85    m_macFullScreenData = NULL;
86    m_initialShowSent = false;
87}
88
89wxNonOwnedWindowIPhoneImpl::~wxNonOwnedWindowIPhoneImpl()
90{
91    [m_macWindow release];
92}
93
94void wxNonOwnedWindowIPhoneImpl::WillBeDestroyed()
95{
96}
97
98void wxNonOwnedWindowIPhoneImpl::Create( wxWindow* parent, const wxPoint& pos, const wxSize& size,
99long style, long extraStyle, const wxString& name )
100{
101    m_macWindow = [UIWindow alloc];
102
103    UIWindowLevel level = UIWindowLevelNormal;
104
105    // most styles are not supported on the iphone
106
107    if ( style & wxFRAME_TOOL_WINDOW )
108    {
109        level = UIWindowLevelAlert; ;
110    }
111    else if ( ( style & wxPOPUP_WINDOW ) )
112    {
113        level = UIWindowLevelAlert;;
114    }
115    else if ( ( style & wxCAPTION ) )
116    {
117    }
118    else if ( ( style & wxFRAME_DRAWER ) )
119    {
120    }
121    else
122    {
123    }
124
125    if ( ( style & wxSTAY_ON_TOP ) )
126        level = UIWindowLevelAlert;
127    CGRect r = CGRectMake( 0, 0, size.x, size.y) ;
128    if ( UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]) )
129        std::swap(r.size.width,r.size.height);
130
131    [m_macWindow initWithFrame:r ];
132    [m_macWindow setHidden:YES];
133
134    [m_macWindow setWindowLevel:level];
135}
136
137void wxNonOwnedWindowIPhoneImpl::Create( wxWindow* WXUNUSED(parent), WXWindow nativeWindow )
138{
139    m_macWindow = nativeWindow;
140}
141
142
143WXWindow wxNonOwnedWindowIPhoneImpl::GetWXWindow() const
144{
145    return m_macWindow;
146}
147
148void wxNonOwnedWindowIPhoneImpl::Raise()
149{
150}
151
152void wxNonOwnedWindowIPhoneImpl::Lower()
153{
154}
155
156bool wxNonOwnedWindowIPhoneImpl::Show(bool show)
157{
158    [m_macWindow setHidden:(show ? NO : YES)];
159    if ( show )
160    {
161        if ( !m_initialShowSent )
162        {
163            wxNonOwnedWindow* now = dynamic_cast<wxNonOwnedWindow*> (GetWXPeer());
164            wxShowEvent eventShow(now->GetId(), true);
165            eventShow.SetEventObject(now);
166
167            now->HandleWindowEvent(eventShow);
168
169            m_initialShowSent = true;
170        }
171        //[m_macWindow orderFront: self];
172        [m_macWindow makeKeyWindow];
173    }
174    return true;
175}
176
177bool wxNonOwnedWindowIPhoneImpl::ShowWithEffect(bool show, wxShowEffect effect, unsigned timeout)
178{
179    return Show(show);
180}
181
182void wxNonOwnedWindowIPhoneImpl::Update()
183{
184//  TODO  [m_macWindow displayIfNeeded];
185}
186
187bool wxNonOwnedWindowIPhoneImpl::SetTransparent(wxByte alpha)
188{
189    [m_macWindow setAlpha:(CGFloat) alpha/255.0];
190    return true;
191}
192
193bool wxNonOwnedWindowIPhoneImpl::SetBackgroundColour(const wxColour& col )
194{
195    return true;
196}
197
198void wxNonOwnedWindowIPhoneImpl::SetExtraStyle( long exStyle )
199{
200    // no special styles supported
201}
202
203bool wxNonOwnedWindowIPhoneImpl::SetBackgroundStyle(wxBackgroundStyle style)
204{
205    return true;
206}
207
208bool wxNonOwnedWindowIPhoneImpl::CanSetTransparent()
209{
210    return true;
211}
212
213void wxNonOwnedWindowIPhoneImpl::MoveWindow(int x, int y, int width, int height)
214{
215    CGRect r = CGRectMake( x,y,width,height) ;
216    if ( UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]) )
217        std::swap(r.size.width,r.size.height);
218
219    [m_macWindow setFrame:r];
220}
221
222void wxNonOwnedWindowIPhoneImpl::GetPosition( int &x, int &y ) const
223{
224    CGRect r = [m_macWindow frame];
225    x = r.origin.x;
226    y = r.origin.y;
227}
228
229void wxNonOwnedWindowIPhoneImpl::GetSize( int &width, int &height ) const
230{
231    CGRect r = [m_macWindow frame];
232    if ( UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]) )
233        std::swap(r.size.width,r.size.height);
234    width = r.size.width;
235    height = r.size.height;
236}
237
238void wxNonOwnedWindowIPhoneImpl::GetContentArea( int& left, int &top, int &width, int &height ) const
239{
240    CGRect r = [m_macWindow bounds];
241    if ( UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]) )
242        std::swap(r.size.width,r.size.height);
243    width = r.size.width;
244    height = r.size.height;
245    left = r.origin.x;
246    top = r.origin.y;
247}
248
249bool wxNonOwnedWindowIPhoneImpl::SetShape(const wxRegion& region)
250{
251    return false;
252}
253
254void wxNonOwnedWindowIPhoneImpl::SetTitle( const wxString& title, wxFontEncoding encoding )
255{
256// TODO change title of app ?
257}
258
259bool wxNonOwnedWindowIPhoneImpl::IsMaximized() const
260{
261    return false;
262}
263
264bool wxNonOwnedWindowIPhoneImpl::IsIconized() const
265{
266    return false;
267}
268
269void wxNonOwnedWindowIPhoneImpl::Iconize( bool iconize )
270{
271}
272
273void wxNonOwnedWindowIPhoneImpl::Maximize(bool maximize)
274{
275    if ( maximize )
276    {
277        CGRect r = [[UIScreen mainScreen] bounds];
278        [m_macWindow setFrame:r];
279    }
280}
281
282bool wxNonOwnedWindowIPhoneImpl::IsFullScreen() const
283{
284    return m_macFullScreenData != NULL ;
285}
286
287bool wxNonOwnedWindowIPhoneImpl::EnableFullScreenView(bool WXUNUSED(enable))
288{
289    return true;
290}
291
292bool wxNonOwnedWindowIPhoneImpl::ShowFullScreen(bool show, long style)
293{
294    return true;
295}
296
297void wxNonOwnedWindowIPhoneImpl::RequestUserAttention(int WXUNUSED(flags))
298{
299}
300
301void wxNonOwnedWindowIPhoneImpl::ScreenToWindow( int *x, int *y )
302{
303    CGPoint p = CGPointMake(  (x ? *x : 0), (y ? *y : 0) );
304    p = [m_macWindow convertPoint:p fromWindow:nil];
305    if ( x )
306        *x = p.x;
307    if ( y )
308        *y = p.y;
309}
310
311void wxNonOwnedWindowIPhoneImpl::WindowToScreen( int *x, int *y )
312{
313    CGPoint p = CGPointMake(  (x ? *x : 0), (y ? *y : 0) );
314    p = [m_macWindow convertPoint:p toWindow:nil];
315    if ( x )
316        *x = p.x;
317    if ( y )
318        *y = p.y;
319}
320
321wxNonOwnedWindowImpl* wxNonOwnedWindowImpl::CreateNonOwnedWindow( wxNonOwnedWindow* wxpeer, wxWindow* parent, WXWindow nativeWindow)
322{
323    wxNonOwnedWindowIPhoneImpl* now = new wxNonOwnedWindowIPhoneImpl( wxpeer );
324    now->Create( parent, nativeWindow );
325    return now;
326}
327
328
329wxNonOwnedWindowImpl* wxNonOwnedWindowImpl::CreateNonOwnedWindow( wxNonOwnedWindow* wxpeer, wxWindow* parent, const wxPoint& pos, const wxSize& size,
330    long style, long extraStyle, const wxString& name )
331{
332    wxNonOwnedWindowImpl* now = new wxNonOwnedWindowIPhoneImpl( wxpeer );
333    now->Create( parent, pos, size, style , extraStyle, name );
334    return now;
335}
336
337wxWidgetImpl* wxWidgetImpl::CreateContentView( wxNonOwnedWindow* now )
338{
339    UIWindow* toplevelwindow = now->GetWXWindow();
340    CGRect frame = [toplevelwindow bounds];
341    CGRect appframe = [[UIScreen mainScreen] applicationFrame];
342    BOOL fullscreen = now->GetWindowStyle() == wxDEFAULT_FRAME_STYLE && [[UIApplication sharedApplication] statusBarStyle] == UIStatusBarStyleBlackTranslucent;
343
344    wxUIContentView* contentview = [[wxUIContentView alloc] initWithFrame:( fullscreen ? frame : appframe ) ];
345    contentview.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
346    wxUIContentViewController* controller = [[wxUIContentViewController alloc] initWithNibName:nil bundle:nil];
347
348#ifdef __IPHONE_3_0
349    controller.wantsFullScreenLayout = fullscreen;
350#endif
351
352    controller.view = contentview;
353    [contentview release];
354    [contentview setController:controller];
355    [contentview setHidden:YES];
356
357    wxWidgetIPhoneImpl* impl = new wxWidgetIPhoneImpl( now, contentview, Widget_IsRoot );
358    impl->InstallEventHandler();
359
360    if ([toplevelwindow respondsToSelector:@selector(setRootViewController:)])
361    {
362        toplevelwindow.rootViewController = controller;
363    }
364    else
365    {
366        [toplevelwindow addSubview:contentview];
367    }
368    return impl;
369}
370
371//
372// obj-c impl
373//
374
375@implementation wxUIContentView
376
377- (void) setController: (wxUIContentViewController*) controller
378{
379    _controller = controller;
380}
381
382- (wxUIContentViewController*) controller
383{
384    return _controller;
385}
386
387+ (void)initialize
388{
389    static BOOL initialized = NO;
390    if (!initialized)
391    {
392        initialized = YES;
393        wxOSXIPhoneClassAddWXMethods( self );
394    }
395}
396
397@end
398
399@implementation wxUIContentViewController
400
401- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation
402{
403    wxWidgetIPhoneImpl* impl = (wxWidgetIPhoneImpl* ) wxWidgetImpl::FindFromWXWidget( [self view] );
404    wxNonOwnedWindow* now = dynamic_cast<wxNonOwnedWindow*> (impl->GetWXPeer());
405
406    // TODO: determine NO or YES based on min size requirements (whether it fits on the new orientation)
407
408    return YES;
409}
410
411// iOS 6 support, right now unconditionally supporting all orientations, TODO use a orientation mask
412
413-(BOOL)shouldAutorotate
414{
415    return YES;
416}
417
418 - (NSUInteger)supportedInterfaceOrientations
419{
420     return UIInterfaceOrientationMaskAll;
421}
422
423
424
425
426- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
427{
428    wxWidgetIPhoneImpl* impl = (wxWidgetIPhoneImpl* ) wxWidgetImpl::FindFromWXWidget( [self view] );
429    wxNonOwnedWindow* now = dynamic_cast<wxNonOwnedWindow*> (impl->GetWXPeer());
430
431    now->HandleResized(0);
432}
433
434-(void) viewWillAppear:(BOOL)animated
435{
436    wxWidgetIPhoneImpl* impl = (wxWidgetIPhoneImpl* ) wxWidgetImpl::FindFromWXWidget( [self view] );
437    wxNonOwnedWindow* now = dynamic_cast<wxNonOwnedWindow*> (impl->GetWXPeer());
438    wxNonOwnedWindowIPhoneImpl* nowimpl = dynamic_cast<wxNonOwnedWindowIPhoneImpl*> (now->GetNonOwnedPeer());
439
440    if ( nowimpl->InitialShowEventSent() )
441    {
442        wxShowEvent eventShow(now->GetId(), true);
443        eventShow.SetEventObject(now);
444
445        now->HandleWindowEvent(eventShow);
446    }
447}
448
449-(void) viewWillDisappear:(BOOL)animated
450{
451    wxWidgetIPhoneImpl* impl = (wxWidgetIPhoneImpl* ) wxWidgetImpl::FindFromWXWidget( [self view] );
452    if( impl )
453    {
454        wxNonOwnedWindow* now = dynamic_cast<wxNonOwnedWindow*> (impl->GetWXPeer());
455        wxNonOwnedWindowIPhoneImpl* nowimpl = dynamic_cast<wxNonOwnedWindowIPhoneImpl*> (now->GetNonOwnedPeer());
456
457        if ( nowimpl->InitialShowEventSent() )
458        {
459            wxShowEvent eventShow(now->GetId(), false);
460            eventShow.SetEventObject(now);
461
462            now->HandleWindowEvent(eventShow);
463        }
464    }
465}
466
467-(void) dealloc
468{
469    [super dealloc];
470}
471
472- (UIView*) rotatingFooterView
473{
474    UIView* footerView = [super rotatingFooterView];
475    if ( footerView == nil )
476    {
477        wxWidgetIPhoneImpl* impl = (wxWidgetIPhoneImpl* ) wxWidgetImpl::FindFromWXWidget( [self view] );
478        wxFrame* frame = dynamic_cast<wxFrame*> (impl->GetWXPeer());
479        if ( frame && frame->GetToolBar())
480        {
481            footerView = frame->GetToolBar()->GetHandle();
482        }
483    }
484    return footerView;
485}
486
487@end
488
489
490
491