]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/window.cpp
Consistent tab behaviour
[wxWidgets.git] / src / mac / carbon / window.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: windows.cpp
3 // Purpose: wxWindowMac
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 1998-01-01
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "window.h"
14 #endif
15
16 #include "wx/setup.h"
17 #include "wx/menu.h"
18 #include "wx/window.h"
19 #include "wx/dc.h"
20 #include "wx/dcclient.h"
21 #include "wx/utils.h"
22 #include "wx/app.h"
23 #include "wx/panel.h"
24 #include "wx/layout.h"
25 #include "wx/dialog.h"
26 #include "wx/scrolbar.h"
27 #include "wx/statbox.h"
28 #include "wx/button.h"
29 #include "wx/settings.h"
30 #include "wx/msgdlg.h"
31 #include "wx/frame.h"
32 #include "wx/tooltip.h"
33 #include "wx/statusbr.h"
34 #include "wx/menuitem.h"
35 #include "wx/spinctrl.h"
36 #include "wx/log.h"
37 #include "wx/geometry.h"
38 #include "wx/textctrl.h"
39
40 #include "wx/toolbar.h"
41 #include "wx/dc.h"
42
43 #if wxUSE_CARET
44 #include "wx/caret.h"
45 #endif // wxUSE_CARET
46
47 #define wxWINDOW_HSCROLL 5998
48 #define wxWINDOW_VSCROLL 5997
49 #define MAC_SCROLLBAR_SIZE 16
50
51 #include "wx/mac/uma.h"
52 #ifndef __DARWIN__
53 #include <Windows.h>
54 #include <ToolUtils.h>
55 #include <Scrap.h>
56 #include <MacTextEditor.h>
57 #endif
58
59 #if TARGET_API_MAC_OSX
60 #ifndef __HIVIEW__
61 #include <HIToolbox/HIView.h>
62 #endif
63 #endif
64
65 #if wxUSE_DRAG_AND_DROP
66 #include "wx/dnd.h"
67 #endif
68
69 #include <string.h>
70
71 extern wxList wxPendingDelete;
72
73 #ifdef __WXUNIVERSAL__
74 IMPLEMENT_ABSTRACT_CLASS(wxWindowMac, wxWindowBase)
75 #else // __WXMAC__
76 IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
77 #endif // __WXUNIVERSAL__/__WXMAC__
78
79 #if !USE_SHARED_LIBRARY
80
81 BEGIN_EVENT_TABLE(wxWindowMac, wxWindowBase)
82 EVT_NC_PAINT(wxWindowMac::OnNcPaint)
83 EVT_ERASE_BACKGROUND(wxWindowMac::OnEraseBackground)
84 // TODO EVT_PAINT(wxWindowMac::OnPaint)
85 EVT_SYS_COLOUR_CHANGED(wxWindowMac::OnSysColourChanged)
86 EVT_INIT_DIALOG(wxWindowMac::OnInitDialog)
87 // EVT_SET_FOCUS(wxWindowMac::OnSetFocus)
88 EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent)
89 END_EVENT_TABLE()
90
91 #endif
92
93 #define wxMAC_DEBUG_REDRAW 0
94 #ifndef wxMAC_DEBUG_REDRAW
95 #define wxMAC_DEBUG_REDRAW 0
96 #endif
97
98 #define wxMAC_USE_THEME_BORDER 0
99
100 // ---------------------------------------------------------------------------
101 // Carbon Events
102 // ---------------------------------------------------------------------------
103
104 extern long wxMacTranslateKey(unsigned char key, unsigned char code) ;
105 pascal OSStatus wxMacSetupControlBackground( ControlRef iControl , SInt16 iMessage , SInt16 iDepth , Boolean iIsColor ) ;
106
107 #if TARGET_API_MAC_OSX
108
109 #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3
110 enum {
111 kEventControlVisibilityChanged = 157
112 };
113 #endif
114
115 #endif
116
117 static const EventTypeSpec eventList[] =
118 {
119 { kEventClassControl , kEventControlHit } ,
120 #if TARGET_API_MAC_OSX
121 { kEventClassControl , kEventControlDraw } ,
122 { kEventClassControl , kEventControlVisibilityChanged } ,
123 { kEventClassControl , kEventControlEnabledStateChanged } ,
124 { kEventClassControl , kEventControlHiliteChanged } ,
125 { kEventClassControl , kEventControlSetFocusPart } ,
126
127 { kEventClassService , kEventServiceGetTypes },
128 { kEventClassService , kEventServiceCopy },
129 { kEventClassService , kEventServicePaste },
130
131 // { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only
132 // { kEventClassControl , kEventControlBoundsChanged } ,
133 #endif
134 } ;
135
136 static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
137 {
138 OSStatus result = eventNotHandledErr ;
139
140 wxMacCarbonEvent cEvent( event ) ;
141
142 ControlRef controlRef ;
143 wxWindowMac* thisWindow = (wxWindowMac*) data ;
144
145 cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ;
146
147 switch( GetEventKind( event ) )
148 {
149 #if TARGET_API_MAC_OSX
150 case kEventControlDraw :
151 {
152 RgnHandle updateRgn = NULL ;
153
154 wxRegion visRegion = thisWindow->MacGetVisibleRegion() ;
155 if ( cEvent.GetParameter<RgnHandle>(kEventParamRgnHandle, &updateRgn) != noErr )
156 {
157 updateRgn = (RgnHandle) visRegion.GetWXHRGN() ;
158 }
159 // GrafPtr myport = cEvent.GetParameter<GrafPtr>(kEventParamGrafPort,typeGrafPtr) ;
160
161 #if 0
162 // in case we would need a coregraphics compliant background erase first
163 // now usable to track redraws
164 CGContextRef cgContext = cEvent.GetParameter<CGContextRef>(kEventParamCGContextRef) ;
165 if ( thisWindow->MacIsUserPane() )
166 {
167 static float color = 0.5 ;
168 static channel = 0 ;
169 HIRect bounds;
170 HIViewGetBounds( controlRef, &bounds );
171 CGContextSetRGBFillColor( cgContext, channel == 0 ? color : 0.5 ,
172 channel == 1 ? color : 0.5 , channel == 2 ? color : 0.5 , 1 );
173 CGContextFillRect( cgContext, bounds );
174 color += 0.1 ;
175 if ( color > 0.9 )
176 {
177 color = 0.5 ;
178 channel++ ;
179 if ( channel == 3 )
180 channel = 0 ;
181 }
182 }
183 #endif
184 if ( thisWindow->MacDoRedraw( updateRgn , cEvent.GetTicks() ) )
185 result = noErr ;
186 }
187 break ;
188 case kEventControlVisibilityChanged :
189 thisWindow->MacVisibilityChanged() ;
190 break ;
191 case kEventControlEnabledStateChanged :
192 thisWindow->MacEnabledStateChanged() ;
193 break ;
194 case kEventControlHiliteChanged :
195 thisWindow->MacHiliteChanged() ;
196 break ;
197 case kEventControlSetFocusPart :
198 {
199 Boolean focusEverything = false ;
200 ControlPartCode controlPart = cEvent.GetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode );
201 if ( cEvent.GetParameter<Boolean>(kEventParamControlFocusEverything , &focusEverything ) == noErr )
202 {
203 }
204 if ( controlPart == kControlFocusNoPart )
205 {
206 #if wxUSE_CARET
207 if ( thisWindow->GetCaret() )
208 {
209 thisWindow->GetCaret()->OnKillFocus();
210 }
211 #endif // wxUSE_CARET
212 wxFocusEvent event(wxEVT_KILL_FOCUS, thisWindow->GetId());
213 event.SetEventObject(thisWindow);
214 thisWindow->GetEventHandler()->ProcessEvent(event) ;
215 }
216 else
217 {
218 // panel wants to track the window which was the last to have focus in it
219 wxChildFocusEvent eventFocus(thisWindow);
220 thisWindow->GetEventHandler()->ProcessEvent(eventFocus);
221
222 #if wxUSE_CARET
223 if ( thisWindow->GetCaret() )
224 {
225 thisWindow->GetCaret()->OnSetFocus();
226 }
227 #endif // wxUSE_CARET
228
229 wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId());
230 event.SetEventObject(thisWindow);
231 thisWindow->GetEventHandler()->ProcessEvent(event) ;
232 }
233 if ( thisWindow->MacIsUserPane() )
234 result = noErr ;
235 }
236 break ;
237 #endif
238 case kEventControlHit :
239 {
240 result = thisWindow->MacControlHit( handler , event ) ;
241 }
242 break ;
243 default :
244 break ;
245 }
246 return result ;
247 }
248
249 static pascal OSStatus wxMacWindowServiceEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
250 {
251 OSStatus result = eventNotHandledErr ;
252
253 wxMacCarbonEvent cEvent( event ) ;
254
255 ControlRef controlRef ;
256 wxWindowMac* thisWindow = (wxWindowMac*) data ;
257 wxTextCtrl* textCtrl = wxDynamicCast( thisWindow , wxTextCtrl ) ;
258 cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ;
259
260 switch( GetEventKind( event ) )
261 {
262 case kEventServiceGetTypes :
263 if( textCtrl )
264 {
265 long from, to ;
266 textCtrl->GetSelection( &from , &to ) ;
267
268 CFMutableArrayRef copyTypes = 0 , pasteTypes = 0;
269 if( from != to )
270 copyTypes = cEvent.GetParameter< CFMutableArrayRef >( kEventParamServiceCopyTypes , typeCFMutableArrayRef ) ;
271 if ( textCtrl->IsEditable() )
272 pasteTypes = cEvent.GetParameter< CFMutableArrayRef >( kEventParamServicePasteTypes , typeCFMutableArrayRef ) ;
273
274 static const OSType textDataTypes[] = { kTXNTextData /* , 'utxt' , 'PICT', 'MooV', 'AIFF' */ };
275 for ( size_t i = 0 ; i < WXSIZEOF(textDataTypes) ; ++i )
276 {
277 CFStringRef typestring = CreateTypeStringWithOSType(textDataTypes[i]);
278 if ( typestring )
279 {
280 if ( copyTypes )
281 CFArrayAppendValue (copyTypes, typestring) ;
282 if ( pasteTypes )
283 CFArrayAppendValue (pasteTypes, typestring) ;
284 CFRelease( typestring ) ;
285 }
286 }
287 result = noErr ;
288 }
289 break ;
290 case kEventServiceCopy :
291 if ( textCtrl )
292 {
293 long from, to ;
294 textCtrl->GetSelection( &from , &to ) ;
295 wxString val = textCtrl->GetValue() ;
296 val = val.Mid( from , to - from ) ;
297 ScrapRef scrapRef = cEvent.GetParameter< ScrapRef > ( kEventParamScrapRef , typeScrapRef ) ;
298 verify_noerr( ClearScrap( &scrapRef ) ) ;
299 verify_noerr( PutScrapFlavor( scrapRef , kTXNTextData , 0 , val.Length() , val.c_str() ) ) ;
300 result = noErr ;
301 }
302 break ;
303 case kEventServicePaste :
304 if ( textCtrl )
305 {
306 ScrapRef scrapRef = cEvent.GetParameter< ScrapRef > ( kEventParamScrapRef , typeScrapRef ) ;
307 Size textSize, pastedSize ;
308 verify_noerr( GetScrapFlavorSize (scrapRef, kTXNTextData, &textSize) ) ;
309 textSize++ ;
310 char *content = new char[textSize] ;
311 GetScrapFlavorData (scrapRef, kTXNTextData, &pastedSize, content );
312 content[textSize-1] = 0 ;
313 #if wxUSE_UNICODE
314 textCtrl->WriteText( wxString( content , wxConvLocal ) );
315 #else
316 textCtrl->WriteText( wxString( content ) ) ;
317 #endif
318 delete[] content ;
319 result = noErr ;
320 }
321 break ;
322 }
323
324 return result ;
325 }
326
327 pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
328 {
329 OSStatus result = eventNotHandledErr ;
330
331 switch ( GetEventClass( event ) )
332 {
333 case kEventClassControl :
334 result = wxMacWindowControlEventHandler( handler, event, data ) ;
335 break ;
336 case kEventClassService :
337 result = wxMacWindowServiceEventHandler( handler, event , data ) ;
338 default :
339 break ;
340 }
341 return result ;
342 }
343
344 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler )
345
346 // ---------------------------------------------------------------------------
347 // UserPane events for non OSX builds
348 // ---------------------------------------------------------------------------
349
350 static pascal void wxMacControlUserPaneDrawProc(ControlRef control, SInt16 part)
351 {
352 wxWindow * win = wxFindControlFromMacControl(control) ;
353 wxCHECK_RET( win , wxT("Callback from unkown control") ) ;
354 win->MacControlUserPaneDrawProc(part) ;
355 }
356
357 static pascal ControlPartCode wxMacControlUserPaneHitTestProc(ControlRef control, Point where)
358 {
359 wxWindow * win = wxFindControlFromMacControl(control) ;
360 wxCHECK_MSG( win , kControlNoPart , wxT("Callback from unkown control") ) ;
361 return win->MacControlUserPaneHitTestProc(where.h , where.v) ;
362 }
363
364 static pascal ControlPartCode wxMacControlUserPaneTrackingProc(ControlRef control, Point startPt, ControlActionUPP actionProc)
365 {
366 wxWindow * win = wxFindControlFromMacControl(control) ;
367 wxCHECK_MSG( win , kControlNoPart , wxT("Callback from unkown control") ) ;
368 return win->MacControlUserPaneTrackingProc( startPt.h , startPt.v , (void*) actionProc) ;
369 }
370
371 static pascal void wxMacControlUserPaneIdleProc(ControlRef control)
372 {
373 wxWindow * win = wxFindControlFromMacControl(control) ;
374 wxCHECK_RET( win , wxT("Callback from unkown control") ) ;
375 win->MacControlUserPaneIdleProc() ;
376 }
377
378 static pascal ControlPartCode wxMacControlUserPaneKeyDownProc(ControlRef control, SInt16 keyCode, SInt16 charCode, SInt16 modifiers)
379 {
380 wxWindow * win = wxFindControlFromMacControl(control) ;
381 wxCHECK_MSG( win , kControlNoPart , wxT("Callback from unkown control") ) ;
382 return win->MacControlUserPaneKeyDownProc(keyCode,charCode,modifiers) ;
383 }
384
385 static pascal void wxMacControlUserPaneActivateProc(ControlRef control, Boolean activating)
386 {
387 wxWindow * win = wxFindControlFromMacControl(control) ;
388 wxCHECK_RET( win , wxT("Callback from unkown control") ) ;
389 win->MacControlUserPaneActivateProc(activating) ;
390 }
391
392 static pascal ControlPartCode wxMacControlUserPaneFocusProc(ControlRef control, ControlFocusPart action)
393 {
394 wxWindow * win = wxFindControlFromMacControl(control) ;
395 wxCHECK_MSG( win , kControlNoPart , wxT("Callback from unkown control") ) ;
396 return win->MacControlUserPaneFocusProc(action) ;
397 }
398
399 static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control, ControlBackgroundPtr info)
400 {
401 wxWindow * win = wxFindControlFromMacControl(control) ;
402 wxCHECK_RET( win , wxT("Callback from unkown control") ) ;
403 win->MacControlUserPaneBackgroundProc(info) ;
404 }
405
406 void wxWindowMac::MacControlUserPaneDrawProc(wxInt16 part)
407 {
408 RgnHandle rgn = NewRgn() ;
409 GetClip( rgn ) ;
410 wxMacWindowStateSaver sv( this ) ;
411 SectRgn( rgn , (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , rgn ) ;
412 MacDoRedraw( rgn , 0 ) ;
413 DisposeRgn( rgn ) ;
414 }
415
416 wxInt16 wxWindowMac::MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y)
417 {
418 return kControlNoPart ;
419 }
420
421 wxInt16 wxWindowMac::MacControlUserPaneTrackingProc(wxInt16 x, wxInt16 y, void* actionProc)
422 {
423 return kControlNoPart ;
424 }
425
426 void wxWindowMac::MacControlUserPaneIdleProc()
427 {
428 }
429
430 wxInt16 wxWindowMac::MacControlUserPaneKeyDownProc(wxInt16 keyCode, wxInt16 charCode, wxInt16 modifiers)
431 {
432 return kControlNoPart ;
433 }
434
435 void wxWindowMac::MacControlUserPaneActivateProc(bool activating)
436 {
437 }
438
439 wxInt16 wxWindowMac::MacControlUserPaneFocusProc(wxInt16 action)
440 {
441 return kControlNoPart ;
442 }
443
444 void wxWindowMac::MacControlUserPaneBackgroundProc(void* info)
445 {
446 }
447
448 ControlUserPaneDrawUPP gControlUserPaneDrawUPP = NULL ;
449 ControlUserPaneHitTestUPP gControlUserPaneHitTestUPP = NULL ;
450 ControlUserPaneTrackingUPP gControlUserPaneTrackingUPP = NULL ;
451 ControlUserPaneIdleUPP gControlUserPaneIdleUPP = NULL ;
452 ControlUserPaneKeyDownUPP gControlUserPaneKeyDownUPP = NULL ;
453 ControlUserPaneActivateUPP gControlUserPaneActivateUPP = NULL ;
454 ControlUserPaneFocusUPP gControlUserPaneFocusUPP = NULL ;
455 ControlUserPaneBackgroundUPP gControlUserPaneBackgroundUPP = NULL ;
456
457 // ===========================================================================
458 // implementation
459 // ===========================================================================
460
461 wxList wxWinMacControlList(wxKEY_INTEGER);
462
463 wxWindow *wxFindControlFromMacControl(ControlRef inControl )
464 {
465 wxNode *node = wxWinMacControlList.Find((long)inControl);
466 if (!node)
467 return NULL;
468 return (wxControl *)node->GetData();
469 }
470
471 void wxAssociateControlWithMacControl(ControlRef inControl, wxWindow *control)
472 {
473 // adding NULL ControlRef is (first) surely a result of an error and
474 // (secondly) breaks native event processing
475 wxCHECK_RET( inControl != (ControlRef) NULL, wxT("attempt to add a NULL WindowRef to window list") );
476
477 if ( !wxWinMacControlList.Find((long)inControl) )
478 wxWinMacControlList.Append((long)inControl, control);
479 }
480
481 void wxRemoveMacControlAssociation(wxWindow *control)
482 {
483 wxWinMacControlList.DeleteObject(control);
484 }
485
486 // UPP functions
487 ControlActionUPP wxMacLiveScrollbarActionUPP = NULL ;
488
489 ControlColorUPP wxMacSetupControlBackgroundUPP = NULL ;
490
491 // we have to setup the brush in the current port and return noErr
492 // or return an error code so that the control manager walks further up the
493 // hierarchy to find a correct background
494
495 pascal OSStatus wxMacSetupControlBackground( ControlRef iControl , SInt16 iMessage , SInt16 iDepth , Boolean iIsColor )
496 {
497 OSStatus status = paramErr ;
498 switch( iMessage )
499 {
500 case kControlMsgApplyTextColor :
501 break ;
502 case kControlMsgSetUpBackground :
503 {
504 wxWindow* wx = (wxWindow*) wxFindControlFromMacControl( iControl ) ;
505 if ( wx != NULL )
506 {
507 /*
508 const wxBrush &brush = wx->MacGetBackgroundBrush() ;
509 if ( brush.Ok() )
510 {
511
512 wxDC::MacSetupBackgroundForCurrentPort( brush ) ;
513 */
514 // this clipping is only needed for non HIView
515
516 RgnHandle clip = NewRgn() ;
517 int x = 0 , y = 0;
518
519 wx->MacWindowToRootWindow( &x,&y ) ;
520 CopyRgn( (RgnHandle) wx->MacGetVisibleRegion().GetWXHRGN() , clip ) ;
521 OffsetRgn( clip , x , y ) ;
522 SetClip( clip ) ;
523 DisposeRgn( clip ) ;
524
525 status = noErr ;
526 /*
527 }
528 else if ( wx->MacIsUserPane() )
529 {
530 // if we don't have a valid brush for such a control, we have to call the
531 // setup of our parent ourselves
532 status = SetUpControlBackground( (ControlRef) wx->GetParent()->GetHandle() , iDepth , iIsColor ) ;
533 }
534 */
535 }
536 }
537 break ;
538 default :
539 break ;
540 }
541 return status ;
542 }
543
544
545 pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode partCode ) ;
546 pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode partCode )
547 {
548 if ( partCode != 0)
549 {
550 wxWindow* wx = wxFindControlFromMacControl( control ) ;
551 if ( wx )
552 {
553 wx->MacHandleControlClick( (WXWidget) control , partCode , true /* stillDown */ ) ;
554 }
555 }
556 }
557
558 // ----------------------------------------------------------------------------
559 // constructors and such
560 // ----------------------------------------------------------------------------
561
562 wxWindowMac::wxWindowMac()
563 {
564 Init();
565 }
566
567 wxWindowMac::wxWindowMac(wxWindowMac *parent,
568 wxWindowID id,
569 const wxPoint& pos ,
570 const wxSize& size ,
571 long style ,
572 const wxString& name )
573 {
574 Init();
575 Create(parent, id, pos, size, style, name);
576 }
577
578 void wxWindowMac::Init()
579 {
580 m_peer = NULL ;
581 m_frozenness = 0 ;
582 #if WXWIN_COMPATIBILITY_2_4
583 m_backgroundTransparent = FALSE;
584 #endif
585
586 // as all windows are created with WS_VISIBLE style...
587 m_isShown = TRUE;
588
589 m_hScrollBar = NULL ;
590 m_vScrollBar = NULL ;
591 m_macBackgroundBrush = wxNullBrush ;
592
593 m_macIsUserPane = TRUE;
594
595 // make sure all proc ptrs are available
596
597 if ( gControlUserPaneDrawUPP == NULL )
598 {
599 gControlUserPaneDrawUPP = NewControlUserPaneDrawUPP( wxMacControlUserPaneDrawProc ) ;
600 gControlUserPaneHitTestUPP = NewControlUserPaneHitTestUPP( wxMacControlUserPaneHitTestProc ) ;
601 gControlUserPaneTrackingUPP = NewControlUserPaneTrackingUPP( wxMacControlUserPaneTrackingProc ) ;
602 gControlUserPaneIdleUPP = NewControlUserPaneIdleUPP( wxMacControlUserPaneIdleProc ) ;
603 gControlUserPaneKeyDownUPP = NewControlUserPaneKeyDownUPP( wxMacControlUserPaneKeyDownProc ) ;
604 gControlUserPaneActivateUPP = NewControlUserPaneActivateUPP( wxMacControlUserPaneActivateProc ) ;
605 gControlUserPaneFocusUPP = NewControlUserPaneFocusUPP( wxMacControlUserPaneFocusProc ) ;
606 gControlUserPaneBackgroundUPP = NewControlUserPaneBackgroundUPP( wxMacControlUserPaneBackgroundProc ) ;
607 }
608 if ( wxMacLiveScrollbarActionUPP == NULL )
609 {
610 wxMacLiveScrollbarActionUPP = NewControlActionUPP( wxMacLiveScrollbarActionProc );
611 }
612
613 if ( wxMacSetupControlBackgroundUPP == NULL )
614 {
615 wxMacSetupControlBackgroundUPP = NewControlColorUPP( wxMacSetupControlBackground ) ;
616 }
617
618 // we need a valid font for the encodings
619 wxWindowBase::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
620 }
621
622 // Destructor
623 wxWindowMac::~wxWindowMac()
624 {
625 SendDestroyEvent();
626
627 m_isBeingDeleted = TRUE;
628
629 #ifndef __WXUNIVERSAL__
630 // VS: make sure there's no wxFrame with last focus set to us:
631 for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
632 {
633 wxFrame *frame = wxDynamicCast(win, wxFrame);
634 if ( frame )
635 {
636 if ( frame->GetLastFocus() == this )
637 {
638 frame->SetLastFocus((wxWindow*)NULL);
639 }
640 break;
641 }
642 }
643 #endif // __WXUNIVERSAL__
644
645 // wxRemoveMacControlAssociation( this ) ;
646 // If we delete an item, we should initialize the parent panel,
647 // because it could now be invalid.
648 wxWindow *parent = GetParent() ;
649 if ( parent )
650 {
651 if (parent->GetDefaultItem() == (wxButton*) this)
652 parent->SetDefaultItem(NULL);
653 }
654 if ( m_peer && m_peer->Ok() )
655 {
656 // in case the callback might be called during destruction
657 wxRemoveMacControlAssociation( this) ;
658 ::SetControlColorProc( *m_peer , NULL ) ;
659 ::DisposeControl( *m_peer ) ;
660 }
661
662 if ( g_MacLastWindow == this )
663 {
664 g_MacLastWindow = NULL ;
665 }
666
667 wxFrame* frame = wxDynamicCast( wxGetTopLevelParent( this ) , wxFrame ) ;
668 if ( frame )
669 {
670 if ( frame->GetLastFocus() == this )
671 frame->SetLastFocus( NULL ) ;
672 }
673
674 DestroyChildren();
675
676 // delete our drop target if we've got one
677 #if wxUSE_DRAG_AND_DROP
678 if ( m_dropTarget != NULL )
679 {
680 delete m_dropTarget;
681 m_dropTarget = NULL;
682 }
683 #endif // wxUSE_DRAG_AND_DROP
684 delete m_peer ;
685 }
686
687 WXWidget wxWindowMac::GetHandle() const
688 {
689 return (WXWidget) (ControlRef) *m_peer ;
690 }
691
692
693 void wxWindowMac::MacInstallEventHandler()
694 {
695 wxAssociateControlWithMacControl( *m_peer , this ) ;
696 InstallControlEventHandler( *m_peer, GetwxMacWindowEventHandlerUPP(),
697 GetEventTypeCount(eventList), eventList, this,
698 (EventHandlerRef *)&m_macControlEventHandler);
699
700 }
701
702 // Constructor
703 bool wxWindowMac::Create(wxWindowMac *parent, wxWindowID id,
704 const wxPoint& pos,
705 const wxSize& size,
706 long style,
707 const wxString& name)
708 {
709 wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindowMac without parent") );
710
711 if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
712 return FALSE;
713
714 parent->AddChild(this);
715
716 m_windowVariant = parent->GetWindowVariant() ;
717
718 if ( m_macIsUserPane )
719 {
720 Rect bounds = wxMacGetBoundsForControl( this , pos , size ) ;
721
722 UInt32 features = 0
723 | kControlSupportsEmbedding
724 // | kControlSupportsLiveFeedback
725 // | kControlHasSpecialBackground
726 // | kControlSupportsCalcBestRect
727 // | kControlHandlesTracking
728 | kControlSupportsFocus
729 // | kControlWantsActivate
730 // | kControlWantsIdle
731 ;
732
733 m_peer = new wxMacControl() ;
734 ::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds, features , *m_peer);
735
736
737 MacPostControlCreate(pos,size) ;
738 #if !TARGET_API_MAC_OSX
739 SetControlData(*m_peer,kControlEntireControl,kControlUserPaneDrawProcTag,
740 sizeof(gControlUserPaneDrawUPP),(Ptr) &gControlUserPaneDrawUPP);
741 SetControlData(*m_peer,kControlEntireControl,kControlUserPaneHitTestProcTag,
742 sizeof(gControlUserPaneHitTestUPP),(Ptr) &gControlUserPaneHitTestUPP);
743 SetControlData(*m_peer,kControlEntireControl,kControlUserPaneTrackingProcTag,
744 sizeof(gControlUserPaneTrackingUPP),(Ptr) &gControlUserPaneTrackingUPP);
745 SetControlData(*m_peer,kControlEntireControl,kControlUserPaneIdleProcTag,
746 sizeof(gControlUserPaneIdleUPP),(Ptr) &gControlUserPaneIdleUPP);
747 SetControlData(*m_peer,kControlEntireControl,kControlUserPaneKeyDownProcTag,
748 sizeof(gControlUserPaneKeyDownUPP),(Ptr) &gControlUserPaneKeyDownUPP);
749 SetControlData(*m_peer,kControlEntireControl,kControlUserPaneActivateProcTag,
750 sizeof(gControlUserPaneActivateUPP),(Ptr) &gControlUserPaneActivateUPP);
751 SetControlData(*m_peer,kControlEntireControl,kControlUserPaneFocusProcTag,
752 sizeof(gControlUserPaneFocusUPP),(Ptr) &gControlUserPaneFocusUPP);
753 SetControlData(*m_peer,kControlEntireControl,kControlUserPaneBackgroundProcTag,
754 sizeof(gControlUserPaneBackgroundUPP),(Ptr) &gControlUserPaneBackgroundUPP);
755 #endif
756 }
757 #ifndef __WXUNIVERSAL__
758 // Don't give scrollbars to wxControls unless they ask for them
759 if ( (! IsKindOf(CLASSINFO(wxControl)) && ! IsKindOf(CLASSINFO(wxStatusBar))) ||
760 (IsKindOf(CLASSINFO(wxControl)) && ( style & wxHSCROLL || style & wxVSCROLL)))
761 {
762 MacCreateScrollBars( style ) ;
763 }
764 #endif
765
766 wxWindowCreateEvent event(this);
767 GetEventHandler()->AddPendingEvent(event);
768
769 return TRUE;
770 }
771
772 void wxWindowMac::MacPostControlCreate(const wxPoint& pos, const wxSize& size)
773 {
774 wxASSERT_MSG( m_peer != NULL && m_peer->Ok() , wxT("No valid mac control") ) ;
775
776 ::SetControlReference( *m_peer , (long) this ) ;
777
778 MacInstallEventHandler();
779
780 ControlRef container = (ControlRef) GetParent()->GetHandle() ;
781 wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ;
782 ::EmbedControl( *m_peer , container ) ;
783
784 // adjust font, controlsize etc
785 DoSetWindowVariant( m_windowVariant ) ;
786
787 #if !TARGET_API_MAC_OSX
788 // eventually we can fix some clipping issues be reactivating this hook
789 //if ( m_macIsUserPane )
790 // SetControlColorProc( *m_peer , wxMacSetupControlBackgroundUPP ) ;
791 #endif
792
793 UMASetControlTitle( *m_peer , wxStripMenuCodes(m_label) , m_font.GetEncoding() ) ;
794
795 if (!m_macIsUserPane)
796 {
797 SetInitialBestSize(size);
798 }
799
800 SetCursor( *wxSTANDARD_CURSOR ) ;
801 }
802
803 void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant )
804 {
805 // Don't assert, in case we set the window variant before
806 // the window is created
807 // wxASSERT( m_peer->Ok() ) ;
808
809 m_windowVariant = variant ;
810
811 if (m_peer == NULL || !m_peer->Ok())
812 return;
813
814 ControlSize size ;
815 ThemeFontID themeFont = kThemeSystemFont ;
816
817 // we will get that from the settings later
818 // and make this NORMAL later, but first
819 // we have a few calculations that we must fix
820
821 switch ( variant )
822 {
823 case wxWINDOW_VARIANT_NORMAL :
824 size = kControlSizeNormal;
825 themeFont = kThemeSystemFont ;
826 break ;
827 case wxWINDOW_VARIANT_SMALL :
828 size = kControlSizeSmall;
829 themeFont = kThemeSmallSystemFont ;
830 break ;
831 case wxWINDOW_VARIANT_MINI :
832 if (UMAGetSystemVersion() >= 0x1030 )
833 {
834 // not always defined in the headers
835 size = 3 ;
836 themeFont = 109 ;
837 }
838 else
839 {
840 size = kControlSizeSmall;
841 themeFont = kThemeSmallSystemFont ;
842 }
843 break ;
844 case wxWINDOW_VARIANT_LARGE :
845 size = kControlSizeLarge;
846 themeFont = kThemeSystemFont ;
847 break ;
848 default:
849 wxFAIL_MSG(_T("unexpected window variant"));
850 break ;
851 }
852 ::SetControlData( *m_peer , kControlEntireControl, kControlSizeTag, sizeof( ControlSize ), &size );
853
854 wxFont font ;
855 font.MacCreateThemeFont( themeFont ) ;
856 SetFont( font ) ;
857 }
858
859 void wxWindowMac::MacUpdateControlFont()
860 {
861 ControlFontStyleRec fontStyle;
862 if ( m_font.MacGetThemeFontID() != kThemeCurrentPortFont )
863 {
864 switch( m_font.MacGetThemeFontID() )
865 {
866 case kThemeSmallSystemFont : fontStyle.font = kControlFontSmallSystemFont ; break ;
867 case 109 /*mini font */ : fontStyle.font = -5 ; break ;
868 case kThemeSystemFont : fontStyle.font = kControlFontBigSystemFont ; break ;
869 default : fontStyle.font = kControlFontBigSystemFont ; break ;
870 }
871 fontStyle.flags = kControlUseFontMask ;
872 }
873 else
874 {
875 fontStyle.font = m_font.MacGetFontNum() ;
876 fontStyle.style = m_font.MacGetFontStyle() ;
877 fontStyle.size = m_font.MacGetFontSize() ;
878 fontStyle.flags = kControlUseFontMask | kControlUseFaceMask | kControlUseSizeMask ;
879 }
880
881 fontStyle.just = teJustLeft ;
882 fontStyle.flags |= kControlUseJustMask ;
883 if ( ( GetWindowStyle() & wxALIGN_MASK ) & wxALIGN_CENTER_HORIZONTAL )
884 fontStyle.just = teJustCenter ;
885 else if ( ( GetWindowStyle() & wxALIGN_MASK ) & wxALIGN_RIGHT )
886 fontStyle.just = teJustRight ;
887
888
889 fontStyle.foreColor = MAC_WXCOLORREF(GetForegroundColour().GetPixel() ) ;
890 fontStyle.flags |= kControlUseForeColorMask ;
891
892 ::SetControlFontStyle( *m_peer , &fontStyle );
893 Refresh() ;
894 }
895
896 bool wxWindowMac::SetFont(const wxFont& font)
897 {
898 bool retval = !wxWindowBase::SetFont( font ) ;
899
900 MacUpdateControlFont() ;
901
902 return retval;
903 }
904
905 bool wxWindowMac::SetForegroundColour(const wxColour& col )
906 {
907 if ( !wxWindowBase::SetForegroundColour(col) )
908 return false ;
909
910 MacUpdateControlFont() ;
911
912 return true ;
913 }
914
915 bool wxWindowMac::SetBackgroundColour(const wxColour& col )
916 {
917 if ( !wxWindowBase::SetBackgroundColour(col) && m_hasBgCol )
918 return false ;
919
920 wxBrush brush ;
921 if ( col == wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE) )
922 {
923 brush.MacSetTheme( kThemeBrushDocumentWindowBackground ) ;
924 }
925 else if ( col == wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE ) )
926 {
927 brush.MacSetTheme( kThemeBrushDialogBackgroundActive ) ;
928 }
929 else
930 {
931 brush.SetColour( col ) ;
932 }
933 MacSetBackgroundBrush( brush ) ;
934
935 MacUpdateControlFont() ;
936
937 return true ;
938 }
939
940
941 bool wxWindowMac::MacCanFocus() const
942 {
943 // there is currently no way to determine whether the window is running in full keyboard
944 // access mode, therefore we cannot rely on these features, yet the only other way would be
945 // to issue a SetKeyboardFocus event and verify after whether it succeeded, this would risk problems
946 // in event handlers...
947 UInt32 features = 0 ;
948 GetControlFeatures( *m_peer , &features ) ;
949 return features & ( kControlSupportsFocus | kControlGetsFocusOnClick ) ;
950 }
951
952
953 void wxWindowMac::SetFocus()
954 {
955 if ( AcceptsFocus() )
956 {
957 #if !TARGET_API_MAC_OSX
958 wxWindow* former = FindFocus() ;
959 #endif
960 OSStatus err = SetKeyboardFocus( (WindowRef) MacGetTopLevelWindowRef() , (ControlRef) GetHandle() , kControlFocusNextPart ) ;
961 // as we cannot rely on the control features to find out whether we are in full keyboard mode, we can only
962 // leave in case of an error
963 if ( err == errCouldntSetFocus )
964 return ;
965
966 #if !TARGET_API_MAC_OSX
967 // emulate carbon events when running under carbonlib where they are not natively available
968 if ( former )
969 {
970 EventRef evRef = NULL ;
971 verify_noerr( MacCreateEvent( NULL , kEventClassControl , kEventControlSetFocusPart , TicksToEventTime( TickCount() ) , kEventAttributeUserEvent ,
972 &evRef ) );
973
974 wxMacCarbonEvent cEvent( evRef ) ;
975 cEvent.SetParameter<ControlRef>( kEventParamDirectObject , (ControlRef) former->GetHandle() ) ;
976 cEvent.SetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode , kControlFocusNoPart ) ;
977
978 wxMacWindowEventHandler( NULL , evRef , former ) ;
979 ReleaseEvent(evRef) ;
980 }
981 // send new focus event
982 {
983 EventRef evRef = NULL ;
984 verify_noerr( MacCreateEvent( NULL , kEventClassControl , kEventControlSetFocusPart , TicksToEventTime( TickCount() ) , kEventAttributeUserEvent ,
985 &evRef ) );
986
987 wxMacCarbonEvent cEvent( evRef ) ;
988 cEvent.SetParameter<ControlRef>( kEventParamDirectObject , (ControlRef) GetHandle() ) ;
989 cEvent.SetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode , kControlFocusNextPart ) ;
990
991 wxMacWindowEventHandler( NULL , evRef , this ) ;
992 ReleaseEvent(evRef) ;
993 }
994 #endif
995 }
996 }
997
998
999 void wxWindowMac::DoCaptureMouse()
1000 {
1001 wxTheApp->s_captureWindow = this ;
1002 }
1003
1004 wxWindow* wxWindowBase::GetCapture()
1005 {
1006 return wxTheApp->s_captureWindow ;
1007 }
1008
1009 void wxWindowMac::DoReleaseMouse()
1010 {
1011 wxTheApp->s_captureWindow = NULL ;
1012 }
1013
1014 #if wxUSE_DRAG_AND_DROP
1015
1016 void wxWindowMac::SetDropTarget(wxDropTarget *pDropTarget)
1017 {
1018 if ( m_dropTarget != 0 ) {
1019 delete m_dropTarget;
1020 }
1021
1022 m_dropTarget = pDropTarget;
1023 if ( m_dropTarget != 0 )
1024 {
1025 // TODO
1026 }
1027 }
1028
1029 #endif
1030
1031 // Old style file-manager drag&drop
1032 void wxWindowMac::DragAcceptFiles(bool accept)
1033 {
1034 // TODO
1035 }
1036
1037 void wxWindowMac::MacGetPositionAndSizeFromControl(int& x, int& y,
1038 int& w, int& h) const
1039 {
1040 Rect bounds ;
1041 GetControlBounds( *m_peer , &bounds ) ;
1042
1043
1044 x = bounds.left ;
1045 y = bounds.top ;
1046 w = bounds.right - bounds.left ;
1047 h = bounds.bottom - bounds.top ;
1048
1049 wxTopLevelWindow* tlw = wxDynamicCast( this , wxTopLevelWindow ) ;
1050 if ( tlw )
1051 {
1052 Point tlworigin = { 0 , 0 } ;
1053 QDLocalToGlobalPoint( UMAGetWindowPort( (WindowRef) tlw->MacGetWindowRef() ) , &tlworigin ) ;
1054 x = tlworigin.h ;
1055 y = tlworigin.v ;
1056 }
1057 }
1058
1059 bool wxWindowMac::MacGetBoundsForControl(const wxPoint& pos,
1060 const wxSize& size,
1061 int& x, int& y,
1062 int& w, int& h , bool adjustOrigin ) const
1063 {
1064 x = (int)pos.x;
1065 y = (int)pos.y;
1066 // todo the default calls may be used as soon as PostCreateControl Is moved here
1067 w = size.x ; // WidthDefault( size.x );
1068 h = size.y ; // HeightDefault( size.y ) ;
1069 #if !TARGET_API_MAC_OSX
1070 GetParent()->MacWindowToRootWindow( &x , &y ) ;
1071 #endif
1072 if ( adjustOrigin )
1073 AdjustForParentClientOrigin( x , y ) ;
1074 return true ;
1075 }
1076
1077 // Get total size
1078 void wxWindowMac::DoGetSize(int *x, int *y) const
1079 {
1080 #if TARGET_API_MAC_OSX
1081 int x1 , y1 , w1 ,h1 ;
1082 MacGetPositionAndSizeFromControl( x1 , y1, w1 ,h1 ) ;
1083 if(x) *x = w1 ;
1084 if(y) *y = h1 ;
1085
1086 #else
1087 Rect bounds ;
1088 GetControlBounds( *m_peer , &bounds ) ;
1089 if(x) *x = bounds.right - bounds.left ;
1090 if(y) *y = bounds.bottom - bounds.top ;
1091 #endif
1092 }
1093
1094 void wxWindowMac::DoGetPosition(int *x, int *y) const
1095 {
1096 #if TARGET_API_MAC_OSX
1097 int x1 , y1 , w1 ,h1 ;
1098 MacGetPositionAndSizeFromControl( x1 , y1, w1 ,h1 ) ;
1099 if ( !IsTopLevel() )
1100 {
1101 wxWindow *parent = GetParent();
1102 if ( parent )
1103 {
1104 wxPoint pt(parent->GetClientAreaOrigin());
1105 x1 -= pt.x ;
1106 y1 -= pt.y ;
1107 }
1108 }
1109 if(x) *x = x1 ;
1110 if(y) *y = y1 ;
1111 #else
1112 Rect bounds ;
1113 GetControlBounds( *m_peer , &bounds ) ;
1114 wxCHECK_RET( GetParent() , wxT("Missing Parent") ) ;
1115
1116 int xx = bounds.left ;
1117 int yy = bounds.top ;
1118
1119 if ( !GetParent()->IsTopLevel() )
1120 {
1121 GetControlBounds( (ControlRef) GetParent()->GetHandle() , &bounds ) ;
1122
1123 xx -= bounds.left ;
1124 yy -= bounds.top ;
1125 }
1126
1127 wxPoint pt(GetParent()->GetClientAreaOrigin());
1128 xx -= pt.x;
1129 yy -= pt.y;
1130
1131 if(x) *x = xx;
1132 if(y) *y = yy;
1133 #endif
1134 }
1135
1136 void wxWindowMac::DoScreenToClient(int *x, int *y) const
1137 {
1138 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
1139
1140 wxCHECK_RET( window , wxT("TopLevel Window Missing") ) ;
1141
1142 {
1143 Point localwhere = {0,0} ;
1144
1145 if(x) localwhere.h = * x ;
1146 if(y) localwhere.v = * y ;
1147
1148 QDGlobalToLocalPoint( GetWindowPort( window ) , &localwhere ) ;
1149 if(x) *x = localwhere.h ;
1150 if(y) *y = localwhere.v ;
1151
1152 }
1153 MacRootWindowToWindow( x , y ) ;
1154
1155 wxPoint origin = GetClientAreaOrigin() ;
1156 if(x) *x -= origin.x ;
1157 if(y) *y -= origin.y ;
1158 }
1159
1160 void wxWindowMac::DoClientToScreen(int *x, int *y) const
1161 {
1162 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
1163 wxCHECK_RET( window , wxT("TopLevel Window Missing") ) ;
1164
1165 wxPoint origin = GetClientAreaOrigin() ;
1166 if(x) *x += origin.x ;
1167 if(y) *y += origin.y ;
1168
1169 MacWindowToRootWindow( x , y ) ;
1170
1171 {
1172 Point localwhere = { 0,0 };
1173 if(x) localwhere.h = * x ;
1174 if(y) localwhere.v = * y ;
1175 QDLocalToGlobalPoint( GetWindowPort( window ) , &localwhere ) ;
1176 if(x) *x = localwhere.h ;
1177 if(y) *y = localwhere.v ;
1178 }
1179 }
1180
1181 void wxWindowMac::MacClientToRootWindow( int *x , int *y ) const
1182 {
1183 wxPoint origin = GetClientAreaOrigin() ;
1184 if(x) *x += origin.x ;
1185 if(y) *y += origin.y ;
1186
1187 MacWindowToRootWindow( x , y ) ;
1188 }
1189
1190 void wxWindowMac::MacRootWindowToClient( int *x , int *y ) const
1191 {
1192 MacRootWindowToWindow( x , y ) ;
1193
1194 wxPoint origin = GetClientAreaOrigin() ;
1195 if(x) *x -= origin.x ;
1196 if(y) *y -= origin.y ;
1197 }
1198
1199 void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const
1200 {
1201 #if TARGET_API_MAC_OSX
1202 HIPoint pt ;
1203 if ( x ) pt.x = *x ;
1204 if ( y ) pt.y = *y ;
1205
1206 if ( !IsTopLevel() )
1207 {
1208 wxTopLevelWindowMac* top = MacGetTopLevelWindow();
1209 if (top)
1210 HIViewConvertPoint( &pt , *m_peer , (ControlRef) top->GetHandle() ) ;
1211 }
1212
1213 if ( x ) *x = (int) pt.x ;
1214 if ( y ) *y = (int) pt.y ;
1215 #else
1216 if ( !IsTopLevel() )
1217 {
1218 Rect bounds ;
1219 GetControlBounds( *m_peer , &bounds ) ;
1220 if(x) *x += bounds.left ;
1221 if(y) *y += bounds.top ;
1222 }
1223 #endif
1224 }
1225
1226 void wxWindowMac::MacWindowToRootWindow( short *x , short *y ) const
1227 {
1228 int x1 , y1 ;
1229 if ( x ) x1 = *x ;
1230 if ( y ) y1 = *y ;
1231 MacWindowToRootWindow( &x1 , &y1 ) ;
1232 if ( x ) *x = x1 ;
1233 if ( y ) *y = y1 ;
1234 }
1235
1236 void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const
1237 {
1238 #if TARGET_API_MAC_OSX
1239 HIPoint pt ;
1240 if ( x ) pt.x = *x ;
1241 if ( y ) pt.y = *y ;
1242
1243 if ( !IsTopLevel() )
1244 HIViewConvertPoint( &pt , (ControlRef) MacGetTopLevelWindow()->GetHandle() , *m_peer ) ;
1245
1246 if ( x ) *x = (int) pt.x ;
1247 if ( y ) *y = (int) pt.y ;
1248 #else
1249 if ( !IsTopLevel() )
1250 {
1251 Rect bounds ;
1252 GetControlBounds( *m_peer , &bounds ) ;
1253 if(x) *x -= bounds.left ;
1254 if(y) *y -= bounds.top ;
1255 }
1256 #endif
1257 }
1258
1259 void wxWindowMac::MacRootWindowToWindow( short *x , short *y ) const
1260 {
1261 int x1 , y1 ;
1262 if ( x ) x1 = *x ;
1263 if ( y ) y1 = *y ;
1264 MacRootWindowToWindow( &x1 , &y1 ) ;
1265 if ( x ) *x = x1 ;
1266 if ( y ) *y = y1 ;
1267 }
1268
1269 void wxWindowMac::MacGetContentAreaInset( int &left , int &top , int &right , int &bottom )
1270 {
1271 RgnHandle rgn = NewRgn() ;
1272 Rect content ;
1273 if ( GetControlRegion( *m_peer , kControlContentMetaPart , rgn ) == noErr )
1274 {
1275 GetRegionBounds( rgn , &content ) ;
1276 DisposeRgn( rgn ) ;
1277 }
1278 else
1279 {
1280 GetControlBounds( *m_peer , &content ) ;
1281 }
1282 Rect structure ;
1283 GetControlBounds( *m_peer , &structure ) ;
1284 #if !TARGET_API_MAC_OSX
1285 OffsetRect( &content , -structure.left , -structure.top ) ;
1286 #endif
1287 left = content.left - structure.left ;
1288 top = content.top - structure.top ;
1289 right = structure.right - content.right ;
1290 bottom = structure.bottom - content.bottom ;
1291 }
1292
1293 wxSize wxWindowMac::DoGetSizeFromClientSize( const wxSize & size ) const
1294 {
1295 wxSize sizeTotal = size;
1296
1297 RgnHandle rgn = NewRgn() ;
1298
1299 Rect content ;
1300
1301 if ( GetControlRegion( *m_peer , kControlContentMetaPart , rgn ) == noErr )
1302 {
1303 GetRegionBounds( rgn , &content ) ;
1304 DisposeRgn( rgn ) ;
1305 }
1306 else
1307 {
1308 GetControlBounds( *m_peer , &content ) ;
1309 }
1310 Rect structure ;
1311 GetControlBounds( *m_peer , &structure ) ;
1312 #if !TARGET_API_MAC_OSX
1313 OffsetRect( &content , -structure.left , -structure.top ) ;
1314 #endif
1315
1316 sizeTotal.x += (structure.right - structure.left) - (content.right - content.left) ;
1317 sizeTotal.y += (structure.bottom - structure.top) - (content.bottom - content.top ) ;
1318
1319 sizeTotal.x += MacGetLeftBorderSize( ) + MacGetRightBorderSize( ) ;
1320 sizeTotal.y += MacGetTopBorderSize( ) + MacGetBottomBorderSize( ) ;
1321
1322 return sizeTotal;
1323 }
1324
1325
1326 // Get size *available for subwindows* i.e. excluding menu bar etc.
1327 void wxWindowMac::DoGetClientSize(int *x, int *y) const
1328 {
1329 int ww, hh;
1330
1331 RgnHandle rgn = NewRgn() ;
1332 Rect content ;
1333 if ( GetControlRegion( *m_peer , kControlContentMetaPart , rgn ) == noErr )
1334 {
1335 GetRegionBounds( rgn , &content ) ;
1336 DisposeRgn( rgn ) ;
1337 }
1338 else
1339 {
1340 GetControlBounds( *m_peer , &content ) ;
1341 }
1342 #if !TARGET_API_MAC_OSX
1343 Rect structure ;
1344 GetControlBounds( *m_peer , &structure ) ;
1345 OffsetRect( &content , -structure.left , -structure.top ) ;
1346 #endif
1347 ww = content.right - content.left ;
1348 hh = content.bottom - content.top ;
1349
1350 ww -= MacGetLeftBorderSize( ) + MacGetRightBorderSize( ) ;
1351 hh -= MacGetTopBorderSize( ) + MacGetBottomBorderSize( );
1352
1353 if ( (m_vScrollBar && m_vScrollBar->IsShown()) || (m_hScrollBar && m_hScrollBar->IsShown()) )
1354 {
1355 int x1 = 0 ;
1356 int y1 = 0 ;
1357 int w ;
1358 int h ;
1359 GetSize( &w , &h ) ;
1360
1361 MacClientToRootWindow( &x1 , &y1 ) ;
1362 MacClientToRootWindow( &w , &h ) ;
1363
1364 wxWindowMac *iter = (wxWindowMac*)this ;
1365
1366 int totW = 10000 , totH = 10000;
1367 while( iter )
1368 {
1369 if ( iter->IsTopLevel() )
1370 {
1371 iter->GetSize( &totW , &totH ) ;
1372 break ;
1373 }
1374
1375 iter = iter->GetParent() ;
1376 }
1377
1378 if (m_hScrollBar && m_hScrollBar->IsShown() )
1379 {
1380 hh -= MAC_SCROLLBAR_SIZE;
1381 if ( h-y1 >= totH )
1382 {
1383 hh += 1 ;
1384 }
1385 }
1386 if (m_vScrollBar && m_vScrollBar->IsShown() )
1387 {
1388 ww -= MAC_SCROLLBAR_SIZE;
1389 if ( w-x1 >= totW )
1390 {
1391 ww += 1 ;
1392 }
1393 }
1394 }
1395 if(x) *x = ww;
1396 if(y) *y = hh;
1397
1398 }
1399
1400 bool wxWindowMac::SetCursor(const wxCursor& cursor)
1401 {
1402 if (m_cursor == cursor)
1403 return FALSE;
1404
1405 if (wxNullCursor == cursor)
1406 {
1407 if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ) )
1408 return FALSE ;
1409 }
1410 else
1411 {
1412 if ( ! wxWindowBase::SetCursor( cursor ) )
1413 return FALSE ;
1414 }
1415
1416 wxASSERT_MSG( m_cursor.Ok(),
1417 wxT("cursor must be valid after call to the base version"));
1418
1419 /*
1420
1421 TODO why do we have to use current coordinates ?
1422
1423 Point pt ;
1424 wxWindowMac *mouseWin ;
1425 GetMouse( &pt ) ;
1426
1427 // Change the cursor NOW if we're within the correct window
1428
1429
1430 if ( MacGetWindowFromPoint( wxPoint( pt.h , pt.v ) , &mouseWin ) )
1431 {
1432 if ( mouseWin == this && !wxIsBusy() )
1433 {
1434 m_cursor.MacInstall() ;
1435 }
1436 }
1437 */
1438 if ( !wxIsBusy() )
1439 {
1440 m_cursor.MacInstall() ;
1441 }
1442
1443 return TRUE ;
1444 }
1445
1446 #if wxUSE_MENUS
1447 bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y)
1448 {
1449 menu->SetInvokingWindow(this);
1450 menu->UpdateUI();
1451
1452 if ( x == -1 && y == -1 )
1453 {
1454 wxPoint mouse = wxGetMousePosition();
1455 x = mouse.x; y = mouse.y;
1456 }
1457 else
1458 {
1459 ClientToScreen( &x , &y ) ;
1460 }
1461
1462 menu->MacBeforeDisplay( true ) ;
1463 long menuResult = ::PopUpMenuSelect((MenuHandle) menu->GetHMenu() ,y,x, 0) ;
1464 if ( HiWord(menuResult) != 0 )
1465 {
1466 MenuCommand id ;
1467 GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult)) , LoWord(menuResult) , &id ) ;
1468 wxMenuItem* item = NULL ;
1469 wxMenu* realmenu ;
1470 item = menu->FindItem(id, &realmenu) ;
1471 if (item->IsCheckable())
1472 {
1473 item->Check( !item->IsChecked() ) ;
1474 }
1475 menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ;
1476 }
1477 menu->MacAfterDisplay( true ) ;
1478
1479 menu->SetInvokingWindow(NULL);
1480
1481 return TRUE;
1482 }
1483 #endif
1484
1485 // ----------------------------------------------------------------------------
1486 // tooltips
1487 // ----------------------------------------------------------------------------
1488
1489 #if wxUSE_TOOLTIPS
1490
1491 void wxWindowMac::DoSetToolTip(wxToolTip *tooltip)
1492 {
1493 wxWindowBase::DoSetToolTip(tooltip);
1494
1495 if ( m_tooltip )
1496 m_tooltip->SetWindow(this);
1497 }
1498
1499 #endif // wxUSE_TOOLTIPS
1500
1501 void wxWindowMac::DoMoveWindow(int x, int y, int width, int height)
1502 {
1503 int former_x , former_y , former_w, former_h ;
1504 #if !TARGET_API_MAC_OSX
1505 DoGetPosition( &former_x , &former_y ) ;
1506 DoGetSize( &former_w , &former_h ) ;
1507 #else
1508 MacGetPositionAndSizeFromControl( former_x , former_y , former_w , former_h ) ;
1509 #endif
1510
1511 int actualWidth = width;
1512 int actualHeight = height;
1513 int actualX = x;
1514 int actualY = y;
1515
1516 if ((m_minWidth != -1) && (actualWidth < m_minWidth))
1517 actualWidth = m_minWidth;
1518 if ((m_minHeight != -1) && (actualHeight < m_minHeight))
1519 actualHeight = m_minHeight;
1520 if ((m_maxWidth != -1) && (actualWidth > m_maxWidth))
1521 actualWidth = m_maxWidth;
1522 if ((m_maxHeight != -1) && (actualHeight > m_maxHeight))
1523 actualHeight = m_maxHeight;
1524
1525 bool doMove = false ;
1526 bool doResize = false ;
1527
1528 if ( actualX != former_x || actualY != former_y )
1529 {
1530 doMove = true ;
1531 }
1532 if ( actualWidth != former_w || actualHeight != former_h )
1533 {
1534 doResize = true ;
1535 }
1536
1537 if ( doMove || doResize )
1538 {
1539 // we don't adjust twice for the origin
1540 Rect r = wxMacGetBoundsForControl(this , wxPoint( actualX,actualY), wxSize( actualWidth, actualHeight ) , false ) ;
1541 bool vis = IsControlVisible( *m_peer ) ;
1542 #if TARGET_API_MAC_OSX
1543 // the HIViewSetFrame call itself should invalidate the areas, but when testing with the UnicodeTextCtrl it does not !
1544 if ( vis )
1545 SetControlVisibility( *m_peer , false , true ) ;
1546 HIRect hir = { r.left , r.top , r.right - r.left , r.bottom - r.top } ;
1547 HIViewSetFrame ( *m_peer , &hir ) ;
1548 if ( vis )
1549 SetControlVisibility( *m_peer , true , true ) ;
1550 #else
1551 if ( vis )
1552 SetControlVisibility( *m_peer , false , true ) ;
1553 SetControlBounds( *m_peer , &r ) ;
1554 if ( vis )
1555 SetControlVisibility( *m_peer , true , true ) ;
1556 #endif
1557 MacRepositionScrollBars() ;
1558 if ( doMove )
1559 {
1560 wxPoint point(actualX,actualY);
1561 wxMoveEvent event(point, m_windowId);
1562 event.SetEventObject(this);
1563 GetEventHandler()->ProcessEvent(event) ;
1564 }
1565 if ( doResize )
1566 {
1567 MacRepositionScrollBars() ;
1568 wxSize size(actualWidth, actualHeight);
1569 wxSizeEvent event(size, m_windowId);
1570 event.SetEventObject(this);
1571 GetEventHandler()->ProcessEvent(event);
1572 }
1573 }
1574
1575 }
1576
1577 wxSize wxWindowMac::DoGetBestSize() const
1578 {
1579 if ( m_macIsUserPane || IsTopLevel() )
1580 return wxWindowBase::DoGetBestSize() ;
1581
1582 Rect bestsize = { 0 , 0 , 0 , 0 } ;
1583 short baselineoffset ;
1584 int bestWidth, bestHeight ;
1585 ::GetBestControlRect( *m_peer , &bestsize , &baselineoffset ) ;
1586
1587 if ( EmptyRect( &bestsize ) )
1588 {
1589 baselineoffset = 0;
1590 bestsize.left = bestsize.top = 0 ;
1591 bestsize.right = 16 ;
1592 bestsize.bottom = 16 ;
1593 if ( IsKindOf( CLASSINFO( wxScrollBar ) ) )
1594 {
1595 bestsize.bottom = 16 ;
1596 }
1597 else if ( IsKindOf( CLASSINFO( wxSpinButton ) ) )
1598 {
1599 bestsize.bottom = 24 ;
1600 }
1601 else
1602 {
1603 // return wxWindowBase::DoGetBestSize() ;
1604 }
1605 }
1606
1607 bestWidth = bestsize.right - bestsize.left ;
1608 bestHeight = bestsize.bottom - bestsize.top ;
1609 if ( bestHeight < 10 )
1610 bestHeight = 13 ;
1611
1612 return wxSize(bestWidth, bestHeight);
1613 // return wxWindowBase::DoGetBestSize() ;
1614 }
1615
1616
1617 // set the size of the window: if the dimensions are positive, just use them,
1618 // but if any of them is equal to -1, it means that we must find the value for
1619 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
1620 // which case -1 is a valid value for x and y)
1621 //
1622 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
1623 // the width/height to best suit our contents, otherwise we reuse the current
1624 // width/height
1625 void wxWindowMac::DoSetSize(int x, int y, int width, int height, int sizeFlags)
1626 {
1627 // get the current size and position...
1628 int currentX, currentY;
1629 GetPosition(&currentX, &currentY);
1630
1631 int currentW,currentH;
1632 GetSize(&currentW, &currentH);
1633
1634 // ... and don't do anything (avoiding flicker) if it's already ok
1635 if ( x == currentX && y == currentY &&
1636 width == currentW && height == currentH && ( height != -1 && width != -1 ) )
1637 {
1638 // TODO REMOVE
1639 MacRepositionScrollBars() ; // we might have a real position shift
1640 return;
1641 }
1642
1643 if ( x == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
1644 x = currentX;
1645 if ( y == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
1646 y = currentY;
1647
1648 AdjustForParentClientOrigin(x, y, sizeFlags);
1649
1650 wxSize size(-1, -1);
1651 if ( width == -1 )
1652 {
1653 if ( sizeFlags & wxSIZE_AUTO_WIDTH )
1654 {
1655 size = DoGetBestSize();
1656 width = size.x;
1657 }
1658 else
1659 {
1660 // just take the current one
1661 width = currentW;
1662 }
1663 }
1664
1665 if ( height == -1 )
1666 {
1667 if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
1668 {
1669 if ( size.x == -1 )
1670 {
1671 size = DoGetBestSize();
1672 }
1673 //else: already called DoGetBestSize() above
1674
1675 height = size.y;
1676 }
1677 else
1678 {
1679 // just take the current one
1680 height = currentH;
1681 }
1682 }
1683
1684 DoMoveWindow(x, y, width, height);
1685
1686 }
1687
1688 wxPoint wxWindowMac::GetClientAreaOrigin() const
1689 {
1690 RgnHandle rgn = NewRgn() ;
1691 Rect content ;
1692 GetControlRegion( *m_peer , kControlContentMetaPart , rgn ) ;
1693 GetRegionBounds( rgn , &content ) ;
1694 DisposeRgn( rgn ) ;
1695 #if !TARGET_API_MAC_OSX
1696 // if the content rgn is empty / not supported
1697 // don't attempt to correct the coordinates to wxWindow relative ones
1698 if (!::EmptyRect( &content ) )
1699 {
1700 Rect structure ;
1701 GetControlBounds( *m_peer , &structure ) ;
1702 OffsetRect( &content , -structure.left , -structure.top ) ;
1703 }
1704 #endif
1705
1706 return wxPoint( content.left + MacGetLeftBorderSize( ) , content.top + MacGetTopBorderSize( ) );
1707 }
1708
1709 void wxWindowMac::DoSetClientSize(int clientwidth, int clientheight)
1710 {
1711 if ( clientheight != -1 || clientheight != -1 )
1712 {
1713 int currentclientwidth , currentclientheight ;
1714 int currentwidth , currentheight ;
1715
1716 GetClientSize( &currentclientwidth , &currentclientheight ) ;
1717 GetSize( &currentwidth , &currentheight ) ;
1718
1719 DoSetSize( -1 , -1 , currentwidth + clientwidth - currentclientwidth ,
1720 currentheight + clientheight - currentclientheight , wxSIZE_USE_EXISTING ) ;
1721 }
1722 }
1723
1724 void wxWindowMac::SetTitle(const wxString& title)
1725 {
1726 m_label = wxStripMenuCodes(title) ;
1727
1728 if ( m_peer && m_peer->Ok() )
1729 {
1730 UMASetControlTitle( *m_peer , m_label , m_font.GetEncoding() ) ;
1731 }
1732 Refresh() ;
1733 }
1734
1735 wxString wxWindowMac::GetTitle() const
1736 {
1737 return m_label ;
1738 }
1739
1740 bool wxWindowMac::Show(bool show)
1741 {
1742 if ( !wxWindowBase::Show(show) )
1743 return FALSE;
1744
1745 // TODO use visibilityChanged Carbon Event for OSX
1746 bool former = MacIsReallyShown() ;
1747
1748 SetControlVisibility( *m_peer , show , true ) ;
1749 if ( former != MacIsReallyShown() )
1750 MacPropagateVisibilityChanged() ;
1751 return TRUE;
1752 }
1753
1754 bool wxWindowMac::Enable(bool enable)
1755 {
1756 wxASSERT( m_peer->Ok() ) ;
1757 if ( !wxWindowBase::Enable(enable) )
1758 return FALSE;
1759
1760 bool former = MacIsReallyEnabled() ;
1761 #if TARGET_API_MAC_OSX
1762 if ( enable )
1763 EnableControl( *m_peer ) ;
1764 else
1765 DisableControl( *m_peer ) ;
1766 #else
1767 if ( enable )
1768 ActivateControl( *m_peer ) ;
1769 else
1770 DeactivateControl( *m_peer ) ;
1771 #endif
1772
1773 if ( former != MacIsReallyEnabled() )
1774 MacPropagateEnabledStateChanged() ;
1775 return TRUE;
1776 }
1777
1778 //
1779 // status change propagations (will be not necessary for OSX later )
1780 //
1781
1782 void wxWindowMac::MacPropagateVisibilityChanged()
1783 {
1784 #if !TARGET_API_MAC_OSX
1785 MacVisibilityChanged() ;
1786
1787 wxWindowListNode *node = GetChildren().GetFirst();
1788 while ( node )
1789 {
1790 wxWindowMac *child = node->GetData();
1791 if ( child->IsShown() )
1792 child->MacPropagateVisibilityChanged( ) ;
1793 node = node->GetNext();
1794 }
1795 #endif
1796 }
1797
1798 void wxWindowMac::MacPropagateEnabledStateChanged( )
1799 {
1800 #if !TARGET_API_MAC_OSX
1801 MacEnabledStateChanged() ;
1802
1803 wxWindowListNode *node = GetChildren().GetFirst();
1804 while ( node )
1805 {
1806 wxWindowMac *child = node->GetData();
1807 if ( child->IsEnabled() )
1808 child->MacPropagateEnabledStateChanged() ;
1809 node = node->GetNext();
1810 }
1811 #endif
1812 }
1813
1814 void wxWindowMac::MacPropagateHiliteChanged( )
1815 {
1816 #if !TARGET_API_MAC_OSX
1817 MacHiliteChanged() ;
1818
1819 wxWindowListNode *node = GetChildren().GetFirst();
1820 while ( node )
1821 {
1822 wxWindowMac *child = node->GetData();
1823 // if ( child->IsEnabled() )
1824 child->MacPropagateHiliteChanged() ;
1825 node = node->GetNext();
1826 }
1827 #endif
1828 }
1829
1830 //
1831 // status change notifications
1832 //
1833
1834 void wxWindowMac::MacVisibilityChanged()
1835 {
1836 }
1837
1838 void wxWindowMac::MacHiliteChanged()
1839 {
1840 }
1841
1842 void wxWindowMac::MacEnabledStateChanged()
1843 {
1844 }
1845
1846 //
1847 // status queries on the inherited window's state
1848 //
1849
1850 bool wxWindowMac::MacIsReallyShown()
1851 {
1852 // only under OSX the visibility of the TLW is taken into account
1853 #if TARGET_API_MAC_OSX
1854 return IsControlVisible( *m_peer ) ;
1855 #else
1856 wxWindow* win = this ;
1857 while( win->IsShown() )
1858 {
1859 if ( win->IsTopLevel() )
1860 return true ;
1861
1862 win = win->GetParent() ;
1863 if ( win == NULL )
1864 return true ;
1865
1866 } ;
1867 return false ;
1868 #endif
1869 }
1870
1871 bool wxWindowMac::MacIsReallyEnabled()
1872 {
1873 #if TARGET_API_MAC_OSX
1874 return IsControlEnabled( *m_peer ) ;
1875 #else
1876 return IsControlActive( *m_peer ) ;
1877 #endif
1878 }
1879
1880 bool wxWindowMac::MacIsReallyHilited()
1881 {
1882 return IsControlActive( *m_peer ) ;
1883 }
1884
1885 void wxWindowMac::MacFlashInvalidAreas()
1886 {
1887 #if TARGET_API_MAC_OSX
1888 HIViewFlashDirtyArea( (WindowRef) MacGetTopLevelWindowRef() ) ;
1889 #endif
1890 }
1891
1892 //
1893 //
1894 //
1895
1896 int wxWindowMac::GetCharHeight() const
1897 {
1898 wxClientDC dc ( (wxWindowMac*)this ) ;
1899 return dc.GetCharHeight() ;
1900 }
1901
1902 int wxWindowMac::GetCharWidth() const
1903 {
1904 wxClientDC dc ( (wxWindowMac*)this ) ;
1905 return dc.GetCharWidth() ;
1906 }
1907
1908 void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y,
1909 int *descent, int *externalLeading, const wxFont *theFont ) const
1910 {
1911 const wxFont *fontToUse = theFont;
1912 if ( !fontToUse )
1913 fontToUse = &m_font;
1914
1915 wxClientDC dc( (wxWindowMac*) this ) ;
1916 long lx,ly,ld,le ;
1917 dc.GetTextExtent( string , &lx , &ly , &ld, &le, (wxFont *)fontToUse ) ;
1918 if ( externalLeading )
1919 *externalLeading = le ;
1920 if ( descent )
1921 *descent = ld ;
1922 if ( x )
1923 *x = lx ;
1924 if ( y )
1925 *y = ly ;
1926 }
1927
1928 /*
1929 * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect
1930 * we always intersect with the entire window, not only with the client area
1931 */
1932
1933 void wxWindowMac::Refresh(bool eraseBack, const wxRect *rect)
1934 {
1935 #if TARGET_API_MAC_OSX
1936 if ( rect == NULL )
1937 HIViewSetNeedsDisplay( *m_peer , true ) ;
1938 else
1939 {
1940 RgnHandle update = NewRgn() ;
1941 SetRectRgn( update , rect->x , rect->y , rect->x + rect->width , rect->y + rect->height ) ;
1942 SectRgn( (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , update , update ) ;
1943 wxPoint origin = GetClientAreaOrigin() ;
1944 OffsetRgn( update, origin.x , origin.y ) ;
1945 HIViewSetNeedsDisplayInRegion( *m_peer , update , true ) ;
1946 }
1947 #else
1948 /*
1949 RgnHandle updateRgn = NewRgn() ;
1950 if ( rect == NULL )
1951 {
1952 CopyRgn( (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , updateRgn ) ;
1953 }
1954 else
1955 {
1956 SetRectRgn( updateRgn , rect->x , rect->y , rect->x + rect->width , rect->y + rect->height ) ;
1957 SectRgn( (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , updateRgn , updateRgn ) ;
1958 }
1959 InvalWindowRgn( (WindowRef) MacGetTopLevelWindowRef() , updateRgn ) ;
1960 DisposeRgn(updateRgn) ;
1961 */
1962 if ( IsControlVisible( *m_peer ) )
1963 {
1964 SetControlVisibility( *m_peer , false , false ) ;
1965 SetControlVisibility( *m_peer , true , true ) ;
1966 }
1967 /*
1968 if ( MacGetTopLevelWindow() == NULL )
1969 return ;
1970
1971 if ( !IsControlVisible( *m_peer ) )
1972 return ;
1973
1974 wxPoint client = GetClientAreaOrigin();
1975 int x1 = -client.x;
1976 int y1 = -client.y;
1977 int x2 = m_width - client.x;
1978 int y2 = m_height - client.y;
1979
1980 if (IsKindOf( CLASSINFO(wxButton)))
1981 {
1982 // buttons have an "aura"
1983 y1 -= 5;
1984 x1 -= 5;
1985 y2 += 5;
1986 x2 += 5;
1987 }
1988
1989 Rect clientrect = { y1, x1, y2, x2 };
1990
1991 if ( rect )
1992 {
1993 Rect r = { rect->y , rect->x , rect->y + rect->height , rect->x + rect->width } ;
1994 SectRect( &clientrect , &r , &clientrect ) ;
1995 }
1996
1997 if ( !EmptyRect( &clientrect ) )
1998 {
1999 int top = 0 , left = 0 ;
2000
2001 MacClientToRootWindow( &left , &top ) ;
2002 OffsetRect( &clientrect , left , top ) ;
2003
2004 MacGetTopLevelWindow()->MacInvalidate( &clientrect , eraseBack ) ;
2005 }
2006 */
2007 #endif
2008 }
2009
2010 void wxWindowMac::Freeze()
2011 {
2012 #if TARGET_API_MAC_OSX
2013 if ( !m_frozenness++ )
2014 {
2015 HIViewSetDrawingEnabled( *m_peer , false ) ;
2016 }
2017 #endif
2018 }
2019
2020 #if TARGET_API_MAC_OSX
2021 static void InvalidateControlAndChildren( HIViewRef control )
2022 {
2023 HIViewSetNeedsDisplay( control , true ) ;
2024 UInt16 childrenCount = 0 ;
2025 OSStatus err = CountSubControls( control , &childrenCount ) ;
2026 if ( err == errControlIsNotEmbedder )
2027 return ;
2028 wxASSERT_MSG( err == noErr , wxT("Unexpected error when accessing subcontrols") ) ;
2029
2030 for ( UInt16 i = childrenCount ; i >=1 ; --i )
2031 {
2032 HIViewRef child ;
2033 err = GetIndexedSubControl( control , i , & child ) ;
2034 if ( err == errControlIsNotEmbedder )
2035 return ;
2036 InvalidateControlAndChildren( child ) ;
2037 }
2038 }
2039 #endif
2040
2041 void wxWindowMac::Thaw()
2042 {
2043 #if TARGET_API_MAC_OSX
2044 wxASSERT_MSG( m_frozenness > 0, _T("Thaw() without matching Freeze()") );
2045
2046 if ( !--m_frozenness )
2047 {
2048 HIViewSetDrawingEnabled( *m_peer , true ) ;
2049 InvalidateControlAndChildren( *m_peer ) ;
2050 // HIViewSetNeedsDisplay( *m_peer , true ) ;
2051 }
2052 #endif
2053 }
2054
2055 void wxWindowMac::MacRedrawControl()
2056 {
2057 /*
2058 if ( *m_peer && MacGetTopLevelWindowRef() && IsControlVisible( *m_peer ) )
2059 {
2060 #if TARGET_API_MAC_CARBON
2061 Update() ;
2062 #else
2063 wxClientDC dc(this) ;
2064 wxMacPortSetter helper(&dc) ;
2065 wxMacWindowClipper clipper(this) ;
2066 wxDC::MacSetupBackgroundForCurrentPort( MacGetBackgroundBrush() ) ;
2067 UMADrawControl( *m_peer ) ;
2068 #endif
2069 }
2070 */
2071 }
2072
2073 /* TODO
2074 void wxWindowMac::OnPaint(wxPaintEvent& event)
2075 {
2076 // why don't we skip that here ?
2077 }
2078 */
2079
2080 wxWindowMac *wxGetActiveWindow()
2081 {
2082 // actually this is a windows-only concept
2083 return NULL;
2084 }
2085
2086 // Coordinates relative to the window
2087 void wxWindowMac::WarpPointer (int x_pos, int y_pos)
2088 {
2089 // We really don't move the mouse programmatically under Mac.
2090 }
2091
2092 void wxWindowMac::OnEraseBackground(wxEraseEvent& event)
2093 {
2094 if ( m_macBackgroundBrush.Ok() == false || m_macBackgroundBrush.GetStyle() == wxTRANSPARENT )
2095 {
2096 event.Skip() ;
2097 }
2098 else
2099 event.GetDC()->Clear() ;
2100 }
2101
2102 void wxWindowMac::OnNcPaint( wxNcPaintEvent& event )
2103 {
2104 wxWindowDC dc(this) ;
2105 wxMacPortSetter helper(&dc) ;
2106
2107 MacPaintBorders( dc.m_macLocalOrigin.x , dc.m_macLocalOrigin.y) ;
2108 }
2109
2110 int wxWindowMac::GetScrollPos(int orient) const
2111 {
2112 if ( orient == wxHORIZONTAL )
2113 {
2114 if ( m_hScrollBar )
2115 return m_hScrollBar->GetThumbPosition() ;
2116 }
2117 else
2118 {
2119 if ( m_vScrollBar )
2120 return m_vScrollBar->GetThumbPosition() ;
2121 }
2122 return 0;
2123 }
2124
2125 // This now returns the whole range, not just the number
2126 // of positions that we can scroll.
2127 int wxWindowMac::GetScrollRange(int orient) const
2128 {
2129 if ( orient == wxHORIZONTAL )
2130 {
2131 if ( m_hScrollBar )
2132 return m_hScrollBar->GetRange() ;
2133 }
2134 else
2135 {
2136 if ( m_vScrollBar )
2137 return m_vScrollBar->GetRange() ;
2138 }
2139 return 0;
2140 }
2141
2142 int wxWindowMac::GetScrollThumb(int orient) const
2143 {
2144 if ( orient == wxHORIZONTAL )
2145 {
2146 if ( m_hScrollBar )
2147 return m_hScrollBar->GetThumbSize() ;
2148 }
2149 else
2150 {
2151 if ( m_vScrollBar )
2152 return m_vScrollBar->GetThumbSize() ;
2153 }
2154 return 0;
2155 }
2156
2157 void wxWindowMac::SetScrollPos(int orient, int pos, bool refresh)
2158 {
2159 if ( orient == wxHORIZONTAL )
2160 {
2161 if ( m_hScrollBar )
2162 m_hScrollBar->SetThumbPosition( pos ) ;
2163 }
2164 else
2165 {
2166 if ( m_vScrollBar )
2167 m_vScrollBar->SetThumbPosition( pos ) ;
2168 }
2169 }
2170
2171 void wxWindowMac::MacPaintBorders( int left , int top )
2172 {
2173 if( IsTopLevel() )
2174 return ;
2175
2176 int major,minor;
2177 wxGetOsVersion( &major, &minor );
2178
2179 RGBColor white = { 0xFFFF, 0xFFFF , 0xFFFF } ;
2180 RGBColor face = { 0xDDDD, 0xDDDD , 0xDDDD } ;
2181
2182 RGBColor darkShadow = { 0x0000, 0x0000 , 0x0000 } ;
2183 RGBColor lightShadow = { 0x4444, 0x4444 , 0x4444 } ;
2184 // OS X has lighter border edges than classic:
2185 if (major >= 10)
2186 {
2187 darkShadow.red = 0x8E8E;
2188 darkShadow.green = 0x8E8E;
2189 darkShadow.blue = 0x8E8E;
2190 lightShadow.red = 0xBDBD;
2191 lightShadow.green = 0xBDBD;
2192 lightShadow.blue = 0xBDBD;
2193 }
2194
2195 PenNormal() ;
2196
2197 int w , h ;
2198 GetSize( &w , &h ) ;
2199 if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) )
2200 {
2201 #if wxMAC_USE_THEME_BORDER
2202 Rect rect = { top , left , m_height + top , m_width + left } ;
2203 SInt32 border = 0 ;
2204 /*
2205 GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
2206 InsetRect( &rect , border , border );
2207 DrawThemeListBoxFrame(&rect,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ;
2208 */
2209
2210 DrawThemePrimaryGroup(&rect ,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ;
2211 #else
2212 bool sunken = HasFlag( wxSUNKEN_BORDER ) ;
2213 RGBForeColor( &face );
2214 MoveTo( left + 0 , top + h - 2 );
2215 LineTo( left + 0 , top + 0 );
2216 LineTo( left + w - 2 , top + 0 );
2217
2218 MoveTo( left + 2 , top + h - 3 );
2219 LineTo( left + w - 3 , top + h - 3 );
2220 LineTo( left + w - 3 , top + 2 );
2221
2222 RGBForeColor( sunken ? &face : &darkShadow );
2223 MoveTo( left + 0 , top + h - 1 );
2224 LineTo( left + w - 1 , top + h - 1 );
2225 LineTo( left + w - 1 , top + 0 );
2226
2227 RGBForeColor( sunken ? &lightShadow : &white );
2228 MoveTo( left + 1 , top + h - 3 );
2229 LineTo( left + 1, top + 1 );
2230 LineTo( left + w - 3 , top + 1 );
2231
2232 RGBForeColor( sunken ? &white : &lightShadow );
2233 MoveTo( left + 1 , top + h - 2 );
2234 LineTo( left + w - 2 , top + h - 2 );
2235 LineTo( left + w - 2 , top + 1 );
2236
2237 RGBForeColor( sunken ? &darkShadow : &face );
2238 MoveTo( left + 2 , top + h - 4 );
2239 LineTo( left + 2 , top + 2 );
2240 LineTo( left + w - 4 , top + 2 );
2241 #endif
2242 }
2243 else if (HasFlag(wxSIMPLE_BORDER))
2244 {
2245 Rect rect = { top , left , h + top , w + left } ;
2246 RGBForeColor( &darkShadow ) ;
2247 FrameRect( &rect ) ;
2248 }
2249 }
2250
2251 void wxWindowMac::RemoveChild( wxWindowBase *child )
2252 {
2253 if ( child == m_hScrollBar )
2254 m_hScrollBar = NULL ;
2255 if ( child == m_vScrollBar )
2256 m_vScrollBar = NULL ;
2257
2258 wxWindowBase::RemoveChild( child ) ;
2259 }
2260
2261 // New function that will replace some of the above.
2262 void wxWindowMac::SetScrollbar(int orient, int pos, int thumbVisible,
2263 int range, bool refresh)
2264 {
2265 if ( orient == wxHORIZONTAL )
2266 {
2267 if ( m_hScrollBar )
2268 {
2269 if ( range == 0 || thumbVisible >= range )
2270 {
2271 if ( m_hScrollBar->IsShown() )
2272 m_hScrollBar->Show(false) ;
2273 }
2274 else
2275 {
2276 if ( !m_hScrollBar->IsShown() )
2277 m_hScrollBar->Show(true) ;
2278 m_hScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ;
2279 }
2280 }
2281 }
2282 else
2283 {
2284 if ( m_vScrollBar )
2285 {
2286 if ( range == 0 || thumbVisible >= range )
2287 {
2288 if ( m_vScrollBar->IsShown() )
2289 m_vScrollBar->Show(false) ;
2290 }
2291 else
2292 {
2293 if ( !m_vScrollBar->IsShown() )
2294 m_vScrollBar->Show(true) ;
2295 m_vScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ;
2296 }
2297 }
2298 }
2299 MacRepositionScrollBars() ;
2300 }
2301
2302 // Does a physical scroll
2303 void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
2304 {
2305 if( dx == 0 && dy ==0 )
2306 return ;
2307
2308
2309 {
2310
2311 int width , height ;
2312 GetClientSize( &width , &height ) ;
2313 #if TARGET_API_MAC_OSX
2314 // note there currently is a bug in OSX which makes inefficient refreshes in case an entire control
2315 // area is scrolled, this does not occur if width and height are 2 pixels less,
2316 // TODO write optimal workaround
2317 HIRect scrollrect = CGRectMake( MacGetLeftBorderSize() , MacGetTopBorderSize() , width , height ) ;
2318 if ( rect )
2319 {
2320 HIRect scrollarea = CGRectMake( rect->x , rect->y , rect->width , rect->height) ;
2321 scrollrect = CGRectIntersection( scrollrect , scrollarea ) ;
2322 }
2323 if ( HIViewGetNeedsDisplay( *m_peer ) )
2324 {
2325 // becuase HIViewScrollRect does not scroll the already invalidated area we have two options
2326 // either immediate redraw or full invalidate
2327 #if 1
2328 // is the better overall solution, as it does not slow down scrolling
2329 HIViewSetNeedsDisplay( *m_peer , true ) ;
2330 #else
2331 // this would be the preferred version for fast drawing controls
2332 if( UMAGetSystemVersion() < 0x1030 )
2333 Update() ;
2334 else
2335 HIViewRender(*m_peer) ;
2336 #endif
2337 }
2338 HIViewScrollRect ( *m_peer , &scrollrect , dx ,dy ) ;
2339 #else
2340
2341 wxPoint pos;
2342 pos.x = pos.y = 0;
2343
2344 Rect scrollrect;
2345 RgnHandle updateRgn = NewRgn() ;
2346
2347 {
2348 wxClientDC dc(this) ;
2349 wxMacPortSetter helper(&dc) ;
2350
2351 GetControlBounds( *m_peer, &scrollrect);
2352 scrollrect.top += MacGetTopBorderSize() ;
2353 scrollrect.left += MacGetLeftBorderSize() ;
2354 scrollrect.bottom = scrollrect.top + height ;
2355 scrollrect.right = scrollrect.left + width ;
2356
2357 if ( rect )
2358 {
2359 Rect r = { dc.YLOG2DEVMAC(rect->y) , dc.XLOG2DEVMAC(rect->x) , dc.YLOG2DEVMAC(rect->y + rect->height) ,
2360 dc.XLOG2DEVMAC(rect->x + rect->width) } ;
2361 SectRect( &scrollrect , &r , &scrollrect ) ;
2362 }
2363 ScrollRect( &scrollrect , dx , dy , updateRgn ) ;
2364 }
2365 // ScrollWindowRect( (WindowRef) MacGetTopLevelWindowRef() , &scrollrect , dx , dy , kScrollWindowInvalidate, updateRgn ) ;
2366 #endif
2367 }
2368
2369 for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext())
2370 {
2371 wxWindowMac *child = node->GetData();
2372 if (child == m_vScrollBar) continue;
2373 if (child == m_hScrollBar) continue;
2374 if (child->IsTopLevel()) continue;
2375
2376 int x,y;
2377 child->GetPosition( &x, &y );
2378 int w,h;
2379 child->GetSize( &w, &h );
2380 if (rect)
2381 {
2382 wxRect rc(x,y,w,h);
2383 if (rect->Intersects(rc))
2384 child->SetSize( x+dx, y+dy, w, h );
2385 }
2386 else
2387 {
2388 child->SetSize( x+dx, y+dy, w, h );
2389 }
2390 }
2391 }
2392
2393 void wxWindowMac::MacOnScroll(wxScrollEvent &event )
2394 {
2395 if ( event.m_eventObject == m_vScrollBar || event.m_eventObject == m_hScrollBar )
2396 {
2397 wxScrollWinEvent wevent;
2398 wevent.SetPosition(event.GetPosition());
2399 wevent.SetOrientation(event.GetOrientation());
2400 wevent.m_eventObject = this;
2401
2402 if (event.m_eventType == wxEVT_SCROLL_TOP)
2403 wevent.m_eventType = wxEVT_SCROLLWIN_TOP;
2404 else if (event.m_eventType == wxEVT_SCROLL_BOTTOM)
2405 wevent.m_eventType = wxEVT_SCROLLWIN_BOTTOM;
2406 else if (event.m_eventType == wxEVT_SCROLL_LINEUP)
2407 wevent.m_eventType = wxEVT_SCROLLWIN_LINEUP;
2408 else if (event.m_eventType == wxEVT_SCROLL_LINEDOWN)
2409 wevent.m_eventType = wxEVT_SCROLLWIN_LINEDOWN;
2410 else if (event.m_eventType == wxEVT_SCROLL_PAGEUP)
2411 wevent.m_eventType = wxEVT_SCROLLWIN_PAGEUP;
2412 else if (event.m_eventType == wxEVT_SCROLL_PAGEDOWN)
2413 wevent.m_eventType = wxEVT_SCROLLWIN_PAGEDOWN;
2414 else if (event.m_eventType == wxEVT_SCROLL_THUMBTRACK)
2415 wevent.m_eventType = wxEVT_SCROLLWIN_THUMBTRACK;
2416 else if (event.m_eventType == wxEVT_SCROLL_THUMBRELEASE)
2417 wevent.m_eventType = wxEVT_SCROLLWIN_THUMBRELEASE;
2418
2419 GetEventHandler()->ProcessEvent(wevent);
2420 }
2421 }
2422
2423 // Get the window with the focus
2424 wxWindowMac *wxWindowBase::FindFocus()
2425 {
2426 ControlRef control ;
2427 GetKeyboardFocus( GetUserFocusWindow() , &control ) ;
2428 return wxFindControlFromMacControl( control ) ;
2429 }
2430
2431 void wxWindowMac::OnSetFocus(wxFocusEvent& event)
2432 {
2433 // panel wants to track the window which was the last to have focus in it,
2434 // so we want to set ourselves as the window which last had focus
2435 //
2436 // notice that it's also important to do it upwards the tree becaus
2437 // otherwise when the top level panel gets focus, it won't set it back to
2438 // us, but to some other sibling
2439
2440 // CS:don't know if this is still needed:
2441 //wxChildFocusEvent eventFocus(this);
2442 //(void)GetEventHandler()->ProcessEvent(eventFocus);
2443
2444 event.Skip();
2445 }
2446
2447 void wxWindowMac::OnInternalIdle()
2448 {
2449 // This calls the UI-update mechanism (querying windows for
2450 // menu/toolbar/control state information)
2451 if (wxUpdateUIEvent::CanUpdate(this))
2452 UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
2453 }
2454
2455 // Raise the window to the top of the Z order
2456 void wxWindowMac::Raise()
2457 {
2458 #if TARGET_API_MAC_OSX
2459 HIViewSetZOrder(*m_peer,kHIViewZOrderAbove, NULL) ;
2460 #endif
2461 }
2462
2463 // Lower the window to the bottom of the Z order
2464 void wxWindowMac::Lower()
2465 {
2466 #if TARGET_API_MAC_OSX
2467 HIViewSetZOrder(*m_peer,kHIViewZOrderBelow, NULL) ;
2468 #endif
2469 }
2470
2471
2472 // static wxWindow *gs_lastWhich = NULL;
2473
2474 bool wxWindowMac::MacSetupCursor( const wxPoint& pt)
2475 {
2476 // first trigger a set cursor event
2477
2478 wxPoint clientorigin = GetClientAreaOrigin() ;
2479 wxSize clientsize = GetClientSize() ;
2480 wxCursor cursor ;
2481 if ( wxRect2DInt( clientorigin.x , clientorigin.y , clientsize.x , clientsize.y ).Contains( wxPoint2DInt( pt ) ) )
2482 {
2483 wxSetCursorEvent event( pt.x , pt.y );
2484
2485 bool processedEvtSetCursor = GetEventHandler()->ProcessEvent(event);
2486 if ( processedEvtSetCursor && event.HasCursor() )
2487 {
2488 cursor = event.GetCursor() ;
2489 }
2490 else
2491 {
2492
2493 // the test for processedEvtSetCursor is here to prevent using m_cursor
2494 // if the user code caught EVT_SET_CURSOR() and returned nothing from
2495 // it - this is a way to say that our cursor shouldn't be used for this
2496 // point
2497 if ( !processedEvtSetCursor && m_cursor.Ok() )
2498 {
2499 cursor = m_cursor ;
2500 }
2501 if ( wxIsBusy() )
2502 {
2503 }
2504 else
2505 {
2506 if ( !GetParent() )
2507 cursor = *wxSTANDARD_CURSOR ;
2508 }
2509 }
2510 if ( cursor.Ok() )
2511 cursor.MacInstall() ;
2512 }
2513 return cursor.Ok() ;
2514 }
2515
2516 wxString wxWindowMac::MacGetToolTipString( wxPoint &pt )
2517 {
2518 if ( m_tooltip )
2519 {
2520 return m_tooltip->GetTip() ;
2521 }
2522 return wxEmptyString ;
2523 }
2524
2525 void wxWindowMac::Update()
2526 {
2527 #if TARGET_API_MAC_OSX
2528 WindowRef window = (WindowRef)MacGetTopLevelWindowRef() ;
2529 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
2530 // for composited windows this also triggers a redraw of all
2531 // invalid views in the window
2532 if( UMAGetSystemVersion() >= 0x1030 )
2533 HIWindowFlush(window) ;
2534 else
2535 #endif
2536 {
2537 // the only way to trigger the redrawing on earlier systems is to call
2538 // ReceiveNextEvent
2539
2540 EventRef currentEvent = (EventRef) wxTheApp->MacGetCurrentEvent() ;
2541 UInt32 currentEventClass = 0 ;
2542 UInt32 currentEventKind = 0 ;
2543 if ( currentEvent != NULL )
2544 {
2545 currentEventClass = ::GetEventClass( currentEvent ) ;
2546 currentEventKind = ::GetEventKind( currentEvent ) ;
2547 }
2548 if ( currentEventClass != kEventClassMenu )
2549 {
2550 // when tracking a menu, strange redraw errors occur if we flush now, so leave..
2551
2552 EventRef theEvent;
2553 OSStatus status = noErr ;
2554 status = ReceiveNextEvent( 0 , NULL , kEventDurationNoWait , false , &theEvent ) ;
2555 }
2556 else
2557 HIViewSetNeedsDisplay( *m_peer , true ) ;
2558 }
2559 #else
2560 ::Draw1Control( *m_peer ) ;
2561 #endif
2562 }
2563
2564 wxTopLevelWindowMac* wxWindowMac::MacGetTopLevelWindow() const
2565 {
2566 wxTopLevelWindowMac* win = NULL ;
2567 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
2568 if ( window )
2569 {
2570 win = wxFindWinFromMacWindow( window ) ;
2571 }
2572 return win ;
2573 }
2574 wxRegion wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures )
2575 {
2576
2577 Rect r ;
2578 RgnHandle visRgn = NewRgn() ;
2579 RgnHandle tempRgn = NewRgn() ;
2580 if ( IsControlVisible( *m_peer ) )
2581 {
2582 GetControlBounds( *m_peer , &r ) ;
2583 if (! MacGetTopLevelWindow()->MacUsesCompositing() )
2584 {
2585 MacRootWindowToWindow( &r.left , & r.top ) ;
2586 MacRootWindowToWindow( &r.right , & r.bottom ) ;
2587 }
2588 else
2589 {
2590 r.right -= r.left ;
2591 r.bottom -= r.top ;
2592 r.left = 0 ;
2593 r.top = 0 ;
2594 }
2595 if ( includeOuterStructures )
2596 InsetRect( &r , -3 , -3 ) ;
2597 RectRgn( visRgn , &r ) ;
2598 if ( !IsTopLevel() )
2599 {
2600 wxWindow* child = this ;
2601 wxWindow* parent = child->GetParent() ;
2602 while( parent )
2603 {
2604 int x , y ;
2605 wxSize size ;
2606 // we have to find a better clipping algorithm here, in order not to clip things
2607 // positioned like status and toolbar
2608 if ( 1 /* parent->IsTopLevel() && child->IsKindOf( CLASSINFO( wxToolBar ) ) */ )
2609 {
2610 size = parent->GetSize() ;
2611 x = y = 0 ;
2612 }
2613 else
2614 {
2615 size = parent->GetClientSize() ;
2616 wxPoint origin = parent->GetClientAreaOrigin() ;
2617 x = origin.x ;
2618 y = origin.y ;
2619 }
2620 parent->MacWindowToRootWindow( &x, &y ) ;
2621 MacRootWindowToWindow( &x , &y ) ;
2622
2623 SetRectRgn( tempRgn ,
2624 x + parent->MacGetLeftBorderSize() , y + parent->MacGetTopBorderSize() ,
2625 x + size.x - parent->MacGetRightBorderSize(),
2626 y + size.y - parent->MacGetBottomBorderSize()) ;
2627
2628 SectRgn( visRgn , tempRgn , visRgn ) ;
2629 if ( parent->IsTopLevel() )
2630 break ;
2631 child = parent ;
2632 parent = child->GetParent() ;
2633 }
2634 }
2635 }
2636
2637 wxRegion vis = visRgn ;
2638 DisposeRgn( visRgn ) ;
2639 DisposeRgn( tempRgn ) ;
2640 return vis ;
2641 }
2642
2643 /*
2644 This function must not change the updatergn !
2645 */
2646 bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time )
2647 {
2648 RgnHandle updatergn = (RgnHandle) updatergnr ;
2649 bool handled = false ;
2650
2651 // calculate a client-origin version of the update rgn and set m_updateRegion to that
2652 {
2653 RgnHandle newupdate = NewRgn() ;
2654 wxSize point = GetClientSize() ;
2655 wxPoint origin = GetClientAreaOrigin() ;
2656 SetRectRgn( newupdate , origin.x , origin.y , origin.x + point.x , origin.y+point.y ) ;
2657 SectRgn( newupdate , updatergn , newupdate ) ;
2658 OffsetRgn( newupdate , -origin.x , -origin.y ) ;
2659 m_updateRegion = newupdate ;
2660 DisposeRgn( newupdate ) ;
2661 }
2662
2663 if ( !EmptyRgn(updatergn) )
2664 {
2665 wxWindowDC dc(this);
2666 if (!EmptyRgn(updatergn))
2667 dc.SetClippingRegion(wxRegion(updatergn));
2668
2669 wxEraseEvent eevent( GetId(), &dc );
2670 eevent.SetEventObject( this );
2671 GetEventHandler()->ProcessEvent( eevent );
2672
2673 if ( !m_updateRegion.Empty() )
2674 {
2675 // paint the window itself
2676 wxPaintEvent event;
2677 event.m_timeStamp = time ;
2678 event.SetEventObject(this);
2679 handled = GetEventHandler()->ProcessEvent(event);
2680
2681 // paint custom borders
2682 wxNcPaintEvent eventNc( GetId() );
2683 eventNc.SetEventObject( this );
2684 GetEventHandler()->ProcessEvent( eventNc );
2685 }
2686 }
2687 return handled ;
2688 }
2689
2690 void wxWindowMac::MacRedraw( WXHRGN updatergnr , long time, bool erase)
2691 {
2692 RgnHandle updatergn = (RgnHandle) updatergnr ;
2693 // updatergn is always already clipped to our boundaries
2694 // if we are in compositing mode then it is in relative to the upper left of the control
2695 // if we are in non-compositing, then it is relatvie to the uppder left of the content area
2696 // of the toplevel window
2697 // it is in window coordinates, not in client coordinates
2698
2699 // ownUpdateRgn is the area that this window has to repaint, it is in window coordinates
2700 RgnHandle ownUpdateRgn = NewRgn() ;
2701 CopyRgn( updatergn , ownUpdateRgn ) ;
2702
2703 if ( MacGetTopLevelWindow()->MacUsesCompositing() == false )
2704 {
2705 Rect bounds;
2706 UMAGetControlBoundsInWindowCoords( *m_peer, &bounds );
2707 RgnHandle controlRgn = NewRgn();
2708 RectRgn( controlRgn, &bounds );
2709 //KO: This sets the ownUpdateRgn to the area of this control that is inside
2710 // the window update region
2711 SectRgn( ownUpdateRgn, controlRgn, ownUpdateRgn );
2712 DisposeRgn( controlRgn );
2713
2714 //KO: convert ownUpdateRgn to local coordinates
2715 OffsetRgn( ownUpdateRgn, -bounds.left, -bounds.top );
2716 }
2717
2718 MacDoRedraw( ownUpdateRgn , time ) ;
2719 DisposeRgn( ownUpdateRgn ) ;
2720
2721 }
2722
2723 WXWindow wxWindowMac::MacGetTopLevelWindowRef() const
2724 {
2725 wxWindowMac *iter = (wxWindowMac*)this ;
2726
2727 while( iter )
2728 {
2729 if ( iter->IsTopLevel() )
2730 return ((wxTopLevelWindow*)iter)->MacGetWindowRef() ;
2731
2732 iter = iter->GetParent() ;
2733 }
2734 wxASSERT_MSG( 1 , wxT("No valid mac root window") ) ;
2735 return NULL ;
2736 }
2737
2738 void wxWindowMac::MacCreateScrollBars( long style )
2739 {
2740 wxASSERT_MSG( m_vScrollBar == NULL && m_hScrollBar == NULL , wxT("attempt to create window twice") ) ;
2741
2742 bool hasBoth = ( style & wxVSCROLL ) && ( style & wxHSCROLL ) ;
2743 int adjust = hasBoth ? MAC_SCROLLBAR_SIZE - 1: 0 ;
2744 int width, height ;
2745 GetClientSize( &width , &height ) ;
2746
2747 wxPoint vPoint(width-MAC_SCROLLBAR_SIZE, 0) ;
2748 wxSize vSize(MAC_SCROLLBAR_SIZE, height - adjust) ;
2749 wxPoint hPoint(0 , height-MAC_SCROLLBAR_SIZE ) ;
2750 wxSize hSize( width - adjust, MAC_SCROLLBAR_SIZE) ;
2751
2752 m_vScrollBar = new wxScrollBar(this, wxWINDOW_VSCROLL, vPoint,
2753 vSize , wxVERTICAL);
2754
2755 if ( style & wxVSCROLL )
2756 {
2757
2758 }
2759 else
2760 {
2761 m_vScrollBar->Show(false) ;
2762 }
2763 m_hScrollBar = new wxScrollBar(this, wxWINDOW_HSCROLL, hPoint,
2764 hSize , wxHORIZONTAL);
2765 if ( style & wxHSCROLL )
2766 {
2767 }
2768 else
2769 {
2770 m_hScrollBar->Show(false) ;
2771 }
2772
2773 // because the create does not take into account the client area origin
2774 MacRepositionScrollBars() ; // we might have a real position shift
2775 }
2776
2777 void wxWindowMac::MacRepositionScrollBars()
2778 {
2779 bool hasBoth = ( m_hScrollBar && m_hScrollBar->IsShown()) && ( m_vScrollBar && m_vScrollBar->IsShown()) ;
2780 int adjust = hasBoth ? MAC_SCROLLBAR_SIZE - 1 : 0 ;
2781
2782 // get real client area
2783
2784 int width ;
2785 int height ;
2786 GetSize( &width , &height ) ;
2787
2788 width -= MacGetLeftBorderSize() + MacGetRightBorderSize();
2789 height -= MacGetTopBorderSize() + MacGetBottomBorderSize();
2790
2791 wxPoint vPoint(width-MAC_SCROLLBAR_SIZE, 0) ;
2792 wxSize vSize(MAC_SCROLLBAR_SIZE, height - adjust) ;
2793 wxPoint hPoint(0 , height-MAC_SCROLLBAR_SIZE ) ;
2794 wxSize hSize( width - adjust, MAC_SCROLLBAR_SIZE) ;
2795
2796 int x = 0 ;
2797 int y = 0 ;
2798 int w ;
2799 int h ;
2800 GetSize( &w , &h ) ;
2801
2802 MacClientToRootWindow( &x , &y ) ;
2803 MacClientToRootWindow( &w , &h ) ;
2804
2805 wxWindowMac *iter = (wxWindowMac*)this ;
2806
2807 int totW = 10000 , totH = 10000;
2808 while( iter )
2809 {
2810 if ( iter->IsTopLevel() )
2811 {
2812 iter->GetSize( &totW , &totH ) ;
2813 break ;
2814 }
2815
2816 iter = iter->GetParent() ;
2817 }
2818
2819 if ( x == 0 )
2820 {
2821 hPoint.x = -1 ;
2822 hSize.x += 1 ;
2823 }
2824 if ( y == 0 )
2825 {
2826 vPoint.y = -1 ;
2827 vSize.y += 1 ;
2828 }
2829
2830 if ( w-x >= totW )
2831 {
2832 hSize.x += 1 ;
2833 vPoint.x += 1 ;
2834 }
2835
2836 if ( h-y >= totH )
2837 {
2838 vSize.y += 1 ;
2839 hPoint.y += 1 ;
2840 }
2841
2842 if ( m_vScrollBar )
2843 {
2844 m_vScrollBar->SetSize( vPoint.x , vPoint.y, vSize.x, vSize.y , wxSIZE_ALLOW_MINUS_ONE);
2845 }
2846 if ( m_hScrollBar )
2847 {
2848 m_hScrollBar->SetSize( hPoint.x , hPoint.y, hSize.x, hSize.y, wxSIZE_ALLOW_MINUS_ONE);
2849 }
2850 }
2851
2852 bool wxWindowMac::AcceptsFocus() const
2853 {
2854 return MacCanFocus() && wxWindowBase::AcceptsFocus();
2855 }
2856
2857 void wxWindowMac::MacSuperChangedPosition()
2858 {
2859 // only window-absolute structures have to be moved i.e. controls
2860
2861 wxWindowListNode *node = GetChildren().GetFirst();
2862 while ( node )
2863 {
2864 wxWindowMac *child = node->GetData();
2865 child->MacSuperChangedPosition() ;
2866 node = node->GetNext();
2867 }
2868 }
2869
2870 void wxWindowMac::MacTopLevelWindowChangedPosition()
2871 {
2872 // only screen-absolute structures have to be moved i.e. glcanvas
2873
2874 wxWindowListNode *node = GetChildren().GetFirst();
2875 while ( node )
2876 {
2877 wxWindowMac *child = node->GetData();
2878 child->MacTopLevelWindowChangedPosition() ;
2879 node = node->GetNext();
2880 }
2881 }
2882
2883 long wxWindowMac::MacGetLeftBorderSize( ) const
2884 {
2885 if( IsTopLevel() )
2886 return 0 ;
2887
2888 if (m_windowStyle & wxRAISED_BORDER || m_windowStyle & wxSUNKEN_BORDER )
2889 {
2890 SInt32 border = 3 ;
2891 #if wxMAC_USE_THEME_BORDER
2892 GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
2893 #endif
2894 return border ;
2895 }
2896 else if ( m_windowStyle &wxDOUBLE_BORDER)
2897 {
2898 SInt32 border = 3 ;
2899 #if wxMAC_USE_THEME_BORDER
2900 GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
2901 #endif
2902 return border ;
2903 }
2904 else if (m_windowStyle &wxSIMPLE_BORDER)
2905 {
2906 return 1 ;
2907 }
2908 return 0 ;
2909 }
2910
2911 long wxWindowMac::MacGetRightBorderSize( ) const
2912 {
2913 // they are all symmetric in mac themes
2914 return MacGetLeftBorderSize() ;
2915 }
2916
2917 long wxWindowMac::MacGetTopBorderSize( ) const
2918 {
2919 // they are all symmetric in mac themes
2920 return MacGetLeftBorderSize() ;
2921 }
2922
2923 long wxWindowMac::MacGetBottomBorderSize( ) const
2924 {
2925 // they are all symmetric in mac themes
2926 return MacGetLeftBorderSize() ;
2927 }
2928
2929 long wxWindowMac::MacRemoveBordersFromStyle( long style )
2930 {
2931 return style & ~( wxDOUBLE_BORDER | wxSUNKEN_BORDER | wxRAISED_BORDER | wxBORDER | wxSTATIC_BORDER ) ;
2932 }
2933
2934 // Find the wxWindowMac at the current mouse position, returning the mouse
2935 // position.
2936 wxWindowMac* wxFindWindowAtPointer(wxPoint& pt)
2937 {
2938 pt = wxGetMousePosition();
2939 wxWindowMac* found = wxFindWindowAtPoint(pt);
2940 return found;
2941 }
2942
2943 // Get the current mouse position.
2944 wxPoint wxGetMousePosition()
2945 {
2946 int x, y;
2947 wxGetMousePosition(& x, & y);
2948 return wxPoint(x, y);
2949 }
2950
2951 void wxWindowMac::OnMouseEvent( wxMouseEvent &event )
2952 {
2953 if ( event.GetEventType() == wxEVT_RIGHT_DOWN )
2954 {
2955 // copied from wxGTK : CS
2956 // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN
2957 // except that:
2958 //
2959 // (a) it's a command event and so is propagated to the parent
2960 // (b) under MSW it can be generated from kbd too
2961 // (c) it uses screen coords (because of (a))
2962 wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU,
2963 this->GetId(),
2964 this->ClientToScreen(event.GetPosition()));
2965 if ( ! GetEventHandler()->ProcessEvent(evtCtx) )
2966 event.Skip() ;
2967 }
2968 else
2969 {
2970 event.Skip() ;
2971 }
2972 }
2973
2974 void wxWindowMac::MacHandleControlClick( WXWidget control , wxInt16 controlpart , bool WXUNUSED( mouseStillDown ) )
2975 {
2976 }
2977
2978 Rect wxMacGetBoundsForControl( wxWindow* window , const wxPoint& pos , const wxSize &size , bool adjustForOrigin )
2979 {
2980 int x ,y , w ,h ;
2981
2982 window->MacGetBoundsForControl( pos , size , x , y, w, h , adjustForOrigin) ;
2983 Rect bounds = { y , x , y+h , x+w };
2984 return bounds ;
2985 }
2986
2987 wxInt32 wxWindowMac::MacControlHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF WXUNUSED(event) )
2988 {
2989 return eventNotHandledErr ;
2990 }
2991
2992