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