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"
18 #include "wx/hashmap.h"
19 #include "wx/evtloop.h"
20 #include "wx/tooltip.h"
21 #include "wx/nonownedwnd.h"
23 #include "wx/osx/private.h"
24 #include "wx/settings.h"
27 #if wxUSE_SYSTEM_OPTIONS
28 #include "wx/sysopt.h"
31 // ----------------------------------------------------------------------------
33 // ----------------------------------------------------------------------------
35 // trace mask for activation tracing messages
36 #define TRACE_ACTIVATE "activation"
38 wxWindow
* g_MacLastWindow
= NULL
;
40 // unified title and toolbar constant - not in Tiger headers, so we duplicate it here
41 #define kWindowUnifiedTitleAndToolbarAttribute (1 << 7)
43 // ---------------------------------------------------------------------------
44 // wxWindowMac utility functions
45 // ---------------------------------------------------------------------------
47 // Find an item given the Macintosh Window Reference
49 WX_DECLARE_HASH_MAP(WXWindow
, wxNonOwnedWindow
*, wxPointerHash
, wxPointerEqual
, MacWindowMap
);
51 static MacWindowMap wxWinMacWindowList
;
53 wxNonOwnedWindow
*wxFindWindowFromWXWindow(WXWindow inWindowRef
)
55 MacWindowMap::iterator node
= wxWinMacWindowList
.find(inWindowRef
);
57 return (node
== wxWinMacWindowList
.end()) ? NULL
: node
->second
;
60 void wxAssociateWindowWithWXWindow(WXWindow inWindowRef
, wxNonOwnedWindow
*win
) ;
61 void wxAssociateWindowWithWXWindow(WXWindow inWindowRef
, wxNonOwnedWindow
*win
)
63 // adding NULL WindowRef is (first) surely a result of an error and
65 wxCHECK_RET( inWindowRef
!= (WXWindow
) NULL
, wxT("attempt to add a NULL WindowRef to window list") );
67 wxWinMacWindowList
[inWindowRef
] = win
;
70 void wxRemoveWXWindowAssociation(wxNonOwnedWindow
*win
) ;
71 void wxRemoveWXWindowAssociation(wxNonOwnedWindow
*win
)
73 MacWindowMap::iterator it
;
74 for ( it
= wxWinMacWindowList
.begin(); it
!= wxWinMacWindowList
.end(); ++it
)
76 if ( it
->second
== win
)
78 wxWinMacWindowList
.erase(it
);
84 wxNonOwnedWindow
* wxNonOwnedWindow::GetFromWXWindow( WXWindow win
)
86 return wxFindWindowFromWXWindow( win
);
89 // ----------------------------------------------------------------------------
90 // wxNonOwnedWindow creation
91 // ----------------------------------------------------------------------------
93 IMPLEMENT_ABSTRACT_CLASS( wxNonOwnedWindowImpl
, wxObject
)
95 wxNonOwnedWindow
*wxNonOwnedWindow::s_macDeactivateWindow
= NULL
;
97 void wxNonOwnedWindow::Init()
102 bool wxNonOwnedWindow::Create(wxWindow
*parent
,
107 const wxString
& name
)
112 m_windowStyle
= style
;
116 m_windowId
= id
== -1 ? NewControlId() : id
;
117 m_windowStyle
= style
;
124 wxRect display
= wxGetClientDisplayRect() ;
126 if ( x
== wxDefaultPosition
.x
)
129 if ( y
== wxDefaultPosition
.y
)
132 int w
= WidthDefault(size
.x
);
133 int h
= HeightDefault(size
.y
);
135 // temporary define, TODO
137 m_nowpeer
= new wxNonOwnedWindowCarbonImpl( this );
138 #elif wxOSX_USE_COCOA
139 m_nowpeer
= new wxNonOwnedWindowCocoaImpl( this );
140 #elif wxOSX_USE_IPHONE
141 m_nowpeer
= new wxNonOwnedWindowIPhoneImpl( this );
144 m_nowpeer
->Create( parent
, wxPoint(x
,y
) , wxSize(w
,h
) , style
, GetExtraStyle(), name
) ;
145 wxAssociateWindowWithWXWindow( m_nowpeer
->GetWXWindow() , this ) ;
147 // temporary cast, TODO
148 m_peer
= (wxMacControl
*) wxWidgetImpl::CreateContentView(this);
150 m_peer
= wxWidgetImpl::CreateContentView(this);
153 DoSetWindowVariant( m_windowVariant
) ;
155 wxWindowCreateEvent
event(this);
156 HandleWindowEvent(event
);
158 SetBackgroundColour(wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE
));
161 parent
->AddChild(this);
166 wxNonOwnedWindow::~wxNonOwnedWindow()
168 wxRemoveWXWindowAssociation( this ) ;
170 m_nowpeer
->Destroy();
172 // avoid dangling refs
173 if ( s_macDeactivateWindow
== this )
174 s_macDeactivateWindow
= NULL
;
177 // ----------------------------------------------------------------------------
178 // wxNonOwnedWindow misc
179 // ----------------------------------------------------------------------------
181 bool wxNonOwnedWindow::ShowWithEffect(wxShowEffect effect
,
184 if ( !wxWindow::Show(true) )
187 // because apps expect a size event to occur at this moment
188 wxSizeEvent
event(GetSize() , m_windowId
);
189 event
.SetEventObject(this);
190 HandleWindowEvent(event
);
193 return m_nowpeer
->ShowWithEffect(true, effect
, timeout
);
196 bool wxNonOwnedWindow::HideWithEffect(wxShowEffect effect
,
199 if ( !wxWindow::Show(false) )
202 return m_nowpeer
->ShowWithEffect(false, effect
, timeout
);
205 wxPoint
wxNonOwnedWindow::GetClientAreaOrigin() const
207 int left
, top
, width
, height
;
208 m_nowpeer
->GetContentArea(left
, top
, width
, height
);
209 return wxPoint(left
, top
);
212 bool wxNonOwnedWindow::SetBackgroundColour(const wxColour
& c
)
214 if ( !wxWindow::SetBackgroundColour(c
) && m_hasBgCol
)
217 if ( GetBackgroundStyle() != wxBG_STYLE_CUSTOM
)
219 return m_nowpeer
->SetBackgroundColour(c
);
224 // Raise the window to the top of the Z order
225 void wxNonOwnedWindow::Raise()
230 // Lower the window to the bottom of the Z order
231 void wxNonOwnedWindow::Lower()
236 void wxNonOwnedWindow::HandleActivated( double timestampsec
, bool didActivate
)
238 MacActivate( (int) (timestampsec
* 1000) , didActivate
);
239 wxActivateEvent
wxevent(wxEVT_ACTIVATE
, didActivate
, GetId());
240 wxevent
.SetTimestamp( (int) (timestampsec
* 1000) );
241 wxevent
.SetEventObject(this);
242 HandleWindowEvent(wxevent
);
245 void wxNonOwnedWindow::HandleResized( double timestampsec
)
247 wxSizeEvent
wxevent( GetSize() , GetId());
248 wxevent
.SetTimestamp( (int) (timestampsec
* 1000) );
249 wxevent
.SetEventObject( this );
250 HandleWindowEvent(wxevent
);
251 // we have to inform some controls that have to reset things
252 // relative to the toplevel window (e.g. OpenGL buffers)
253 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
256 void wxNonOwnedWindow::HandleResizing( double timestampsec
, wxRect
* rect
)
260 // this is a EVT_SIZING not a EVT_SIZE type !
261 wxSizeEvent
wxevent( r
, GetId() ) ;
262 wxevent
.SetEventObject( this ) ;
263 if ( HandleWindowEvent(wxevent
) )
264 r
= wxevent
.GetRect() ;
266 if ( GetMaxWidth() != -1 && r
.GetWidth() > GetMaxWidth() )
267 r
.SetWidth( GetMaxWidth() ) ;
268 if ( GetMaxHeight() != -1 && r
.GetHeight() > GetMaxHeight() )
269 r
.SetHeight( GetMaxHeight() ) ;
270 if ( GetMinWidth() != -1 && r
.GetWidth() < GetMinWidth() )
271 r
.SetWidth( GetMinWidth() ) ;
272 if ( GetMinHeight() != -1 && r
.GetHeight() < GetMinHeight() )
273 r
.SetHeight( GetMinHeight() ) ;
276 // TODO actuall this is too early, in case the window extents are adjusted
277 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
280 void wxNonOwnedWindow::HandleMoved( double timestampsec
)
282 wxMoveEvent
wxevent( GetPosition() , GetId());
283 wxevent
.SetTimestamp( (int) (timestampsec
* 1000) );
284 wxevent
.SetEventObject( this );
285 HandleWindowEvent(wxevent
);
288 void wxNonOwnedWindow::MacDelayedDeactivation(long timestamp
)
290 if (s_macDeactivateWindow
)
292 wxLogTrace(TRACE_ACTIVATE
,
293 wxT("Doing delayed deactivation of %p"),
294 s_macDeactivateWindow
);
296 s_macDeactivateWindow
->MacActivate(timestamp
, false);
300 void wxNonOwnedWindow::MacActivate( long timestamp
, bool WXUNUSED(inIsActivating
) )
302 wxLogTrace(TRACE_ACTIVATE
, wxT("TopLevel=%p::MacActivate"), this);
304 if (s_macDeactivateWindow
== this)
305 s_macDeactivateWindow
= NULL
;
307 MacDelayedDeactivation(timestamp
);
310 bool wxNonOwnedWindow::Show(bool show
)
312 if ( !wxWindow::Show(show
) )
316 m_nowpeer
->Show(show
);
320 // because apps expect a size event to occur at this moment
321 wxSizeEvent
event(GetSize() , m_windowId
);
322 event
.SetEventObject(this);
323 HandleWindowEvent(event
);
329 bool wxNonOwnedWindow::SetTransparent(wxByte alpha
)
331 return m_nowpeer
->SetTransparent(alpha
);
335 bool wxNonOwnedWindow::CanSetTransparent()
337 return m_nowpeer
->CanSetTransparent();
341 void wxNonOwnedWindow::SetExtraStyle(long exStyle
)
343 if ( GetExtraStyle() == exStyle
)
346 wxWindow::SetExtraStyle( exStyle
) ;
349 m_nowpeer
->SetExtraStyle(exStyle
);
352 bool wxNonOwnedWindow::SetBackgroundStyle(wxBackgroundStyle style
)
354 if ( !wxWindow::SetBackgroundStyle(style
) )
357 return m_nowpeer
->SetBackgroundStyle(style
);
360 void wxNonOwnedWindow::DoMoveWindow(int x
, int y
, int width
, int height
)
362 m_cachedClippedRectValid
= false ;
364 m_nowpeer
->MoveWindow(x
, y
, width
, height
);
365 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
368 void wxNonOwnedWindow::DoGetPosition( int *x
, int *y
) const
371 m_nowpeer
->GetPosition(x1
, y1
);
379 void wxNonOwnedWindow::DoGetSize( int *width
, int *height
) const
383 m_nowpeer
->GetSize(w
, h
);
391 void wxNonOwnedWindow::DoGetClientSize( int *width
, int *height
) const
394 m_nowpeer
->GetContentArea(left
, top
, w
, h
);
403 void wxNonOwnedWindow::Update()
408 WXWindow
wxNonOwnedWindow::GetWXWindow() const
410 return m_nowpeer
? m_nowpeer
->GetWXWindow() : NULL
;
413 // ---------------------------------------------------------------------------
414 // Shape implementation
415 // ---------------------------------------------------------------------------
418 bool wxNonOwnedWindow::SetShape(const wxRegion
& region
)
420 wxCHECK_MSG( HasFlag(wxFRAME_SHAPED
), false,
421 _T("Shaped windows must be created with the wxFRAME_SHAPED style."));
423 // The empty region signifies that the shape
424 // should be removed from the window.
425 if ( region
.IsEmpty() )
427 wxSize sz
= GetClientSize();
428 wxRegion
rgn(0, 0, sz
.x
, sz
.y
);
432 return SetShape(rgn
);
435 return m_nowpeer
->SetShape(region
);