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