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