]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/window.cpp
no real changes, just some cleanup: add wxIsAltDown() in addition to the existing...
[wxWidgets.git] / src / mac / carbon / window.cpp
CommitLineData
e9576ca5 1/////////////////////////////////////////////////////////////////////////////
fb5246be 2// Name: src/mac/carbon/window.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
3d1a4878
SC
12#include "wx/wxprec.h"
13
5fde6fcc 14#include "wx/window.h"
e4db172a
WS
15
16#ifndef WX_PRECOMP
17 #include "wx/log.h"
670f9935 18 #include "wx/app.h"
de6185e2 19 #include "wx/utils.h"
8e609c82 20 #include "wx/panel.h"
76b49cf4 21 #include "wx/frame.h"
da80ae71 22 #include "wx/dc.h"
ed4b0fdc 23 #include "wx/dcclient.h"
f1e01716 24 #include "wx/button.h"
3b3dc801 25 #include "wx/menu.h"
fdf565fe 26 #include "wx/dialog.h"
9eddec69 27 #include "wx/settings.h"
246c5004 28 #include "wx/msgdlg.h"
851dee09 29 #include "wx/scrolbar.h"
876cd6f7 30 #include "wx/statbox.h"
fec9cc08 31 #include "wx/textctrl.h"
4e3e485b 32 #include "wx/toolbar.h"
ed2fbeb8 33 #include "wx/layout.h"
3304646d 34 #include "wx/statusbr.h"
25466131 35 #include "wx/menuitem.h"
ed9a7a63
KO
36 #include "wx/treectrl.h"
37 #include "wx/listctrl.h"
e4db172a
WS
38#endif
39
2f1ae414 40#include "wx/tooltip.h"
4ac219f6 41#include "wx/spinctrl.h"
467e3168 42#include "wx/geometry.h"
e9576ca5 43
c1cef60b
CE
44#if wxUSE_LISTCTRL
45 #include "wx/listctrl.h"
46#endif
47
48#if wxUSE_TREECTRL
49 #include "wx/treectrl.h"
50#endif
51
7c551d95
SC
52#if wxUSE_CARET
53 #include "wx/caret.h"
e15f0a5e 54#endif
7c551d95 55
6239ee05
SC
56#if wxUSE_POPUPWIN
57 #include "wx/popupwin.h"
58#endif
59
b46dde27
DS
60#if wxUSE_DRAG_AND_DROP
61#include "wx/dnd.h"
62#endif
519cb848 63
d497dca4 64#include "wx/mac/uma.h"
898d9035 65
b46dde27
DS
66#define MAC_SCROLLBAR_SIZE 15
67#define MAC_SMALL_SCROLLBAR_SIZE 11
68
66a09d47
SC
69#ifndef __DARWIN__
70#include <Windows.h>
71#include <ToolUtils.h>
1d879215 72#include <MacTextEditor.h>
66a09d47 73#endif
519cb848 74
41218df1 75#if TARGET_API_MAC_OSX
facd6764 76#ifndef __HIVIEW__
8b573fb8 77 #include <HIToolbox/HIView.h>
facd6764 78#endif
41218df1 79#endif
facd6764 80
e9576ca5
SC
81#include <string.h>
82
fc0daf84
SC
83#ifdef __WXUNIVERSAL__
84 IMPLEMENT_ABSTRACT_CLASS(wxWindowMac, wxWindowBase)
898d9035 85#else
fc0daf84 86 IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
898d9035 87#endif
fc0daf84 88
fc0daf84 89BEGIN_EVENT_TABLE(wxWindowMac, wxWindowBase)
facd6764
SC
90 EVT_NC_PAINT(wxWindowMac::OnNcPaint)
91 EVT_ERASE_BACKGROUND(wxWindowMac::OnEraseBackground)
ff3795ee
SC
92#if TARGET_API_MAC_OSX
93 EVT_PAINT(wxWindowMac::OnPaint)
94#endif
5ca0d812
SC
95 EVT_SET_FOCUS(wxWindowMac::OnSetFocus)
96 EVT_KILL_FOCUS(wxWindowMac::OnSetFocus)
facd6764 97 EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent)
e9576ca5
SC
98END_EVENT_TABLE()
99
94abc21f
SC
100#define wxMAC_DEBUG_REDRAW 0
101#ifndef wxMAC_DEBUG_REDRAW
102#define wxMAC_DEBUG_REDRAW 0
103#endif
104
42ef83fa
SC
105// ---------------------------------------------------------------------------
106// Utility Routines to move between different coordinate systems
107// ---------------------------------------------------------------------------
108
109/*
110 * Right now we have the following setup :
111 * a border that is not part of the native control is always outside the
112 * control's border (otherwise we loose all native intelligence, future ways
113 * may be to have a second embedding control responsible for drawing borders
114 * and backgrounds eventually)
115 * so all this border calculations have to be taken into account when calling
116 * native methods or getting native oriented data
117 * so we have three coordinate systems here
118 * wx client coordinates
119 * wx window coordinates (including window frames)
120 * native coordinates
121 */
8b573fb8 122
42ef83fa
SC
123//
124// originating from native control
125//
126
127
128void wxMacNativeToWindow( const wxWindow* window , RgnHandle handle )
129{
8b573fb8 130 OffsetRgn( handle , window->MacGetLeftBorderSize() , window->MacGetTopBorderSize() ) ;
42ef83fa
SC
131}
132
133void wxMacNativeToWindow( const wxWindow* window , Rect *rect )
134{
8b573fb8 135 OffsetRect( rect , window->MacGetLeftBorderSize() , window->MacGetTopBorderSize() ) ;
42ef83fa
SC
136}
137
138//
139// directed towards native control
140//
141
142void wxMacWindowToNative( const wxWindow* window , RgnHandle handle )
143{
8b573fb8 144 OffsetRgn( handle , -window->MacGetLeftBorderSize() , -window->MacGetTopBorderSize() );
42ef83fa
SC
145}
146
147void wxMacWindowToNative( const wxWindow* window , Rect *rect )
148{
8b573fb8 149 OffsetRect( rect , -window->MacGetLeftBorderSize() , -window->MacGetTopBorderSize() ) ;
42ef83fa
SC
150}
151
facd6764
SC
152// ---------------------------------------------------------------------------
153// Carbon Events
154// ---------------------------------------------------------------------------
8b573fb8 155
facd6764
SC
156static const EventTypeSpec eventList[] =
157{
e3aeade0
SC
158 { kEventClassCommand, kEventProcessCommand } ,
159 { kEventClassCommand, kEventCommandUpdateStatus } ,
b46dde27 160
e9a4bf7d 161 { kEventClassControl , kEventControlGetClickActivation } ,
f1d527c1 162 { kEventClassControl , kEventControlHit } ,
898d9035 163
980ee83f
SC
164 { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } ,
165 { kEventClassTextInput, kEventTextInputUpdateActiveInputArea } ,
b46dde27 166
73fe67bd 167 { kEventClassControl , kEventControlDraw } ,
cdef0334 168#if TARGET_API_MAC_OSX
73fe67bd
SC
169 { kEventClassControl , kEventControlVisibilityChanged } ,
170 { kEventClassControl , kEventControlEnabledStateChanged } ,
171 { kEventClassControl , kEventControlHiliteChanged } ,
ed9a7a63
KO
172
173 { kEventClassControl , kEventControlActivate } ,
174 { kEventClassControl , kEventControlDeactivate } ,
cdef0334 175#endif
f1d527c1 176 { kEventClassControl , kEventControlSetFocusPart } ,
8b573fb8
VZ
177
178 { kEventClassService , kEventServiceGetTypes },
179 { kEventClassService , kEventServiceCopy },
180 { kEventClassService , kEventServicePaste },
181
898d9035
DS
182// { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only
183// { kEventClassControl , kEventControlBoundsChanged } ,
facd6764
SC
184} ;
185
186static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
187{
188 OSStatus result = eventNotHandledErr ;
189
190 wxMacCarbonEvent cEvent( event ) ;
8b573fb8 191
facd6764
SC
192 ControlRef controlRef ;
193 wxWindowMac* thisWindow = (wxWindowMac*) data ;
194
195 cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ;
196
898d9035 197 switch ( GetEventKind( event ) )
facd6764 198 {
f1d527c1 199#if TARGET_API_MAC_OSX
facd6764
SC
200 case kEventControlDraw :
201 {
1e8cde71 202 RgnHandle updateRgn = NULL ;
055a486b 203 RgnHandle allocatedRgn = NULL ;
1e8cde71 204 wxRegion visRegion = thisWindow->MacGetVisibleRegion() ;
898d9035 205
76c7012c 206 if ( cEvent.GetParameter<RgnHandle>(kEventParamRgnHandle, &updateRgn) != noErr )
1e8cde71
SC
207 {
208 updateRgn = (RgnHandle) visRegion.GetWXHRGN() ;
209 }
055a486b
SC
210 else
211 {
a9b456ff 212 if ( thisWindow->MacGetLeftBorderSize() != 0 || thisWindow->MacGetTopBorderSize() != 0 )
055a486b 213 {
a9b456ff 214 // as this update region is in native window locals we must adapt it to wx window local
055a486b
SC
215 allocatedRgn = NewRgn() ;
216 CopyRgn( updateRgn , allocatedRgn ) ;
898d9035 217
42ef83fa
SC
218 // hide the given region by the new region that must be shifted
219 wxMacNativeToWindow( thisWindow , allocatedRgn ) ;
902725ee 220 updateRgn = allocatedRgn ;
e6616741 221 }
055a486b 222 }
e15f0a5e 223
e6616741
SC
224 Rect rgnBounds ;
225 GetRegionBounds( updateRgn , &rgnBounds ) ;
898d9035 226
1f1c8bd4 227#if wxMAC_DEBUG_REDRAW
facd6764
SC
228 if ( thisWindow->MacIsUserPane() )
229 {
bcbd6987
SC
230 static float color = 0.5 ;
231 static channel = 0 ;
898d9035
DS
232 HIRect bounds;
233 CGContextRef cgContext = cEvent.GetParameter<CGContextRef>(kEventParamCGContextRef) ;
234
235 HIViewGetBounds( controlRef, &bounds );
8b573fb8
VZ
236 CGContextSetRGBFillColor( cgContext, channel == 0 ? color : 0.5 ,
237 channel == 1 ? color : 0.5 , channel == 2 ? color : 0.5 , 1 );
238 CGContextFillRect( cgContext, bounds );
239 color += 0.1 ;
240 if ( color > 0.9 )
241 {
242 color = 0.5 ;
243 channel++ ;
244 if ( channel == 3 )
245 channel = 0 ;
246 }
facd6764 247 }
20b69855 248#endif
898d9035 249
c79aad8b 250 {
20b69855 251#if wxMAC_USE_CORE_GRAPHICS
e6616741 252 bool created = false ;
8523a5f5 253 CGContextRef cgContext = NULL ;
a9b456ff
SC
254 OSStatus err = cEvent.GetParameter<CGContextRef>(kEventParamCGContextRef, &cgContext) ;
255 wxASSERT_MSG( err == noErr , wxT("Unable to retrieve CGContextRef") ) ;
c79aad8b 256 thisWindow->MacSetCGContextRef( cgContext ) ;
898d9035 257
e6616741
SC
258 {
259 wxMacCGContextStateSaver sg( cgContext ) ;
a9b456ff
SC
260 float alpha = 1.0 ;
261 {
262 wxWindow* iter = thisWindow ;
89954433 263 while ( iter )
a9b456ff
SC
264 {
265 alpha *= (float) iter->GetTransparent()/255.0 ;
266 if ( iter->IsTopLevel() )
267 iter = NULL ;
268 else
269 iter = iter->GetParent() ;
270 }
271 }
272 CGContextSetAlpha( cgContext , alpha ) ;
4488a1d3
VZ
273
274 if ( thisWindow->GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT )
275 {
276 HIRect bounds;
277 HIViewGetBounds( controlRef, &bounds );
278 CGContextClearRect( cgContext, bounds );
279 }
280
281
facd6764 282#endif
e6616741
SC
283 if ( thisWindow->MacDoRedraw( updateRgn , cEvent.GetTicks() ) )
284 result = noErr ;
898d9035 285
20b69855 286#if wxMAC_USE_CORE_GRAPHICS
e6616741
SC
287 thisWindow->MacSetCGContextRef( NULL ) ;
288 }
898d9035 289
e6616741 290 if ( created )
e6616741 291 CGContextRelease( cgContext ) ;
20b69855 292#endif
c79aad8b 293 }
e15f0a5e 294
055a486b
SC
295 if ( allocatedRgn )
296 DisposeRgn( allocatedRgn ) ;
facd6764
SC
297 }
298 break ;
e15f0a5e 299
73fe67bd 300 case kEventControlVisibilityChanged :
e15f0a5e 301 thisWindow->MacVisibilityChanged() ;
73fe67bd 302 break ;
e15f0a5e 303
73fe67bd 304 case kEventControlEnabledStateChanged :
e15f0a5e 305 thisWindow->MacEnabledStateChanged() ;
73fe67bd 306 break ;
e15f0a5e 307
73fe67bd 308 case kEventControlHiliteChanged :
e15f0a5e 309 thisWindow->MacHiliteChanged() ;
73fe67bd 310 break ;
89954433 311
ed9a7a63
KO
312 case kEventControlActivate :
313 case kEventControlDeactivate :
0b8055d2
VZ
314 // FIXME: we should have a virtual function for this!
315#if wxUSE_TREECTRL
316 if ( thisWindow->IsKindOf( CLASSINFO( wxTreeCtrl ) ) )
ed9a7a63 317 thisWindow->Refresh();
6449b3a8 318#endif
0b8055d2
VZ
319#if wxUSE_LISTCTRL
320 if ( thisWindow->IsKindOf( CLASSINFO( wxListCtrl ) ) )
321 thisWindow->Refresh();
322#endif
323 break ;
324#endif // TARGET_API_MAC_OSX
e15f0a5e 325
6449b3a8 326 // we emulate this event under Carbon CFM
f1d527c1
SC
327 case kEventControlSetFocusPart :
328 {
329 Boolean focusEverything = false ;
330 ControlPartCode controlPart = cEvent.GetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode );
898d9035 331
f1d527c1
SC
332 if ( cEvent.GetParameter<Boolean>(kEventParamControlFocusEverything , &focusEverything ) == noErr )
333 {
334 }
e15f0a5e 335
6a74af89
VZ
336 if ( thisWindow->MacIsUserPane() )
337 result = noErr ;
338
f1d527c1
SC
339 if ( controlPart == kControlFocusNoPart )
340 {
e15f0a5e 341#if wxUSE_CARET
f1d527c1 342 if ( thisWindow->GetCaret() )
f1d527c1 343 thisWindow->GetCaret()->OnKillFocus();
e15f0a5e
DS
344#endif
345
92b6cd62 346 static bool inKillFocusEvent = false ;
898d9035 347
92b6cd62
SC
348 if ( !inKillFocusEvent )
349 {
350 inKillFocusEvent = true ;
351 wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId());
352 event.SetEventObject(thisWindow);
353 thisWindow->GetEventHandler()->ProcessEvent(event) ;
354 inKillFocusEvent = false ;
355 }
f1d527c1
SC
356 }
357 else
358 {
359 // panel wants to track the window which was the last to have focus in it
360 wxChildFocusEvent eventFocus(thisWindow);
361 thisWindow->GetEventHandler()->ProcessEvent(eventFocus);
8b573fb8 362
e15f0a5e 363#if wxUSE_CARET
f1d527c1 364 if ( thisWindow->GetCaret() )
f1d527c1 365 thisWindow->GetCaret()->OnSetFocus();
e15f0a5e 366#endif
f1d527c1
SC
367
368 wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId());
369 event.SetEventObject(thisWindow);
370 thisWindow->GetEventHandler()->ProcessEvent(event) ;
371 }
372 }
373 break ;
e15f0a5e 374
f1d527c1 375 case kEventControlHit :
e15f0a5e 376 result = thisWindow->MacControlHit( handler , event ) ;
f1d527c1 377 break ;
e15f0a5e 378
e9a4bf7d
SC
379 case kEventControlGetClickActivation :
380 {
381 // fix to always have a proper activation for DataBrowser controls (stay in bkgnd otherwise)
382 WindowRef owner = cEvent.GetParameter<WindowRef>(kEventParamWindowRef);
383 if ( !IsWindowActive(owner) )
384 {
385 cEvent.SetParameter(kEventParamClickActivation,(UInt32) kActivateAndIgnoreClick) ;
386 result = noErr ;
387 }
388 }
389 break ;
390
facd6764
SC
391 default :
392 break ;
393 }
e15f0a5e 394
facd6764
SC
395 return result ;
396}
397
89954433
VZ
398static pascal OSStatus
399wxMacWindowServiceEventHandler(EventHandlerCallRef WXUNUSED(handler),
400 EventRef event,
401 void *data)
e4727773
SC
402{
403 OSStatus result = eventNotHandledErr ;
404
405 wxMacCarbonEvent cEvent( event ) ;
8b573fb8 406
e4727773
SC
407 ControlRef controlRef ;
408 wxWindowMac* thisWindow = (wxWindowMac*) data ;
409 wxTextCtrl* textCtrl = wxDynamicCast( thisWindow , wxTextCtrl ) ;
410 cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ;
411
e15f0a5e 412 switch ( GetEventKind( event ) )
e4727773
SC
413 {
414 case kEventServiceGetTypes :
e15f0a5e 415 if ( textCtrl )
e4727773
SC
416 {
417 long from, to ;
418 textCtrl->GetSelection( &from , &to ) ;
419
8b573fb8 420 CFMutableArrayRef copyTypes = 0 , pasteTypes = 0;
e15f0a5e 421 if ( from != to )
e4727773
SC
422 copyTypes = cEvent.GetParameter< CFMutableArrayRef >( kEventParamServiceCopyTypes , typeCFMutableArrayRef ) ;
423 if ( textCtrl->IsEditable() )
424 pasteTypes = cEvent.GetParameter< CFMutableArrayRef >( kEventParamServicePasteTypes , typeCFMutableArrayRef ) ;
8b573fb8 425
898d9035 426 static const OSType textDataTypes[] = { kTXNTextData /* , 'utxt', 'PICT', 'MooV', 'AIFF' */ };
e4727773
SC
427 for ( size_t i = 0 ; i < WXSIZEOF(textDataTypes) ; ++i )
428 {
429 CFStringRef typestring = CreateTypeStringWithOSType(textDataTypes[i]);
430 if ( typestring )
431 {
432 if ( copyTypes )
898d9035 433 CFArrayAppendValue(copyTypes, typestring) ;
e4727773 434 if ( pasteTypes )
898d9035 435 CFArrayAppendValue(pasteTypes, typestring) ;
e15f0a5e 436
e4727773
SC
437 CFRelease( typestring ) ;
438 }
439 }
e15f0a5e 440
e4727773
SC
441 result = noErr ;
442 }
443 break ;
e15f0a5e 444
e4727773
SC
445 case kEventServiceCopy :
446 if ( textCtrl )
447 {
448 long from, to ;
e15f0a5e 449
e4727773
SC
450 textCtrl->GetSelection( &from , &to ) ;
451 wxString val = textCtrl->GetValue() ;
452 val = val.Mid( from , to - from ) ;
6239ee05
SC
453 PasteboardRef pasteboard = cEvent.GetParameter<PasteboardRef>( kEventParamPasteboardRef, typePasteboardRef );
454 verify_noerr( PasteboardClear( pasteboard ) ) ;
455 PasteboardSynchronize( pasteboard );
456 // TODO add proper conversion
457 CFDataRef data = CFDataCreate( kCFAllocatorDefault, (const UInt8*)val.c_str(), val.length() );
458 PasteboardPutItemFlavor( pasteboard, (PasteboardItemID) 1, CFSTR("com.apple.traditional-mac-plain-text"), data, 0);
459 CFRelease( data );
e4727773
SC
460 result = noErr ;
461 }
462 break ;
e15f0a5e 463
e4727773
SC
464 case kEventServicePaste :
465 if ( textCtrl )
466 {
6239ee05
SC
467 PasteboardRef pasteboard = cEvent.GetParameter<PasteboardRef>( kEventParamPasteboardRef, typePasteboardRef );
468 PasteboardSynchronize( pasteboard );
469 ItemCount itemCount;
470 verify_noerr( PasteboardGetItemCount( pasteboard, &itemCount ) );
471 for( UInt32 itemIndex = 1; itemIndex <= itemCount; itemIndex++ )
472 {
473 PasteboardItemID itemID;
474 if ( PasteboardGetItemIdentifier( pasteboard, itemIndex, &itemID ) == noErr )
475 {
476 CFDataRef flavorData = NULL;
477 if ( PasteboardCopyItemFlavorData( pasteboard, itemID, CFSTR("com.apple.traditional-mac-plain-text"), &flavorData ) == noErr )
478 {
479 CFIndex flavorDataSize = CFDataGetLength( flavorData );
480 char *content = new char[flavorDataSize+1] ;
481 memcpy( content, CFDataGetBytePtr( flavorData ), flavorDataSize );
482 content[flavorDataSize]=0;
483 CFRelease( flavorData );
8ef4d6e2 484#if wxUSE_UNICODE
6239ee05 485 textCtrl->WriteText( wxString( content , wxConvLocal ) );
8ef4d6e2 486#else
6239ee05 487 textCtrl->WriteText( wxString( content ) ) ;
8ef4d6e2 488#endif
e15f0a5e 489
6239ee05
SC
490 delete[] content ;
491 result = noErr ;
492 }
493 }
494 }
e4727773
SC
495 }
496 break ;
e15f0a5e
DS
497
498 default:
499 break ;
e4727773 500 }
8b573fb8 501
e4727773 502 return result ;
8b573fb8 503}
e4727773 504
980ee83f
SC
505pascal OSStatus wxMacUnicodeTextEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
506{
507 OSStatus result = eventNotHandledErr ;
508 wxWindowMac* focus = (wxWindowMac*) data ;
b46dde27 509
980ee83f
SC
510 wchar_t* uniChars = NULL ;
511 UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ;
b46dde27 512
75b32421 513 UniChar* charBuf = NULL;
4f74e0d1 514 ByteCount dataSize = 0 ;
980ee83f
SC
515 int numChars = 0 ;
516 UniChar buf[2] ;
517 if ( GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText, NULL, 0 , &dataSize, NULL ) == noErr )
518 {
3281bf67 519 numChars = dataSize / sizeof( UniChar) + 1;
980ee83f 520 charBuf = buf ;
b46dde27 521
6d49e4bb 522 if ( (size_t) numChars * 2 > sizeof(buf) )
980ee83f
SC
523 charBuf = new UniChar[ numChars ] ;
524 else
525 charBuf = buf ;
b46dde27 526
980ee83f
SC
527 uniChars = new wchar_t[ numChars ] ;
528 GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText, NULL, dataSize , NULL , charBuf ) ;
e4db172a 529 charBuf[ numChars - 1 ] = 0;
980ee83f 530#if SIZEOF_WCHAR_T == 2
cdef0334 531 uniChars = (wchar_t*) charBuf ;
5ca930b1 532/* memcpy( uniChars , charBuf , numChars * 2 ) ;*/ // is there any point in copying charBuf over itself? (in fact, memcpy isn't even guaranteed to work correctly if the source and destination ranges overlap...)
980ee83f
SC
533#else
534 // the resulting string will never have more chars than the utf16 version, so this is safe
535 wxMBConvUTF16 converter ;
536 numChars = converter.MB2WC( uniChars , (const char*)charBuf , numChars ) ;
537#endif
538 }
b46dde27 539
980ee83f
SC
540 switch ( GetEventKind( event ) )
541 {
542 case kEventTextInputUpdateActiveInputArea :
543 {
544 // An IME input event may return several characters, but we need to send one char at a time to
545 // EVT_CHAR
546 for (int pos=0 ; pos < numChars ; pos++)
547 {
980ee83f
SC
548 WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ;
549 WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ;
550 wxTheApp->MacSetCurrentEvent( event , handler ) ;
b46dde27 551
5ca930b1
VZ
552 UInt32 message = uniChars[pos] < 128 ? (char)uniChars[pos] : '?';
553/*
554 NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
555 multiple times to update the active range during inline input, so this handler will often receive
556 uncommited text, which should usually not trigger side effects. It might be a good idea to check the
557 kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
558 On the other hand, it can be useful for some applications to react to uncommitted text (for example,
559 to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
560 should add new event types to support advanced text input. For now, I would keep things as they are.
89954433 561
5ca930b1 562 However, the code that was being used caused additional problems:
980ee83f 563 UInt32 message = (0 << 8) + ((char)uniChars[pos] );
5ca930b1
VZ
564 Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
565 input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
566 for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
567 (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
568 (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
569 Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
570 overlap with Unicode within the (7-bit) ASCII range.
571 But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
572 for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
573 characters as they are and replaces the rest with '?', ensuring that update events are triggered.
574 It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
575 I don't have time to look into that right now.
576 -- CL
577*/
980ee83f
SC
578 if ( wxTheApp->MacSendCharEvent(
579 focus , message , 0 , when , 0 , 0 , uniChars[pos] ) )
580 {
581 result = noErr ;
582 }
b46dde27 583
980ee83f
SC
584 wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ;
585 }
586 }
587 break ;
588 case kEventTextInputUnicodeForKeyEvent :
589 {
590 UInt32 keyCode, modifiers ;
591 Point point ;
592 EventRef rawEvent ;
593 unsigned char charCode ;
594
595 GetEventParameter( event, kEventParamTextInputSendKeyboardEvent, typeEventRef, NULL, sizeof(rawEvent), NULL, &rawEvent ) ;
596 GetEventParameter( rawEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &charCode );
597 GetEventParameter( rawEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode );
598 GetEventParameter( rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers );
599 GetEventParameter( rawEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &point );
b46dde27 600
980ee83f 601 UInt32 message = (keyCode << 8) + charCode;
aa44b55d 602
980ee83f
SC
603 // An IME input event may return several characters, but we need to send one char at a time to
604 // EVT_CHAR
605 for (int pos=0 ; pos < numChars ; pos++)
606 {
980ee83f
SC
607 WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ;
608 WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ;
609 wxTheApp->MacSetCurrentEvent( event , handler ) ;
b46dde27 610
980ee83f
SC
611 if ( wxTheApp->MacSendCharEvent(
612 focus , message , modifiers , when , point.h , point.v , uniChars[pos] ) )
613 {
614 result = noErr ;
615 }
b46dde27 616
980ee83f
SC
617 wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ;
618 }
619 }
620 break;
621 default:
622 break ;
623 }
b46dde27
DS
624
625 delete [] uniChars ;
980ee83f 626 if ( charBuf != buf )
b46dde27 627 delete [] charBuf ;
2e91d506 628
980ee83f 629 return result ;
980ee83f
SC
630}
631
89954433
VZ
632static pascal OSStatus
633wxMacWindowCommandEventHandler(EventHandlerCallRef WXUNUSED(handler),
634 EventRef event,
635 void *data)
e3aeade0
SC
636{
637 OSStatus result = eventNotHandledErr ;
638 wxWindowMac* focus = (wxWindowMac*) data ;
b46dde27 639
e3aeade0 640 HICommand command ;
b46dde27 641
e3aeade0
SC
642 wxMacCarbonEvent cEvent( event ) ;
643 cEvent.GetParameter<HICommand>(kEventParamDirectObject,typeHICommand,&command) ;
b46dde27 644
e3aeade0
SC
645 wxMenuItem* item = NULL ;
646 wxMenu* itemMenu = wxFindMenuFromMacCommand( command , item ) ;
647 int id = wxMacCommandToId( command.commandID ) ;
b46dde27 648
e3aeade0
SC
649 if ( item )
650 {
651 wxASSERT( itemMenu != NULL ) ;
b46dde27 652
e3aeade0
SC
653 switch ( cEvent.GetKind() )
654 {
655 case kEventProcessCommand :
6239ee05 656 result = itemMenu->MacHandleCommandProcess( item, id, focus );
e3aeade0 657 break ;
b46dde27 658
e3aeade0 659 case kEventCommandUpdateStatus:
6239ee05 660 result = itemMenu->MacHandleCommandUpdateStatus( item, id, focus );
e3aeade0 661 break ;
b46dde27 662
e3aeade0
SC
663 default :
664 break ;
665 }
666 }
667 return result ;
668}
669
facd6764
SC
670pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
671{
af6b7b80
SC
672 EventRef formerEvent = (EventRef) wxTheApp->MacGetCurrentEvent() ;
673 EventHandlerCallRef formerEventHandlerCallRef = (EventHandlerCallRef) wxTheApp->MacGetCurrentEventHandlerCallRef() ;
674 wxTheApp->MacSetCurrentEvent( event , handler ) ;
facd6764
SC
675 OSStatus result = eventNotHandledErr ;
676
677 switch ( GetEventClass( event ) )
678 {
e3aeade0
SC
679 case kEventClassCommand :
680 result = wxMacWindowCommandEventHandler( handler , event , data ) ;
681 break ;
682
facd6764
SC
683 case kEventClassControl :
684 result = wxMacWindowControlEventHandler( handler, event, data ) ;
685 break ;
e15f0a5e 686
e4727773
SC
687 case kEventClassService :
688 result = wxMacWindowServiceEventHandler( handler, event , data ) ;
902725ee 689 break ;
e15f0a5e 690
980ee83f
SC
691 case kEventClassTextInput :
692 result = wxMacUnicodeTextEventHandler( handler , event , data ) ;
693 break ;
b46dde27 694
facd6764
SC
695 default :
696 break ;
697 }
e15f0a5e 698
af6b7b80 699 wxTheApp->MacSetCurrentEvent( formerEvent, formerEventHandlerCallRef ) ;
e15f0a5e 700
facd6764
SC
701 return result ;
702}
703
704DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler )
705
20b69855
SC
706#if !TARGET_API_MAC_OSX
707
facd6764
SC
708// ---------------------------------------------------------------------------
709// UserPane events for non OSX builds
710// ---------------------------------------------------------------------------
8b573fb8 711
facd6764
SC
712static pascal void wxMacControlUserPaneDrawProc(ControlRef control, SInt16 part)
713{
714 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
715 if ( win )
716 win->MacControlUserPaneDrawProc(part) ;
facd6764 717}
1f1c8bd4 718wxMAC_DEFINE_PROC_GETTER( ControlUserPaneDrawUPP , wxMacControlUserPaneDrawProc ) ;
facd6764
SC
719
720static pascal ControlPartCode wxMacControlUserPaneHitTestProc(ControlRef control, Point where)
721{
722 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
723 if ( win )
724 return win->MacControlUserPaneHitTestProc(where.h , where.v) ;
725 else
726 return kControlNoPart ;
facd6764 727}
1f1c8bd4 728wxMAC_DEFINE_PROC_GETTER( ControlUserPaneHitTestUPP , wxMacControlUserPaneHitTestProc ) ;
facd6764
SC
729
730static pascal ControlPartCode wxMacControlUserPaneTrackingProc(ControlRef control, Point startPt, ControlActionUPP actionProc)
731{
732 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
733 if ( win )
734 return win->MacControlUserPaneTrackingProc( startPt.h , startPt.v , (void*) actionProc) ;
735 else
736 return kControlNoPart ;
facd6764 737}
1f1c8bd4 738wxMAC_DEFINE_PROC_GETTER( ControlUserPaneTrackingUPP , wxMacControlUserPaneTrackingProc ) ;
facd6764
SC
739
740static pascal void wxMacControlUserPaneIdleProc(ControlRef control)
741{
742 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
743 if ( win )
744 win->MacControlUserPaneIdleProc() ;
facd6764 745}
1f1c8bd4 746wxMAC_DEFINE_PROC_GETTER( ControlUserPaneIdleUPP , wxMacControlUserPaneIdleProc ) ;
facd6764
SC
747
748static pascal ControlPartCode wxMacControlUserPaneKeyDownProc(ControlRef control, SInt16 keyCode, SInt16 charCode, SInt16 modifiers)
749{
750 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
751 if ( win )
752 return win->MacControlUserPaneKeyDownProc(keyCode,charCode,modifiers) ;
753 else
754 return kControlNoPart ;
facd6764 755}
1f1c8bd4 756wxMAC_DEFINE_PROC_GETTER( ControlUserPaneKeyDownUPP , wxMacControlUserPaneKeyDownProc ) ;
facd6764
SC
757
758static pascal void wxMacControlUserPaneActivateProc(ControlRef control, Boolean activating)
759{
760 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
761 if ( win )
762 win->MacControlUserPaneActivateProc(activating) ;
facd6764 763}
1f1c8bd4 764wxMAC_DEFINE_PROC_GETTER( ControlUserPaneActivateUPP , wxMacControlUserPaneActivateProc ) ;
facd6764
SC
765
766static pascal ControlPartCode wxMacControlUserPaneFocusProc(ControlRef control, ControlFocusPart action)
767{
768 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
769 if ( win )
770 return win->MacControlUserPaneFocusProc(action) ;
771 else
772 return kControlNoPart ;
facd6764 773}
1f1c8bd4 774wxMAC_DEFINE_PROC_GETTER( ControlUserPaneFocusUPP , wxMacControlUserPaneFocusProc ) ;
facd6764
SC
775
776static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control, ControlBackgroundPtr info)
777{
778 wxWindow * win = wxFindControlFromMacControl(control) ;
542f604f
SC
779 if ( win )
780 win->MacControlUserPaneBackgroundProc(info) ;
facd6764 781}
1f1c8bd4 782wxMAC_DEFINE_PROC_GETTER( ControlUserPaneBackgroundUPP , wxMacControlUserPaneBackgroundProc ) ;
facd6764 783
8b573fb8 784void wxWindowMac::MacControlUserPaneDrawProc(wxInt16 part)
facd6764 785{
e15f0a5e 786 int x = 0 , y = 0;
bcbd6987
SC
787 RgnHandle rgn = NewRgn() ;
788 GetClip( rgn ) ;
8523a5f5 789 MacWindowToRootWindow( &x, &y ) ;
d35bd499 790 OffsetRgn( rgn , -x , -y ) ;
bcbd6987
SC
791 wxMacWindowStateSaver sv( this ) ;
792 SectRgn( rgn , (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , rgn ) ;
793 MacDoRedraw( rgn , 0 ) ;
794 DisposeRgn( rgn ) ;
facd6764
SC
795}
796
8b573fb8 797wxInt16 wxWindowMac::MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y)
facd6764
SC
798{
799 return kControlNoPart ;
800}
801
8b573fb8 802wxInt16 wxWindowMac::MacControlUserPaneTrackingProc(wxInt16 x, wxInt16 y, void* actionProc)
facd6764
SC
803{
804 return kControlNoPart ;
805}
806
8b573fb8 807void wxWindowMac::MacControlUserPaneIdleProc()
facd6764
SC
808{
809}
810
8b573fb8 811wxInt16 wxWindowMac::MacControlUserPaneKeyDownProc(wxInt16 keyCode, wxInt16 charCode, wxInt16 modifiers)
facd6764
SC
812{
813 return kControlNoPart ;
814}
815
8b573fb8 816void wxWindowMac::MacControlUserPaneActivateProc(bool activating)
facd6764
SC
817{
818}
819
8b573fb8 820wxInt16 wxWindowMac::MacControlUserPaneFocusProc(wxInt16 action)
facd6764 821{
fb5246be
WS
822 if ( AcceptsFocus() )
823 return 1 ;
824 else
825 return kControlNoPart ;
facd6764
SC
826}
827
8b573fb8 828void wxWindowMac::MacControlUserPaneBackgroundProc(void* info)
facd6764
SC
829{
830}
831
20b69855
SC
832#endif
833
1f1c8bd4
SC
834// ---------------------------------------------------------------------------
835// Scrollbar Tracking for all
836// ---------------------------------------------------------------------------
837
838pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode partCode ) ;
839pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode partCode )
840{
841 if ( partCode != 0)
842 {
843 wxWindow* wx = wxFindControlFromMacControl( control ) ;
844 if ( wx )
1f1c8bd4 845 wx->MacHandleControlClick( (WXWidget) control , partCode , true /* stillDown */ ) ;
1f1c8bd4
SC
846 }
847}
848wxMAC_DEFINE_PROC_GETTER( ControlActionUPP , wxMacLiveScrollbarActionProc ) ;
849
e7549107
SC
850// ===========================================================================
851// implementation
852// ===========================================================================
853
71f2fb52
RN
854WX_DECLARE_HASH_MAP(ControlRef, wxWindow*, wxPointerHash, wxPointerEqual, MacControlMap);
855
856static MacControlMap wxWinMacControlList;
857
858wxWindow *wxFindControlFromMacControl(ControlRef inControl )
859{
860 MacControlMap::iterator node = wxWinMacControlList.find(inControl);
861
862 return (node == wxWinMacControlList.end()) ? NULL : node->second;
863}
864
865void wxAssociateControlWithMacControl(ControlRef inControl, wxWindow *control)
866{
867 // adding NULL ControlRef is (first) surely a result of an error and
868 // (secondly) breaks native event processing
869 wxCHECK_RET( inControl != (ControlRef) NULL, wxT("attempt to add a NULL WindowRef to window list") );
870
871 wxWinMacControlList[inControl] = control;
872}
873
874void wxRemoveMacControlAssociation(wxWindow *control)
875{
876 // iterate over all the elements in the class
a8683134
SC
877 // is the iterator stable ? as we might have two associations pointing to the same wxWindow
878 // we should go on...
879
880 bool found = true ;
e15f0a5e 881 while ( found )
71f2fb52 882 {
a8683134
SC
883 found = false ;
884 MacControlMap::iterator it;
885 for ( it = wxWinMacControlList.begin(); it != wxWinMacControlList.end(); ++it )
71f2fb52 886 {
a8683134
SC
887 if ( it->second == control )
888 {
889 wxWinMacControlList.erase(it);
890 found = true ;
891 break;
892 }
71f2fb52
RN
893 }
894 }
895}
facd6764 896
e7549107 897// ----------------------------------------------------------------------------
facd6764 898 // constructors and such
e7549107
SC
899// ----------------------------------------------------------------------------
900
94f9b1f0 901wxWindowMac::wxWindowMac()
8b573fb8
VZ
902{
903 Init();
94f9b1f0
SC
904}
905
906wxWindowMac::wxWindowMac(wxWindowMac *parent,
907 wxWindowID id,
908 const wxPoint& pos ,
909 const wxSize& size ,
910 long style ,
911 const wxString& name )
912{
913 Init();
914 Create(parent, id, pos, size, style, name);
915}
916
e766c8a9 917void wxWindowMac::Init()
519cb848 918{
21fd5529 919 m_peer = NULL ;
79392158 920 m_frozenness = 0 ;
a9b456ff 921 m_macAlpha = 255 ;
898d9035 922
e15f0a5e
DS
923#if wxMAC_USE_CORE_GRAPHICS
924 m_cgContextRef = NULL ;
925#endif
926
e7549107 927 // as all windows are created with WS_VISIBLE style...
902725ee 928 m_isShown = true;
e7549107 929
6264b550
RR
930 m_hScrollBar = NULL ;
931 m_vScrollBar = NULL ;
c1142003
VZ
932 m_hScrollBarAlwaysShown = false;
933 m_vScrollBarAlwaysShown = false;
934
facd6764
SC
935 m_macBackgroundBrush = wxNullBrush ;
936
902725ee 937 m_macIsUserPane = true;
8adc196b 938 m_clipChildren = false ;
5c840e5b 939 m_cachedClippedRectValid = false ;
e15f0a5e 940
c6f9fb05
SC
941 // we need a valid font for the encodings
942 wxWindowBase::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
e9576ca5
SC
943}
944
e766c8a9 945wxWindowMac::~wxWindowMac()
e9576ca5 946{
7de59551
RD
947 SendDestroyEvent();
948
902725ee 949 m_isBeingDeleted = true;
6ed71b4f 950
6449b3a8 951 MacInvalidateBorders() ;
7ebf5540 952
d4380aaf
SC
953#ifndef __WXUNIVERSAL__
954 // VS: make sure there's no wxFrame with last focus set to us:
955 for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
956 {
957 wxFrame *frame = wxDynamicCast(win, wxFrame);
958 if ( frame )
959 {
960 if ( frame->GetLastFocus() == this )
d4380aaf 961 frame->SetLastFocus((wxWindow*)NULL);
d4380aaf
SC
962 break;
963 }
964 }
b46dde27 965#endif
8b573fb8
VZ
966
967 // destroy children before destroying this window itself
968 DestroyChildren();
969
facd6764
SC
970 // wxRemoveMacControlAssociation( this ) ;
971 // If we delete an item, we should initialize the parent panel,
972 // because it could now be invalid.
6c20e8f8
VZ
973 wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow);
974 if ( tlw )
facd6764 975 {
6c20e8f8
VZ
976 if ( tlw->GetDefaultItem() == (wxButton*) this)
977 tlw->SetDefaultItem(NULL);
facd6764 978 }
e15f0a5e 979
21fd5529 980 if ( m_peer && m_peer->Ok() )
facd6764
SC
981 {
982 // in case the callback might be called during destruction
983 wxRemoveMacControlAssociation( this) ;
229f6270 984 ::RemoveEventHandler( (EventHandlerRef ) m_macControlEventHandler ) ;
5ca0d812
SC
985 // we currently are not using this hook
986 // ::SetControlColorProc( *m_peer , NULL ) ;
987 m_peer->Dispose() ;
facd6764 988 }
d4380aaf 989
facd6764 990 if ( g_MacLastWindow == this )
facd6764 991 g_MacLastWindow = NULL ;
7de59551 992
6239ee05
SC
993#ifndef __WXUNIVERSAL__
994 wxFrame* frame = wxDynamicCast( wxGetTopLevelParent( (wxWindow*)this ) , wxFrame ) ;
fd76aa8d
SC
995 if ( frame )
996 {
e40298d5
JS
997 if ( frame->GetLastFocus() == this )
998 frame->SetLastFocus( NULL ) ;
fd76aa8d 999 }
6239ee05 1000#endif
e7549107 1001
42683dfb
SC
1002 // delete our drop target if we've got one
1003#if wxUSE_DRAG_AND_DROP
1004 if ( m_dropTarget != NULL )
1005 {
1006 delete m_dropTarget;
1007 m_dropTarget = NULL;
1008 }
e15f0a5e
DS
1009#endif
1010
21fd5529
SC
1011 delete m_peer ;
1012}
1013
8b573fb8
VZ
1014WXWidget wxWindowMac::GetHandle() const
1015{
1016 return (WXWidget) m_peer->GetControlRef() ;
e9576ca5
SC
1017}
1018
5ca0d812 1019void wxWindowMac::MacInstallEventHandler( WXWidget control )
facd6764 1020{
898d9035
DS
1021 wxAssociateControlWithMacControl( (ControlRef) control , this ) ;
1022 InstallControlEventHandler( (ControlRef)control , GetwxMacWindowEventHandlerUPP(),
8b573fb8 1023 GetEventTypeCount(eventList), eventList, this,
facd6764 1024 (EventHandlerRef *)&m_macControlEventHandler);
e15f0a5e 1025
4a63451b
SC
1026#if !TARGET_API_MAC_OSX
1027 if ( (ControlRef) control == m_peer->GetControlRef() )
1028 {
898d9035
DS
1029 m_peer->SetData<ControlUserPaneDrawUPP>(kControlEntireControl, kControlUserPaneDrawProcTag, GetwxMacControlUserPaneDrawProc()) ;
1030 m_peer->SetData<ControlUserPaneHitTestUPP>(kControlEntireControl, kControlUserPaneHitTestProcTag, GetwxMacControlUserPaneHitTestProc()) ;
1031 m_peer->SetData<ControlUserPaneTrackingUPP>(kControlEntireControl, kControlUserPaneTrackingProcTag, GetwxMacControlUserPaneTrackingProc()) ;
1032 m_peer->SetData<ControlUserPaneIdleUPP>(kControlEntireControl, kControlUserPaneIdleProcTag, GetwxMacControlUserPaneIdleProc()) ;
1033 m_peer->SetData<ControlUserPaneKeyDownUPP>(kControlEntireControl, kControlUserPaneKeyDownProcTag, GetwxMacControlUserPaneKeyDownProc()) ;
1034 m_peer->SetData<ControlUserPaneActivateUPP>(kControlEntireControl, kControlUserPaneActivateProcTag, GetwxMacControlUserPaneActivateProc()) ;
1035 m_peer->SetData<ControlUserPaneFocusUPP>(kControlEntireControl, kControlUserPaneFocusProcTag, GetwxMacControlUserPaneFocusProc()) ;
1036 m_peer->SetData<ControlUserPaneBackgroundUPP>(kControlEntireControl, kControlUserPaneBackgroundProcTag, GetwxMacControlUserPaneBackgroundProc()) ;
4a63451b
SC
1037 }
1038#endif
facd6764
SC
1039}
1040
e9576ca5 1041// Constructor
58603178
DS
1042bool wxWindowMac::Create(wxWindowMac *parent,
1043 wxWindowID id,
1044 const wxPoint& pos,
1045 const wxSize& size,
1046 long style,
1047 const wxString& name)
e9576ca5 1048{
902725ee 1049 wxCHECK_MSG( parent, false, wxT("can't create wxWindowMac without parent") );
e9576ca5 1050
e7549107 1051 if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
902725ee 1052 return false;
e9576ca5 1053
facd6764 1054 m_windowVariant = parent->GetWindowVariant() ;
8b573fb8 1055
facd6764
SC
1056 if ( m_macIsUserPane )
1057 {
1058 Rect bounds = wxMacGetBoundsForControl( this , pos , size ) ;
8b573fb8 1059
ebe86b1e 1060 UInt32 features = 0
8b573fb8 1061 | kControlSupportsEmbedding
1f1c8bd4
SC
1062 | kControlSupportsLiveFeedback
1063 | kControlGetsFocusOnClick
8b573fb8
VZ
1064// | kControlHasSpecialBackground
1065// | kControlSupportsCalcBestRect
1f1c8bd4 1066 | kControlHandlesTracking
8b573fb8 1067 | kControlSupportsFocus
1f1c8bd4 1068 | kControlWantsActivate
58603178 1069 | kControlWantsIdle ;
ebe86b1e 1070
6449b3a8 1071 m_peer = new wxMacControl(this) ;
58603178
DS
1072 OSStatus err =::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds, features , m_peer->GetControlRefAddr() );
1073 verify_noerr( err );
8b573fb8 1074
898d9035 1075 MacPostControlCreate(pos, size) ;
facd6764 1076 }
898d9035 1077
e766c8a9 1078#ifndef __WXUNIVERSAL__
14c9cbdb 1079 // Don't give scrollbars to wxControls unless they ask for them
58603178
DS
1080 if ( (! IsKindOf(CLASSINFO(wxControl)) && ! IsKindOf(CLASSINFO(wxStatusBar)))
1081 || (IsKindOf(CLASSINFO(wxControl)) && ((style & wxHSCROLL) || (style & wxVSCROLL))))
6264b550
RR
1082 {
1083 MacCreateScrollBars( style ) ;
1084 }
e766c8a9 1085#endif
3dfafdb9
RD
1086
1087 wxWindowCreateEvent event(this);
7e4a196e 1088 GetEventHandler()->AddPendingEvent(event);
3dfafdb9 1089
902725ee 1090 return true;
e9576ca5
SC
1091}
1092
902725ee 1093void wxWindowMac::MacChildAdded()
08422003
SC
1094{
1095 if ( m_vScrollBar )
08422003 1096 m_vScrollBar->Raise() ;
08422003 1097 if ( m_hScrollBar )
08422003 1098 m_hScrollBar->Raise() ;
08422003
SC
1099}
1100
89954433 1101void wxWindowMac::MacPostControlCreate(const wxPoint& WXUNUSED(pos), const wxSize& size)
facd6764 1102{
21fd5529 1103 wxASSERT_MSG( m_peer != NULL && m_peer->Ok() , wxT("No valid mac control") ) ;
facd6764 1104
4f74e0d1 1105 m_peer->SetReference( (URefCon) this ) ;
58603178 1106 GetParent()->AddChild( this );
facd6764 1107
5ca0d812 1108 MacInstallEventHandler( (WXWidget) m_peer->GetControlRef() );
facd6764
SC
1109
1110 ControlRef container = (ControlRef) GetParent()->GetHandle() ;
1111 wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ;
5ca0d812 1112 ::EmbedControl( m_peer->GetControlRef() , container ) ;
08422003 1113 GetParent()->MacChildAdded() ;
facd6764
SC
1114
1115 // adjust font, controlsize etc
1116 DoSetWindowVariant( m_windowVariant ) ;
1117
32cd189d 1118 m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics) ) ;
facd6764 1119
facd6764 1120 if (!m_macIsUserPane)
170acdc9 1121 SetInitialSize(size);
facd6764
SC
1122
1123 SetCursor( *wxSTANDARD_CURSOR ) ;
facd6764
SC
1124}
1125
1126void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant )
1127{
23176131
JS
1128 // Don't assert, in case we set the window variant before
1129 // the window is created
21fd5529 1130 // wxASSERT( m_peer->Ok() ) ;
facd6764 1131
23176131
JS
1132 m_windowVariant = variant ;
1133
21fd5529 1134 if (m_peer == NULL || !m_peer->Ok())
23176131 1135 return;
facd6764 1136
8b573fb8 1137 ControlSize size ;
facd6764
SC
1138 ThemeFontID themeFont = kThemeSystemFont ;
1139
1140 // we will get that from the settings later
8b573fb8 1141 // and make this NORMAL later, but first
facd6764 1142 // we have a few calculations that we must fix
8b573fb8 1143
facd6764
SC
1144 switch ( variant )
1145 {
1146 case wxWINDOW_VARIANT_NORMAL :
8b573fb8
VZ
1147 size = kControlSizeNormal;
1148 themeFont = kThemeSystemFont ;
facd6764 1149 break ;
e15f0a5e 1150
facd6764 1151 case wxWINDOW_VARIANT_SMALL :
8b573fb8
VZ
1152 size = kControlSizeSmall;
1153 themeFont = kThemeSmallSystemFont ;
facd6764 1154 break ;
e15f0a5e 1155
facd6764 1156 case wxWINDOW_VARIANT_MINI :
9d463591
SC
1157 // not always defined in the headers
1158 size = 3 ;
1159 themeFont = 109 ;
facd6764 1160 break ;
e15f0a5e 1161
facd6764 1162 case wxWINDOW_VARIANT_LARGE :
8b573fb8
VZ
1163 size = kControlSizeLarge;
1164 themeFont = kThemeSystemFont ;
facd6764 1165 break ;
e15f0a5e 1166
facd6764
SC
1167 default:
1168 wxFAIL_MSG(_T("unexpected window variant"));
1169 break ;
1170 }
e15f0a5e 1171
898d9035 1172 m_peer->SetData<ControlSize>(kControlEntireControl, kControlSizeTag, &size ) ;
facd6764
SC
1173
1174 wxFont font ;
1175 font.MacCreateThemeFont( themeFont ) ;
1176 SetFont( font ) ;
1177}
1178
8b573fb8 1179void wxWindowMac::MacUpdateControlFont()
facd6764 1180{
ac99838a 1181 m_peer->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ;
6239ee05
SC
1182 // do not trigger refreshes upon invisible and possible partly created objects
1183 if ( MacIsReallyShown() )
1184 Refresh() ;
facd6764
SC
1185}
1186
1187bool wxWindowMac::SetFont(const wxFont& font)
1188{
58603178 1189 bool retval = wxWindowBase::SetFont( font );
8b573fb8 1190
facd6764 1191 MacUpdateControlFont() ;
8b573fb8 1192
facd6764
SC
1193 return retval;
1194}
1195
1196bool wxWindowMac::SetForegroundColour(const wxColour& col )
1197{
58603178 1198 bool retval = wxWindowBase::SetForegroundColour( col );
8b573fb8 1199
898d9035 1200 if (retval)
58603178 1201 MacUpdateControlFont();
8b573fb8 1202
898d9035 1203 return retval;
facd6764
SC
1204}
1205
1206bool wxWindowMac::SetBackgroundColour(const wxColour& col )
1207{
1208 if ( !wxWindowBase::SetBackgroundColour(col) && m_hasBgCol )
1209 return false ;
1210
1211 wxBrush brush ;
b52acd03 1212 wxColour newCol(GetBackgroundColour());
58603178 1213
26af4dbd 1214 if ( newCol == wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) )
facd6764 1215 brush.MacSetTheme( kThemeBrushDocumentWindowBackground ) ;
58603178 1216 else if ( newCol == wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE ) )
8b573fb8 1217 brush.MacSetTheme( kThemeBrushDialogBackgroundActive ) ;
facd6764 1218 else
b52acd03 1219 brush.SetColour( newCol ) ;
e15f0a5e 1220
facd6764 1221 MacSetBackgroundBrush( brush ) ;
db7a550b 1222 MacUpdateControlFont() ;
8b573fb8 1223
facd6764
SC
1224 return true ;
1225}
1226
7ea087b7
SC
1227void wxWindowMac::MacSetBackgroundBrush( const wxBrush &brush )
1228{
1229 m_macBackgroundBrush = brush ;
1230 m_peer->SetBackground( brush ) ;
1231}
facd6764
SC
1232
1233bool wxWindowMac::MacCanFocus() const
1234{
90b4f7b5 1235 // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so
2e91d506
DS
1236 // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning,
1237 // but the value range is nowhere documented
90b4f7b5 1238 Boolean keyExistsAndHasValidFormat ;
2e91d506
DS
1239 CFIndex fullKeyboardAccess = CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) ,
1240 kCFPreferencesCurrentApplication, &keyExistsAndHasValidFormat );
1241
90b4f7b5 1242 if ( keyExistsAndHasValidFormat && fullKeyboardAccess > 0 )
2e91d506 1243 {
90b4f7b5 1244 return true ;
2e91d506 1245 }
90b4f7b5
SC
1246 else
1247 {
1248 UInt32 features = 0 ;
1249 m_peer->GetFeatures( &features ) ;
1250
1251 return features & ( kControlSupportsFocus | kControlGetsFocusOnClick ) ;
1252 }
facd6764
SC
1253}
1254
e766c8a9 1255void wxWindowMac::SetFocus()
e9576ca5 1256{
e15f0a5e 1257 if ( !AcceptsFocus() )
7d0cfe71
SC
1258 return ;
1259
e15f0a5e
DS
1260 wxWindow* former = FindFocus() ;
1261 if ( former == this )
1262 return ;
1263
1264 // as we cannot rely on the control features to find out whether we are in full keyboard mode,
1265 // we can only leave in case of an error
1266 OSStatus err = m_peer->SetFocus( kControlFocusNextPart ) ;
1267 if ( err == errCouldntSetFocus )
1268 return ;
1269
e15f0a5e 1270 SetUserFocusWindow( (WindowRef)MacGetTopLevelWindowRef() );
f1d527c1
SC
1271
1272#if !TARGET_API_MAC_OSX
e15f0a5e
DS
1273 // emulate carbon events when running under CarbonLib where they are not natively available
1274 if ( former )
1275 {
1276 EventRef evRef = NULL ;
58603178
DS
1277
1278 err = MacCreateEvent(
1279 NULL , kEventClassControl , kEventControlSetFocusPart , TicksToEventTime( TickCount() ) ,
1280 kEventAttributeUserEvent , &evRef );
1281 verify_noerr( err );
f1d527c1 1282
e15f0a5e
DS
1283 wxMacCarbonEvent cEvent( evRef ) ;
1284 cEvent.SetParameter<ControlRef>( kEventParamDirectObject , (ControlRef) former->GetHandle() ) ;
1285 cEvent.SetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode , kControlFocusNoPart ) ;
8b573fb8 1286
e15f0a5e 1287 wxMacWindowEventHandler( NULL , evRef , former ) ;
58603178 1288 ReleaseEvent( evRef ) ;
e15f0a5e 1289 }
f1d527c1 1290
e15f0a5e
DS
1291 // send new focus event
1292 {
1293 EventRef evRef = NULL ;
58603178
DS
1294
1295 err = MacCreateEvent(
1296 NULL , kEventClassControl , kEventControlSetFocusPart , TicksToEventTime( TickCount() ) ,
1297 kEventAttributeUserEvent , &evRef );
1298 verify_noerr( err );
8b573fb8 1299
e15f0a5e
DS
1300 wxMacCarbonEvent cEvent( evRef ) ;
1301 cEvent.SetParameter<ControlRef>( kEventParamDirectObject , (ControlRef) GetHandle() ) ;
1302 cEvent.SetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode , kControlFocusNextPart ) ;
1303
1304 wxMacWindowEventHandler( NULL , evRef , this ) ;
58603178 1305 ReleaseEvent( evRef ) ;
6264b550 1306 }
e15f0a5e 1307#endif
e9576ca5
SC
1308}
1309
4116c221 1310void wxWindowMac::DoCaptureMouse()
e9576ca5 1311{
2a1f999f 1312 wxApp::s_captureWindow = this ;
e9576ca5
SC
1313}
1314
2e91d506 1315wxWindow * wxWindowBase::GetCapture()
90b959ae 1316{
2a1f999f 1317 return wxApp::s_captureWindow ;
90b959ae
SC
1318}
1319
4116c221 1320void wxWindowMac::DoReleaseMouse()
e9576ca5 1321{
2a1f999f 1322 wxApp::s_captureWindow = NULL ;
e9576ca5
SC
1323}
1324
e15f0a5e 1325#if wxUSE_DRAG_AND_DROP
e9576ca5 1326
e766c8a9 1327void wxWindowMac::SetDropTarget(wxDropTarget *pDropTarget)
e9576ca5 1328{
e15f0a5e 1329 if ( m_dropTarget != NULL )
e40298d5 1330 delete m_dropTarget;
6ed71b4f 1331
e40298d5 1332 m_dropTarget = pDropTarget;
e15f0a5e 1333 if ( m_dropTarget != NULL )
e40298d5 1334 {
58603178 1335 // TODO:
e40298d5 1336 }
e9576ca5
SC
1337}
1338
1339#endif
1340
2e91d506 1341// Old-style File Manager Drag & Drop
89954433 1342void wxWindowMac::DragAcceptFiles(bool WXUNUSED(accept))
e9576ca5 1343{
58603178 1344 // TODO:
e9576ca5
SC
1345}
1346
055a486b
SC
1347// Returns the size of the native control. In the case of the toplevel window
1348// this is the content area root control
1349
89954433
VZ
1350void wxWindowMac::MacGetPositionAndSizeFromControl(int& WXUNUSED(x),
1351 int& WXUNUSED(y),
1352 int& WXUNUSED(w),
1353 int& WXUNUSED(h)) const
e9576ca5 1354{
898d9035 1355 wxFAIL_MSG( wxT("Not currently supported") ) ;
e9576ca5
SC
1356}
1357
055a486b 1358// From a wx position / size calculate the appropriate size of the native control
8b573fb8 1359
898d9035
DS
1360bool wxWindowMac::MacGetBoundsForControl(
1361 const wxPoint& pos,
1362 const wxSize& size,
1363 int& x, int& y,
1364 int& w, int& h , bool adjustOrigin ) const
51abe921 1365{
5ca0d812 1366 // the desired size, minus the border pixels gives the correct size of the control
facd6764
SC
1367 x = (int)pos.x;
1368 y = (int)pos.y;
58603178
DS
1369
1370 // TODO: the default calls may be used as soon as PostCreateControl Is moved here
898d9035
DS
1371 w = wxMax(size.x, 0) ; // WidthDefault( size.x );
1372 h = wxMax(size.y, 0) ; // HeightDefault( size.y ) ;
789ae0cf 1373
5ca0d812
SC
1374 x += MacGetLeftBorderSize() ;
1375 y += MacGetTopBorderSize() ;
1376 w -= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1377 h -= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
8b573fb8 1378
79392158
SC
1379 if ( adjustOrigin )
1380 AdjustForParentClientOrigin( x , y ) ;
789ae0cf 1381
7ebf5540 1382 // this is in window relative coordinate, as this parent may have a border, its physical position is offset by this border
789ae0cf 1383 if ( !GetParent()->IsTopLevel() )
7ebf5540
SC
1384 {
1385 x -= GetParent()->MacGetLeftBorderSize() ;
1386 y -= GetParent()->MacGetTopBorderSize() ;
1387 }
789ae0cf 1388
facd6764
SC
1389 return true ;
1390}
1391
42ef83fa 1392// Get window size (not client size)
facd6764
SC
1393void wxWindowMac::DoGetSize(int *x, int *y) const
1394{
1f1c8bd4
SC
1395 Rect bounds ;
1396 m_peer->GetRect( &bounds ) ;
8b573fb8 1397
e15f0a5e
DS
1398 if (x)
1399 *x = bounds.right - bounds.left + MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1400 if (y)
1401 *y = bounds.bottom - bounds.top + MacGetTopBorderSize() + MacGetBottomBorderSize() ;
facd6764
SC
1402}
1403
42ef83fa 1404// get the position of the bounds of this window in client coordinates of its parent
facd6764
SC
1405void wxWindowMac::DoGetPosition(int *x, int *y) const
1406{
1f1c8bd4
SC
1407 Rect bounds ;
1408 m_peer->GetRect( &bounds ) ;
902725ee 1409
1f1c8bd4
SC
1410 int x1 = bounds.left ;
1411 int y1 = bounds.top ;
789ae0cf 1412
bc2b0c1b
SC
1413 // get the wx window position from the native one
1414 x1 -= MacGetLeftBorderSize() ;
1415 y1 -= MacGetTopBorderSize() ;
1416
facd6764 1417 if ( !IsTopLevel() )
2b5f62a0 1418 {
facd6764
SC
1419 wxWindow *parent = GetParent();
1420 if ( parent )
8950f7cc 1421 {
e15f0a5e
DS
1422 // we must first adjust it to be in window coordinates of the parent,
1423 // as otherwise it gets lost by the ClientAreaOrigin fix
1a02aff9
SC
1424 x1 += parent->MacGetLeftBorderSize() ;
1425 y1 += parent->MacGetTopBorderSize() ;
e15f0a5e 1426
1a02aff9 1427 // and now to client coordinates
facd6764
SC
1428 wxPoint pt(parent->GetClientAreaOrigin());
1429 x1 -= pt.x ;
1430 y1 -= pt.y ;
6ed71b4f 1431 }
2b5f62a0 1432 }
e15f0a5e
DS
1433
1434 if (x)
1435 *x = x1 ;
1436 if (y)
1437 *y = y1 ;
facd6764 1438}
51abe921 1439
e766c8a9 1440void wxWindowMac::DoScreenToClient(int *x, int *y) const
e9576ca5 1441{
facd6764 1442 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
58603178 1443 wxCHECK_RET( window , wxT("TopLevel Window missing") ) ;
8b573fb8 1444
58603178 1445 Point localwhere = { 0, 0 } ;
519cb848 1446
58603178
DS
1447 if (x)
1448 localwhere.h = *x ;
1449 if (y)
1450 localwhere.v = *y ;
8b573fb8 1451
4f74e0d1 1452 wxMacGlobalToLocal( window , &localwhere ) ;
6ed71b4f 1453
58603178
DS
1454 if (x)
1455 *x = localwhere.h ;
1456 if (y)
1457 *y = localwhere.v ;
e15f0a5e 1458
2078220e 1459 MacRootWindowToWindow( x , y ) ;
8b573fb8 1460
facd6764 1461 wxPoint origin = GetClientAreaOrigin() ;
e15f0a5e
DS
1462 if (x)
1463 *x -= origin.x ;
1464 if (y)
1465 *y -= origin.y ;
e9576ca5
SC
1466}
1467
e766c8a9 1468void wxWindowMac::DoClientToScreen(int *x, int *y) const
e9576ca5 1469{
facd6764 1470 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
8523a5f5 1471 wxCHECK_RET( window , wxT("TopLevel window missing") ) ;
14c9cbdb 1472
facd6764 1473 wxPoint origin = GetClientAreaOrigin() ;
e15f0a5e
DS
1474 if (x)
1475 *x += origin.x ;
1476 if (y)
1477 *y += origin.y ;
14c9cbdb 1478
2078220e 1479 MacWindowToRootWindow( x , y ) ;
14c9cbdb 1480
58603178
DS
1481 Point localwhere = { 0, 0 };
1482 if (x)
1483 localwhere.h = *x ;
1484 if (y)
1485 localwhere.v = *y ;
e15f0a5e 1486
4f74e0d1 1487 wxMacLocalToGlobal( window, &localwhere ) ;
e15f0a5e 1488
58603178
DS
1489 if (x)
1490 *x = localwhere.h ;
1491 if (y)
1492 *y = localwhere.v ;
519cb848
SC
1493}
1494
e766c8a9 1495void wxWindowMac::MacClientToRootWindow( int *x , int *y ) const
519cb848 1496{
1c310985 1497 wxPoint origin = GetClientAreaOrigin() ;
e15f0a5e
DS
1498 if (x)
1499 *x += origin.x ;
1500 if (y)
1501 *y += origin.y ;
14c9cbdb 1502
1c310985
SC
1503 MacWindowToRootWindow( x , y ) ;
1504}
1505
1506void wxWindowMac::MacRootWindowToClient( int *x , int *y ) const
1507{
1c310985 1508 MacRootWindowToWindow( x , y ) ;
facd6764
SC
1509
1510 wxPoint origin = GetClientAreaOrigin() ;
e15f0a5e
DS
1511 if (x)
1512 *x -= origin.x ;
1513 if (y)
1514 *y -= origin.y ;
1c310985
SC
1515}
1516
1517void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const
1518{
5ca0d812 1519 wxPoint pt ;
58603178 1520
e15f0a5e
DS
1521 if (x)
1522 pt.x = *x ;
1523 if (y)
1524 pt.y = *y ;
facd6764 1525
125c7984 1526 if ( !IsTopLevel() )
5437ff47
RD
1527 {
1528 wxTopLevelWindowMac* top = MacGetTopLevelWindow();
1529 if (top)
5ca0d812
SC
1530 {
1531 pt.x -= MacGetLeftBorderSize() ;
1532 pt.y -= MacGetTopBorderSize() ;
1533 wxMacControl::Convert( &pt , m_peer , top->m_peer ) ;
1534 }
5437ff47 1535 }
8b573fb8 1536
e15f0a5e
DS
1537 if (x)
1538 *x = (int) pt.x ;
1539 if (y)
1540 *y = (int) pt.y ;
facd6764
SC
1541}
1542
1543void wxWindowMac::MacWindowToRootWindow( short *x , short *y ) const
1544{
1545 int x1 , y1 ;
e15f0a5e
DS
1546
1547 if (x)
1548 x1 = *x ;
1549 if (y)
1550 y1 = *y ;
1551
facd6764 1552 MacWindowToRootWindow( &x1 , &y1 ) ;
e15f0a5e
DS
1553
1554 if (x)
1555 *x = x1 ;
1556 if (y)
1557 *y = y1 ;
519cb848
SC
1558}
1559
1c310985 1560void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const
519cb848 1561{
5ca0d812 1562 wxPoint pt ;
e15f0a5e
DS
1563
1564 if (x)
1565 pt.x = *x ;
1566 if (y)
1567 pt.y = *y ;
facd6764 1568
125c7984 1569 if ( !IsTopLevel() )
5ca0d812 1570 {
5c840e5b
SC
1571 wxTopLevelWindowMac* top = MacGetTopLevelWindow();
1572 if (top)
1573 {
1574 wxMacControl::Convert( &pt , top->m_peer , m_peer ) ;
1575 pt.x += MacGetLeftBorderSize() ;
1576 pt.y += MacGetTopBorderSize() ;
1577 }
5ca0d812 1578 }
8b573fb8 1579
e15f0a5e
DS
1580 if (x)
1581 *x = (int) pt.x ;
1582 if (y)
1583 *y = (int) pt.y ;
e9576ca5
SC
1584}
1585
facd6764 1586void wxWindowMac::MacRootWindowToWindow( short *x , short *y ) const
e9576ca5 1587{
facd6764 1588 int x1 , y1 ;
e15f0a5e
DS
1589
1590 if (x)
1591 x1 = *x ;
1592 if (y)
1593 y1 = *y ;
1594
facd6764 1595 MacRootWindowToWindow( &x1 , &y1 ) ;
e15f0a5e
DS
1596
1597 if (x)
1598 *x = x1 ;
1599 if (y)
1600 *y = y1 ;
facd6764 1601}
6ed71b4f 1602
29281095
SC
1603void wxWindowMac::MacGetContentAreaInset( int &left , int &top , int &right , int &bottom )
1604{
1605 RgnHandle rgn = NewRgn() ;
898d9035 1606
5ca0d812 1607 if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr )
29281095 1608 {
898d9035
DS
1609 Rect structure, content ;
1610
29281095 1611 GetRegionBounds( rgn , &content ) ;
1f1c8bd4
SC
1612 m_peer->GetRect( &structure ) ;
1613 OffsetRect( &structure, -structure.left , -structure.top ) ;
902725ee 1614
1f1c8bd4 1615 left = content.left - structure.left ;
898d9035 1616 top = content.top - structure.top ;
1f1c8bd4
SC
1617 right = structure.right - content.right ;
1618 bottom = structure.bottom - content.bottom ;
29281095
SC
1619 }
1620 else
1621 {
1f1c8bd4 1622 left = top = right = bottom = 0 ;
29281095 1623 }
898d9035 1624
7596e51d 1625 DisposeRgn( rgn ) ;
29281095
SC
1626}
1627
facd6764
SC
1628wxSize wxWindowMac::DoGetSizeFromClientSize( const wxSize & size ) const
1629{
1630 wxSize sizeTotal = size;
1631
1632 RgnHandle rgn = NewRgn() ;
5ca0d812 1633 if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr )
6618870d 1634 {
898d9035 1635 Rect content, structure ;
facd6764 1636 GetRegionBounds( rgn , &content ) ;
1f1c8bd4 1637 m_peer->GetRect( &structure ) ;
898d9035 1638
1f1c8bd4 1639 // structure is in parent coordinates, but we only need width and height, so it's ok
6ed71b4f 1640
1f1c8bd4 1641 sizeTotal.x += (structure.right - structure.left) - (content.right - content.left) ;
8523a5f5 1642 sizeTotal.y += (structure.bottom - structure.top) - (content.bottom - content.top) ;
1f1c8bd4 1643 }
898d9035 1644
1f1c8bd4 1645 DisposeRgn( rgn ) ;
6ed71b4f 1646
e15f0a5e
DS
1647 sizeTotal.x += MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1648 sizeTotal.y += MacGetTopBorderSize() + MacGetBottomBorderSize() ;
6ed71b4f 1649
facd6764 1650 return sizeTotal;
e9576ca5
SC
1651}
1652
e9576ca5 1653// Get size *available for subwindows* i.e. excluding menu bar etc.
e15f0a5e 1654void wxWindowMac::DoGetClientSize( int *x, int *y ) const
e9576ca5 1655{
9453cf2b 1656 int ww, hh;
6ed71b4f 1657
facd6764
SC
1658 RgnHandle rgn = NewRgn() ;
1659 Rect content ;
5ca0d812 1660 if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr )
facd6764 1661 GetRegionBounds( rgn , &content ) ;
facd6764 1662 else
5ca0d812 1663 m_peer->GetRect( &content ) ;
7596e51d 1664 DisposeRgn( rgn ) ;
789ae0cf 1665
facd6764
SC
1666 ww = content.right - content.left ;
1667 hh = content.bottom - content.top ;
6ed71b4f 1668
db7a550b 1669 if (m_hScrollBar && m_hScrollBar->IsShown() )
e905b636 1670 hh -= m_hScrollBar->GetSize().y ;
e15f0a5e 1671
db7a550b 1672 if (m_vScrollBar && m_vScrollBar->IsShown() )
e905b636 1673 ww -= m_vScrollBar->GetSize().x ;
e15f0a5e
DS
1674
1675 if (x)
1676 *x = ww;
1677 if (y)
1678 *y = hh;
facd6764
SC
1679}
1680
1681bool wxWindowMac::SetCursor(const wxCursor& cursor)
1682{
a3ab1c18 1683 if (m_cursor.IsSameAs(cursor))
902725ee 1684 return false;
facd6764 1685
2e573683 1686 if (!cursor.IsOk())
facd6764
SC
1687 {
1688 if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ) )
902725ee 1689 return false ;
facd6764
SC
1690 }
1691 else
1692 {
1693 if ( ! wxWindowBase::SetCursor( cursor ) )
902725ee 1694 return false ;
facd6764
SC
1695 }
1696
1697 wxASSERT_MSG( m_cursor.Ok(),
1698 wxT("cursor must be valid after call to the base version"));
8b573fb8 1699
2d1760d3 1700 wxWindowMac *mouseWin = 0 ;
facd6764 1701 {
789ae0cf
SC
1702 wxTopLevelWindowMac *tlw = MacGetTopLevelWindow() ;
1703 WindowRef window = (WindowRef) ( tlw ? tlw->MacGetWindowRef() : 0 ) ;
4f74e0d1
SC
1704
1705 ControlPartCode part ;
1706 ControlRef control ;
1707 Point pt ;
1708 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
1709 HIPoint hiPoint ;
1710 HIGetMousePosition(kHICoordSpaceWindow, window, &hiPoint);
1711 pt.h = hiPoint.x;
1712 pt.v = hiPoint.y;
89954433 1713 #else
2d1760d3
SC
1714 CGrafPtr savePort ;
1715 Boolean swapped = QDSwapPort( GetWindowPort( window ) , &savePort ) ;
8b573fb8 1716
58603178
DS
1717 // TODO: If we ever get a GetCurrentEvent... replacement
1718 // for the mouse position, use it...
8b573fb8 1719
58603178
DS
1720
1721 GetMouse( &pt ) ;
4f74e0d1 1722#endif
9d463591 1723 control = FindControlUnderMouse( pt , window , &part ) ;
2d1760d3
SC
1724 if ( control )
1725 mouseWin = wxFindControlFromMacControl( control ) ;
8b573fb8 1726
4f74e0d1
SC
1727#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
1728 if ( swapped )
2d1760d3 1729 QDSwapPort( savePort , NULL ) ;
4f74e0d1 1730#endif
facd6764 1731 }
2d1760d3
SC
1732
1733 if ( mouseWin == this && !wxIsBusy() )
facd6764 1734 m_cursor.MacInstall() ;
facd6764 1735
902725ee 1736 return true ;
519cb848
SC
1737}
1738
facd6764
SC
1739#if wxUSE_MENUS
1740bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y)
1741{
6239ee05
SC
1742#ifndef __WXUNIVERSAL__
1743 menu->SetInvokingWindow((wxWindow*)this);
facd6764 1744 menu->UpdateUI();
8b573fb8 1745
851dee09 1746 if ( x == wxDefaultCoord && y == wxDefaultCoord )
971562cb
VS
1747 {
1748 wxPoint mouse = wxGetMousePosition();
898d9035
DS
1749 x = mouse.x;
1750 y = mouse.y;
971562cb
VS
1751 }
1752 else
1753 {
1754 ClientToScreen( &x , &y ) ;
1755 }
facd6764
SC
1756
1757 menu->MacBeforeDisplay( true ) ;
898d9035 1758 long menuResult = ::PopUpMenuSelect((MenuHandle) menu->GetHMenu() , y, x, 0) ;
facd6764
SC
1759 if ( HiWord(menuResult) != 0 )
1760 {
e8027adb
SC
1761 MenuCommand macid;
1762 GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult)) , LoWord(menuResult) , &macid );
b46dde27
DS
1763 int id = wxMacCommandToId( macid );
1764 wxMenuItem* item = NULL ;
facd6764 1765 wxMenu* realmenu ;
58603178 1766 item = menu->FindItem( id, &realmenu ) ;
e8027adb
SC
1767 if ( item )
1768 {
1769 if (item->IsCheckable())
1770 item->Check( !item->IsChecked() ) ;
e15f0a5e 1771
e8027adb
SC
1772 menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ;
1773 }
facd6764 1774 }
facd6764 1775
898d9035 1776 menu->MacAfterDisplay( true ) ;
8523a5f5 1777 menu->SetInvokingWindow( NULL );
facd6764 1778
902725ee 1779 return true;
6239ee05
SC
1780#else
1781 // actually this shouldn't be called, because universal is having its own implementation
1782 return false;
1783#endif
facd6764
SC
1784}
1785#endif
51abe921
SC
1786
1787// ----------------------------------------------------------------------------
1788// tooltips
1789// ----------------------------------------------------------------------------
1790
1791#if wxUSE_TOOLTIPS
1792
e766c8a9 1793void wxWindowMac::DoSetToolTip(wxToolTip *tooltip)
51abe921
SC
1794{
1795 wxWindowBase::DoSetToolTip(tooltip);
6ed71b4f 1796
6264b550
RR
1797 if ( m_tooltip )
1798 m_tooltip->SetWindow(this);
51abe921
SC
1799}
1800
898d9035 1801#endif
51abe921 1802
902725ee 1803void wxWindowMac::MacInvalidateBorders()
6449b3a8
SC
1804{
1805 if ( m_peer == NULL )
1806 return ;
1807
1808 bool vis = MacIsReallyShown() ;
1809 if ( !vis )
1810 return ;
902725ee 1811
6449b3a8
SC
1812 int outerBorder = MacGetLeftBorderSize() ;
1813 if ( m_peer->NeedsFocusRect() && m_peer->HasFocus() )
1814 outerBorder += 4 ;
1815
1816 if ( outerBorder == 0 )
1817 return ;
902725ee
WS
1818
1819 // now we know that we have something to do at all
6449b3a8
SC
1820
1821 // as the borders are drawn on the parent we have to properly invalidate all these areas
58603178
DS
1822 RgnHandle updateInner , updateOuter;
1823 Rect rect ;
6449b3a8
SC
1824
1825 // this rectangle is in HIViewCoordinates under OSX and in Window Coordinates under Carbon
58603178
DS
1826 updateInner = NewRgn() ;
1827 updateOuter = NewRgn() ;
1828
6449b3a8 1829 m_peer->GetRect( &rect ) ;
898d9035 1830 RectRgn( updateInner, &rect ) ;
6449b3a8 1831 InsetRect( &rect , -outerBorder , -outerBorder ) ;
898d9035
DS
1832 RectRgn( updateOuter, &rect ) ;
1833 DiffRgn( updateOuter, updateInner , updateOuter ) ;
e15f0a5e 1834
1f1c8bd4 1835 GetParent()->m_peer->SetNeedsDisplay( updateOuter ) ;
e15f0a5e 1836
58603178
DS
1837 DisposeRgn( updateOuter ) ;
1838 DisposeRgn( updateInner ) ;
6449b3a8
SC
1839}
1840
e766c8a9 1841void wxWindowMac::DoMoveWindow(int x, int y, int width, int height)
51abe921 1842{
db7a550b 1843 // this is never called for a toplevel window, so we know we have a parent
facd6764 1844 int former_x , former_y , former_w, former_h ;
db7a550b
SC
1845
1846 // Get true coordinates of former position
facd6764
SC
1847 DoGetPosition( &former_x , &former_y ) ;
1848 DoGetSize( &former_w , &former_h ) ;
db7a550b
SC
1849
1850 wxWindow *parent = GetParent();
1851 if ( parent )
1852 {
1853 wxPoint pt(parent->GetClientAreaOrigin());
1854 former_x += pt.x ;
1855 former_y += pt.y ;
1856 }
6ed71b4f 1857
29ee02df
SC
1858 int actualWidth = width ;
1859 int actualHeight = height ;
e40298d5
JS
1860 int actualX = x;
1861 int actualY = y;
6ed71b4f 1862
14c9cbdb 1863 if ((m_minWidth != -1) && (actualWidth < m_minWidth))
6264b550 1864 actualWidth = m_minWidth;
14c9cbdb 1865 if ((m_minHeight != -1) && (actualHeight < m_minHeight))
6264b550 1866 actualHeight = m_minHeight;
14c9cbdb 1867 if ((m_maxWidth != -1) && (actualWidth > m_maxWidth))
6264b550 1868 actualWidth = m_maxWidth;
14c9cbdb 1869 if ((m_maxHeight != -1) && (actualHeight > m_maxHeight))
902725ee 1870 actualHeight = m_maxHeight;
6ed71b4f 1871
898d9035 1872 bool doMove = false, doResize = false ;
6ed71b4f 1873
6264b550 1874 if ( actualX != former_x || actualY != former_y )
6264b550 1875 doMove = true ;
e15f0a5e 1876
6264b550 1877 if ( actualWidth != former_w || actualHeight != former_h )
6264b550 1878 doResize = true ;
6ed71b4f 1879
6264b550
RR
1880 if ( doMove || doResize )
1881 {
902725ee 1882 // as the borders are drawn outside the native control, we adjust now
1f1c8bd4 1883
902725ee
WS
1884 wxRect bounds( wxPoint( actualX + MacGetLeftBorderSize() ,actualY + MacGetTopBorderSize() ),
1885 wxSize( actualWidth - (MacGetLeftBorderSize() + MacGetRightBorderSize()) ,
1f1c8bd4
SC
1886 actualHeight - (MacGetTopBorderSize() + MacGetBottomBorderSize()) ) ) ;
1887
1888 Rect r ;
1889 wxMacRectToNative( &bounds , &r ) ;
1890
1891 if ( !GetParent()->IsTopLevel() )
1f1c8bd4 1892 wxMacWindowToNative( GetParent() , &r ) ;
8b573fb8 1893
6449b3a8 1894 MacInvalidateBorders() ;
902725ee 1895
5c840e5b 1896 m_cachedClippedRectValid = false ;
8b573fb8 1897 m_peer->SetRect( &r ) ;
902725ee 1898
e905b636 1899 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
91ae6e3a 1900
6449b3a8
SC
1901 MacInvalidateBorders() ;
1902
6264b550
RR
1903 MacRepositionScrollBars() ;
1904 if ( doMove )
1905 {
898d9035 1906 wxPoint point(actualX, actualY);
6264b550
RR
1907 wxMoveEvent event(point, m_windowId);
1908 event.SetEventObject(this);
1909 GetEventHandler()->ProcessEvent(event) ;
1910 }
e15f0a5e 1911
6264b550
RR
1912 if ( doResize )
1913 {
e40298d5 1914 MacRepositionScrollBars() ;
facd6764 1915 wxSize size(actualWidth, actualHeight);
e40298d5
JS
1916 wxSizeEvent event(size, m_windowId);
1917 event.SetEventObject(this);
1918 GetEventHandler()->ProcessEvent(event);
6264b550
RR
1919 }
1920 }
954fc50b
SC
1921}
1922
facd6764
SC
1923wxSize wxWindowMac::DoGetBestSize() const
1924{
eb69d46e
SC
1925 if ( m_macIsUserPane || IsTopLevel() )
1926 return wxWindowBase::DoGetBestSize() ;
8b573fb8 1927
facd6764 1928 Rect bestsize = { 0 , 0 , 0 , 0 } ;
facd6764 1929 int bestWidth, bestHeight ;
facd6764 1930
898d9035 1931 m_peer->GetBestRect( &bestsize ) ;
facd6764
SC
1932 if ( EmptyRect( &bestsize ) )
1933 {
898d9035
DS
1934 bestsize.left =
1935 bestsize.top = 0 ;
1936 bestsize.right =
facd6764 1937 bestsize.bottom = 16 ;
898d9035 1938
facd6764
SC
1939 if ( IsKindOf( CLASSINFO( wxScrollBar ) ) )
1940 {
1941 bestsize.bottom = 16 ;
1942 }
902725ee 1943#if wxUSE_SPINBTN
facd6764
SC
1944 else if ( IsKindOf( CLASSINFO( wxSpinButton ) ) )
1945 {
8b573fb8 1946 bestsize.bottom = 24 ;
facd6764 1947 }
898d9035 1948#endif
facd6764
SC
1949 else
1950 {
8b573fb8 1951 // return wxWindowBase::DoGetBestSize() ;
facd6764
SC
1952 }
1953 }
1954
1955 bestWidth = bestsize.right - bestsize.left ;
1956 bestHeight = bestsize.bottom - bestsize.top ;
1957 if ( bestHeight < 10 )
1958 bestHeight = 13 ;
8b573fb8 1959
facd6764
SC
1960 return wxSize(bestWidth, bestHeight);
1961}
1962
954fc50b
SC
1963// set the size of the window: if the dimensions are positive, just use them,
1964// but if any of them is equal to -1, it means that we must find the value for
1965// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
1966// which case -1 is a valid value for x and y)
1967//
1968// If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
1969// the width/height to best suit our contents, otherwise we reuse the current
1970// width/height
1971void wxWindowMac::DoSetSize(int x, int y, int width, int height, int sizeFlags)
1972{
1973 // get the current size and position...
1974 int currentX, currentY;
898d9035 1975 int currentW, currentH;
6ed71b4f 1976
898d9035 1977 GetPosition(&currentX, &currentY);
954fc50b 1978 GetSize(&currentW, &currentH);
6ed71b4f 1979
954fc50b
SC
1980 // ... and don't do anything (avoiding flicker) if it's already ok
1981 if ( x == currentX && y == currentY &&
769ac869 1982 width == currentW && height == currentH && ( height != -1 && width != -1 ) )
954fc50b 1983 {
e15f0a5e 1984 // TODO: REMOVE
6264b550 1985 MacRepositionScrollBars() ; // we might have a real position shift
898d9035 1986
954fc50b
SC
1987 return;
1988 }
6ed71b4f 1989
58603178
DS
1990 if ( !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
1991 {
1992 if ( x == wxDefaultCoord )
1993 x = currentX;
1994 if ( y == wxDefaultCoord )
1995 y = currentY;
1996 }
6ed71b4f 1997
58603178 1998 AdjustForParentClientOrigin( x, y, sizeFlags );
6ed71b4f 1999
3dee36ae
WS
2000 wxSize size = wxDefaultSize;
2001 if ( width == wxDefaultCoord )
954fc50b
SC
2002 {
2003 if ( sizeFlags & wxSIZE_AUTO_WIDTH )
2004 {
2005 size = DoGetBestSize();
2006 width = size.x;
2007 }
2008 else
2009 {
2010 // just take the current one
2011 width = currentW;
2012 }
2013 }
6ed71b4f 2014
3dee36ae 2015 if ( height == wxDefaultCoord )
954fc50b
SC
2016 {
2017 if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
2018 {
3dee36ae 2019 if ( size.x == wxDefaultCoord )
954fc50b 2020 size = DoGetBestSize();
898d9035 2021 // else: already called DoGetBestSize() above
6ed71b4f 2022
954fc50b
SC
2023 height = size.y;
2024 }
2025 else
2026 {
2027 // just take the current one
2028 height = currentH;
2029 }
2030 }
6ed71b4f 2031
58603178 2032 DoMoveWindow( x, y, width, height );
e9576ca5 2033}
519cb848 2034
e766c8a9 2035wxPoint wxWindowMac::GetClientAreaOrigin() const
e9576ca5 2036{
facd6764
SC
2037 RgnHandle rgn = NewRgn() ;
2038 Rect content ;
04d4e684 2039 if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr )
21638402
SC
2040 {
2041 GetRegionBounds( rgn , &content ) ;
2042 }
2043 else
2044 {
898d9035
DS
2045 content.left =
2046 content.top = 0 ;
21638402 2047 }
898d9035 2048
facd6764 2049 DisposeRgn( rgn ) ;
e15f0a5e
DS
2050
2051 return wxPoint( content.left + MacGetLeftBorderSize() , content.top + MacGetTopBorderSize() );
facd6764
SC
2052}
2053
2054void wxWindowMac::DoSetClientSize(int clientwidth, int clientheight)
2055{
d0dec992 2056 if ( clientwidth != wxDefaultCoord || clientheight != wxDefaultCoord )
facd6764
SC
2057 {
2058 int currentclientwidth , currentclientheight ;
2059 int currentwidth , currentheight ;
2060
2061 GetClientSize( &currentclientwidth , &currentclientheight ) ;
2062 GetSize( &currentwidth , &currentheight ) ;
2063
3dee36ae 2064 DoSetSize( wxDefaultCoord , wxDefaultCoord , currentwidth + clientwidth - currentclientwidth ,
facd6764
SC
2065 currentheight + clientheight - currentclientheight , wxSIZE_USE_EXISTING ) ;
2066 }
e9576ca5
SC
2067}
2068
fb5246be 2069void wxWindowMac::SetLabel(const wxString& title)
e9576ca5 2070{
6239ee05 2071 m_label = title ;
facd6764 2072
21fd5529 2073 if ( m_peer && m_peer->Ok() )
6239ee05 2074 m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics) ) ;
e15f0a5e 2075
6239ee05
SC
2076 // do not trigger refreshes upon invisible and possible partly created objects
2077 if ( MacIsReallyShown() )
2078 Refresh() ;
519cb848
SC
2079}
2080
fb5246be 2081wxString wxWindowMac::GetLabel() const
519cb848 2082{
ed60b502 2083 return m_label ;
519cb848
SC
2084}
2085
8ab50549
SC
2086bool wxWindowMac::Show(bool show)
2087{
542f604f 2088 bool former = MacIsReallyShown() ;
8ab50549 2089 if ( !wxWindowBase::Show(show) )
902725ee 2090 return false;
8b573fb8 2091
58603178 2092 // TODO: use visibilityChanged Carbon Event for OSX
2c899c20 2093 if ( m_peer )
2c899c20 2094 m_peer->SetVisibility( show , true ) ;
e15f0a5e 2095
542f604f
SC
2096 if ( former != MacIsReallyShown() )
2097 MacPropagateVisibilityChanged() ;
898d9035 2098
902725ee 2099 return true;
8ab50549
SC
2100}
2101
47a8a4d5 2102void wxWindowMac::DoEnable(bool enable)
8ab50549 2103{
5ca0d812 2104 m_peer->Enable( enable ) ;
8ab50549
SC
2105}
2106
8b573fb8 2107//
8ab50549
SC
2108// status change propagations (will be not necessary for OSX later )
2109//
2110
facd6764
SC
2111void wxWindowMac::MacPropagateVisibilityChanged()
2112{
73fe67bd 2113#if !TARGET_API_MAC_OSX
facd6764 2114 MacVisibilityChanged() ;
8b573fb8 2115
e15f0a5e 2116 wxWindowMac *child;
71f2fb52 2117 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
facd6764
SC
2118 while ( node )
2119 {
e15f0a5e 2120 child = node->GetData();
facd6764 2121 if ( child->IsShown() )
e15f0a5e
DS
2122 child->MacPropagateVisibilityChanged() ;
2123
facd6764
SC
2124 node = node->GetNext();
2125 }
73fe67bd 2126#endif
facd6764
SC
2127}
2128
89954433 2129void wxWindowMac::OnEnabled(bool WXUNUSED(enabled))
e9576ca5 2130{
73fe67bd 2131#if !TARGET_API_MAC_OSX
8ab50549 2132 MacEnabledStateChanged() ;
73fe67bd 2133#endif
8ab50549
SC
2134}
2135
e15f0a5e 2136void wxWindowMac::MacPropagateHiliteChanged()
8ab50549 2137{
73fe67bd 2138#if !TARGET_API_MAC_OSX
8ab50549 2139 MacHiliteChanged() ;
8b573fb8 2140
e15f0a5e 2141 wxWindowMac *child;
71f2fb52 2142 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
8ab50549
SC
2143 while ( node )
2144 {
e15f0a5e 2145 child = node->GetData();
898d9035 2146 if (child /* && child->IsEnabled() */)
8ab50549 2147 child->MacPropagateHiliteChanged() ;
e15f0a5e 2148
8ab50549
SC
2149 node = node->GetNext();
2150 }
73fe67bd 2151#endif
8ab50549
SC
2152}
2153
2154//
2155// status change notifications
8b573fb8 2156//
8ab50549 2157
8b573fb8 2158void wxWindowMac::MacVisibilityChanged()
8ab50549
SC
2159{
2160}
2161
8b573fb8 2162void wxWindowMac::MacHiliteChanged()
8ab50549
SC
2163{
2164}
2165
8b573fb8 2166void wxWindowMac::MacEnabledStateChanged()
8ab50549 2167{
facd6764 2168}
e7549107 2169
8ab50549
SC
2170//
2171// status queries on the inherited window's state
2172//
2173
8b573fb8 2174bool wxWindowMac::MacIsReallyShown()
facd6764
SC
2175{
2176 // only under OSX the visibility of the TLW is taken into account
66ffb23b
SC
2177 if ( m_isBeingDeleted )
2178 return false ;
902725ee 2179
facd6764 2180#if TARGET_API_MAC_OSX
aa522e33
SC
2181 if ( m_peer && m_peer->Ok() )
2182 return m_peer->IsVisible();
2183#endif
e15f0a5e 2184
facd6764 2185 wxWindow* win = this ;
898d9035 2186 while ( win->IsShown() )
facd6764
SC
2187 {
2188 if ( win->IsTopLevel() )
2189 return true ;
8b573fb8 2190
facd6764
SC
2191 win = win->GetParent() ;
2192 if ( win == NULL )
2193 return true ;
e15f0a5e 2194 }
8b573fb8 2195
facd6764 2196 return false ;
facd6764 2197}
4241baae 2198
8b573fb8 2199bool wxWindowMac::MacIsReallyEnabled()
facd6764 2200{
5ca0d812 2201 return m_peer->IsEnabled() ;
facd6764
SC
2202}
2203
8b573fb8 2204bool wxWindowMac::MacIsReallyHilited()
c809f3be 2205{
5ca0d812 2206 return m_peer->IsActive();
c809f3be
SC
2207}
2208
8b573fb8 2209void wxWindowMac::MacFlashInvalidAreas()
002c9672
SC
2210{
2211#if TARGET_API_MAC_OSX
2212 HIViewFlashDirtyArea( (WindowRef) MacGetTopLevelWindowRef() ) ;
2213#endif
2214}
2215
e766c8a9 2216int wxWindowMac::GetCharHeight() const
e9576ca5 2217{
e15f0a5e
DS
2218 wxClientDC dc( (wxWindowMac*)this ) ;
2219
6264b550 2220 return dc.GetCharHeight() ;
e9576ca5
SC
2221}
2222
e766c8a9 2223int wxWindowMac::GetCharWidth() const
e9576ca5 2224{
e15f0a5e
DS
2225 wxClientDC dc( (wxWindowMac*)this ) ;
2226
6264b550 2227 return dc.GetCharWidth() ;
e9576ca5
SC
2228}
2229
e766c8a9 2230void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y,
e7549107 2231 int *descent, int *externalLeading, const wxFont *theFont ) const
e9576ca5 2232{
e7549107
SC
2233 const wxFont *fontToUse = theFont;
2234 if ( !fontToUse )
2235 fontToUse = &m_font;
14c9cbdb 2236
e766c8a9 2237 wxClientDC dc( (wxWindowMac*) this ) ;
659863d8 2238 wxCoord lx,ly,ld,le ;
5fde6fcc 2239 dc.GetTextExtent( string , &lx , &ly , &ld, &le, (wxFont *)fontToUse ) ;
2f1ae414 2240 if ( externalLeading )
6264b550 2241 *externalLeading = le ;
2f1ae414 2242 if ( descent )
6264b550 2243 *descent = ld ;
2f1ae414 2244 if ( x )
6264b550 2245 *x = lx ;
2f1ae414 2246 if ( y )
6264b550 2247 *y = ly ;
e9576ca5
SC
2248}
2249
0a67a93b 2250/*
14c9cbdb 2251 * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect
1c310985
SC
2252 * we always intersect with the entire window, not only with the client area
2253 */
14c9cbdb 2254
89954433 2255void wxWindowMac::Refresh(bool WXUNUSED(eraseBack), const wxRect *rect)
e9576ca5 2256{
065ab451
SC
2257 if ( m_peer == NULL )
2258 return ;
8b573fb8 2259
1f1c8bd4
SC
2260 if ( !MacIsReallyShown() )
2261 return ;
789ae0cf 2262
1f1c8bd4 2263 if ( rect )
1e8cde71 2264 {
1f1c8bd4 2265 Rect r ;
898d9035 2266
1f1c8bd4
SC
2267 wxMacRectToNative( rect , &r ) ;
2268 m_peer->SetNeedsDisplay( &r ) ;
facd6764 2269 }
1f1c8bd4 2270 else
9a456218 2271 {
1f1c8bd4 2272 m_peer->SetNeedsDisplay() ;
e9576ca5 2273 }
facd6764
SC
2274}
2275
79392158
SC
2276void wxWindowMac::Freeze()
2277{
2278#if TARGET_API_MAC_OSX
2279 if ( !m_frozenness++ )
2280 {
52ef5c3c
RD
2281 if ( m_peer && m_peer->Ok() )
2282 m_peer->SetDrawingEnabled( false ) ;
79392158
SC
2283 }
2284#endif
2285}
2286
2287void wxWindowMac::Thaw()
2288{
2289#if TARGET_API_MAC_OSX
898d9035 2290 wxASSERT_MSG( m_frozenness > 0, wxT("Thaw() without matching Freeze()") );
79392158
SC
2291
2292 if ( !--m_frozenness )
2293 {
52ef5c3c
RD
2294 if ( m_peer && m_peer->Ok() )
2295 {
2296 m_peer->SetDrawingEnabled( true ) ;
2297 m_peer->InvalidateWithChildren() ;
2298 }
79392158
SC
2299 }
2300#endif
2301}
2302
fd39f7a8
RD
2303bool wxWindowMac::IsFrozen() const
2304{
2305 return m_frozenness != 0;
2306}
2307
e766c8a9 2308wxWindowMac *wxGetActiveWindow()
e9576ca5 2309{
519cb848 2310 // actually this is a windows-only concept
e9576ca5
SC
2311 return NULL;
2312}
2313
e9576ca5 2314// Coordinates relative to the window
89954433 2315void wxWindowMac::WarpPointer(int WXUNUSED(x_pos), int WXUNUSED(y_pos))
e9576ca5 2316{
e40298d5 2317 // We really don't move the mouse programmatically under Mac.
e9576ca5
SC
2318}
2319
facd6764 2320void wxWindowMac::OnEraseBackground(wxEraseEvent& event)
e9576ca5 2321{
3dee36ae
WS
2322 if ( MacGetTopLevelWindow() == NULL )
2323 return ;
898d9035 2324
be346c26 2325#if TARGET_API_MAC_OSX
4488a1d3
VZ
2326 if ( !m_macBackgroundBrush.Ok() || m_macBackgroundBrush.GetStyle() == wxTRANSPARENT
2327 || GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT )
94abc21f 2328 {
facd6764 2329 event.Skip() ;
94abc21f
SC
2330 }
2331 else
be346c26 2332#endif
7ebf5540 2333 {
8b573fb8 2334 event.GetDC()->Clear() ;
7ebf5540 2335 }
1c310985
SC
2336}
2337
2338void wxWindowMac::OnNcPaint( wxNcPaintEvent& event )
2339{
af6b7b80 2340 event.Skip() ;
e9576ca5
SC
2341}
2342
e766c8a9 2343int wxWindowMac::GetScrollPos(int orient) const
e9576ca5 2344{
1c310985
SC
2345 if ( orient == wxHORIZONTAL )
2346 {
2347 if ( m_hScrollBar )
2348 return m_hScrollBar->GetThumbPosition() ;
2349 }
2350 else
2351 {
2352 if ( m_vScrollBar )
2353 return m_vScrollBar->GetThumbPosition() ;
2354 }
e15f0a5e 2355
e9576ca5
SC
2356 return 0;
2357}
2358
2359// This now returns the whole range, not just the number
2360// of positions that we can scroll.
e766c8a9 2361int wxWindowMac::GetScrollRange(int orient) const
e9576ca5 2362{
1c310985
SC
2363 if ( orient == wxHORIZONTAL )
2364 {
2365 if ( m_hScrollBar )
2366 return m_hScrollBar->GetRange() ;
2367 }
2368 else
2369 {
2370 if ( m_vScrollBar )
2371 return m_vScrollBar->GetRange() ;
2372 }
e15f0a5e 2373
e9576ca5
SC
2374 return 0;
2375}
2376
e766c8a9 2377int wxWindowMac::GetScrollThumb(int orient) const
e9576ca5 2378{
1c310985
SC
2379 if ( orient == wxHORIZONTAL )
2380 {
2381 if ( m_hScrollBar )
2382 return m_hScrollBar->GetThumbSize() ;
2383 }
2384 else
2385 {
2386 if ( m_vScrollBar )
2387 return m_vScrollBar->GetThumbSize() ;
2388 }
e15f0a5e 2389
e9576ca5
SC
2390 return 0;
2391}
2392
89954433 2393void wxWindowMac::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh))
e9576ca5 2394{
1c310985 2395 if ( orient == wxHORIZONTAL )
6264b550 2396 {
1c310985
SC
2397 if ( m_hScrollBar )
2398 m_hScrollBar->SetThumbPosition( pos ) ;
6264b550
RR
2399 }
2400 else
2401 {
1c310985
SC
2402 if ( m_vScrollBar )
2403 m_vScrollBar->SetThumbPosition( pos ) ;
6264b550 2404 }
2f1ae414
SC
2405}
2406
c1142003
VZ
2407void
2408wxWindowMac::AlwaysShowScrollbars(bool hflag, bool vflag)
2409{
2410 bool needVisibilityUpdate = false;
2411
2412 if ( m_hScrollBarAlwaysShown != hflag )
2413 {
2414 m_hScrollBarAlwaysShown = hflag;
2415 needVisibilityUpdate = true;
2416 }
2417
2418 if ( m_vScrollBarAlwaysShown != vflag )
2419 {
2420 m_vScrollBarAlwaysShown = vflag;
2421 needVisibilityUpdate = true;
2422 }
2423
2424 if ( needVisibilityUpdate )
2425 DoUpdateScrollbarVisibility();
2426}
6239ee05 2427
c79aad8b
SC
2428//
2429// we draw borders and grow boxes, are already set up and clipped in the current port / cgContextRef
2430// our own window origin is at leftOrigin/rightOrigin
2431//
2432
6239ee05
SC
2433void wxWindowMac::MacPaintGrowBox()
2434{
2435 if ( IsTopLevel() )
2436 return ;
2437
2438#if wxMAC_USE_CORE_GRAPHICS
2439 if ( MacHasScrollBarCorner() )
2440 {
2441 Rect rect ;
2442
2443 CGContextRef cgContext = (CGContextRef) MacGetCGContextRef() ;
2444 wxASSERT( cgContext ) ;
2445
2446 m_peer->GetRect( &rect ) ;
2447
2448 int size = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ;
2449 CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ;
2450 CGPoint cgpoint = CGPointMake( rect.right - size , rect.bottom - size ) ;
2451 CGContextSaveGState( cgContext );
2452
2453 if ( m_macBackgroundBrush.Ok() && m_macBackgroundBrush.GetStyle() != wxTRANSPARENT )
2454 {
2455 wxMacCoreGraphicsColour bkgnd( m_macBackgroundBrush ) ;
2456 bkgnd.Apply( cgContext );
2457 }
2458 else
2459 {
2460 CGContextSetRGBFillColor( cgContext, 1.0, 1.0 , 1.0 , 1.0 );
2461 }
2462 CGContextFillRect( cgContext, cgrect );
2463 CGContextRestoreGState( cgContext );
2464 }
2465#endif
2466}
2467
89954433 2468void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(rightOrigin) )
2f1ae414 2469{
e15f0a5e 2470 if ( IsTopLevel() )
6264b550 2471 return ;
8b573fb8 2472
fd926bcc 2473 Rect rect ;
c79aad8b 2474 bool hasFocus = m_peer->NeedsFocusRect() && m_peer->HasFocus() ;
c79aad8b 2475
8f39b6c4 2476 // back to the surrounding frame rectangle
58603178 2477 m_peer->GetRect( &rect ) ;
8f39b6c4 2478 InsetRect( &rect, -1 , -1 ) ;
fd926bcc 2479
89954433 2480#if wxMAC_USE_CORE_GRAPHICS
c79aad8b 2481 {
8f39b6c4
SC
2482 CGRect cgrect = CGRectMake( rect.left , rect.top , rect.right - rect.left ,
2483 rect.bottom - rect.top ) ;
2484
c79aad8b 2485 HIThemeFrameDrawInfo info ;
58603178 2486 memset( &info, 0 , sizeof(info) ) ;
902725ee 2487
c79aad8b
SC
2488 info.version = 0 ;
2489 info.kind = 0 ;
2490 info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ;
2491 info.isFocused = hasFocus ;
c79aad8b
SC
2492
2493 CGContextRef cgContext = (CGContextRef) GetParent()->MacGetCGContextRef() ;
2494 wxASSERT( cgContext ) ;
902725ee 2495
e15f0a5e 2496 if ( HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) )
c79aad8b 2497 {
c79aad8b 2498 info.kind = kHIThemeFrameTextFieldSquare ;
8f39b6c4 2499 HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ;
c79aad8b 2500 }
e15f0a5e 2501 else if ( HasFlag(wxSIMPLE_BORDER) )
c79aad8b 2502 {
c79aad8b 2503 info.kind = kHIThemeFrameListBox ;
c79aad8b
SC
2504 HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ;
2505 }
2506 else if ( hasFocus )
2507 {
c79aad8b
SC
2508 HIThemeDrawFocusRect( &cgrect , true , cgContext , kHIThemeOrientationNormal ) ;
2509 }
6239ee05 2510#if 0 // TODO REMOVE now done in a separate call earlier in drawing the window itself
c79aad8b 2511 m_peer->GetRect( &rect ) ;
6239ee05 2512 if ( MacHasScrollBarCorner() )
c79aad8b 2513 {
6239ee05
SC
2514 int variant = (m_hScrollBar == NULL ? m_vScrollBar : m_hScrollBar ) ->GetWindowVariant();
2515 int size = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ;
8f39b6c4
SC
2516 CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ;
2517 CGPoint cgpoint = CGPointMake( rect.right - size , rect.bottom - size ) ;
902725ee 2518 HIThemeGrowBoxDrawInfo info ;
e15f0a5e 2519 memset( &info, 0, sizeof(info) ) ;
c79aad8b
SC
2520 info.version = 0 ;
2521 info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ;
2522 info.kind = kHIThemeGrowBoxKindNone ;
6239ee05 2523 // contrary to the docs ...SizeSmall does not work
c79aad8b 2524 info.size = kHIThemeGrowBoxSizeNormal ;
6239ee05 2525 info.direction = 0 ;
c79aad8b
SC
2526 HIThemeDrawGrowBox( &cgpoint , &info , cgContext , kHIThemeOrientationNormal ) ;
2527 }
6239ee05 2528#endif
c79aad8b 2529 }
4f74e0d1 2530 #else
fd926bcc
SC
2531 {
2532 wxTopLevelWindowMac* top = MacGetTopLevelWindow();
e15f0a5e 2533 if ( top )
fd926bcc 2534 {
e15f0a5e 2535 wxPoint pt(0, 0) ;
fd926bcc 2536 wxMacControl::Convert( &pt , GetParent()->m_peer , top->m_peer ) ;
1f1c8bd4 2537 OffsetRect( &rect , pt.x , pt.y ) ;
fd926bcc 2538 }
8b573fb8 2539
e15f0a5e
DS
2540 if ( HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) )
2541 DrawThemeEditTextFrame( &rect, IsEnabled() ? kThemeStateActive : kThemeStateInactive ) ;
2542 else if ( HasFlag(wxSIMPLE_BORDER) )
2543 DrawThemeListBoxFrame( &rect, IsEnabled() ? kThemeStateActive : kThemeStateInactive ) ;
902725ee 2544
c79aad8b 2545 if ( hasFocus )
8f39b6c4 2546 DrawThemeFocusRect( &rect , true ) ;
6239ee05
SC
2547 // TODO REMOVE
2548 /*
2549 if ( hasBothScrollbars ) // hasBothScrollbars is not declared
c79aad8b 2550 {
902725ee 2551 // GetThemeStandaloneGrowBoxBounds
e15f0a5e 2552 // DrawThemeStandaloneNoGrowBox
c79aad8b 2553 }
6239ee05 2554 */
eec462f8 2555 }
4f74e0d1 2556#endif
8208e181
SC
2557}
2558
abda5788
SC
2559void wxWindowMac::RemoveChild( wxWindowBase *child )
2560{
2561 if ( child == m_hScrollBar )
2562 m_hScrollBar = NULL ;
2563 if ( child == m_vScrollBar )
2564 m_vScrollBar = NULL ;
14c9cbdb 2565
abda5788
SC
2566 wxWindowBase::RemoveChild( child ) ;
2567}
2568
c1142003 2569void wxWindowMac::DoUpdateScrollbarVisibility()
e9576ca5 2570{
42cc0b31 2571 bool triggerSizeEvent = false;
58603178 2572
c1142003 2573 if ( m_hScrollBar )
e40298d5 2574 {
c1142003 2575 bool showHScrollBar = m_hScrollBarAlwaysShown || m_hScrollBar->IsNeeded();
e15f0a5e 2576
c1142003
VZ
2577 if ( m_hScrollBar->IsShown() != showHScrollBar )
2578 {
2579 m_hScrollBar->Show( showHScrollBar );
2580 triggerSizeEvent = true;
6264b550 2581 }
e40298d5 2582 }
c1142003
VZ
2583
2584 if ( m_vScrollBar)
e40298d5 2585 {
c1142003 2586 bool showVScrollBar = m_vScrollBarAlwaysShown || m_vScrollBar->IsNeeded();
e15f0a5e 2587
c1142003
VZ
2588 if ( m_vScrollBar->IsShown() != showVScrollBar )
2589 {
2590 m_vScrollBar->Show( showVScrollBar ) ;
2591 triggerSizeEvent = true;
6264b550 2592 }
e40298d5 2593 }
e15f0a5e 2594
e40298d5 2595 MacRepositionScrollBars() ;
42cc0b31
SC
2596 if ( triggerSizeEvent )
2597 {
2598 wxSizeEvent event(GetSize(), m_windowId);
2599 event.SetEventObject(this);
2600 GetEventHandler()->ProcessEvent(event);
2601 }
e9576ca5
SC
2602}
2603
c1142003
VZ
2604// New function that will replace some of the above.
2605void wxWindowMac::SetScrollbar(int orient, int pos, int thumb,
2606 int range, bool refresh)
2607{
2608 if ( orient == wxHORIZONTAL && m_hScrollBar )
2609 m_hScrollBar->SetScrollbar(pos, thumb, range, thumb, refresh);
2610 else if ( orient == wxVERTICAL && m_vScrollBar )
2611 m_vScrollBar->SetScrollbar(pos, thumb, range, thumb, refresh);
2612
2613 DoUpdateScrollbarVisibility();
2614}
2615
e9576ca5 2616// Does a physical scroll
e766c8a9 2617void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
e9576ca5 2618{
898d9035 2619 if ( dx == 0 && dy == 0 )
ba87f54c 2620 return ;
8b573fb8 2621
3dee36ae
WS
2622 int width , height ;
2623 GetClientSize( &width , &height ) ;
e15f0a5e 2624
902725ee 2625 {
002c9672 2626 // note there currently is a bug in OSX which makes inefficient refreshes in case an entire control
8b573fb8 2627 // area is scrolled, this does not occur if width and height are 2 pixels less,
58603178 2628 // TODO: write optimal workaround
898d9035 2629 wxRect scrollrect( MacGetLeftBorderSize() , MacGetTopBorderSize() , width , height ) ;
8b573fb8 2630 if ( rect )
5ca0d812 2631 scrollrect.Intersect( *rect ) ;
e15f0a5e 2632
5ca0d812 2633 if ( m_peer->GetNeedsDisplay() )
002c9672 2634 {
58603178 2635 // because HIViewScrollRect does not scroll the already invalidated area we have two options:
8dd37b03 2636 // in case there is already a pending redraw on that area
002c9672
SC
2637 // either immediate redraw or full invalidate
2638#if 1
2639 // is the better overall solution, as it does not slow down scrolling
1f1c8bd4 2640 m_peer->SetNeedsDisplay() ;
002c9672 2641#else
8b573fb8 2642 // this would be the preferred version for fast drawing controls
80f3f3be 2643 HIViewRender(m_peer->GetControlRef()) ;
002c9672
SC
2644#endif
2645 }
e15f0a5e 2646
84e5d27d
SC
2647 // as the native control might be not a 0/0 wx window coordinates, we have to offset
2648 scrollrect.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ;
898d9035 2649 m_peer->ScrollRect( &scrollrect , dx , dy ) ;
92346151 2650
92346151 2651#if 0
902725ee 2652 // this would be the preferred version for fast drawing controls
4f74e0d1 2653 HIViewRender(m_peer->GetControlRef()) ;
92346151 2654#endif
902725ee 2655 }
6ed71b4f 2656
e15f0a5e
DS
2657 wxWindowMac *child;
2658 int x, y, w, h;
71f2fb52 2659 for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext())
6264b550 2660 {
e15f0a5e
DS
2661 child = node->GetData();
2662 if (child == NULL)
2663 continue;
2664 if (child == m_vScrollBar)
2665 continue;
2666 if (child == m_hScrollBar)
2667 continue;
2668 if (child->IsTopLevel())
2669 continue;
6ed71b4f 2670
6264b550 2671 child->GetPosition( &x, &y );
6264b550 2672 child->GetSize( &w, &h );
00f55394
SC
2673 if (rect)
2674 {
e15f0a5e
DS
2675 wxRect rc( x, y, w, h );
2676 if (rect->Intersects( rc ))
8d1547ef 2677 child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE );
00f55394
SC
2678 }
2679 else
2680 {
8d1547ef 2681 child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE );
8b573fb8 2682 }
6264b550 2683 }
e9576ca5
SC
2684}
2685
e15f0a5e 2686void wxWindowMac::MacOnScroll( wxScrollEvent &event )
7c74e7fe 2687{
687706f5 2688 if ( event.GetEventObject() == m_vScrollBar || event.GetEventObject() == m_hScrollBar )
6264b550
RR
2689 {
2690 wxScrollWinEvent wevent;
2691 wevent.SetPosition(event.GetPosition());
2692 wevent.SetOrientation(event.GetOrientation());
687706f5
KH
2693 wevent.SetEventObject(this);
2694
2695 if (event.GetEventType() == wxEVT_SCROLL_TOP)
2696 wevent.SetEventType( wxEVT_SCROLLWIN_TOP );
2697 else if (event.GetEventType() == wxEVT_SCROLL_BOTTOM)
2698 wevent.SetEventType( wxEVT_SCROLLWIN_BOTTOM );
2699 else if (event.GetEventType() == wxEVT_SCROLL_LINEUP)
2700 wevent.SetEventType( wxEVT_SCROLLWIN_LINEUP );
2701 else if (event.GetEventType() == wxEVT_SCROLL_LINEDOWN)
2702 wevent.SetEventType( wxEVT_SCROLLWIN_LINEDOWN );
2703 else if (event.GetEventType() == wxEVT_SCROLL_PAGEUP)
2704 wevent.SetEventType( wxEVT_SCROLLWIN_PAGEUP );
2705 else if (event.GetEventType() == wxEVT_SCROLL_PAGEDOWN)
2706 wevent.SetEventType( wxEVT_SCROLLWIN_PAGEDOWN );
2707 else if (event.GetEventType() == wxEVT_SCROLL_THUMBTRACK)
2708 wevent.SetEventType( wxEVT_SCROLLWIN_THUMBTRACK );
2709 else if (event.GetEventType() == wxEVT_SCROLL_THUMBRELEASE)
2710 wevent.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE );
6ed71b4f
VZ
2711
2712 GetEventHandler()->ProcessEvent(wevent);
7c74e7fe
SC
2713 }
2714}
2715
e9576ca5 2716// Get the window with the focus
0fe02759 2717wxWindowMac *wxWindowBase::DoFindFocus()
e9576ca5 2718{
f1d527c1
SC
2719 ControlRef control ;
2720 GetKeyboardFocus( GetUserFocusWindow() , &control ) ;
2721 return wxFindControlFromMacControl( control ) ;
519cb848
SC
2722}
2723
e15f0a5e 2724void wxWindowMac::OnSetFocus( wxFocusEvent& event )
7810c95b
SC
2725{
2726 // panel wants to track the window which was the last to have focus in it,
2727 // so we want to set ourselves as the window which last had focus
2728 //
dac390e9 2729 // notice that it's also important to do it upwards the tree because
7810c95b
SC
2730 // otherwise when the top level panel gets focus, it won't set it back to
2731 // us, but to some other sibling
6ed71b4f 2732
dac390e9 2733 // CS: don't know if this is still needed:
c1fb8167
SC
2734 //wxChildFocusEvent eventFocus(this);
2735 //(void)GetEventHandler()->ProcessEvent(eventFocus);
7810c95b 2736
5ca0d812
SC
2737 if ( MacGetTopLevelWindow() && m_peer->NeedsFocusRect() )
2738 {
dac390e9
DS
2739#if wxMAC_USE_CORE_GRAPHICS
2740 GetParent()->Refresh() ;
2741#else
788e118f 2742 wxMacWindowStateSaver sv( this ) ;
6449b3a8 2743 Rect rect ;
dac390e9 2744
6449b3a8 2745 m_peer->GetRect( &rect ) ;
6239ee05 2746 // auf den umgebenden Rahmen zurチᅡ゚ck
8f39b6c4 2747 InsetRect( &rect, -1 , -1 ) ;
1f1c8bd4 2748
6449b3a8 2749 wxTopLevelWindowMac* top = MacGetTopLevelWindow();
dac390e9 2750 if ( top )
6449b3a8 2751 {
898d9035 2752 wxPoint pt(0, 0) ;
6449b3a8
SC
2753 wxMacControl::Convert( &pt , GetParent()->m_peer , top->m_peer ) ;
2754 rect.left += pt.x ;
2755 rect.right += pt.x ;
2756 rect.top += pt.y ;
2757 rect.bottom += pt.y ;
2758 }
5ca0d812 2759
fbc1d11b 2760 bool bIsFocusEvent = (event.GetEventType() == wxEVT_SET_FOCUS);
c394a432 2761 DrawThemeFocusRect( &rect , bIsFocusEvent ) ;
dac390e9 2762 if ( !bIsFocusEvent )
af6b7b80 2763 {
af6b7b80 2764 // as this erases part of the frame we have to redraw borders
101634b2
SC
2765 // and because our z-ordering is not always correct (staticboxes)
2766 // we have to invalidate things, we cannot simple redraw
6449b3a8 2767 MacInvalidateBorders() ;
af6b7b80 2768 }
ff3795ee 2769#endif
5ca0d812
SC
2770 }
2771
7810c95b
SC
2772 event.Skip();
2773}
2774
e39af974 2775void wxWindowMac::OnInternalIdle()
e9576ca5 2776{
e9576ca5
SC
2777 // This calls the UI-update mechanism (querying windows for
2778 // menu/toolbar/control state information)
6239ee05 2779 if (wxUpdateUIEvent::CanUpdate(this) && IsShown())
e39af974 2780 UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
e9576ca5
SC
2781}
2782
2783// Raise the window to the top of the Z order
e766c8a9 2784void wxWindowMac::Raise()
e9576ca5 2785{
5ca0d812 2786 m_peer->SetZOrder( true , NULL ) ;
e9576ca5
SC
2787}
2788
2789// Lower the window to the bottom of the Z order
e766c8a9 2790void wxWindowMac::Lower()
e9576ca5 2791{
5ca0d812 2792 m_peer->SetZOrder( false , NULL ) ;
e9576ca5
SC
2793}
2794
facd6764 2795// static wxWindow *gs_lastWhich = NULL;
519cb848 2796
e15f0a5e 2797bool wxWindowMac::MacSetupCursor( const wxPoint& pt )
467e3168
SC
2798{
2799 // first trigger a set cursor event
6ed71b4f 2800
467e3168
SC
2801 wxPoint clientorigin = GetClientAreaOrigin() ;
2802 wxSize clientsize = GetClientSize() ;
2803 wxCursor cursor ;
2804 if ( wxRect2DInt( clientorigin.x , clientorigin.y , clientsize.x , clientsize.y ).Contains( wxPoint2DInt( pt ) ) )
7de59551 2805 {
467e3168 2806 wxSetCursorEvent event( pt.x , pt.y );
6ed71b4f 2807
467e3168
SC
2808 bool processedEvtSetCursor = GetEventHandler()->ProcessEvent(event);
2809 if ( processedEvtSetCursor && event.HasCursor() )
2810 {
e40298d5 2811 cursor = event.GetCursor() ;
467e3168
SC
2812 }
2813 else
2814 {
467e3168
SC
2815 // the test for processedEvtSetCursor is here to prevent using m_cursor
2816 // if the user code caught EVT_SET_CURSOR() and returned nothing from
2817 // it - this is a way to say that our cursor shouldn't be used for this
2818 // point
2819 if ( !processedEvtSetCursor && m_cursor.Ok() )
467e3168 2820 cursor = m_cursor ;
e15f0a5e
DS
2821
2822 if ( !wxIsBusy() && !GetParent() )
2823 cursor = *wxSTANDARD_CURSOR ;
467e3168 2824 }
e15f0a5e 2825
467e3168
SC
2826 if ( cursor.Ok() )
2827 cursor.MacInstall() ;
2828 }
e15f0a5e 2829
467e3168
SC
2830 return cursor.Ok() ;
2831}
2832
89954433 2833wxString wxWindowMac::MacGetToolTipString( wxPoint &WXUNUSED(pt) )
2f1ae414 2834{
5e0526df 2835#if wxUSE_TOOLTIPS
6264b550 2836 if ( m_tooltip )
6264b550 2837 return m_tooltip->GetTip() ;
5e0526df 2838#endif
e15f0a5e 2839
427ff662 2840 return wxEmptyString ;
2f1ae414 2841}
6264b550 2842
cb4b0966
SC
2843void wxWindowMac::ClearBackground()
2844{
2845 Refresh() ;
2846 Update() ;
2847}
2848
1c310985 2849void wxWindowMac::Update()
519cb848 2850{
facd6764 2851#if TARGET_API_MAC_OSX
5bcdf503
JS
2852 wxTopLevelWindowMac* top = MacGetTopLevelWindow();
2853 if (top)
2854 top->MacPerformUpdates() ;
facd6764 2855#else
5ca0d812 2856 ::Draw1Control( m_peer->GetControlRef() ) ;
bec721ec 2857#endif
519cb848
SC
2858}
2859
14c9cbdb 2860wxTopLevelWindowMac* wxWindowMac::MacGetTopLevelWindow() const
519cb848 2861{
1c310985 2862 wxTopLevelWindowMac* win = NULL ;
facd6764 2863 WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
1c310985 2864 if ( window )
1c310985 2865 win = wxFindWinFromMacWindow( window ) ;
e15f0a5e 2866
1c310985 2867 return win ;
519cb848 2868}
5c840e5b 2869
902725ee 2870const wxRect& wxWindowMac::MacGetClippedClientRect() const
e905b636
SC
2871{
2872 MacUpdateClippedRects() ;
e15f0a5e 2873
e905b636
SC
2874 return m_cachedClippedClientRect ;
2875}
2876
902725ee 2877const wxRect& wxWindowMac::MacGetClippedRect() const
5c840e5b
SC
2878{
2879 MacUpdateClippedRects() ;
e15f0a5e 2880
5c840e5b
SC
2881 return m_cachedClippedRect ;
2882}
2883
902725ee 2884const wxRect&wxWindowMac:: MacGetClippedRectWithOuterStructure() const
5c840e5b
SC
2885{
2886 MacUpdateClippedRects() ;
e15f0a5e 2887
5c840e5b
SC
2888 return m_cachedClippedRectWithOuterStructure ;
2889}
2890
2891const wxRegion& wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures )
94abc21f 2892{
5c840e5b 2893 static wxRegion emptyrgn ;
898d9035 2894
5c840e5b
SC
2895 if ( !m_isBeingDeleted && MacIsReallyShown() /*m_peer->IsVisible() */ )
2896 {
2897 MacUpdateClippedRects() ;
2898 if ( includeOuterStructures )
2899 return m_cachedClippedRegionWithOuterStructure ;
2900 else
2901 return m_cachedClippedRegion ;
2902 }
2903 else
2904 {
2905 return emptyrgn ;
2906 }
2907}
2908
2909void wxWindowMac::MacUpdateClippedRects() const
2910{
2911 if ( m_cachedClippedRectValid )
2912 return ;
2913
0fa8508d
SC
2914 // includeOuterStructures is true if we try to draw somthing like a focus ring etc.
2915 // also a window dc uses this, in this case we only clip in the hierarchy for hard
2916 // borders like a scrollwindow, splitter etc otherwise we end up in a paranoia having
2917 // to add focus borders everywhere
8b573fb8 2918
e15f0a5e 2919 Rect r, rIncludingOuterStructures ;
902725ee 2920
5c840e5b
SC
2921 m_peer->GetRect( &r ) ;
2922 r.left -= MacGetLeftBorderSize() ;
2923 r.top -= MacGetTopBorderSize() ;
2924 r.bottom += MacGetBottomBorderSize() ;
2925 r.right += MacGetRightBorderSize() ;
2926
2927 r.right -= r.left ;
2928 r.bottom -= r.top ;
2929 r.left = 0 ;
2930 r.top = 0 ;
2931
2932 rIncludingOuterStructures = r ;
2933 InsetRect( &rIncludingOuterStructures , -4 , -4 ) ;
902725ee 2934
e905b636
SC
2935 wxRect cl = GetClientRect() ;
2936 Rect rClient = { cl.y , cl.x , cl.y + cl.height , cl.x + cl.width } ;
902725ee 2937
e15f0a5e
DS
2938 int x , y ;
2939 wxSize size ;
e905b636
SC
2940 const wxWindow* child = this ;
2941 const wxWindow* parent = NULL ;
898d9035 2942
e15f0a5e 2943 while ( !child->IsTopLevel() && ( parent = child->GetParent() ) != NULL )
e40298d5 2944 {
e905b636 2945 if ( parent->MacIsChildOfClientArea(child) )
94abc21f 2946 {
e905b636
SC
2947 size = parent->GetClientSize() ;
2948 wxPoint origin = parent->GetClientAreaOrigin() ;
2949 x = origin.x ;
2950 y = origin.y ;
2951 }
2952 else
2953 {
2954 // this will be true for scrollbars, toolbars etc.
2955 size = parent->GetSize() ;
2956 y = parent->MacGetTopBorderSize() ;
2957 x = parent->MacGetLeftBorderSize() ;
2958 size.x -= parent->MacGetLeftBorderSize() + parent->MacGetRightBorderSize() ;
2959 size.y -= parent->MacGetTopBorderSize() + parent->MacGetBottomBorderSize() ;
2960 }
21f9e953 2961
e905b636
SC
2962 parent->MacWindowToRootWindow( &x, &y ) ;
2963 MacRootWindowToWindow( &x , &y ) ;
21f9e953 2964
e905b636 2965 Rect rparent = { y , x , y + size.y , x + size.x } ;
5c840e5b 2966
e905b636
SC
2967 // the wxwindow and client rects will always be clipped
2968 SectRect( &r , &rparent , &r ) ;
2969 SectRect( &rClient , &rparent , &rClient ) ;
5c840e5b 2970
e905b636
SC
2971 // the structure only at 'hard' borders
2972 if ( parent->MacClipChildren() ||
2973 ( parent->GetParent() && parent->GetParent()->MacClipGrandChildren() ) )
2974 {
2975 SectRect( &rIncludingOuterStructures , &rparent , &rIncludingOuterStructures ) ;
94abc21f 2976 }
e15f0a5e 2977
e905b636 2978 child = parent ;
e40298d5 2979 }
902725ee 2980
5c840e5b 2981 m_cachedClippedRect = wxRect( r.left , r.top , r.right - r.left , r.bottom - r.top ) ;
902725ee 2982 m_cachedClippedClientRect = wxRect( rClient.left , rClient.top ,
e905b636 2983 rClient.right - rClient.left , rClient.bottom - rClient.top ) ;
902725ee
WS
2984 m_cachedClippedRectWithOuterStructure = wxRect(
2985 rIncludingOuterStructures.left , rIncludingOuterStructures.top ,
2986 rIncludingOuterStructures.right - rIncludingOuterStructures.left ,
5c840e5b 2987 rIncludingOuterStructures.bottom - rIncludingOuterStructures.top ) ;
902725ee 2988
5c840e5b
SC
2989 m_cachedClippedRegionWithOuterStructure = wxRegion( m_cachedClippedRectWithOuterStructure ) ;
2990 m_cachedClippedRegion = wxRegion( m_cachedClippedRect ) ;
e905b636 2991 m_cachedClippedClientRegion = wxRegion( m_cachedClippedClientRect ) ;
902725ee 2992
5c840e5b 2993 m_cachedClippedRectValid = true ;
94abc21f
SC
2994}
2995
facd6764
SC
2996/*
2997 This function must not change the updatergn !
2998 */
8b573fb8 2999bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time )
519cb848 3000{
facd6764 3001 bool handled = false ;
42ef83fa 3002 Rect updatebounds ;
e15f0a5e 3003 RgnHandle updatergn = (RgnHandle) updatergnr ;
42ef83fa 3004 GetRegionBounds( updatergn , &updatebounds ) ;
20b69855 3005
e15f0a5e 3006 // wxLogDebug(wxT("update for %s bounds %d, %d, %d, %d"), wxString(GetClassInfo()->GetClassName()).c_str(), updatebounds.left, updatebounds.top , updatebounds.right , updatebounds.bottom ) ;
c79aad8b 3007
902725ee 3008 if ( !EmptyRgn(updatergn) )
6264b550 3009 {
1c310985
SC
3010 RgnHandle newupdate = NewRgn() ;
3011 wxSize point = GetClientSize() ;
3012 wxPoint origin = GetClientAreaOrigin() ;
e15f0a5e 3013 SetRectRgn( newupdate , origin.x , origin.y , origin.x + point.x , origin.y + point.y ) ;
facd6764 3014 SectRgn( newupdate , updatergn , newupdate ) ;
8b573fb8 3015
eec462f8
SC
3016 // first send an erase event to the entire update area
3017 {
c79aad8b
SC
3018 // for the toplevel window this really is the entire area
3019 // for all the others only their client area, otherwise they
3020 // might be drawing with full alpha and eg put blue into
3021 // the grow-box area of a scrolled window (scroll sample)
5c840e5b 3022 wxDC* dc = new wxWindowDC(this);
c79aad8b 3023 if ( IsTopLevel() )
5c840e5b 3024 dc->SetClippingRegion(wxRegion(updatergn));
c79aad8b 3025 else
5c840e5b 3026 dc->SetClippingRegion(wxRegion(newupdate));
902725ee 3027
c79aad8b 3028 wxEraseEvent eevent( GetId(), dc );
42ef83fa
SC
3029 eevent.SetEventObject( this );
3030 GetEventHandler()->ProcessEvent( eevent );
c79aad8b 3031 delete dc ;
eec462f8 3032 }
8b573fb8 3033
6239ee05
SC
3034 MacPaintGrowBox();
3035
42ef83fa 3036 // calculate a client-origin version of the update rgn and set m_updateRegion to that
1c310985
SC
3037 OffsetRgn( newupdate , -origin.x , -origin.y ) ;
3038 m_updateRegion = newupdate ;
8b573fb8 3039 DisposeRgn( newupdate ) ;
6ed71b4f 3040
1c310985 3041 if ( !m_updateRegion.Empty() )
6264b550 3042 {
facd6764 3043 // paint the window itself
ff3795ee 3044
e40298d5 3045 wxPaintEvent event;
687706f5 3046 event.SetTimestamp(time);
e40298d5 3047 event.SetEventObject(this);
ff3795ee
SC
3048 GetEventHandler()->ProcessEvent(event);
3049 handled = true ;
eec462f8 3050 }
8b573fb8 3051
eec462f8
SC
3052 // now we cannot rely on having its borders drawn by a window itself, as it does not
3053 // get the updateRgn wide enough to always do so, so we do it from the parent
3054 // this would also be the place to draw any custom backgrounds for native controls
3055 // in Composited windowing
36d7f54e 3056 wxPoint clientOrigin = GetClientAreaOrigin() ;
8b573fb8 3057
e15f0a5e
DS
3058 wxWindowMac *child;
3059 int x, y, w, h;
71f2fb52 3060 for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext())
eec462f8 3061 {
e15f0a5e
DS
3062 child = node->GetData();
3063 if (child == NULL)
3064 continue;
3065 if (child == m_vScrollBar)
3066 continue;
3067 if (child == m_hScrollBar)
3068 continue;
3069 if (child->IsTopLevel())
3070 continue;
3071 if (!child->IsShown())
3072 continue;
fe779e40 3073
c79aad8b
SC
3074 // only draw those in the update region (add a safety margin of 10 pixels for shadow effects
3075
af6b7b80 3076 child->GetPosition( &x, &y );
af6b7b80
SC
3077 child->GetSize( &w, &h );
3078 Rect childRect = { y , x , y + h , x + w } ;
36d7f54e 3079 OffsetRect( &childRect , clientOrigin.x , clientOrigin.y ) ;
c79aad8b
SC
3080 InsetRect( &childRect , -10 , -10) ;
3081
3082 if ( RectInRgn( &childRect , updatergn ) )
eec462f8 3083 {
c79aad8b
SC
3084 // paint custom borders
3085 wxNcPaintEvent eventNc( child->GetId() );
3086 eventNc.SetEventObject( child );
3087 if ( !child->GetEventHandler()->ProcessEvent( eventNc ) )
eec462f8 3088 {
89954433 3089#if wxMAC_USE_CORE_GRAPHICS
4f74e0d1
SC
3090 child->MacPaintBorders(0, 0) ;
3091#else
af6b7b80
SC
3092 {
3093 wxWindowDC dc(this) ;
3094 dc.SetClippingRegion(wxRegion(updatergn));
3095 wxMacPortSetter helper(&dc) ;
898d9035 3096 child->MacPaintBorders(0, 0) ;
c79aad8b 3097 }
4f74e0d1 3098#endif
eec462f8 3099 }
8b573fb8 3100 }
14c9cbdb 3101 }
6264b550 3102 }
e15f0a5e 3103
facd6764
SC
3104 return handled ;
3105}
6ed71b4f 3106
519cb848 3107
facd6764 3108WXWindow wxWindowMac::MacGetTopLevelWindowRef() const
519cb848 3109{
6264b550 3110 wxWindowMac *iter = (wxWindowMac*)this ;
14c9cbdb 3111
e15f0a5e 3112 while ( iter )
6264b550 3113 {
1c310985 3114 if ( iter->IsTopLevel() )
6239ee05
SC
3115 {
3116 wxTopLevelWindow* toplevel = wxDynamicCast(iter,wxTopLevelWindow);
3117 if ( toplevel )
3118 return toplevel->MacGetWindowRef();
3119#if wxUSE_POPUPWIN
3120 wxPopupWindow* popupwin = wxDynamicCast(iter,wxPopupWindow);
3121 if ( popupwin )
3122 return popupwin->MacGetPopupWindowRef();
3123#endif
3124 }
6264b550 3125 iter = iter->GetParent() ;
14c9cbdb 3126 }
e15f0a5e 3127
6264b550 3128 return NULL ;
519cb848
SC
3129}
3130
6239ee05
SC
3131bool wxWindowMac::MacHasScrollBarCorner() const
3132{
3133 /* Returns whether the scroll bars in a wxScrolledWindow should be
3134 * shortened. Scroll bars should be shortened if either:
3135 *
3136 * - both scroll bars are visible, or
3137 *
3138 * - there is a resize box in the parent frame's corner and this
3139 * window shares the bottom and right edge with the parent
3140 * frame.
3141 */
3142
3143 if ( m_hScrollBar == NULL && m_vScrollBar == NULL )
3144 return false;
3145
3146 if ( ( m_hScrollBar && m_hScrollBar->IsShown() )
3147 && ( m_vScrollBar && m_vScrollBar->IsShown() ) )
3148 {
3149 // Both scroll bars visible
3150 return true;
3151 }
3152 else
3153 {
3154 wxPoint thisWindowBottomRight = GetScreenRect().GetBottomRight();
3155
3156 for ( const wxWindow *win = this; win; win = win->GetParent() )
3157 {
3158 const wxFrame *frame = wxDynamicCast( win, wxFrame ) ;
3159 if ( frame )
3160 {
3161 if ( frame->GetWindowStyleFlag() & wxRESIZE_BORDER )
3162 {
3163 // Parent frame has resize handle
3164 wxPoint frameBottomRight = frame->GetScreenRect().GetBottomRight();
3165
3166 // Note: allow for some wiggle room here as wxMac's
3167 // window rect calculations seem to be imprecise
3168 if ( abs( thisWindowBottomRight.x - frameBottomRight.x ) <= 2
3169 && abs( thisWindowBottomRight.y - frameBottomRight.y ) <= 2 )
3170 {
3171 // Parent frame has resize handle and shares
3172 // right bottom corner
3173 return true ;
3174 }
3175 else
3176 {
3177 // Parent frame has resize handle but doesn't
3178 // share right bottom corner
3179 return false ;
3180 }
3181 }
3182 else
3183 {
3184 // Parent frame doesn't have resize handle
3185 return false ;
3186 }
3187 }
3188 }
3189
3190 // No parent frame found
3191 return false ;
3192 }
3193}
3194
14c9cbdb 3195void wxWindowMac::MacCreateScrollBars( long style )
519cb848 3196{
427ff662 3197 wxASSERT_MSG( m_vScrollBar == NULL && m_hScrollBar == NULL , wxT("attempt to create window twice") ) ;
14c9cbdb 3198
aa99e0cd
SC
3199 if ( style & ( wxVSCROLL | wxHSCROLL ) )
3200 {
db7a550b 3201 int scrlsize = MAC_SCROLLBAR_SIZE ;
8b573fb8
VZ
3202 if ( GetWindowVariant() == wxWINDOW_VARIANT_SMALL || GetWindowVariant() == wxWINDOW_VARIANT_MINI )
3203 {
3204 scrlsize = MAC_SMALL_SCROLLBAR_SIZE ;
8b573fb8 3205 }
db7a550b 3206
6239ee05 3207 int adjust = MacHasScrollBarCorner() ? scrlsize - 1: 0 ;
aa99e0cd
SC
3208 int width, height ;
3209 GetClientSize( &width , &height ) ;
3210
898d9035 3211 wxPoint vPoint(width - scrlsize, 0) ;
db7a550b 3212 wxSize vSize(scrlsize, height - adjust) ;
fbc1d11b
DS
3213 wxPoint hPoint(0, height - scrlsize) ;
3214 wxSize hSize(width - adjust, scrlsize) ;
aa99e0cd 3215
6239ee05 3216 // we have to set the min size to a smaller value, otherwise they cannot get smaller (InitialSize sets MinSize)
aa99e0cd 3217 if ( style & wxVSCROLL )
6239ee05
SC
3218 {
3219 m_vScrollBar = new wxScrollBar((wxWindow*)this, wxID_ANY, vPoint, vSize , wxVERTICAL);
3220 m_vScrollBar->SetMinSize( wxDefaultSize );
3221 }
aa99e0cd
SC
3222
3223 if ( style & wxHSCROLL )
6239ee05
SC
3224 {
3225 m_hScrollBar = new wxScrollBar((wxWindow*)this, wxID_ANY, hPoint, hSize , wxHORIZONTAL);
3226 m_hScrollBar->SetMinSize( wxDefaultSize );
3227 }
aa99e0cd 3228 }
aa99e0cd 3229
6264b550 3230 // because the create does not take into account the client area origin
e15f0a5e
DS
3231 // we might have a real position shift
3232 MacRepositionScrollBars() ;
519cb848
SC
3233}
3234
e905b636
SC
3235bool wxWindowMac::MacIsChildOfClientArea( const wxWindow* child ) const
3236{
fbc1d11b
DS
3237 bool result = ((child == NULL) || ((child != m_hScrollBar) && (child != m_vScrollBar)));
3238
3239 return result ;
e905b636
SC
3240}
3241
e766c8a9 3242void wxWindowMac::MacRepositionScrollBars()
519cb848 3243{
aa99e0cd
SC
3244 if ( !m_hScrollBar && !m_vScrollBar )
3245 return ;
8b573fb8 3246
db7a550b 3247 int scrlsize = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ;
6239ee05 3248 int adjust = MacHasScrollBarCorner() ? scrlsize - 1 : 0 ;
14c9cbdb 3249
6264b550 3250 // get real client area
e15f0a5e
DS
3251 int width, height ;
3252 GetSize( &width , &height );
6264b550
RR
3253
3254 width -= MacGetLeftBorderSize() + MacGetRightBorderSize();
3255 height -= MacGetTopBorderSize() + MacGetBottomBorderSize();
14c9cbdb 3256
e15f0a5e
DS
3257 wxPoint vPoint( width - scrlsize, 0 ) ;
3258 wxSize vSize( scrlsize, height - adjust ) ;
3259 wxPoint hPoint( 0 , height - scrlsize ) ;
3260 wxSize hSize( width - adjust, scrlsize ) ;
3261
3262#if 0
3263 int x = 0, y = 0, w, h ;
facd6764 3264 GetSize( &w , &h ) ;
14c9cbdb 3265
6264b550
RR
3266 MacClientToRootWindow( &x , &y ) ;
3267 MacClientToRootWindow( &w , &h ) ;
14c9cbdb 3268
6264b550 3269 wxWindowMac *iter = (wxWindowMac*)this ;
14c9cbdb 3270
6264b550 3271 int totW = 10000 , totH = 10000;
e15f0a5e 3272 while ( iter )
6264b550 3273 {
1c310985 3274 if ( iter->IsTopLevel() )
6264b550 3275 {
facd6764 3276 iter->GetSize( &totW , &totH ) ;
6264b550
RR
3277 break ;
3278 }
3279
3280 iter = iter->GetParent() ;
14c9cbdb
RD
3281 }
3282
6264b550
RR
3283 if ( x == 0 )
3284 {
3285 hPoint.x = -1 ;
3286 hSize.x += 1 ;
3287 }
3288 if ( y == 0 )
3289 {
3290 vPoint.y = -1 ;
3291 vSize.y += 1 ;
3292 }
14c9cbdb 3293
e15f0a5e 3294 if ( w - x >= totW )
6264b550
RR
3295 {
3296 hSize.x += 1 ;
3297 vPoint.x += 1 ;
3298 }
e15f0a5e 3299 if ( h - y >= totH )
6264b550
RR
3300 {
3301 vSize.y += 1 ;
3302 hPoint.y += 1 ;
3303 }
e15f0a5e
DS
3304#endif
3305
6264b550 3306 if ( m_vScrollBar )
e15f0a5e 3307 m_vScrollBar->SetSize( vPoint.x , vPoint.y, vSize.x, vSize.y , wxSIZE_ALLOW_MINUS_ONE );
6264b550 3308 if ( m_hScrollBar )
e15f0a5e 3309 m_hScrollBar->SetSize( hPoint.x , hPoint.y, hSize.x, hSize.y, wxSIZE_ALLOW_MINUS_ONE );
519cb848
SC
3310}
3311
e766c8a9 3312bool wxWindowMac::AcceptsFocus() const
7c551d95
SC
3313{
3314 return MacCanFocus() && wxWindowBase::AcceptsFocus();
3315}
519cb848 3316
14c9cbdb 3317void wxWindowMac::MacSuperChangedPosition()
519cb848 3318{
6264b550 3319 // only window-absolute structures have to be moved i.e. controls
519cb848 3320
e15f0a5e
DS
3321 m_cachedClippedRectValid = false ;
3322
3323 wxWindowMac *child;
71f2fb52 3324 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
6264b550
RR
3325 while ( node )
3326 {
e15f0a5e 3327 child = node->GetData();
6264b550 3328 child->MacSuperChangedPosition() ;
e15f0a5e 3329
eb22f2a6 3330 node = node->GetNext();
6264b550 3331 }
519cb848 3332}
519cb848 3333
14c9cbdb 3334void wxWindowMac::MacTopLevelWindowChangedPosition()
a3bf4a62 3335{
6264b550 3336 // only screen-absolute structures have to be moved i.e. glcanvas
a3bf4a62 3337
e15f0a5e 3338 wxWindowMac *child;
71f2fb52 3339 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
6264b550
RR
3340 while ( node )
3341 {
e15f0a5e 3342 child = node->GetData();
6264b550 3343 child->MacTopLevelWindowChangedPosition() ;
e15f0a5e 3344
eb22f2a6 3345 node = node->GetNext();
6264b550 3346 }
a3bf4a62 3347}
facd6764 3348
e15f0a5e 3349long wxWindowMac::MacGetLeftBorderSize() const
2f1ae414 3350{
e15f0a5e 3351 if ( IsTopLevel() )
6264b550 3352 return 0 ;
2f1ae414 3353
8f39b6c4 3354 SInt32 border = 0 ;
902725ee 3355
e15f0a5e 3356 if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER))
2f1ae414 3357 {
fbc1d11b 3358 // this metric is only the 'outset' outside the simple frame rect
8f39b6c4 3359 GetThemeMetric( kThemeMetricEditTextFrameOutset , &border ) ;
fbc1d11b 3360 border += 1 ;
2f1ae414 3361 }
8f39b6c4 3362 else if (HasFlag(wxSIMPLE_BORDER))
2f1ae414 3363 {
fbc1d11b 3364 // this metric is only the 'outset' outside the simple frame rect
8f39b6c4 3365 GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
fbc1d11b 3366 border += 1 ;
2f1ae414 3367 }
e15f0a5e 3368
8f39b6c4 3369 return border ;
2f1ae414
SC
3370}
3371
e15f0a5e 3372long wxWindowMac::MacGetRightBorderSize() const
5b781a67 3373{
1c310985
SC
3374 // they are all symmetric in mac themes
3375 return MacGetLeftBorderSize() ;
5b781a67
SC
3376}
3377
e15f0a5e 3378long wxWindowMac::MacGetTopBorderSize() const
5b781a67 3379{
1c310985
SC
3380 // they are all symmetric in mac themes
3381 return MacGetLeftBorderSize() ;
5b781a67
SC
3382}
3383
e15f0a5e 3384long wxWindowMac::MacGetBottomBorderSize() const
5b781a67 3385{
1c310985
SC
3386 // they are all symmetric in mac themes
3387 return MacGetLeftBorderSize() ;
5b781a67
SC
3388}
3389
14c9cbdb 3390long wxWindowMac::MacRemoveBordersFromStyle( long style )
2f1ae414 3391{
055a486b 3392 return style & ~wxBORDER_MASK ;
2f1ae414 3393}
0a67a93b 3394
e766c8a9 3395// Find the wxWindowMac at the current mouse position, returning the mouse
3723b7b1 3396// position.
e15f0a5e 3397wxWindowMac * wxFindWindowAtPointer( wxPoint& pt )
3723b7b1 3398{
59a12e90 3399 pt = wxGetMousePosition();
e766c8a9 3400 wxWindowMac* found = wxFindWindowAtPoint(pt);
e15f0a5e 3401
59a12e90 3402 return found;
3723b7b1
JS
3403}
3404
3405// Get the current mouse position.
3406wxPoint wxGetMousePosition()
3407{
57591e0e 3408 int x, y;
e15f0a5e
DS
3409
3410 wxGetMousePosition( &x, &y );
3411
57591e0e 3412 return wxPoint(x, y);
3723b7b1
JS
3413}
3414
6ed71b4f 3415void wxWindowMac::OnMouseEvent( wxMouseEvent &event )
8950f7cc 3416{
8b573fb8
VZ
3417 if ( event.GetEventType() == wxEVT_RIGHT_DOWN )
3418 {
3419 // copied from wxGTK : CS
fe224552
VZ
3420 // VZ: shouldn't we move this to base class then?
3421
249aad30 3422 // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN
8950f7cc
SC
3423 // except that:
3424 //
3425 // (a) it's a command event and so is propagated to the parent
3426 // (b) under MSW it can be generated from kbd too
3427 // (c) it uses screen coords (because of (a))
3428 wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU,
3429 this->GetId(),
3430 this->ClientToScreen(event.GetPosition()));
249aad30
SC
3431 if ( ! GetEventHandler()->ProcessEvent(evtCtx) )
3432 event.Skip() ;
8b573fb8 3433 }
facd6764
SC
3434 else
3435 {
8b573fb8 3436 event.Skip() ;
facd6764 3437 }
8950f7cc
SC
3438}
3439
89954433 3440void wxWindowMac::OnPaint( wxPaintEvent & WXUNUSED(event) )
ff3795ee 3441{
4488a1d3
VZ
3442 if ( wxTheApp->MacGetCurrentEvent() != NULL && wxTheApp->MacGetCurrentEventHandlerCallRef() != NULL
3443 && GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT )
e15f0a5e
DS
3444 CallNextEventHandler(
3445 (EventHandlerCallRef)wxTheApp->MacGetCurrentEventHandlerCallRef() ,
3446 (EventRef) wxTheApp->MacGetCurrentEvent() ) ;
ff3795ee
SC
3447}
3448
89954433
VZ
3449void wxWindowMac::MacHandleControlClick(WXWidget WXUNUSED(control),
3450 wxInt16 WXUNUSED(controlpart),
3451 bool WXUNUSED(mouseStillDown))
facd6764 3452{
facd6764
SC
3453}
3454
8b573fb8 3455Rect wxMacGetBoundsForControl( wxWindow* window , const wxPoint& pos , const wxSize &size , bool adjustForOrigin )
3083eb85 3456{
e15f0a5e 3457 int x, y, w, h ;
8b573fb8 3458
58603178
DS
3459 window->MacGetBoundsForControl( pos , size , x , y, w, h , adjustForOrigin ) ;
3460 Rect bounds = { y, x, y + h, x + w };
e15f0a5e 3461
3083eb85
SC
3462 return bounds ;
3463}
3464
8b573fb8 3465wxInt32 wxWindowMac::MacControlHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF WXUNUSED(event) )
f1d527c1
SC
3466{
3467 return eventNotHandledErr ;
3468}
3469
50779e06
JS
3470bool wxWindowMac::Reparent(wxWindowBase *newParentBase)
3471{
3472 wxWindowMac *newParent = (wxWindowMac *)newParentBase;
50779e06 3473 if ( !wxWindowBase::Reparent(newParent) )
3dee36ae
WS
3474 return false;
3475
e15f0a5e 3476 // copied from MacPostControlCreate
50779e06 3477 ControlRef container = (ControlRef) GetParent()->GetHandle() ;
e15f0a5e 3478
50779e06 3479 wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ;
e15f0a5e 3480
50779e06 3481 ::EmbedControl( m_peer->GetControlRef() , container ) ;
facd6764 3482
3dee36ae
WS
3483 return true;
3484}
a9b456ff
SC
3485
3486bool wxWindowMac::SetTransparent(wxByte alpha)
3487{
3488#if wxMAC_USE_CORE_GRAPHICS
4488a1d3
VZ
3489 SetBackgroundStyle(wxBG_STYLE_TRANSPARENT);
3490
a9b456ff
SC
3491 if ( alpha != m_macAlpha )
3492 {
3493 m_macAlpha = alpha ;
3494 Refresh() ;
3495 }
3496 return true ;
3497#else
3498 return false ;
3499#endif
3500}
3501
3502
3503bool wxWindowMac::CanSetTransparent()
3504{
3505#if wxMAC_USE_CORE_GRAPHICS
3506 return true ;
3507#else
3508 return false ;
3509#endif
3510}
3511
89954433 3512wxByte wxWindowMac::GetTransparent() const
a9b456ff
SC
3513{
3514 return m_macAlpha ;
8444b6cb 3515}