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