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