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