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