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