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