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