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