1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/osx/window_osx.cpp
3 // Purpose:     wxWindowMac
4 // Author:      Stefan Csomor
5 // Modified by:
6 // Created:     1998-01-01
7 // Copyright:   (c) Stefan Csomor
8 // Licence:     wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10 
11 #include "wx/wxprec.h"
12 
13 #include "wx/window.h"
14 
15 #ifndef WX_PRECOMP
16     #include "wx/log.h"
17     #include "wx/math.h"
18     #include "wx/app.h"
19     #include "wx/utils.h"
20     #include "wx/panel.h"
21     #include "wx/frame.h"
22     #include "wx/dc.h"
23     #include "wx/dcclient.h"
24     #include "wx/button.h"
25     #include "wx/menu.h"
26     #include "wx/dialog.h"
27     #include "wx/settings.h"
28     #include "wx/msgdlg.h"
29     #include "wx/scrolbar.h"
30     #include "wx/statbox.h"
31     #include "wx/textctrl.h"
32     #include "wx/toolbar.h"
33     #include "wx/layout.h"
34     #include "wx/statusbr.h"
35     #include "wx/menuitem.h"
36     #include "wx/treectrl.h"
37     #include "wx/listctrl.h"
38     #include "wx/platinfo.h"
39 #endif
40 
41 #include "wx/tooltip.h"
42 #include "wx/spinbutt.h"
43 #include "wx/geometry.h"
44 #include "wx/weakref.h"
45 
46 #if wxUSE_LISTCTRL
47     #include "wx/listctrl.h"
48 #endif
49 
50 #if wxUSE_TREECTRL
51     #include "wx/treectrl.h"
52 #endif
53 
54 #if wxUSE_CARET
55     #include "wx/caret.h"
56 #endif
57 
58 #if wxUSE_POPUPWIN
59     #include "wx/popupwin.h"
60 #endif
61 
62 #if wxUSE_DRAG_AND_DROP
63     #include "wx/dnd.h"
64 #endif
65 
66 #include "wx/graphics.h"
67 
68 #include "wx/osx/private.h"
69 
70 #define MAC_SCROLLBAR_SIZE 15
71 #define MAC_SMALL_SCROLLBAR_SIZE 11
72 
73 #include <string.h>
74 
75 #define TRACE_KEYS  "keyevent"
76 
77 #ifdef __WXUNIVERSAL__
78     wxIMPLEMENT_ABSTRACT_CLASS(wxWindowMac, wxWindowBase);
79 #endif
80 
81 wxBEGIN_EVENT_TABLE(wxWindowMac, wxWindowBase)
82     EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent)
83     EVT_DPI_CHANGED(wxWindowMac::OnDPIChanged)
84 wxEND_EVENT_TABLE()
85 
86 #define wxMAC_DEBUG_REDRAW 0
87 #ifndef wxMAC_DEBUG_REDRAW
88 #define wxMAC_DEBUG_REDRAW 0
89 #endif
90 
91 wxWidgetImplType* kOSXNoWidgetImpl = (wxWidgetImplType*) -1L;
92 
93 #if wxUSE_HOTKEY && wxOSX_USE_COCOA_OR_CARBON
94 
95 typedef struct  {
96     EventHotKeyRef ref;
97     int keyId;
98     wxWindow* window;
99 } wxHotKeyRec;
100 
101 wxVector<wxHotKeyRec> s_hotkeys;
102 
103 #endif
104 
105 // ===========================================================================
106 // implementation
107 // ===========================================================================
108 
109 // the grow box has to be implemented as an inactive window, so that nothing can direct
110 // the focus to it
111 
112 class WXDLLIMPEXP_CORE wxBlindPlateWindow : public wxWindow
113 {
114 public:
wxBlindPlateWindow()115     wxBlindPlateWindow() { Init(); }
116 
117     // Old-style constructor (no default values for coordinates to avoid
118     // ambiguity with the new one)
wxBlindPlateWindow(wxWindow * parent,int x,int y,int width,int height,long style=wxTAB_TRAVERSAL|wxNO_BORDER,const wxString & name=wxPanelNameStr)119     wxBlindPlateWindow(wxWindow *parent,
120             int x, int y, int width, int height,
121             long style = wxTAB_TRAVERSAL | wxNO_BORDER,
122             const wxString& name = wxPanelNameStr)
123     {
124         Init();
125 
126         Create(parent, wxID_ANY, wxPoint(x, y), wxSize(width, height), style, name);
127     }
128 
129     // Constructor
wxBlindPlateWindow(wxWindow * parent,wxWindowID winid=wxID_ANY,const wxPoint & pos=wxDefaultPosition,const wxSize & size=wxDefaultSize,long style=wxTAB_TRAVERSAL|wxNO_BORDER,const wxString & name=wxPanelNameStr)130     wxBlindPlateWindow(wxWindow *parent,
131             wxWindowID winid = wxID_ANY,
132             const wxPoint& pos = wxDefaultPosition,
133             const wxSize& size = wxDefaultSize,
134             long style = wxTAB_TRAVERSAL | wxNO_BORDER,
135             const wxString& name = wxPanelNameStr)
136     {
137         Init();
138 
139         Create(parent, winid, pos, size, style, name);
140     }
141 
142     // Pseudo ctor
Create(wxWindow * parent,wxWindowID winid=wxID_ANY,const wxPoint & pos=wxDefaultPosition,const wxSize & size=wxDefaultSize,long style=wxTAB_TRAVERSAL|wxNO_BORDER,const wxString & name=wxPanelNameStr)143     bool Create(wxWindow *parent,
144                 wxWindowID winid = wxID_ANY,
145                 const wxPoint& pos = wxDefaultPosition,
146                 const wxSize& size = wxDefaultSize,
147                 long style = wxTAB_TRAVERSAL | wxNO_BORDER,
148                 const wxString& name = wxPanelNameStr)
149     {
150         if ( !wxWindow::Create(parent, winid, pos, size, style, name) )
151             return false;
152 
153         // so that non-solid background renders correctly under GTK+:
154         SetThemeEnabled(true);
155         return true;
156     }
157 
158     virtual ~wxBlindPlateWindow();
159 
AcceptsFocus() const160     virtual bool AcceptsFocus() const wxOVERRIDE
161     {
162         return false;
163     }
164 
165 protected:
166     // common part of all ctors
Init()167     void Init()
168     {
169     }
170 
171     wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxBlindPlateWindow);
172     wxDECLARE_EVENT_TABLE();
173 };
174 
~wxBlindPlateWindow()175 wxBlindPlateWindow::~wxBlindPlateWindow()
176 {
177 }
178 
179 wxIMPLEMENT_DYNAMIC_CLASS(wxBlindPlateWindow, wxWindow);
180 
wxBEGIN_EVENT_TABLE(wxBlindPlateWindow,wxWindow)181 wxBEGIN_EVENT_TABLE(wxBlindPlateWindow, wxWindow)
182 wxEND_EVENT_TABLE()
183 
184 // ----------------------------------------------------------------------------
185 // debug helpers
186 // ----------------------------------------------------------------------------
187 
188 // Function used to dump a brief description of a window.
189 extern
190 wxString wxDumpWindow(wxWindowMac* win)
191 {
192     if ( !win )
193         return "(no window)";
194 
195     wxString s = wxString::Format("%s(%p",
196                                   win->GetClassInfo()->GetClassName(), win);
197 
198     wxString label = win->GetLabel();
199     if ( !label.empty() )
200         s += wxString::Format(", \"%s\"", label);
201     s += ")";
202 
203     return s;
204 }
205 
206 // ----------------------------------------------------------------------------
207  // constructors and such
208 // ----------------------------------------------------------------------------
209 
wxWindowMac()210 wxWindowMac::wxWindowMac()
211 {
212     Init();
213 }
214 
wxWindowMac(wxWindowMac * parent,wxWindowID id,const wxPoint & pos,const wxSize & size,long style,const wxString & name)215 wxWindowMac::wxWindowMac(wxWindowMac *parent,
216             wxWindowID id,
217             const wxPoint& pos ,
218             const wxSize& size ,
219             long style ,
220             const wxString& name )
221 {
222     Init();
223     Create(parent, id, pos, size, style, name);
224 }
225 
Init()226 void wxWindowMac::Init()
227 {
228     m_peer = NULL ;
229     m_macAlpha = 255 ;
230     m_cgContextRef = NULL ;
231 
232     // as all windows are created with WS_VISIBLE style...
233     m_isShown = true;
234 
235     m_hScrollBar = NULL ;
236     m_vScrollBar = NULL ;
237     m_hScrollBarAlwaysShown = false;
238     m_vScrollBarAlwaysShown = false;
239     m_growBox = NULL ;
240 
241     m_clipChildren = false ;
242     m_cachedClippedRectValid = false ;
243     m_isNativeWindowWrapper = false;
244 }
245 
~wxWindowMac()246 wxWindowMac::~wxWindowMac()
247 {
248     SendDestroyEvent();
249 
250 #if wxUSE_HOTKEY && wxOSX_USE_COCOA_OR_CARBON
251     for ( int i = s_hotkeys.size()-1; i>=0; -- i )
252     {
253         if ( s_hotkeys[i].window == this )
254         {
255             EventHotKeyRef ref = s_hotkeys[i].ref;
256             s_hotkeys.erase(s_hotkeys.begin() + i);
257             if ( UnregisterEventHotKey(ref) != noErr )
258             {
259                 wxLogLastError(wxT("UnregisterHotKey"));
260             }
261         }
262     }
263 #endif
264 
265     MacInvalidateBorders() ;
266 
267     // destroy children before destroying this window itself
268     DestroyChildren();
269 
270     // wxRemoveMacControlAssociation( this ) ;
271     // If we delete an item, we should initialize the parent panel,
272     // because it could now be invalid.
273     wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent((wxWindow*)this), wxTopLevelWindow);
274     if ( tlw )
275     {
276         if ( tlw->GetDefaultItem() == (wxButton*) this)
277             tlw->SetDefaultItem(NULL);
278     }
279 
280     // delete our drop target if we've got one
281 #if wxUSE_DRAG_AND_DROP
282     wxDELETE(m_dropTarget);
283 #endif
284 
285     delete GetPeer() ;
286 }
287 
GetHandle() const288 WXWidget wxWindowMac::GetHandle() const
289 {
290     if ( GetPeer() )
291         return (WXWidget) GetPeer()->GetWXWidget() ;
292     return NULL;
293 }
294 
GetPeer() const295 wxOSXWidgetImpl* wxWindowMac::GetPeer() const
296 {
297     return m_peer == kOSXNoWidgetImpl ? NULL : m_peer ;
298 }
299 
ShouldCreatePeer() const300 bool wxWindowMac::ShouldCreatePeer() const
301 {
302     return m_peer != kOSXNoWidgetImpl;
303 }
304 
DontCreatePeer()305 void wxWindowMac::DontCreatePeer()
306 {
307     m_peer = kOSXNoWidgetImpl;
308 }
309 
SetWrappingPeer(wxOSXWidgetImpl * wrapper)310 void wxWindowMac::SetWrappingPeer(wxOSXWidgetImpl* wrapper)
311 {
312     wxOSXWidgetImpl* inner = GetPeer();
313     wxASSERT_MSG( inner != NULL && inner->IsOk(), "missing or incomplete inner peer" );
314     wxASSERT_MSG( wrapper != NULL && wrapper->IsOk(), "missing or incomplete wrapper" );
315 
316     if ( !(inner != NULL && inner->IsOk() && wrapper != NULL && wrapper->IsOk()) )
317         return;
318 
319     inner->RemoveFromParent();
320     wrapper->InstallEventHandler();
321     wrapper->Embed(inner);
322     m_peer = wrapper;
323 }
324 
SetPeer(wxOSXWidgetImpl * peer)325 void wxWindowMac::SetPeer(wxOSXWidgetImpl* peer)
326 {
327     if ( GetPeer() )
328     {
329         if ( !GetPeer()->IsRootControl() )
330             GetPeer()->RemoveFromParent();
331         wxDELETE(m_peer);
332     }
333 
334     m_peer = peer;
335 
336     if ( GetPeer() && !GetPeer()->IsRootControl())
337     {
338         wxASSERT_MSG( GetPeer()->IsOk() , wxT("The native control must exist already") ) ;
339 
340         if (!GetParent()->GetChildren().Find((wxWindow*)this))
341             GetParent()->AddChild( this );
342 
343         GetPeer()->InstallEventHandler();
344         GetPeer()->Embed(GetParent()->GetPeer());
345 
346         GetParent()->MacChildAdded() ;
347 
348         // adjust font, controlsize etc
349         GetPeer()->SetControlSize( m_windowVariant );
350         InheritAttributes();
351         // in case nothing has been set, use the variant default fonts
352         if ( !m_hasFont )
353             DoSetWindowVariant( m_windowVariant );
354 
355         GetPeer()->SetInitialLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics), GetFont().GetEncoding() ) ;
356 
357         // for controls we want to use best size for wxDefaultSize params )
358         if ( !GetPeer()->IsUserPane() )
359             SetInitialSize(GetMinSize());
360 
361         SetCursor( *wxSTANDARD_CURSOR ) ;
362     }
363 }
364 
365 #if WXWIN_COMPATIBILITY_2_8
366 
MacIsUserPane()367 bool wxWindowMac::MacIsUserPane()
368 {
369     return GetPeer() == NULL || GetPeer()->IsUserPane();
370 }
371 
372 #endif
373 
MacIsUserPane() const374 bool wxWindowMac::MacIsUserPane() const
375 {
376     return GetPeer() == NULL || GetPeer()->IsUserPane();
377 }
378 
379 // ---------------------------------------------------------------------------
380 // Utility Routines to move between different coordinate systems
381 // ---------------------------------------------------------------------------
382 
383 /*
384  * Right now we have the following setup :
385  * a border that is not part of the native control is always outside the
386  * control's border (otherwise we lose all native intelligence, future ways
387  * may be to have a second embedding control responsible for drawing borders
388  * and backgrounds eventually)
389  * so all this border calculations have to be taken into account when calling
390  * native methods or getting native oriented data
391  * so we have three coordinate systems here
392  * wx client coordinates
393  * wx window coordinates (including window frames)
394  * native coordinates
395  */
396 
397 //
398 //
399 
400 // Constructor
Create(wxWindowMac * parent,wxWindowID id,const wxPoint & pos,const wxSize & size,long style,const wxString & name)401 bool wxWindowMac::Create(wxWindowMac *parent,
402     wxWindowID id,
403     const wxPoint& pos,
404     const wxSize& size,
405     long style,
406     const wxString& name)
407 {
408     wxCHECK_MSG( parent, false, wxT("can't create wxWindowMac without parent") );
409 
410     if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
411         return false;
412 
413     m_windowVariant = parent->GetWindowVariant() ;
414 
415     m_hScrollBarAlwaysShown =
416     m_vScrollBarAlwaysShown = HasFlag(wxALWAYS_SHOW_SB);
417 
418     if ( m_peer != kOSXNoWidgetImpl )
419     {
420         SetPeer(wxWidgetImpl::CreateUserPane( this, parent, id, pos, size , style, GetExtraStyle() ));
421         MacPostControlCreate(pos, size) ;
422     }
423 
424 #ifndef __WXUNIVERSAL__
425     // Don't give scrollbars to wxControls unless they ask for them
426     if ( (! IsKindOf(CLASSINFO(wxControl))
427 #if wxUSE_STATUSBAR
428         && ! IsKindOf(CLASSINFO(wxStatusBar))
429 #endif
430         )
431          || (IsKindOf(CLASSINFO(wxControl)) && ((style & wxHSCROLL) || (style & wxVSCROLL))))
432     {
433         MacCreateScrollBars( style ) ;
434     }
435 #endif
436 
437     wxWindowCreateEvent event((wxWindow*)this);
438     GetEventHandler()->AddPendingEvent(event);
439 
440     return true;
441 }
442 
MacChildAdded()443 void wxWindowMac::MacChildAdded()
444 {
445 #if wxUSE_SCROLLBAR
446     if ( m_vScrollBar )
447         m_vScrollBar->Raise() ;
448     if ( m_hScrollBar )
449         m_hScrollBar->Raise() ;
450     if ( m_growBox )
451         m_growBox->Raise() ;
452 #endif
453 }
454 
MacPostControlCreate(const wxPoint & pos,const wxSize & WXUNUSED (size))455 void wxWindowMac::MacPostControlCreate(const wxPoint& pos,
456                                        const wxSize& WXUNUSED(size))
457 {
458     // Some controls may have a nonzero layout inset,
459     // so we may need to adjust control position.
460     if ( pos.IsFullySpecified() && GetPosition() != pos )
461     {
462         SetPosition(pos);
463     }
464 }
465 
DoSetWindowVariant(wxWindowVariant variant)466 void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant )
467 {
468     // Don't assert, in case we set the window variant before
469     // the window is created
470     // wxASSERT( GetPeer()->IsOk() ) ;
471 
472     m_windowVariant = variant ;
473 
474     if (GetPeer() == NULL || !GetPeer()->IsOk())
475         return;
476 
477     GetPeer()->SetControlSize( variant );
478 
479     switch ( variant )
480     {
481         case wxWINDOW_VARIANT_NORMAL :
482             static wxFont sysNormal(wxOSX_SYSTEM_FONT_NORMAL);
483             SetFont(sysNormal) ;
484             break ;
485 
486         case wxWINDOW_VARIANT_SMALL :
487             static wxFont sysSmall(wxOSX_SYSTEM_FONT_SMALL);
488             SetFont(sysSmall) ;
489             break ;
490 
491         case wxWINDOW_VARIANT_MINI :
492             static wxFont sysMini(wxOSX_SYSTEM_FONT_MINI);
493             SetFont(sysMini) ;
494             break ;
495 
496         case wxWINDOW_VARIANT_LARGE :
497             static wxFont sysLarge(wxOSX_SYSTEM_FONT_NORMAL);
498             SetFont(sysLarge) ;
499             break ;
500 
501         default:
502             wxFAIL_MSG(wxT("unexpected window variant"));
503             break ;
504     }
505 }
506 
SetFont(const wxFont & font)507 bool wxWindowMac::SetFont(const wxFont& font)
508 {
509     bool retval = wxWindowBase::SetFont( font );
510 
511     if (retval)
512     {
513         if ( GetPeer() )
514             GetPeer()->SetFont(GetFont()) ;
515 
516         // do not trigger refreshes upon invisible and possible partly created objects
517         if ( IsShownOnScreen() )
518             Refresh() ;
519     }
520 
521     return retval;
522 }
523 
SetForegroundColour(const wxColour & col)524 bool wxWindowMac::SetForegroundColour(const wxColour& col )
525 {
526     if ( !wxWindowBase::SetForegroundColour( col ) )
527         return false;
528 
529     if ( GetPeer() )
530         GetPeer()->SetForegroundColour(col);
531 
532     return true;
533 }
534 
SetBackgroundStyle(wxBackgroundStyle style)535 bool wxWindowMac::SetBackgroundStyle(wxBackgroundStyle style)
536 {
537     if ( !wxWindowBase::SetBackgroundStyle(style) )
538         return false;
539 
540     if ( GetPeer() )
541         GetPeer()->SetBackgroundStyle(style);
542     return true;
543 }
544 
IsTransparentBackgroundSupported(wxString * WXUNUSED (reason)) const545 bool wxWindowMac::IsTransparentBackgroundSupported(wxString* WXUNUSED(reason)) const
546 {
547     return true;
548 }
549 
SetBackgroundColour(const wxColour & col)550 bool wxWindowMac::SetBackgroundColour(const wxColour& col )
551 {
552     if (m_growBox)
553     {
554         if ( m_backgroundColour.IsOk() )
555             m_growBox->SetBackgroundColour(m_backgroundColour);
556         else
557             m_growBox->SetBackgroundColour(*wxWHITE);
558     }
559 
560     if ( !wxWindowBase::SetBackgroundColour(col) && m_hasBgCol )
561         return false ;
562 
563     if ( GetPeer() )
564         GetPeer()->SetBackgroundColour( col ) ;
565 
566     return true ;
567 }
568 
SetFocus()569 void wxWindowMac::SetFocus()
570 {
571     if ( !IsEnabled() )
572         return;
573 
574     wxWindow* former = FindFocus() ;
575     if ( former == this )
576         return ;
577 
578     GetPeer()->SetFocus() ;
579 }
580 
OSXSimulateFocusEvents()581 void wxWindowMac::OSXSimulateFocusEvents()
582 {
583     wxWeakRef<wxWindow> former = FindFocus() ;
584     if ( former != NULL && former != this )
585     {
586         {
587             wxFocusEvent event( wxEVT_KILL_FOCUS, former->GetId());
588             event.SetEventObject(former);
589             event.SetWindow(this);
590             former->HandleWindowEvent(event) ;
591         }
592 
593         // 'former' could have been destroyed by a wxEVT_KILL_FOCUS handler,
594         // so we must test it for non-NULL again
595         if ( former )
596         {
597             wxFocusEvent event(wxEVT_SET_FOCUS, former->GetId());
598             event.SetEventObject(former);
599             event.SetWindow(this);
600             former->HandleWindowEvent(event);
601         }
602     }
603 }
604 
DoCaptureMouse()605 void wxWindowMac::DoCaptureMouse()
606 {
607     wxApp::s_captureWindow = (wxWindow*) this ;
608     GetPeer()->CaptureMouse() ;
609 }
610 
GetCapture()611 wxWindow * wxWindowBase::GetCapture()
612 {
613     return wxApp::s_captureWindow ;
614 }
615 
DoReleaseMouse()616 void wxWindowMac::DoReleaseMouse()
617 {
618     wxApp::s_captureWindow = NULL ;
619 
620     GetPeer()->ReleaseMouse() ;
621 }
622 
623 #if wxUSE_DRAG_AND_DROP
624 
SetDropTarget(wxDropTarget * pDropTarget)625 void wxWindowMac::SetDropTarget(wxDropTarget *pDropTarget)
626 {
627     delete m_dropTarget;
628 
629     m_dropTarget = pDropTarget;
630 
631     GetPeer()->SetDropTarget(m_dropTarget) ;
632 }
633 
634 #endif
635 
636 // From a wx position / size calculate the appropriate size of the native control
637 
MacGetBoundsForControl(const wxPoint & pos,const wxSize & size,int & x,int & y,int & w,int & h,bool adjustOrigin) const638 bool wxWindowMac::MacGetBoundsForControl(
639     const wxPoint& pos,
640     const wxSize& size,
641     int& x, int& y,
642     int& w, int& h , bool adjustOrigin ) const
643 {
644     // the desired size, minus the border pixels gives the correct size of the control
645     x = (int)pos.x;
646     y = (int)pos.y;
647 
648     w = WidthDefault( size.x );
649     h = HeightDefault( size.y );
650 
651     x += MacGetLeftBorderSize() ;
652     y += MacGetTopBorderSize() ;
653     w -= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
654     h -= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
655 
656     if ( adjustOrigin )
657         AdjustForParentClientOrigin( x , y ) ;
658 
659     // this is in window relative coordinate, as this parent may have a border, its physical position is offset by this border
660     if ( GetParent() && !GetParent()->IsTopLevel() )
661     {
662         x -= GetParent()->MacGetLeftBorderSize() ;
663         y -= GetParent()->MacGetTopBorderSize() ;
664     }
665 
666     return true ;
667 }
668 
669 // Get window size (not client size)
DoGetSize(int * x,int * y) const670 void wxWindowMac::DoGetSize(int *x, int *y) const
671 {
672     int width, height;
673     GetPeer()->GetSize( width, height );
674 
675     if (x)
676        *x = width + MacGetLeftBorderSize() + MacGetRightBorderSize() ;
677     if (y)
678        *y = height + MacGetTopBorderSize() + MacGetBottomBorderSize() ;
679 }
680 
681 // get the position of the bounds of this window in client coordinates of its parent
DoGetPosition(int * x,int * y) const682 void wxWindowMac::DoGetPosition(int *x, int *y) const
683 {
684     int x1, y1;
685 
686     GetPeer()->GetPosition( x1, y1 ) ;
687 
688     // get the wx window position from the native one
689     x1 -= MacGetLeftBorderSize() ;
690     y1 -= MacGetTopBorderSize() ;
691 
692     if ( !IsTopLevel() )
693     {
694         wxWindow *parent = GetParent();
695         if ( parent )
696         {
697             // we must first adjust it to be in window coordinates of the parent,
698             // as otherwise it gets lost by the ClientAreaOrigin fix
699             x1 += parent->MacGetLeftBorderSize() ;
700             y1 += parent->MacGetTopBorderSize() ;
701 
702             // and now to client coordinates
703             wxPoint pt(parent->GetClientAreaOrigin());
704             x1 -= pt.x ;
705             y1 -= pt.y ;
706         }
707     }
708 
709     if (x)
710        *x = x1 ;
711     if (y)
712        *y = y1 ;
713 }
714 
DoScreenToClient(int * x,int * y) const715 void wxWindowMac::DoScreenToClient(int *x, int *y) const
716 {
717     wxNonOwnedWindow* tlw = MacGetTopLevelWindow() ;
718     wxCHECK_RET( tlw , wxT("TopLevel Window missing") ) ;
719     tlw->GetNonOwnedPeer()->ScreenToWindow( x, y);
720     MacRootWindowToWindow( x , y ) ;
721 
722     wxPoint origin = GetClientAreaOrigin() ;
723     if (x)
724        *x -= origin.x ;
725     if (y)
726        *y -= origin.y ;
727 }
728 
DoClientToScreen(int * x,int * y) const729 void wxWindowMac::DoClientToScreen(int *x, int *y) const
730 {
731     wxNonOwnedWindow* tlw = MacGetTopLevelWindow() ;
732     wxCHECK_RET( tlw , wxT("TopLevel window missing") ) ;
733 
734     wxPoint origin = GetClientAreaOrigin() ;
735     if (x)
736        *x += origin.x ;
737     if (y)
738        *y += origin.y ;
739 
740     MacWindowToRootWindow( x , y ) ;
741     tlw->GetNonOwnedPeer()->WindowToScreen( x , y );
742 }
743 
MacClientToRootWindow(int * x,int * y) const744 void wxWindowMac::MacClientToRootWindow( int *x , int *y ) const
745 {
746     wxPoint origin = GetClientAreaOrigin() ;
747     if (x)
748        *x += origin.x ;
749     if (y)
750        *y += origin.y ;
751 
752     MacWindowToRootWindow( x , y ) ;
753 }
754 
MacWindowToRootWindow(int * x,int * y) const755 void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const
756 {
757     wxPoint pt ;
758 
759     if (x)
760         pt.x = *x ;
761     if (y)
762         pt.y = *y ;
763 
764     if ( !IsTopLevel() )
765     {
766         wxNonOwnedWindow* top = MacGetTopLevelWindow();
767         if (top)
768         {
769             pt.x -= MacGetLeftBorderSize() ;
770             pt.y -= MacGetTopBorderSize() ;
771             wxWidgetImpl::Convert( &pt , GetPeer() , top->GetPeer() ) ;
772         }
773     }
774 
775     if (x)
776         *x = (int) pt.x ;
777     if (y)
778         *y = (int) pt.y ;
779 }
780 
MacRootWindowToWindow(int * x,int * y) const781 void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const
782 {
783     wxPoint pt ;
784 
785     if (x)
786         pt.x = *x ;
787     if (y)
788         pt.y = *y ;
789 
790     if ( !IsTopLevel() )
791     {
792         wxNonOwnedWindow* top = MacGetTopLevelWindow();
793         if (top)
794         {
795             wxWidgetImpl::Convert( &pt , top->GetPeer() , GetPeer() ) ;
796             pt.x += MacGetLeftBorderSize() ;
797             pt.y += MacGetTopBorderSize() ;
798         }
799     }
800 
801     if (x)
802         *x = (int) pt.x ;
803     if (y)
804         *y = (int) pt.y ;
805 }
806 
DoGetSizeFromClientSize(const wxSize & size) const807 wxSize wxWindowMac::DoGetSizeFromClientSize( const wxSize & size )  const
808 {
809     wxSize sizeTotal = size;
810 
811     int innerwidth, innerheight;
812     int left, top;
813     int outerwidth, outerheight;
814 
815     GetPeer()->GetContentArea( left, top, innerwidth, innerheight );
816     GetPeer()->GetSize( outerwidth, outerheight );
817 
818     sizeTotal.x += outerwidth-innerwidth;
819     sizeTotal.y += outerheight-innerheight;
820 
821     sizeTotal.x += MacGetLeftBorderSize() + MacGetRightBorderSize() ;
822     sizeTotal.y += MacGetTopBorderSize() + MacGetBottomBorderSize() ;
823 
824     return sizeTotal;
825 }
826 
827 // Get size *available for subwindows* i.e. excluding menu bar etc.
DoGetClientSize(int * x,int * y) const828 void wxWindowMac::DoGetClientSize( int *x, int *y ) const
829 {
830     int ww, hh;
831 
832     int left, top;
833 
834     GetPeer()->GetContentArea( left, top, ww, hh );
835 #if wxUSE_SCROLLBAR
836     if (m_hScrollBar  && m_hScrollBar->IsShown() )
837         hh -= m_hScrollBar->GetSize().y ;
838 
839     if (m_vScrollBar  && m_vScrollBar->IsShown() )
840         ww -= m_vScrollBar->GetSize().x ;
841 
842 #endif
843     if (x)
844     {
845         // we shouldn't return invalid width
846         if ( ww < 0 )
847             ww = 0;
848 
849         *x = ww;
850     }
851 
852     if (y)
853     {
854         // we shouldn't return invalid height
855         if ( hh < 0 )
856             hh = 0;
857 
858         *y = hh;
859     }
860 }
861 
SetCursor(const wxCursor & cursor)862 bool wxWindowMac::SetCursor(const wxCursor& cursor)
863 {
864     if (m_cursor.IsSameAs(cursor))
865         return false;
866 
867     if (!cursor.IsOk())
868     {
869         if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ) )
870             return false ;
871     }
872     else
873     {
874         if ( ! wxWindowBase::SetCursor( cursor ) )
875             return false ;
876     }
877 
878     wxASSERT_MSG( m_cursor.IsOk(),
879         wxT("cursor must be valid after call to the base version"));
880 
881     if ( GetPeer() != NULL )
882         GetPeer()->SetCursor( m_cursor );
883 
884     return true ;
885 }
886 
887 #if wxUSE_MENUS
DoPopupMenu(wxMenu * menu,int x,int y)888 bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y)
889 {
890 #ifndef __WXUNIVERSAL__
891     if ( x == wxDefaultCoord && y == wxDefaultCoord )
892     {
893         wxPoint mouse = wxGetMousePosition();
894         x = mouse.x;
895         y = mouse.y;
896     }
897     else
898     {
899         ClientToScreen( &x , &y ) ;
900     }
901     menu->GetPeer()->PopUp(this, x, y);
902     return true;
903 #else
904     // actually this shouldn't be called, because universal is having its own implementation
905     return false;
906 #endif
907 }
908 #endif
909 
910 // ----------------------------------------------------------------------------
911 // tooltips
912 // ----------------------------------------------------------------------------
913 
914 #if wxUSE_TOOLTIPS
915 
DoSetToolTip(wxToolTip * tooltip)916 void wxWindowMac::DoSetToolTip(wxToolTip *tooltip)
917 {
918     wxWindowBase::DoSetToolTip(tooltip);
919 
920     if ( m_tooltip )
921         m_tooltip->SetWindow(this);
922 
923     if (GetPeer())
924         GetPeer()->SetToolTip(tooltip);
925 }
926 
927 #endif
928 
MacInvalidateBorders()929 void wxWindowMac::MacInvalidateBorders()
930 {
931     if ( GetPeer() == NULL )
932         return ;
933 
934     bool vis = IsShownOnScreen() ;
935     if ( !vis )
936         return ;
937 
938     int outerBorder = MacGetLeftBorderSize() ;
939 
940     if ( outerBorder == 0 )
941         return ;
942 
943     // now we know that we have something to do at all
944 
945     int tx,ty,tw,th;
946 
947     GetPeer()->GetSize( tw, th );
948     GetPeer()->GetPosition( tx, ty );
949 
950     wxRect leftupdate( tx-outerBorder,ty,outerBorder,th );
951     wxRect rightupdate( tx+tw, ty, outerBorder, th );
952     wxRect topupdate( tx-outerBorder, ty-outerBorder, tw + 2 * outerBorder, outerBorder );
953     wxRect bottomupdate( tx-outerBorder, ty + th, tw + 2 * outerBorder, outerBorder );
954 
955     if (GetParent()) {
956         GetParent()->GetPeer()->SetNeedsDisplay(&leftupdate);
957         GetParent()->GetPeer()->SetNeedsDisplay(&rightupdate);
958         GetParent()->GetPeer()->SetNeedsDisplay(&topupdate);
959         GetParent()->GetPeer()->SetNeedsDisplay(&bottomupdate);
960     }
961 }
962 
DoMoveWindow(int x,int y,int width,int height)963 void wxWindowMac::DoMoveWindow(int x, int y, int width, int height)
964 {
965     // this is never called for a toplevel window, so we know we have a parent
966     int former_x , former_y , former_w, former_h ;
967 
968     // Get true coordinates of former position
969     DoGetPosition( &former_x , &former_y ) ;
970     DoGetSize( &former_w , &former_h ) ;
971 
972     wxWindow *parent = GetParent();
973     if ( parent )
974     {
975         wxPoint pt(parent->GetClientAreaOrigin());
976         former_x += pt.x ;
977         former_y += pt.y ;
978     }
979 
980     int actualWidth = width ;
981     int actualHeight = height ;
982     int actualX = x;
983     int actualY = y;
984 
985 #if 0
986     // min and max sizes are only for sizers, not for explicit size setting
987     if ((m_minWidth != -1) && (actualWidth < m_minWidth))
988         actualWidth = m_minWidth;
989     if ((m_minHeight != -1) && (actualHeight < m_minHeight))
990         actualHeight = m_minHeight;
991     if ((m_maxWidth != -1) && (actualWidth > m_maxWidth))
992         actualWidth = m_maxWidth;
993     if ((m_maxHeight != -1) && (actualHeight > m_maxHeight))
994         actualHeight = m_maxHeight;
995 #endif
996 
997     bool doMove = false, doResize = false ;
998 
999     if ( actualX != former_x || actualY != former_y )
1000         doMove = true ;
1001 
1002     if ( actualWidth != former_w || actualHeight != former_h )
1003         doResize = true ;
1004 
1005     if ( doMove || doResize )
1006     {
1007         // as the borders are drawn outside the native control, we adjust now
1008 
1009         wxRect bounds( wxPoint( actualX + MacGetLeftBorderSize() ,actualY + MacGetTopBorderSize() ),
1010             wxSize( actualWidth - (MacGetLeftBorderSize() + MacGetRightBorderSize()) ,
1011                 actualHeight - (MacGetTopBorderSize() + MacGetBottomBorderSize()) ) ) ;
1012 
1013         if ( parent && !parent->IsTopLevel() )
1014         {
1015             bounds.Offset( -parent->MacGetLeftBorderSize(), -parent->MacGetTopBorderSize() );
1016         }
1017 
1018         MacInvalidateBorders() ;
1019 
1020         m_cachedClippedRectValid = false ;
1021 
1022         GetPeer()->Move( bounds.x, bounds.y, bounds.width, bounds.height);
1023 
1024         wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
1025 
1026         MacInvalidateBorders() ;
1027 
1028         MacRepositionScrollBars() ;
1029         if ( doMove )
1030         {
1031             wxPoint point(actualX, actualY);
1032             wxMoveEvent event(point, m_windowId);
1033             event.SetEventObject(this);
1034             HandleWindowEvent(event) ;
1035         }
1036 
1037         if ( doResize )
1038         {
1039             MacRepositionScrollBars() ;
1040             SendSizeEvent();
1041         }
1042     }
1043 }
1044 
DoGetBestSize() const1045 wxSize wxWindowMac::DoGetBestSize() const
1046 {
1047     if ( GetPeer() == NULL || GetPeer()->IsUserPane() || IsTopLevel() )
1048     {
1049         return wxWindowBase::DoGetBestSize() ;
1050     }
1051     else
1052     {
1053         wxRect r ;
1054 
1055         GetPeer()->GetBestRect(&r);
1056 
1057         if ( r.GetWidth() == 0 && r.GetHeight() == 0 )
1058         {
1059             r.x =
1060             r.y = 0 ;
1061             r.width =
1062             r.height = 16 ;
1063 
1064 #if wxUSE_SCROLLBAR
1065             if ( IsKindOf( CLASSINFO( wxScrollBar ) ) )
1066             {
1067                 r.height = 16 ;
1068             }
1069             else
1070 #endif
1071 #if wxUSE_SPINBTN
1072             if ( IsKindOf( CLASSINFO( wxSpinButton ) ) )
1073             {
1074                 r.height = 24 ;
1075             }
1076             else
1077 #endif
1078             {
1079                 // return wxWindowBase::DoGetBestSize() ;
1080             }
1081         }
1082 
1083         int bestWidth = r.width + MacGetLeftBorderSize() +
1084                     MacGetRightBorderSize();
1085         int bestHeight = r.height + MacGetTopBorderSize() +
1086                      MacGetBottomBorderSize();
1087         if ( bestHeight < 10 )
1088             bestHeight = 13 ;
1089 
1090         return wxSize(bestWidth, bestHeight);
1091     }
1092 }
1093 
SendSizeEvent(int flags)1094 void wxWindowMac::SendSizeEvent(int flags)
1095 {
1096     MacOnInternalSize();
1097     wxWindowBase::SendSizeEvent(flags);
1098 }
1099 
1100 // set the size of the window: if the dimensions are positive, just use them,
1101 // but if any of them is equal to -1, it means that we must find the value for
1102 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
1103 // which case -1 is a valid value for x and y)
1104 //
1105 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
1106 // the width/height to best suit our contents, otherwise we reuse the current
1107 // width/height
DoSetSize(int x,int y,int width,int height,int sizeFlags)1108 void wxWindowMac::DoSetSize(int x, int y, int width, int height, int sizeFlags)
1109 {
1110     // get the current size and position...
1111     int currentX, currentY;
1112     int currentW, currentH;
1113 
1114     GetPosition(&currentX, &currentY);
1115     GetSize(&currentW, &currentH);
1116 
1117     // ... and don't do anything (avoiding flicker) if it's already ok
1118     if ( x == currentX && y == currentY &&
1119         width == currentW && height == currentH && ( height != -1 && width != -1 ) )
1120     {
1121         // TODO: REMOVE
1122         MacRepositionScrollBars() ; // we might have a real position shift
1123 
1124         if (sizeFlags & wxSIZE_FORCE_EVENT)
1125         {
1126             SendSizeEvent();
1127         }
1128 
1129         return;
1130     }
1131 
1132     if ( !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
1133     {
1134         if ( x == wxDefaultCoord )
1135             x = currentX;
1136         if ( y == wxDefaultCoord )
1137             y = currentY;
1138     }
1139 
1140     AdjustForParentClientOrigin( x, y, sizeFlags );
1141 
1142     wxSize size = wxDefaultSize;
1143     if ( width == wxDefaultCoord )
1144     {
1145         if ( sizeFlags & wxSIZE_AUTO_WIDTH )
1146         {
1147             size = DoGetBestSize();
1148             width = size.x;
1149         }
1150         else
1151         {
1152             // just take the current one
1153             width = currentW;
1154         }
1155     }
1156 
1157     if ( height == wxDefaultCoord )
1158     {
1159         if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
1160         {
1161             if ( size.x == wxDefaultCoord )
1162                 size = DoGetBestSize();
1163             // else: already called DoGetBestSize() above
1164 
1165             height = size.y;
1166         }
1167         else
1168         {
1169             // just take the current one
1170             height = currentH;
1171         }
1172     }
1173 
1174     DoMoveWindow( x, y, width, height );
1175 }
1176 
GetClientAreaOrigin() const1177 wxPoint wxWindowMac::GetClientAreaOrigin() const
1178 {
1179     int left,top,width,height;
1180     GetPeer()->GetContentArea( left , top , width , height);
1181     return wxPoint( left + MacGetLeftBorderSize() , top + MacGetTopBorderSize() );
1182 }
1183 
DoSetClientSize(int clientwidth,int clientheight)1184 void wxWindowMac::DoSetClientSize(int clientwidth, int clientheight)
1185 {
1186     if ( clientwidth != wxDefaultCoord || clientheight != wxDefaultCoord )
1187     {
1188         int currentclientwidth , currentclientheight ;
1189         int currentwidth , currentheight ;
1190 
1191         GetClientSize( &currentclientwidth , &currentclientheight ) ;
1192         GetSize( &currentwidth , &currentheight ) ;
1193 
1194         DoSetSize( wxDefaultCoord , wxDefaultCoord , currentwidth + clientwidth - currentclientwidth ,
1195             currentheight + clientheight - currentclientheight , wxSIZE_USE_EXISTING ) ;
1196     }
1197 }
1198 
GetContentScaleFactor() const1199 double wxWindowMac::GetContentScaleFactor() const
1200 {
1201     return GetPeer()->GetContentScaleFactor();
1202 }
1203 
SetLabel(const wxString & title)1204 void wxWindowMac::SetLabel(const wxString& title)
1205 {
1206     if ( title == m_label )
1207         return;
1208 
1209     m_label = title ;
1210 
1211     InvalidateBestSize();
1212 
1213     if ( GetPeer() && GetPeer()->IsOk() )
1214         GetPeer()->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics), GetFont().GetEncoding() ) ;
1215 
1216     // do not trigger refreshes upon invisible and possible partly created objects
1217     if ( IsShownOnScreen() )
1218         Refresh() ;
1219 }
1220 
GetLabel() const1221 wxString wxWindowMac::GetLabel() const
1222 {
1223     return m_label ;
1224 }
1225 
Show(bool show)1226 bool wxWindowMac::Show(bool show)
1227 {
1228     if ( !show )
1229         MacInvalidateBorders();
1230 
1231     if ( !wxWindowBase::Show(show) )
1232         return false;
1233 
1234     if ( GetPeer() )
1235         GetPeer()->SetVisibility( show ) ;
1236 
1237     if ( show )
1238         MacInvalidateBorders();
1239 
1240 #ifdef __WXOSX_IPHONE__
1241     // only when there's no native event support
1242     if ( !IsTopLevel() )
1243 #endif
1244     {
1245         wxShowEvent eventShow(GetId(), show);
1246         eventShow.SetEventObject(this);
1247 
1248         HandleWindowEvent(eventShow);
1249     }
1250 
1251     return true;
1252 }
1253 
OSXShowWithEffect(bool show,wxShowEffect effect,unsigned timeout)1254 bool wxWindowMac::OSXShowWithEffect(bool show,
1255                                     wxShowEffect effect,
1256                                     unsigned timeout)
1257 {
1258     if ( effect == wxSHOW_EFFECT_NONE ||
1259             !GetPeer() || !GetPeer()->ShowWithEffect(show, effect, timeout) )
1260         return Show(show);
1261 
1262     return true;
1263 }
1264 
DoEnable(bool enable)1265 void wxWindowMac::DoEnable(bool enable)
1266 {
1267     GetPeer()->Enable( enable ) ;
1268     MacInvalidateBorders();
1269 }
1270 
1271 //
1272 // status change notifications
1273 //
1274 
MacVisibilityChanged()1275 void wxWindowMac::MacVisibilityChanged()
1276 {
1277 }
1278 
MacHiliteChanged()1279 void wxWindowMac::MacHiliteChanged()
1280 {
1281 }
1282 
MacEnabledStateChanged()1283 void wxWindowMac::MacEnabledStateChanged()
1284 {
1285 }
1286 
1287 //
1288 // status queries on the inherited window's state
1289 //
1290 
MacIsReallyEnabled()1291 bool wxWindowMac::MacIsReallyEnabled()
1292 {
1293     return GetPeer()->IsEnabled() ;
1294 }
1295 
MacIsReallyHilited()1296 bool wxWindowMac::MacIsReallyHilited()
1297 {
1298     return true; // TODO
1299 }
1300 
GetCharHeight() const1301 int wxWindowMac::GetCharHeight() const
1302 {
1303     wxCoord height;
1304     GetTextExtent( wxT("g") , NULL , &height , NULL , NULL , NULL );
1305 
1306     return height;
1307 }
1308 
GetCharWidth() const1309 int wxWindowMac::GetCharWidth() const
1310 {
1311     wxCoord width;
1312     GetTextExtent( wxT("g") , &width , NULL , NULL , NULL , NULL );
1313 
1314     return width;
1315 }
1316 
DoGetTextExtent(const wxString & str,int * x,int * y,int * descent,int * externalLeading,const wxFont * theFont) const1317 void wxWindowMac::DoGetTextExtent(const wxString& str,
1318                                   int *x, int *y,
1319                                   int *descent,
1320                                   int *externalLeading,
1321                                   const wxFont *theFont) const
1322 {
1323     const wxFont *fontToUse = theFont;
1324     wxFont tempFont;
1325     if ( !fontToUse )
1326     {
1327         tempFont = GetFont();
1328         fontToUse = &tempFont;
1329     }
1330 
1331     wxGraphicsContext* ctx = wxGraphicsContext::Create();
1332     ctx->SetFont( *fontToUse, *wxBLACK );
1333 
1334     wxDouble h , d , e , w;
1335     ctx->GetTextExtent( str, &w, &h, &d, &e );
1336 
1337     delete ctx;
1338 
1339     if ( externalLeading )
1340         *externalLeading = (wxCoord)wxRound(e);
1341     if ( descent )
1342         *descent = (wxCoord)wxRound(d);
1343     if ( x )
1344         *x = (wxCoord)wxRound(w);
1345     if ( y )
1346         *y = (wxCoord)wxRound(h);
1347 }
1348 
1349 /*
1350  * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect
1351  * we always intersect with the entire window, not only with the client area
1352  */
1353 
Refresh(bool WXUNUSED (eraseBack),const wxRect * rect)1354 void wxWindowMac::Refresh(bool WXUNUSED(eraseBack), const wxRect *rect)
1355 {
1356     if ( GetPeer() == NULL )
1357         return ;
1358 
1359     if ( !IsShownOnScreen() )
1360         return ;
1361 
1362     if ( IsFrozen() )
1363         return;
1364 
1365     GetPeer()->SetNeedsDisplay( rect ) ;
1366 }
1367 
DoFreeze()1368 void wxWindowMac::DoFreeze()
1369 {
1370     if ( GetPeer() && GetPeer()->IsOk() )
1371         GetPeer()->SetDrawingEnabled( false ) ;
1372 }
1373 
DoThaw()1374 void wxWindowMac::DoThaw()
1375 {
1376     if ( GetPeer() && GetPeer()->IsOk() )
1377         GetPeer()->SetDrawingEnabled( true ) ;
1378 }
1379 
wxGetActiveWindow()1380 wxWindow *wxGetActiveWindow()
1381 {
1382     // actually this is a windows-only concept
1383     return NULL;
1384 }
1385 
1386 // Coordinates relative to the window
WarpPointer(int x_pos,int y_pos)1387 void wxWindowMac::WarpPointer(int x_pos, int y_pos)
1388 {
1389 #if wxOSX_USE_COCOA_OR_CARBON
1390     int x = x_pos;
1391     int y = y_pos;
1392     DoClientToScreen(&x, &y);
1393     CGPoint cgpoint = CGPointMake( x, y );
1394     CGWarpMouseCursorPosition( cgpoint );
1395     CGAssociateMouseAndMouseCursorPosition(true);
1396 
1397     // At least GTK sends a mouse moved event after WarpMouse
1398     wxMouseEvent event(wxEVT_MOTION);
1399     event.m_x = x_pos;
1400     event.m_y = y_pos;
1401     wxMouseState mState = ::wxGetMouseState();
1402 
1403     event.m_altDown = mState.AltDown();
1404     event.m_controlDown = mState.ControlDown();
1405     event.m_leftDown = mState.LeftIsDown();
1406     event.m_middleDown = mState.MiddleIsDown();
1407     event.m_rightDown = mState.RightIsDown();
1408     event.m_metaDown = mState.MetaDown();
1409     event.m_shiftDown = mState.ShiftDown();
1410     event.SetId(GetId());
1411     event.SetEventObject(this);
1412     GetEventHandler()->ProcessEvent(event);
1413 #endif
1414 }
1415 
EnableTouchEvents(int eventsMask)1416 bool wxWindowMac::EnableTouchEvents(int eventsMask)
1417 {
1418     return GetPeer() ? GetPeer()->EnableTouchEvents(eventsMask) : false;
1419 }
1420 
GetScrollPos(int orient) const1421 int wxWindowMac::GetScrollPos(int orient) const
1422 {
1423 #if wxUSE_SCROLLBAR
1424     if ( orient == wxHORIZONTAL )
1425     {
1426        if ( m_hScrollBar )
1427            return m_hScrollBar->GetThumbPosition() ;
1428     }
1429     else
1430     {
1431        if ( m_vScrollBar )
1432            return m_vScrollBar->GetThumbPosition() ;
1433     }
1434 #endif
1435     return 0;
1436 }
1437 
1438 // This now returns the whole range, not just the number
1439 // of positions that we can scroll.
GetScrollRange(int orient) const1440 int wxWindowMac::GetScrollRange(int orient) const
1441 {
1442 #if wxUSE_SCROLLBAR
1443     if ( orient == wxHORIZONTAL )
1444     {
1445        if ( m_hScrollBar )
1446            return m_hScrollBar->GetRange() ;
1447     }
1448     else
1449     {
1450        if ( m_vScrollBar )
1451            return m_vScrollBar->GetRange() ;
1452     }
1453 #endif
1454     return 0;
1455 }
1456 
GetScrollThumb(int orient) const1457 int wxWindowMac::GetScrollThumb(int orient) const
1458 {
1459 #if wxUSE_SCROLLBAR
1460     if ( orient == wxHORIZONTAL )
1461     {
1462        if ( m_hScrollBar )
1463            return m_hScrollBar->GetThumbSize() ;
1464     }
1465     else
1466     {
1467        if ( m_vScrollBar )
1468            return m_vScrollBar->GetThumbSize() ;
1469     }
1470 #endif
1471     return 0;
1472 }
1473 
SetScrollPos(int orient,int pos,bool WXUNUSED (refresh))1474 void wxWindowMac::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh))
1475 {
1476 #if wxUSE_SCROLLBAR
1477     if ( orient == wxHORIZONTAL )
1478     {
1479        if ( m_hScrollBar )
1480            m_hScrollBar->SetThumbPosition( pos ) ;
1481     }
1482     else
1483     {
1484        if ( m_vScrollBar )
1485            m_vScrollBar->SetThumbPosition( pos ) ;
1486     }
1487 #endif
1488 }
1489 
1490 void
AlwaysShowScrollbars(bool hflag,bool vflag)1491 wxWindowMac::AlwaysShowScrollbars(bool hflag, bool vflag)
1492 {
1493     bool needVisibilityUpdate = false;
1494 
1495     if ( m_hScrollBarAlwaysShown != hflag )
1496     {
1497         m_hScrollBarAlwaysShown = hflag;
1498         needVisibilityUpdate = true;
1499     }
1500 
1501     if ( m_vScrollBarAlwaysShown != vflag )
1502     {
1503         m_vScrollBarAlwaysShown = vflag;
1504         needVisibilityUpdate = true;
1505     }
1506 
1507     if ( needVisibilityUpdate )
1508         DoUpdateScrollbarVisibility();
1509 }
1510 
1511 //
1512 // we draw borders and grow boxes, are already set up and clipped in the current port / cgContextRef
1513 // our own window origin is at leftOrigin/rightOrigin
1514 //
1515 
MacPaintGrowBox()1516 void  wxWindowMac::MacPaintGrowBox()
1517 {
1518     if ( IsTopLevel() )
1519         return ;
1520 
1521 #if wxUSE_SCROLLBAR
1522     if ( MacHasScrollBarCorner() )
1523     {
1524 #if 0
1525         CGContextRef cgContext = (CGContextRef) MacGetCGContextRef() ;
1526         wxASSERT( cgContext ) ;
1527 
1528         int tx,ty,tw,th;
1529 
1530         GetPeer()->GetSize( tw, th );
1531         GetPeer()->GetPosition( tx, ty );
1532 
1533         Rect rect  = { ty,tx, ty+th, tx+tw };
1534 
1535 
1536         int size = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ;
1537         CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ;
1538         CGContextSaveGState( cgContext );
1539 
1540         if ( m_backgroundColour.IsOk() )
1541         {
1542             CGContextSetFillColorWithColor( cgContext, m_backgroundColour.GetCGColor() );
1543         }
1544         else
1545         {
1546             CGContextSetRGBFillColor( cgContext, (CGFloat) 1.0, (CGFloat)1.0 ,(CGFloat) 1.0 , (CGFloat)1.0 );
1547         }
1548         CGContextFillRect( cgContext, cgrect );
1549         CGContextRestoreGState( cgContext );
1550 #else
1551         if (m_growBox)
1552         {
1553              if ( m_backgroundColour.IsOk() )
1554                  m_growBox->SetBackgroundColour(m_backgroundColour);
1555              else
1556                  m_growBox->SetBackgroundColour(*wxWHITE);
1557         }
1558 #endif
1559     }
1560 
1561 #endif
1562 }
1563 
MacPaintBorders(int WXUNUSED (leftOrigin),int WXUNUSED (rightOrigin))1564 void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(rightOrigin) )
1565 {
1566     if ( IsTopLevel() )
1567         return ;
1568 
1569     // back to the surrounding frame rectangle
1570     int tx,ty,tw,th;
1571 
1572     GetPeer()->GetSize( tw, th );
1573     GetPeer()->GetPosition( tx, ty );
1574 
1575 #if wxOSX_USE_COCOA_OR_CARBON
1576     {
1577         CGRect cgrect = CGRectMake( tx-1 , ty-1 , tw+2 ,
1578             th+2 ) ;
1579 
1580         CGContextRef cgContext = (CGContextRef) GetParent()->MacGetCGContextRef() ;
1581         wxASSERT( cgContext ) ;
1582 
1583         if ( GetPeer()->NeedsFrame() )
1584         {
1585             HIThemeFrameDrawInfo info ;
1586             memset( &info, 0 , sizeof(info) ) ;
1587 
1588             info.version = 0 ;
1589             info.kind = 0 ;
1590             info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ;
1591 
1592             if ( HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) )
1593             {
1594                 info.kind = kHIThemeFrameTextFieldSquare ;
1595                 HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ;
1596             }
1597             else if ( HasFlag(wxSIMPLE_BORDER) )
1598             {
1599                 info.kind = kHIThemeFrameListBox ;
1600                 HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ;
1601             }
1602         }
1603     }
1604 #endif // wxOSX_USE_COCOA_OR_CARBON
1605 }
1606 
RemoveChild(wxWindowBase * child)1607 void wxWindowMac::RemoveChild( wxWindowBase *child )
1608 {
1609 #if wxUSE_SCROLLBAR
1610     if ( child == m_hScrollBar )
1611         m_hScrollBar = NULL ;
1612     if ( child == m_vScrollBar )
1613         m_vScrollBar = NULL ;
1614     if ( child == m_growBox )
1615         m_growBox = NULL ;
1616 #endif
1617     if (!child->IsBeingDeleted() && !child->IsTopLevel())
1618     {
1619         // Must be removed prior to RemoveChild and next AddChild call
1620         // Otherwise the next AddChild may freeze the wrong window
1621         wxWindowMac *mac = (wxWindowMac *)child;
1622         if (mac->GetPeer() && mac->GetPeer()->IsOk())
1623             mac->GetPeer()->RemoveFromParent();
1624     }
1625 
1626     wxWindowBase::RemoveChild( child ) ;
1627 }
1628 
DoUpdateScrollbarVisibility()1629 void wxWindowMac::DoUpdateScrollbarVisibility()
1630 {
1631 #if wxUSE_SCROLLBAR
1632     bool triggerSizeEvent = false;
1633 
1634     if ( m_hScrollBar )
1635     {
1636         bool showHScrollBar = m_hScrollBarAlwaysShown || m_hScrollBar->IsNeeded();
1637 
1638         if ( m_hScrollBar->IsShown() != showHScrollBar )
1639         {
1640             m_hScrollBar->Show( showHScrollBar );
1641             triggerSizeEvent = true;
1642         }
1643     }
1644 
1645     if ( m_vScrollBar)
1646     {
1647         bool showVScrollBar = m_vScrollBarAlwaysShown || m_vScrollBar->IsNeeded();
1648 
1649         if ( m_vScrollBar->IsShown() != showVScrollBar )
1650         {
1651             m_vScrollBar->Show( showVScrollBar ) ;
1652             triggerSizeEvent = true;
1653         }
1654     }
1655 
1656     MacRepositionScrollBars() ;
1657     if ( triggerSizeEvent )
1658     {
1659         SendSizeEvent();
1660     }
1661 #endif
1662 }
1663 
1664 // New function that will replace some of the above.
SetScrollbar(int orient,int pos,int thumb,int range,bool refresh)1665 void wxWindowMac::SetScrollbar(int orient, int pos, int thumb,
1666                                int range, bool refresh)
1667 {
1668 #if wxUSE_SCROLLBAR
1669     // Updating scrollbars when window is being deleted is useless and
1670     // currently results in asserts in client-to-screen coordinates conversion
1671     // code which is used by DoUpdateScrollbarVisibility() so just skip it.
1672     if ( m_isBeingDeleted )
1673         return;
1674 
1675     if ( orient == wxHORIZONTAL && m_hScrollBar )
1676         m_hScrollBar->SetScrollbar(pos, thumb, range, thumb, refresh);
1677     else if ( orient == wxVERTICAL && m_vScrollBar )
1678         m_vScrollBar->SetScrollbar(pos, thumb, range, thumb, refresh);
1679 
1680     DoUpdateScrollbarVisibility();
1681 #endif
1682 }
1683 
1684 // Does a physical scroll
ScrollWindow(int dx,int dy,const wxRect * rect)1685 void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
1686 {
1687     if ( dx == 0 && dy == 0 )
1688         return ;
1689 
1690     int width , height ;
1691     GetClientSize( &width , &height ) ;
1692 
1693     {
1694         wxRect scrollrect( MacGetLeftBorderSize() , MacGetTopBorderSize() , width , height ) ;
1695         if ( rect )
1696             scrollrect.Intersect( *rect ) ;
1697         // as the native control might be not a 0/0 wx window coordinates, we have to offset
1698         scrollrect.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ;
1699 
1700         GetPeer()->ScrollRect( &scrollrect, dx, dy );
1701     }
1702 
1703     for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext())
1704     {
1705         wxWindowMac* child;
1706         child = node->GetData();
1707         if (child == NULL)
1708             continue;
1709 
1710         if (child->IsTopLevel())
1711             continue;
1712 
1713         if ( !IsClientAreaChild(child) )
1714             continue;
1715 
1716         int x, y, w, h;
1717         child->GetPosition( &x, &y );
1718         child->GetSize( &w, &h );
1719         if (rect)
1720         {
1721             wxRect rc( x, y, w, h );
1722             if (rect->Intersects( rc ))
1723                 child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE );
1724         }
1725         else
1726         {
1727             child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE );
1728         }
1729     }
1730 }
1731 
MacOnScroll(wxScrollEvent & event)1732 void wxWindowMac::MacOnScroll( wxScrollEvent &event )
1733 {
1734 #if wxUSE_SCROLLBAR
1735     if ( event.GetEventObject() == m_vScrollBar || event.GetEventObject() == m_hScrollBar )
1736     {
1737         wxScrollWinEvent wevent;
1738         wevent.SetPosition(event.GetPosition());
1739         wevent.SetOrientation(event.GetOrientation());
1740         wevent.SetEventObject(this);
1741 
1742         if (event.GetEventType() == wxEVT_SCROLL_TOP)
1743             wevent.SetEventType( wxEVT_SCROLLWIN_TOP );
1744         else if (event.GetEventType() == wxEVT_SCROLL_BOTTOM)
1745             wevent.SetEventType( wxEVT_SCROLLWIN_BOTTOM );
1746         else if (event.GetEventType() == wxEVT_SCROLL_LINEUP)
1747             wevent.SetEventType( wxEVT_SCROLLWIN_LINEUP );
1748         else if (event.GetEventType() == wxEVT_SCROLL_LINEDOWN)
1749             wevent.SetEventType( wxEVT_SCROLLWIN_LINEDOWN );
1750         else if (event.GetEventType() == wxEVT_SCROLL_PAGEUP)
1751             wevent.SetEventType( wxEVT_SCROLLWIN_PAGEUP );
1752         else if (event.GetEventType() == wxEVT_SCROLL_PAGEDOWN)
1753             wevent.SetEventType( wxEVT_SCROLLWIN_PAGEDOWN );
1754         else if (event.GetEventType() == wxEVT_SCROLL_THUMBTRACK)
1755             wevent.SetEventType( wxEVT_SCROLLWIN_THUMBTRACK );
1756         else if (event.GetEventType() == wxEVT_SCROLL_THUMBRELEASE)
1757             wevent.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE );
1758 
1759         HandleWindowEvent(wevent);
1760     }
1761 #endif
1762 }
1763 
DoFindFocus()1764 wxWindow *wxWindowBase::DoFindFocus()
1765 {
1766     return wxFindWindowFromWXWidget(wxWidgetImpl::FindFocus());
1767 }
1768 
1769 // Raise the window to the top of the Z order
Raise()1770 void wxWindowMac::Raise()
1771 {
1772     GetPeer()->Raise();
1773 }
1774 
1775 // Lower the window to the bottom of the Z order
Lower()1776 void wxWindowMac::Lower()
1777 {
1778     GetPeer()->Lower();
1779 }
1780 
1781 // static wxWindow *gs_lastWhich = NULL;
1782 
MacSetupCursor(const wxPoint & pt)1783 bool wxWindowMac::MacSetupCursor( const wxPoint& pt )
1784 {
1785     // first trigger a set cursor event
1786 
1787     wxPoint clientorigin = GetClientAreaOrigin() ;
1788     wxSize clientsize = GetClientSize() ;
1789     wxCursor cursor ;
1790     if ( wxRect2DInt( clientorigin.x , clientorigin.y , clientsize.x , clientsize.y ).Contains( wxPoint2DInt( pt ) ) )
1791     {
1792         wxSetCursorEvent event( pt.x , pt.y );
1793         event.SetId(GetId());
1794         event.SetEventObject(this);
1795 
1796         bool processedEvtSetCursor = HandleWindowEvent(event);
1797         if ( processedEvtSetCursor && event.HasCursor() )
1798         {
1799             cursor = event.GetCursor() ;
1800         }
1801         else
1802         {
1803             // the test for processedEvtSetCursor is here to prevent using m_cursor
1804             // if the user code caught EVT_SET_CURSOR() and returned nothing from
1805             // it - this is a way to say that our cursor shouldn't be used for this
1806             // point
1807             if ( !processedEvtSetCursor && m_cursor.IsOk() )
1808                 cursor = m_cursor ;
1809 
1810             if ( !wxIsBusy() && !GetParent() )
1811                 cursor = *wxSTANDARD_CURSOR ;
1812         }
1813 
1814         if ( cursor.IsOk() )
1815             cursor.MacInstall() ;
1816     }
1817 
1818     return cursor.IsOk() ;
1819 }
1820 
MacGetToolTipString(wxPoint & WXUNUSED (pt))1821 wxString wxWindowMac::MacGetToolTipString( wxPoint &WXUNUSED(pt) )
1822 {
1823 #if wxUSE_TOOLTIPS
1824     if ( m_tooltip )
1825         return m_tooltip->GetTip() ;
1826 #endif
1827 
1828     return wxEmptyString ;
1829 }
1830 
ClearBackground()1831 void wxWindowMac::ClearBackground()
1832 {
1833     Refresh() ;
1834     Update() ;
1835 }
1836 
Update()1837 void wxWindowMac::Update()
1838 {
1839     wxNonOwnedWindow* top = MacGetTopLevelWindow();
1840     if (top)
1841         top->Update() ;
1842 }
1843 
MacGetTopLevelWindow() const1844 wxNonOwnedWindow* wxWindowMac::MacGetTopLevelWindow() const
1845 {
1846     wxWindowMac* iter = const_cast<wxWindowMac*>(this);
1847 
1848     while ( iter )
1849     {
1850         if ( iter->IsTopLevel() )
1851         {
1852             wxTopLevelWindow* toplevel = wxDynamicCast(iter,wxTopLevelWindow);
1853             if ( toplevel )
1854                 return toplevel;
1855 #if wxUSE_POPUPWIN
1856             wxPopupWindow* popupwin = wxDynamicCast(iter,wxPopupWindow);
1857             if ( popupwin )
1858                 return popupwin;
1859 #endif
1860         }
1861         iter = iter->GetParent() ;
1862     }
1863 
1864     return NULL ;
1865 }
1866 
MacGetClippedClientRect() const1867 const wxRect& wxWindowMac::MacGetClippedClientRect() const
1868 {
1869     MacUpdateClippedRects() ;
1870 
1871     return m_cachedClippedClientRect ;
1872 }
1873 
MacGetClippedRect() const1874 const wxRect& wxWindowMac::MacGetClippedRect() const
1875 {
1876     MacUpdateClippedRects() ;
1877 
1878     return m_cachedClippedRect ;
1879 }
1880 
MacGetClippedRectWithOuterStructure() const1881 const wxRect&wxWindowMac:: MacGetClippedRectWithOuterStructure() const
1882 {
1883     MacUpdateClippedRects() ;
1884 
1885     return m_cachedClippedRectWithOuterStructure ;
1886 }
1887 
MacGetVisibleRegion(bool includeOuterStructures)1888 const wxRegion& wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures )
1889 {
1890     static wxRegion emptyrgn ;
1891 
1892     if ( !m_isBeingDeleted && IsShownOnScreen() )
1893     {
1894         MacUpdateClippedRects() ;
1895         if ( includeOuterStructures )
1896             return m_cachedClippedRegionWithOuterStructure ;
1897         else
1898             return m_cachedClippedRegion ;
1899     }
1900     else
1901     {
1902         return emptyrgn ;
1903     }
1904 }
1905 
MacUpdateClippedRects() const1906 void wxWindowMac::MacUpdateClippedRects() const
1907 {
1908 }
1909 
1910 /*
1911     This function must not change the updatergn !
1912  */
MacDoRedraw(long time)1913 bool wxWindowMac::MacDoRedraw( long time )
1914 {
1915     bool handled = false ;
1916     if ( !IsShownOnScreen() )
1917         return handled;
1918 
1919     wxRegion formerUpdateRgn = m_updateRegion;
1920     wxRegion clientUpdateRgn = formerUpdateRgn;
1921 
1922     const wxRect clientRect = GetClientRect();
1923 
1924     clientUpdateRgn.Intersect(clientRect);
1925 
1926     // first send an erase event to the entire update area
1927     const wxBackgroundStyle bgStyle = GetBackgroundStyle();
1928     switch ( bgStyle )
1929     {
1930         case wxBG_STYLE_ERASE:
1931         case wxBG_STYLE_SYSTEM:
1932         case wxBG_STYLE_COLOUR:
1933             {
1934                 // for the toplevel window this really is the entire area for
1935                 // all the others only their client area, otherwise they might
1936                 // be drawing with full alpha and eg put blue into the grow-box
1937                 // area of a scrolled window (scroll sample)
1938                 wxWindowDC dc(this);
1939                 if ( IsTopLevel() )
1940                     dc.SetDeviceClippingRegion(formerUpdateRgn);
1941                 else
1942                     dc.SetDeviceClippingRegion(clientUpdateRgn);
1943 
1944                 if ( bgStyle == wxBG_STYLE_ERASE )
1945                 {
1946                     wxEraseEvent eevent( GetId(), &dc );
1947                     eevent.SetEventObject( this );
1948                     if ( ProcessWindowEvent( eevent ) )
1949                         break;
1950                 }
1951 
1952                 if ( UseBgCol() )
1953                 {
1954                     dc.SetBackground(GetBackgroundColour());
1955                     dc.Clear();
1956                 }
1957             }
1958             break;
1959 
1960         case wxBG_STYLE_PAINT:
1961         case wxBG_STYLE_TRANSPARENT:
1962             // nothing to do, user-defined EVT_PAINT handler will overwrite the
1963             // entire window client area
1964             break;
1965 
1966         default:
1967             wxFAIL_MSG( "unsupported background style" );
1968     }
1969 
1970     // as this is a full window, shouldn't be necessary anymore
1971     // MacPaintGrowBox();
1972 
1973     // calculate a client-origin version of the update rgn and set
1974     // m_updateRegion to that
1975     clientUpdateRgn.Offset(-clientRect.GetPosition());
1976     m_updateRegion = clientUpdateRgn ;
1977 
1978     if ( !m_updateRegion.Empty() )
1979     {
1980         // paint the window itself
1981 
1982         wxPaintEvent event(this);
1983         event.SetTimestamp(time);
1984         handled = HandleWindowEvent(event);
1985     }
1986 
1987     m_updateRegion = formerUpdateRgn;
1988 
1989     wxNonOwnedWindow* top = MacGetTopLevelWindow();
1990     if (top)
1991         top->WindowWasPainted() ;
1992 
1993     return handled;
1994 }
1995 
MacPaintChildrenBorders()1996 void wxWindowMac::MacPaintChildrenBorders()
1997 {
1998     // now we cannot rely on having its borders drawn by a window itself, as it does not
1999     // get the updateRgn wide enough to always do so, so we do it from the parent
2000     // this would also be the place to draw any custom backgrounds for native controls
2001     // in Composited windowing
2002     wxPoint clientOrigin = GetClientAreaOrigin() ;
2003 
2004     int x, y, w, h;
2005     for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext())
2006     {
2007         wxWindowMac* child;
2008         child = node->GetData();
2009         if (child == NULL)
2010             continue;
2011 #if wxUSE_SCROLLBAR
2012         if (child == m_vScrollBar)
2013             continue;
2014         if (child == m_hScrollBar)
2015             continue;
2016          if (child == m_growBox)
2017              continue;
2018 #endif
2019         if (child->IsTopLevel())
2020             continue;
2021         if (!child->IsShown())
2022             continue;
2023 
2024         // only draw those in the update region (add a safety margin of 10 pixels for shadow effects
2025 
2026         child->GetPosition( &x, &y );
2027         child->GetSize( &w, &h );
2028 
2029         if ( m_updateRegion.Contains(clientOrigin.x+x-10, clientOrigin.y+y-10, w+20, h+20) )
2030         {
2031             // paint custom borders
2032             wxNcPaintEvent eventNc( child );
2033             if ( !child->HandleWindowEvent( eventNc ) )
2034             {
2035                 child->MacPaintBorders(0, 0) ;
2036             }
2037         }
2038     }
2039 }
2040 
2041 
MacGetTopLevelWindowRef() const2042 WXWindow wxWindowMac::MacGetTopLevelWindowRef() const
2043 {
2044     wxNonOwnedWindow* tlw = MacGetTopLevelWindow();
2045     return tlw ? tlw->GetWXWindow() : NULL ;
2046 }
2047 
MacHasScrollBarCorner() const2048 bool wxWindowMac::MacHasScrollBarCorner() const
2049 {
2050 #if wxUSE_SCROLLBAR && !wxOSX_USE_IPHONE
2051     /* Returns whether the scroll bars in a wxScrolledWindow should be
2052      * shortened, which happens only when both scroll bars are visible.
2053      */
2054 
2055     if ( ( m_hScrollBar && m_hScrollBar->IsShown() )
2056          && ( m_vScrollBar && m_vScrollBar->IsShown() ) )
2057     {
2058         // Both scroll bars visible
2059         return true;
2060     }
2061 #endif
2062 
2063     return false;
2064 }
2065 
MacCreateScrollBars(long style)2066 void wxWindowMac::MacCreateScrollBars( long style )
2067 {
2068 #if wxUSE_SCROLLBAR
2069     wxASSERT_MSG( m_vScrollBar == NULL && m_hScrollBar == NULL , wxT("attempt to create window twice") ) ;
2070 
2071     if ( style & ( wxVSCROLL | wxHSCROLL ) )
2072     {
2073         int scrlsize = MAC_SCROLLBAR_SIZE ;
2074         if ( GetWindowVariant() == wxWINDOW_VARIANT_SMALL || GetWindowVariant() == wxWINDOW_VARIANT_MINI )
2075         {
2076             scrlsize = MAC_SMALL_SCROLLBAR_SIZE ;
2077         }
2078 
2079         int adjust = MacHasScrollBarCorner() ? scrlsize - 1: 0 ;
2080         int width, height ;
2081         GetClientSize( &width , &height ) ;
2082 
2083         wxPoint vPoint(width - scrlsize, 0) ;
2084         wxSize vSize(scrlsize, height - adjust) ;
2085         wxPoint hPoint(0, height - scrlsize) ;
2086         wxSize hSize(width - adjust, scrlsize) ;
2087 
2088         // we have to set the min size to a smaller value, otherwise they cannot get smaller (InitialSize sets MinSize)
2089         if ( style & wxVSCROLL )
2090         {
2091             m_vScrollBar = new wxScrollBar((wxWindow*)this, wxID_ANY, vPoint, vSize , wxVERTICAL);
2092             m_vScrollBar->SetMinSize( wxDefaultSize );
2093         }
2094 
2095         if ( style  & wxHSCROLL )
2096         {
2097             m_hScrollBar = new wxScrollBar((wxWindow*)this, wxID_ANY, hPoint, hSize , wxHORIZONTAL);
2098             m_hScrollBar->SetMinSize( wxDefaultSize );
2099         }
2100 
2101         wxPoint gPoint(width - scrlsize, height - scrlsize);
2102         wxSize gSize(scrlsize, scrlsize);
2103         m_growBox = new wxBlindPlateWindow((wxWindow *)this, wxID_ANY, gPoint, gSize, 0);
2104     }
2105 
2106     // because the create does not take into account the client area origin
2107     // we might have a real position shift
2108     MacRepositionScrollBars() ;
2109 #endif
2110 }
2111 
MacIsChildOfClientArea(const wxWindow * child) const2112 bool wxWindowMac::MacIsChildOfClientArea( const wxWindow* child ) const
2113 {
2114     bool result = ((child == NULL)
2115 #if wxUSE_SCROLLBAR
2116       || ((child != m_hScrollBar) && (child != m_vScrollBar) && (child != m_growBox))
2117 #endif
2118      );
2119 
2120     return result ;
2121 }
2122 
MacRepositionScrollBars()2123 void wxWindowMac::MacRepositionScrollBars()
2124 {
2125 #if wxUSE_SCROLLBAR
2126     if ( !m_hScrollBar && !m_vScrollBar )
2127         return ;
2128 
2129     int scrlsize = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ;
2130     int adjust = MacHasScrollBarCorner() ? scrlsize - 1 : 0 ;
2131 
2132     // get real client area
2133     int width, height ;
2134     GetSize( &width , &height );
2135 
2136     width -= MacGetLeftBorderSize() + MacGetRightBorderSize();
2137     height -= MacGetTopBorderSize() + MacGetBottomBorderSize();
2138 
2139     wxPoint vPoint( width - scrlsize, 0 ) ;
2140     wxSize vSize( scrlsize, height - adjust ) ;
2141     wxPoint hPoint( 0 , height - scrlsize ) ;
2142     wxSize hSize( width - adjust, scrlsize ) ;
2143 
2144     if ( m_vScrollBar )
2145         m_vScrollBar->SetSize( vPoint.x , vPoint.y, vSize.x, vSize.y , wxSIZE_ALLOW_MINUS_ONE );
2146     if ( m_hScrollBar )
2147         m_hScrollBar->SetSize( hPoint.x , hPoint.y, hSize.x, hSize.y, wxSIZE_ALLOW_MINUS_ONE );
2148     if ( m_growBox )
2149     {
2150         if ( MacHasScrollBarCorner() )
2151         {
2152             m_growBox->SetSize( width - scrlsize, height - scrlsize, wxDefaultCoord, wxDefaultCoord, wxSIZE_USE_EXISTING );
2153             if ( !m_growBox->IsShown() )
2154                 m_growBox->Show();
2155         }
2156         else
2157         {
2158             if ( m_growBox->IsShown() )
2159                 m_growBox->Hide();
2160         }
2161     }
2162 #endif
2163 }
2164 
AcceptsFocus() const2165 bool wxWindowMac::AcceptsFocus() const
2166 {
2167     if ( GetPeer() == NULL || GetPeer()->HasUserKeyHandling() )
2168         return wxWindowBase::AcceptsFocus();
2169     else
2170         return GetPeer()->CanFocus();
2171 }
2172 
EnableVisibleFocus(bool enabled)2173 void wxWindowMac::EnableVisibleFocus(bool enabled)
2174 {
2175     GetPeer()->EnableFocusRing(enabled);
2176 }
2177 
MacSuperChangedPosition()2178 void wxWindowMac::MacSuperChangedPosition()
2179 {
2180     // only window-absolute structures have to be moved i.e. controls
2181 
2182     m_cachedClippedRectValid = false ;
2183 
2184     wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
2185     while ( node )
2186     {
2187         wxWindowMac* child;
2188         child = node->GetData();
2189         child->MacSuperChangedPosition() ;
2190 
2191         node = node->GetNext();
2192     }
2193 }
2194 
MacTopLevelWindowChangedPosition()2195 void wxWindowMac::MacTopLevelWindowChangedPosition()
2196 {
2197     // only screen-absolute structures have to be moved i.e. glcanvas
2198 
2199     wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
2200     while ( node )
2201     {
2202         wxWindowMac* child;
2203         child = node->GetData();
2204         child->MacTopLevelWindowChangedPosition() ;
2205 
2206         node = node->GetNext();
2207     }
2208 }
2209 
MacGetWXBorderSize() const2210 long wxWindowMac::MacGetWXBorderSize() const
2211 {
2212     if ( IsTopLevel() )
2213         return 0 ;
2214 
2215     SInt32 border = 0 ;
2216 
2217     if ( GetPeer() && GetPeer()->NeedsFrame() )
2218     {
2219         if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER))
2220         {
2221 #if wxOSX_USE_COCOA_OR_CARBON
2222             // this metric is only the 'outset' outside the simple frame rect
2223             GetThemeMetric( kThemeMetricEditTextFrameOutset , &border ) ;
2224             border += 1;
2225 #else
2226             border += 2;
2227 #endif
2228         }
2229         else if (HasFlag(wxSIMPLE_BORDER))
2230         {
2231 #if wxOSX_USE_COCOA_OR_CARBON
2232             // this metric is only the 'outset' outside the simple frame rect
2233             GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
2234             border += 1;
2235 #else
2236             border += 1;
2237 #endif
2238         }
2239     }
2240 
2241     return border ;
2242 }
2243 
MacGetLeftBorderSize() const2244 long wxWindowMac::MacGetLeftBorderSize() const
2245 {
2246     // the wx borders are all symmetric in mac themes
2247     long border = MacGetWXBorderSize() ;
2248 
2249     if ( GetPeer() )
2250     {
2251         int left, top, right, bottom;
2252         GetPeer()->GetLayoutInset( left, top, right, bottom );
2253         border -= left;
2254     }
2255 
2256     return border;
2257 }
2258 
2259 
MacGetRightBorderSize() const2260 long wxWindowMac::MacGetRightBorderSize() const
2261 {
2262     // the wx borders are all symmetric in mac themes
2263     long border = MacGetWXBorderSize() ;
2264 
2265     if ( GetPeer() )
2266     {
2267         int left, top, right, bottom;
2268         GetPeer()->GetLayoutInset( left, top, right, bottom );
2269         border -= right;
2270     }
2271 
2272     return border;
2273 }
2274 
MacGetTopBorderSize() const2275 long wxWindowMac::MacGetTopBorderSize() const
2276 {
2277     // the wx borders are all symmetric in mac themes
2278     long border = MacGetWXBorderSize() ;
2279 
2280     if ( GetPeer() )
2281     {
2282         int left, top, right, bottom;
2283         GetPeer()->GetLayoutInset( left, top, right, bottom );
2284         border -= top;
2285     }
2286 
2287     return border;
2288 }
2289 
MacGetBottomBorderSize() const2290 long wxWindowMac::MacGetBottomBorderSize() const
2291 {
2292     // the wx borders are all symmetric in mac themes
2293     long border = MacGetWXBorderSize() ;
2294 
2295     if ( GetPeer() )
2296     {
2297         int left, top, right, bottom;
2298         GetPeer()->GetLayoutInset( left, top, right, bottom );
2299         border -= bottom;
2300     }
2301 
2302     return border;
2303 }
2304 
MacRemoveBordersFromStyle(long style)2305 long wxWindowMac::MacRemoveBordersFromStyle( long style )
2306 {
2307     return style & ~wxBORDER_MASK ;
2308 }
2309 
2310 // Find the wxWindowMac at the current mouse position, returning the mouse
2311 // position.
wxFindWindowAtPointer(wxPoint & pt)2312 wxWindow * wxFindWindowAtPointer( wxPoint& pt )
2313 {
2314     pt = wxGetMousePosition();
2315     wxWindowMac* found = wxFindWindowAtPoint(pt);
2316 
2317     return (wxWindow*) found;
2318 }
2319 
2320 // Get the current mouse position.
wxGetMousePosition()2321 wxPoint wxGetMousePosition()
2322 {
2323     int x, y;
2324 
2325     wxGetMousePosition( &x, &y );
2326 
2327     return wxPoint(x, y);
2328 }
2329 
OnMouseEvent(wxMouseEvent & event)2330 void wxWindowMac::OnMouseEvent( wxMouseEvent &event )
2331 {
2332     if ( event.GetEventType() == wxEVT_RIGHT_DOWN )
2333     {
2334         if ( !WXSendContextMenuEvent(ClientToScreen(event.GetPosition())) )
2335             event.Skip() ;
2336     }
2337     else
2338     {
2339         event.Skip() ;
2340     }
2341 }
2342 
2343 // propagate the dpi changed event to the subwindows
OnDPIChanged(wxDPIChangedEvent & event)2344 void wxWindowMac::OnDPIChanged(wxDPIChangedEvent& event)
2345 {
2346     wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
2347     while ( node )
2348     {
2349         // Only propagate to non-top-level windows
2350         wxWindow *win = node->GetData();
2351         if ( !win->IsTopLevel() )
2352         {
2353             wxDPIChangedEvent event2( event.GetOldDPI(), event.GetNewDPI() );
2354             event2.SetEventObject(win);
2355             win->GetEventHandler()->ProcessEvent(event2);
2356         }
2357 
2358         node = node->GetNext();
2359     }
2360 }
2361 
TriggerScrollEvent(wxEventType WXUNUSED (scrollEvent))2362 void wxWindowMac::TriggerScrollEvent( wxEventType WXUNUSED(scrollEvent) )
2363 {
2364 }
2365 
wxMacGetBoundsForControl(wxWindowMac * window,const wxPoint & pos,const wxSize & size,bool adjustForOrigin)2366 Rect wxMacGetBoundsForControl( wxWindowMac* window , const wxPoint& pos , const wxSize &size , bool adjustForOrigin )
2367 {
2368     int x, y, w, h ;
2369 
2370     window->MacGetBoundsForControl( pos , size , x , y, w, h , adjustForOrigin ) ;
2371     Rect bounds = { static_cast<short>(y), static_cast<short>(x), static_cast<short>(y + h), static_cast<short>(x + w) };
2372 
2373     return bounds ;
2374 }
2375 
OSXHandleClicked(double WXUNUSED (timestampsec))2376 bool wxWindowMac::OSXHandleClicked( double WXUNUSED(timestampsec) )
2377 {
2378     return false;
2379 }
2380 
2381 #if wxOSX_USE_COCOA_OR_IPHONE
OSXGetViewOrWindow() const2382 void *wxWindowMac::OSXGetViewOrWindow() const
2383 {
2384     return GetHandle();
2385 }
2386 #endif
2387 
MacControlHit(WXEVENTHANDLERREF WXUNUSED (handler),WXEVENTREF event)2388 wxInt32 wxWindowMac::MacControlHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF event )
2389 {
2390 #if wxOSX_USE_COCOA_OR_CARBON
2391     if ( OSXHandleClicked( GetEventTime((EventRef)event) ) )
2392         return noErr;
2393 
2394     return eventNotHandledErr ;
2395 #else
2396     return 0;
2397 #endif
2398 }
2399 
Reparent(wxWindowBase * newParentBase)2400 bool wxWindowMac::Reparent(wxWindowBase *newParentBase)
2401 {
2402     wxWindowMac *newParent = (wxWindowMac *)newParentBase;
2403     if ( !wxWindowBase::Reparent(newParent) )
2404         return false;
2405 
2406     GetPeer()->Embed( GetParent()->GetPeer() );
2407 
2408     GetParent()->MacChildAdded();
2409     return true;
2410 }
2411 
SetTransparent(wxByte alpha)2412 bool wxWindowMac::SetTransparent(wxByte alpha)
2413 {
2414     SetBackgroundStyle(wxBG_STYLE_TRANSPARENT);
2415 
2416     if ( alpha != m_macAlpha )
2417     {
2418         m_macAlpha = alpha ;
2419         Refresh() ;
2420     }
2421     return true ;
2422 }
2423 
2424 
CanSetTransparent()2425 bool wxWindowMac::CanSetTransparent()
2426 {
2427     return true ;
2428 }
2429 
GetTransparent() const2430 wxByte wxWindowMac::GetTransparent() const
2431 {
2432     return m_macAlpha ;
2433 }
2434 
2435 #if wxUSE_HOTKEY && wxOSX_USE_COCOA_OR_CARBON
2436 
2437 OSStatus
wxHotKeyHandler(EventHandlerCallRef WXUNUSED (nextHandler),EventRef event,void * WXUNUSED (userData))2438 wxHotKeyHandler(EventHandlerCallRef WXUNUSED(nextHandler),
2439                 EventRef event,
2440                 void* WXUNUSED(userData))
2441 {
2442     EventHotKeyID hotKeyId;
2443 
2444     GetEventParameter( event, kEventParamDirectObject, typeEventHotKeyID, NULL, sizeof(hotKeyId), NULL, &hotKeyId);
2445 
2446     for ( unsigned i = 0; i < s_hotkeys.size(); ++i )
2447     {
2448         if ( s_hotkeys[i].keyId == static_cast<int>(hotKeyId.id) )
2449         {
2450             unsigned char charCode ;
2451             UInt32 keyCode ;
2452             UInt32 modifiers ;
2453             UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ;
2454 
2455             GetEventParameter( event, kEventParamKeyMacCharCodes, typeChar, NULL, 1, NULL, &charCode );
2456             GetEventParameter( event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode );
2457             GetEventParameter( event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers );
2458 
2459             UInt32 keymessage = (keyCode << 8) + charCode;
2460 
2461             wxKeyEvent wxevent(wxEVT_HOTKEY);
2462             wxevent.SetId(hotKeyId.id);
2463             wxTheApp->MacCreateKeyEvent( wxevent, s_hotkeys[i].window , keymessage ,
2464                                         modifiers , when , 0 ) ;
2465 
2466             s_hotkeys[i].window->HandleWindowEvent(wxevent);
2467         }
2468     }
2469 
2470     return noErr;
2471 }
2472 
RegisterHotKey(int hotkeyId,int modifiers,int keycode)2473 bool wxWindowMac::RegisterHotKey(int hotkeyId, int modifiers, int keycode)
2474 {
2475     for ( unsigned i = 0; i < s_hotkeys.size(); ++i )
2476     {
2477         if ( s_hotkeys[i].keyId == hotkeyId )
2478         {
2479             wxLogLastError(wxT("hotkeyId already registered"));
2480 
2481             return false;
2482         }
2483     }
2484 
2485     static bool installed = false;
2486     if ( !installed )
2487     {
2488         EventTypeSpec eventType;
2489         eventType.eventClass=kEventClassKeyboard;
2490         eventType.eventKind=kEventHotKeyPressed;
2491 
2492         InstallApplicationEventHandler(&wxHotKeyHandler, 1, &eventType, NULL, NULL);
2493         installed = true;
2494     }
2495 
2496     UInt32 mac_modifiers=0;
2497     if ( modifiers & wxMOD_ALT )
2498         mac_modifiers |= optionKey;
2499     if ( modifiers & wxMOD_SHIFT )
2500         mac_modifiers |= shiftKey;
2501     if ( modifiers & wxMOD_RAW_CONTROL )
2502         mac_modifiers |= controlKey;
2503     if ( modifiers & wxMOD_CONTROL )
2504         mac_modifiers |= cmdKey;
2505 
2506     EventHotKeyRef hotKeyRef;
2507     EventHotKeyID hotKeyIDmac;
2508 
2509     hotKeyIDmac.signature = 'WXMC';
2510     hotKeyIDmac.id = hotkeyId;
2511 
2512     if ( RegisterEventHotKey(wxCharCodeWXToOSX((wxKeyCode)keycode), mac_modifiers, hotKeyIDmac,
2513                         GetApplicationEventTarget(), 0, &hotKeyRef) != noErr )
2514     {
2515         wxLogLastError(wxT("RegisterHotKey"));
2516 
2517         return false;
2518     }
2519     else
2520     {
2521         wxHotKeyRec v;
2522         v.ref = hotKeyRef;
2523         v.keyId = hotkeyId;
2524         v.window = this;
2525 
2526         s_hotkeys.push_back(v);
2527     }
2528 
2529     return true;
2530 }
2531 
UnregisterHotKey(int hotkeyId)2532 bool wxWindowMac::UnregisterHotKey(int hotkeyId)
2533 {
2534     for ( int i = ((int)s_hotkeys.size())-1; i>=0; -- i )
2535     {
2536         if ( s_hotkeys[i].keyId == hotkeyId )
2537         {
2538             EventHotKeyRef ref = s_hotkeys[i].ref;
2539             s_hotkeys.erase(s_hotkeys.begin() + i);
2540             if ( UnregisterEventHotKey(ref) != noErr )
2541             {
2542                 wxLogLastError(wxT("UnregisterHotKey"));
2543 
2544                 return false;
2545             }
2546             else
2547                 return true;
2548         }
2549     }
2550 
2551     return false;
2552 }
2553 
2554 #endif // wxUSE_HOTKEY
2555 
OSXHandleKeyEvent(wxKeyEvent & event)2556 bool wxWindowMac::OSXHandleKeyEvent( wxKeyEvent& event )
2557 {
2558     wxLogTrace(TRACE_KEYS, "Handling %s event in %s",
2559                event.GetEventType() == wxEVT_KEY_DOWN
2560                 ? "key down"
2561                 : event.GetEventType() == wxEVT_CHAR
2562                     ? "char"
2563                     : event.GetEventType() == wxEVT_KEY_UP
2564                         ? "key up"
2565                         : event.GetEventType() == wxEVT_CHAR_HOOK
2566                             ? "char hook"
2567                             : "unknown",
2568                wxDumpWindow(this));
2569 
2570     if ( HandleWindowEvent(event) )
2571         return true;
2572 
2573 #if wxUSE_ACCEL
2574     if (event.GetEventType() == wxEVT_CHAR_HOOK)
2575     {
2576         wxWindow *ancestor = this;
2577         while (ancestor)
2578         {
2579             int command = ancestor->GetAcceleratorTable()->GetCommand( event );
2580             if (command != -1)
2581             {
2582                 wxEvtHandler * const handler = ancestor->GetEventHandler();
2583 
2584                 wxCommandEvent command_event( wxEVT_MENU, command );
2585                 if ( !handler->ProcessEvent( command_event ) )
2586                 {
2587                     // accelerators can also be used with buttons, try them too
2588                     command_event.SetEventType(wxEVT_BUTTON);
2589                     handler->ProcessEvent( command_event );
2590                 }
2591 
2592                 // In any case, the event was handled as it triggered an
2593                 // accelerator.
2594                 return true;
2595             }
2596 
2597             if (ancestor->IsTopNavigationDomain(wxWindow::Navigation_Accel))
2598                 break;
2599 
2600             ancestor = ancestor->GetParent();
2601         }
2602     }
2603 #endif // wxUSE_ACCEL
2604 
2605     return false;
2606 }
2607 
2608 /* static */
OSXMakeDPIFromScaleFactor(double scaleFactor)2609 wxSize wxWindowMac::OSXMakeDPIFromScaleFactor(double scaleFactor)
2610 {
2611     const int dpi = wxRound(scaleFactor*72.0);
2612 
2613     return wxSize(dpi, dpi);
2614 }
2615 
GetDPI() const2616 wxSize wxWindowMac::GetDPI() const
2617 {
2618     return OSXMakeDPIFromScaleFactor(GetDPIScaleFactor());
2619 }
2620 
2621 // on mac ContentScale and DPIScale are identical
GetDPIScaleFactor() const2622 double wxWindowMac::GetDPIScaleFactor() const
2623 {
2624     return GetContentScaleFactor();
2625 }
2626 
2627 
2628 //
2629 // wxWidgetImpl
2630 //
2631 
2632 // we are maintaining a n:1 map from native controls (ControlRef / NSView*) to their wxWidgetImpl
2633 // n:1 because we might have an embedded view eg within a scrollview, both being part of the same impl
2634 // the impl is calling Associate with its newly created native control(s), e.g. in InstallHandler
2635 
2636 WX_DECLARE_HASH_MAP(WXWidget, wxWidgetImpl*, wxPointerHash, wxPointerEqual, MacControlMap);
2637 
2638 static MacControlMap wxWinMacControlList;
2639 
wxFindWindowFromWXWidget(WXWidget inControl)2640 wxWindowMac *wxFindWindowFromWXWidget(WXWidget inControl )
2641 {
2642     wxWidgetImpl* impl = wxWidgetImpl::FindFromWXWidget( inControl );
2643     if ( impl )
2644         return impl->GetWXPeer();
2645 
2646     return NULL;
2647 }
2648 
FindFromWXWidget(WXWidget inControl)2649 wxWidgetImpl *wxWidgetImpl::FindFromWXWidget(WXWidget inControl )
2650 {
2651     MacControlMap::iterator node = wxWinMacControlList.find(inControl);
2652 
2653     return (node == wxWinMacControlList.end()) ? NULL : node->second;
2654 }
2655 
Associate(WXWidget inControl,wxWidgetImpl * impl)2656 void wxWidgetImpl::Associate(WXWidget inControl, wxWidgetImpl *impl)
2657 {
2658     // adding NULL ControlRef is (first) surely a result of an error and
2659     // (secondly) breaks native event processing
2660     wxCHECK_RET( inControl != (WXWidget) NULL, wxT("attempt to add a NULL WXWidget to control map") );
2661 
2662     wxWinMacControlList[inControl] = impl;
2663 }
2664 
RemoveAssociations(wxWidgetImpl * impl)2665 void wxWidgetImpl::RemoveAssociations(wxWidgetImpl* impl)
2666 {
2667    // iterate over all the elements in the class
2668     // is the iterator stable ? as we might have two associations pointing to the same wxWindow
2669     // we should go on...
2670 
2671     bool found = true ;
2672     while ( found )
2673     {
2674         found = false ;
2675         MacControlMap::iterator it;
2676         for ( it = wxWinMacControlList.begin(); it != wxWinMacControlList.end(); ++it )
2677         {
2678             if ( it->second == impl )
2679             {
2680                 wxWinMacControlList.erase(it);
2681                 found = true ;
2682                 break;
2683             }
2684         }
2685     }
2686 }
2687 
RemoveAssociation(WXWidget control)2688 void wxWidgetImpl::RemoveAssociation(WXWidget control)
2689 {
2690     wxCHECK_RET( control != NULL, wxT("attempt to remove a NULL WXWidget from control map") );
2691 
2692     wxWinMacControlList.erase(control);
2693 }
2694 
2695 wxIMPLEMENT_ABSTRACT_CLASS(wxWidgetImpl, wxObject);
2696 
wxWidgetImpl(wxWindowMac * peer,int flags)2697 wxWidgetImpl::wxWidgetImpl( wxWindowMac* peer , int flags )
2698 {
2699     Init();
2700     m_isRootControl = flags & Widget_IsRoot;
2701     m_isUserPane = flags & Widget_IsUserPane;
2702     m_wantsUserKey = m_isUserPane || (flags & Widget_UserKeyEvents);
2703     m_wantsUserMouse = m_isUserPane || (flags & Widget_UserMouseEvents);
2704     m_wxPeer = peer;
2705     m_shouldSendEvents = true;
2706 }
2707 
wxWidgetImpl(wxWindowMac * peer,bool isRootControl,bool isUserPane,bool wantsUserKey)2708 wxWidgetImpl::wxWidgetImpl( wxWindowMac* peer , bool isRootControl, bool isUserPane, bool wantsUserKey )
2709 {
2710     Init();
2711     m_isRootControl = isRootControl;
2712     m_isUserPane = isUserPane;
2713     m_wantsUserKey = wantsUserKey;
2714     m_wxPeer = peer;
2715     m_shouldSendEvents = true;
2716 }
2717 
wxWidgetImpl()2718 wxWidgetImpl::wxWidgetImpl()
2719 {
2720     Init();
2721 }
2722 
~wxWidgetImpl()2723 wxWidgetImpl::~wxWidgetImpl()
2724 {
2725     m_wxPeer = NULL;
2726 }
2727 
Init()2728 void wxWidgetImpl::Init()
2729 {
2730     m_isRootControl = false;
2731     m_wantsUserKey = false;
2732     m_wantsUserMouse = false;
2733     m_wxPeer = NULL;
2734     m_needsFrame = true;
2735 }
2736 
SetNeedsFrame(bool needs)2737 void wxWidgetImpl::SetNeedsFrame( bool needs )
2738 {
2739     m_needsFrame = needs;
2740 }
2741 
NeedsFrame() const2742 bool wxWidgetImpl::NeedsFrame() const
2743 {
2744     return m_needsFrame;
2745 }
2746 
SetDrawingEnabled(bool WXUNUSED (enabled))2747 void wxWidgetImpl::SetDrawingEnabled(bool WXUNUSED(enabled))
2748 {
2749 }
2750