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