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