1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/nonownedwnd_osx.cpp
3 // Purpose: implementation of wxNonOwnedWindow
4 // Author: Stefan Csomor
6 // RCS-ID: $Id: nonownedwnd.cpp 50329 2007-11-29 17:00:58Z VS $
7 // Copyright: (c) Stefan Csomor 2008
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
19 #include "wx/hashmap.h"
20 #include "wx/evtloop.h"
21 #include "wx/tooltip.h"
22 #include "wx/nonownedwnd.h"
24 #include "wx/osx/private.h"
25 #include "wx/settings.h"
28 #if wxUSE_SYSTEM_OPTIONS
29 #include "wx/sysopt.h"
32 // ----------------------------------------------------------------------------
34 // ----------------------------------------------------------------------------
36 // trace mask for activation tracing messages
37 #define TRACE_ACTIVATE "activation"
39 wxWindow
* g_MacLastWindow
= NULL
;
41 // unified title and toolbar constant - not in Tiger headers, so we duplicate it here
42 #define kWindowUnifiedTitleAndToolbarAttribute (1 << 7)
44 // ---------------------------------------------------------------------------
45 // wxWindowMac utility functions
46 // ---------------------------------------------------------------------------
48 // Find an item given the Macintosh Window Reference
50 WX_DECLARE_HASH_MAP(WXWindow
, wxNonOwnedWindow
*, wxPointerHash
, wxPointerEqual
, MacWindowMap
);
52 static MacWindowMap wxWinMacWindowList
;
54 wxNonOwnedWindow
*wxFindWindowFromWXWindow(WXWindow inWindowRef
)
56 MacWindowMap::iterator node
= wxWinMacWindowList
.find(inWindowRef
);
58 return (node
== wxWinMacWindowList
.end()) ? NULL
: node
->second
;
61 void wxAssociateWindowWithWXWindow(WXWindow inWindowRef
, wxNonOwnedWindow
*win
) ;
62 void wxAssociateWindowWithWXWindow(WXWindow inWindowRef
, wxNonOwnedWindow
*win
)
64 // adding NULL WindowRef is (first) surely a result of an error and
66 wxCHECK_RET( inWindowRef
!= (WXWindow
) NULL
, wxT("attempt to add a NULL WindowRef to window list") );
68 wxWinMacWindowList
[inWindowRef
] = win
;
71 void wxRemoveWXWindowAssociation(wxNonOwnedWindow
*win
) ;
72 void wxRemoveWXWindowAssociation(wxNonOwnedWindow
*win
)
74 MacWindowMap::iterator it
;
75 for ( it
= wxWinMacWindowList
.begin(); it
!= wxWinMacWindowList
.end(); ++it
)
77 if ( it
->second
== win
)
79 wxWinMacWindowList
.erase(it
);
85 wxNonOwnedWindow
* wxNonOwnedWindow::GetFromWXWindow( WXWindow win
)
87 return wxFindWindowFromWXWindow( win
);
90 // ----------------------------------------------------------------------------
91 // wxNonOwnedWindow creation
92 // ----------------------------------------------------------------------------
94 IMPLEMENT_ABSTRACT_CLASS( wxNonOwnedWindowImpl
, wxObject
)
96 wxNonOwnedWindow
*wxNonOwnedWindow::s_macDeactivateWindow
= NULL
;
98 void wxNonOwnedWindow::Init()
101 m_isNativeWindowWrapper
= false;
104 bool wxNonOwnedWindow::Create(wxWindow
*parent
,
109 const wxString
& name
)
111 m_windowStyle
= style
;
115 m_windowId
= id
== -1 ? NewControlId() : id
;
116 m_windowStyle
= style
;
123 wxRect display
= wxGetClientDisplayRect() ;
125 if ( x
== wxDefaultPosition
.x
)
128 if ( y
== wxDefaultPosition
.y
)
131 int w
= WidthDefault(size
.x
);
132 int h
= HeightDefault(size
.y
);
134 m_nowpeer
= wxNonOwnedWindowImpl::CreateNonOwnedWindow(this, parent
, wxPoint(x
,y
) , wxSize(w
,h
) , style
, GetExtraStyle(), name
);
135 wxAssociateWindowWithWXWindow( m_nowpeer
->GetWXWindow() , this ) ;
136 m_peer
= wxWidgetImpl::CreateContentView(this);
138 DoSetWindowVariant( m_windowVariant
) ;
140 wxWindowCreateEvent
event(this);
141 HandleWindowEvent(event
);
143 SetBackgroundColour(wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE
));
146 parent
->AddChild(this);
151 bool wxNonOwnedWindow::Create(wxWindow
*parent
, WXWindow nativeWindow
)
153 m_nowpeer
= wxNonOwnedWindowImpl::CreateNonOwnedWindow(this, parent
, nativeWindow
);
154 m_isNativeWindowWrapper
= true;
155 wxAssociateWindowWithWXWindow( m_nowpeer
->GetWXWindow() , this ) ;
156 m_peer
= wxWidgetImpl::CreateContentView(this);
159 parent
->AddChild(this);
164 wxNonOwnedWindow::~wxNonOwnedWindow()
168 wxRemoveWXWindowAssociation( this ) ;
175 // avoid dangling refs
176 if ( s_macDeactivateWindow
== this )
177 s_macDeactivateWindow
= NULL
;
180 bool wxNonOwnedWindow::Destroy()
184 return wxWindow::Destroy();
187 void wxNonOwnedWindow::WillBeDestroyed()
190 m_nowpeer
->WillBeDestroyed();
193 // ----------------------------------------------------------------------------
194 // wxNonOwnedWindow misc
195 // ----------------------------------------------------------------------------
197 bool wxNonOwnedWindow::OSXShowWithEffect(bool show
,
201 // Cocoa code needs to manage window visibility on its own and so calls
202 // wxWindow::Show() as needed but if we already changed the internal
203 // visibility flag here, Show() would do nothing, so avoid doing it
205 if ( !wxWindow::Show(show
) )
209 if ( effect
== wxSHOW_EFFECT_NONE
||
210 !m_nowpeer
|| !m_nowpeer
->ShowWithEffect(show
, effect
, timeout
) )
215 // as apps expect a size event to occur when the window is shown,
216 // generate one when it is shown with effect too
217 wxSizeEvent
event(GetSize(), m_windowId
);
218 event
.SetEventObject(this);
219 HandleWindowEvent(event
);
225 wxPoint
wxNonOwnedWindow::GetClientAreaOrigin() const
227 int left
, top
, width
, height
;
228 m_nowpeer
->GetContentArea(left
, top
, width
, height
);
229 return wxPoint(left
, top
);
232 bool wxNonOwnedWindow::SetBackgroundColour(const wxColour
& c
)
234 if ( !wxWindow::SetBackgroundColour(c
) && m_hasBgCol
)
237 if ( GetBackgroundStyle() != wxBG_STYLE_CUSTOM
)
240 return m_nowpeer
->SetBackgroundColour(c
);
245 void wxNonOwnedWindow::SetWindowStyleFlag(long flags
)
247 if (flags
== GetWindowStyleFlag())
250 wxWindow::SetWindowStyleFlag(flags
);
253 m_nowpeer
->SetWindowStyleFlag(flags
);
256 // Raise the window to the top of the Z order
257 void wxNonOwnedWindow::Raise()
262 // Lower the window to the bottom of the Z order
263 void wxNonOwnedWindow::Lower()
268 void wxNonOwnedWindow::HandleActivated( double timestampsec
, bool didActivate
)
270 MacActivate( (int) (timestampsec
* 1000) , didActivate
);
271 wxActivateEvent
wxevent(wxEVT_ACTIVATE
, didActivate
, GetId());
272 wxevent
.SetTimestamp( (int) (timestampsec
* 1000) );
273 wxevent
.SetEventObject(this);
274 HandleWindowEvent(wxevent
);
277 void wxNonOwnedWindow::HandleResized( double timestampsec
)
279 wxSizeEvent
wxevent( GetSize() , GetId());
280 wxevent
.SetTimestamp( (int) (timestampsec
* 1000) );
281 wxevent
.SetEventObject( this );
282 HandleWindowEvent(wxevent
);
283 // we have to inform some controls that have to reset things
284 // relative to the toplevel window (e.g. OpenGL buffers)
285 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
288 void wxNonOwnedWindow::HandleResizing( double WXUNUSED(timestampsec
), wxRect
* rect
)
292 // this is a EVT_SIZING not a EVT_SIZE type !
293 wxSizeEvent
wxevent( r
, GetId() ) ;
294 wxevent
.SetEventObject( this ) ;
295 if ( HandleWindowEvent(wxevent
) )
296 r
= wxevent
.GetRect() ;
298 if ( GetMaxWidth() != -1 && r
.GetWidth() > GetMaxWidth() )
299 r
.SetWidth( GetMaxWidth() ) ;
300 if ( GetMaxHeight() != -1 && r
.GetHeight() > GetMaxHeight() )
301 r
.SetHeight( GetMaxHeight() ) ;
302 if ( GetMinWidth() != -1 && r
.GetWidth() < GetMinWidth() )
303 r
.SetWidth( GetMinWidth() ) ;
304 if ( GetMinHeight() != -1 && r
.GetHeight() < GetMinHeight() )
305 r
.SetHeight( GetMinHeight() ) ;
308 // TODO actuall this is too early, in case the window extents are adjusted
309 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
312 void wxNonOwnedWindow::HandleMoved( double timestampsec
)
314 wxMoveEvent
wxevent( GetPosition() , GetId());
315 wxevent
.SetTimestamp( (int) (timestampsec
* 1000) );
316 wxevent
.SetEventObject( this );
317 HandleWindowEvent(wxevent
);
320 void wxNonOwnedWindow::MacDelayedDeactivation(long timestamp
)
322 if (s_macDeactivateWindow
)
324 wxLogTrace(TRACE_ACTIVATE
,
325 wxT("Doing delayed deactivation of %p"),
326 s_macDeactivateWindow
);
328 s_macDeactivateWindow
->MacActivate(timestamp
, false);
332 void wxNonOwnedWindow::MacActivate( long timestamp
, bool WXUNUSED(inIsActivating
) )
334 wxLogTrace(TRACE_ACTIVATE
, wxT("TopLevel=%p::MacActivate"), this);
336 if (s_macDeactivateWindow
== this)
337 s_macDeactivateWindow
= NULL
;
339 MacDelayedDeactivation(timestamp
);
342 bool wxNonOwnedWindow::Show(bool show
)
344 if ( !wxWindow::Show(show
) )
348 m_nowpeer
->Show(show
);
352 // because apps expect a size event to occur at this moment
353 wxSizeEvent
event(GetSize() , m_windowId
);
354 event
.SetEventObject(this);
355 HandleWindowEvent(event
);
361 bool wxNonOwnedWindow::SetTransparent(wxByte alpha
)
363 return m_nowpeer
->SetTransparent(alpha
);
367 bool wxNonOwnedWindow::CanSetTransparent()
369 return m_nowpeer
->CanSetTransparent();
373 void wxNonOwnedWindow::SetExtraStyle(long exStyle
)
375 if ( GetExtraStyle() == exStyle
)
378 wxWindow::SetExtraStyle( exStyle
) ;
381 m_nowpeer
->SetExtraStyle(exStyle
);
384 bool wxNonOwnedWindow::SetBackgroundStyle(wxBackgroundStyle style
)
386 if ( !wxWindow::SetBackgroundStyle(style
) )
389 return m_nowpeer
? m_nowpeer
->SetBackgroundStyle(style
) : true;
392 void wxNonOwnedWindow::DoMoveWindow(int x
, int y
, int width
, int height
)
394 if ( m_nowpeer
== NULL
)
397 m_cachedClippedRectValid
= false ;
399 m_nowpeer
->MoveWindow(x
, y
, width
, height
);
400 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
403 void wxNonOwnedWindow::DoGetPosition( int *x
, int *y
) const
405 if ( m_nowpeer
== NULL
)
409 m_nowpeer
->GetPosition(x1
, y1
);
417 void wxNonOwnedWindow::DoGetSize( int *width
, int *height
) const
419 if ( m_nowpeer
== NULL
)
424 m_nowpeer
->GetSize(w
, h
);
432 void wxNonOwnedWindow::DoGetClientSize( int *width
, int *height
) const
434 if ( m_nowpeer
== NULL
)
438 m_nowpeer
->GetContentArea(left
, top
, w
, h
);
447 void wxNonOwnedWindow::Update()
452 WXWindow
wxNonOwnedWindow::GetWXWindow() const
454 return m_nowpeer
? m_nowpeer
->GetWXWindow() : NULL
;
457 // ---------------------------------------------------------------------------
458 // Shape implementation
459 // ---------------------------------------------------------------------------
462 bool wxNonOwnedWindow::DoSetShape(const wxRegion
& region
)
464 wxCHECK_MSG( HasFlag(wxFRAME_SHAPED
), false,
465 wxT("Shaped windows must be created with the wxFRAME_SHAPED style."));
469 // The empty region signifies that the shape
470 // should be removed from the window.
471 if ( region
.IsEmpty() )
473 wxSize sz
= GetClientSize();
474 wxRegion
rgn(0, 0, sz
.x
, sz
.y
);
478 return DoSetShape(rgn
);
481 return m_nowpeer
->SetShape(region
);