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