1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/carbon/window.cpp
3 // Purpose: wxWindowMac
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
14 #include "wx/window.h"
23 #include "wx/dcclient.h"
24 #include "wx/button.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"
40 #include "wx/tooltip.h"
41 #include "wx/spinctrl.h"
42 #include "wx/geometry.h"
45 #include "wx/listctrl.h"
49 #include "wx/treectrl.h"
56 #if wxUSE_DRAG_AND_DROP
60 #include "wx/mac/uma.h"
62 #define MAC_SCROLLBAR_SIZE 15
63 #define MAC_SMALL_SCROLLBAR_SIZE 11
67 #include <ToolUtils.h>
69 #include <MacTextEditor.h>
72 #if TARGET_API_MAC_OSX
74 #include <HIToolbox/HIView.h>
80 #ifdef __WXUNIVERSAL__
81 IMPLEMENT_ABSTRACT_CLASS(wxWindowMac
, wxWindowBase
)
83 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
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
)
92 EVT_SET_FOCUS(wxWindowMac::OnSetFocus
)
93 EVT_KILL_FOCUS(wxWindowMac::OnSetFocus
)
94 EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent
)
97 #define wxMAC_DEBUG_REDRAW 0
98 #ifndef wxMAC_DEBUG_REDRAW
99 #define wxMAC_DEBUG_REDRAW 0
102 // ---------------------------------------------------------------------------
103 // Utility Routines to move between different coordinate systems
104 // ---------------------------------------------------------------------------
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)
121 // originating from native control
125 void wxMacNativeToWindow( const wxWindow
* window
, RgnHandle handle
)
127 OffsetRgn( handle
, window
->MacGetLeftBorderSize() , window
->MacGetTopBorderSize() ) ;
130 void wxMacNativeToWindow( const wxWindow
* window
, Rect
*rect
)
132 OffsetRect( rect
, window
->MacGetLeftBorderSize() , window
->MacGetTopBorderSize() ) ;
136 // directed towards native control
139 void wxMacWindowToNative( const wxWindow
* window
, RgnHandle handle
)
141 OffsetRgn( handle
, -window
->MacGetLeftBorderSize() , -window
->MacGetTopBorderSize() );
144 void wxMacWindowToNative( const wxWindow
* window
, Rect
*rect
)
146 OffsetRect( rect
, -window
->MacGetLeftBorderSize() , -window
->MacGetTopBorderSize() ) ;
149 // ---------------------------------------------------------------------------
151 // ---------------------------------------------------------------------------
153 #if TARGET_API_MAC_OSX
155 #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3
158 kEventControlVisibilityChanged
= 157
164 static const EventTypeSpec eventList
[] =
166 { kEventClassCommand
, kEventProcessCommand
} ,
167 { kEventClassCommand
, kEventCommandUpdateStatus
} ,
169 { kEventClassControl
, kEventControlGetClickActivation
} ,
170 { kEventClassControl
, kEventControlHit
} ,
172 { kEventClassTextInput
, kEventTextInputUnicodeForKeyEvent
} ,
173 { kEventClassTextInput
, kEventTextInputUpdateActiveInputArea
} ,
175 { kEventClassControl
, kEventControlDraw
} ,
176 #if TARGET_API_MAC_OSX
177 { kEventClassControl
, kEventControlVisibilityChanged
} ,
178 { kEventClassControl
, kEventControlEnabledStateChanged
} ,
179 { kEventClassControl
, kEventControlHiliteChanged
} ,
181 { kEventClassControl
, kEventControlActivate
} ,
182 { kEventClassControl
, kEventControlDeactivate
} ,
184 { kEventClassControl
, kEventControlSetFocusPart
} ,
186 { kEventClassService
, kEventServiceGetTypes
},
187 { kEventClassService
, kEventServiceCopy
},
188 { kEventClassService
, kEventServicePaste
},
190 // { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only
191 // { kEventClassControl , kEventControlBoundsChanged } ,
194 static pascal OSStatus
wxMacWindowControlEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
196 OSStatus result
= eventNotHandledErr
;
198 wxMacCarbonEvent
cEvent( event
) ;
200 ControlRef controlRef
;
201 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
203 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
205 switch ( GetEventKind( event
) )
207 #if TARGET_API_MAC_OSX
208 case kEventControlDraw
:
210 RgnHandle updateRgn
= NULL
;
211 RgnHandle allocatedRgn
= NULL
;
212 wxRegion visRegion
= thisWindow
->MacGetVisibleRegion() ;
214 if ( cEvent
.GetParameter
<RgnHandle
>(kEventParamRgnHandle
, &updateRgn
) != noErr
)
216 updateRgn
= (RgnHandle
) visRegion
.GetWXHRGN() ;
220 if ( thisWindow
->MacGetLeftBorderSize() != 0 || thisWindow
->MacGetTopBorderSize() != 0 )
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
) ;
226 // hide the given region by the new region that must be shifted
227 wxMacNativeToWindow( thisWindow
, allocatedRgn
) ;
228 updateRgn
= allocatedRgn
;
233 GetRegionBounds( updateRgn
, &rgnBounds
) ;
235 #if wxMAC_DEBUG_REDRAW
236 if ( thisWindow
->MacIsUserPane() )
238 static float color
= 0.5 ;
241 CGContextRef cgContext
= cEvent
.GetParameter
<CGContextRef
>(kEventParamCGContextRef
) ;
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
);
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
) ;
267 wxMacCGContextStateSaver
sg( cgContext
) ;
270 wxWindow
* iter
= thisWindow
;
273 alpha
*= (float) iter
->GetTransparent()/255.0 ;
274 if ( iter
->IsTopLevel() )
277 iter
= iter
->GetParent() ;
280 CGContextSetAlpha( cgContext
, alpha
) ;
282 if ( thisWindow
->MacDoRedraw( updateRgn
, cEvent
.GetTicks() ) )
285 #if wxMAC_USE_CORE_GRAPHICS
286 thisWindow
->MacSetCGContextRef( NULL
) ;
290 CGContextRelease( cgContext
) ;
295 DisposeRgn( allocatedRgn
) ;
299 case kEventControlVisibilityChanged
:
300 thisWindow
->MacVisibilityChanged() ;
303 case kEventControlEnabledStateChanged
:
304 thisWindow
->MacEnabledStateChanged() ;
307 case kEventControlHiliteChanged
:
308 thisWindow
->MacHiliteChanged() ;
311 case kEventControlActivate
:
312 case kEventControlDeactivate
:
313 // FIXME: we should have a virtual function for this!
315 if ( thisWindow
->IsKindOf( CLASSINFO( wxTreeCtrl
) ) )
316 thisWindow
->Refresh();
319 if ( thisWindow
->IsKindOf( CLASSINFO( wxListCtrl
) ) )
320 thisWindow
->Refresh();
323 #endif // TARGET_API_MAC_OSX
325 // we emulate this event under Carbon CFM
326 case kEventControlSetFocusPart
:
328 Boolean focusEverything
= false ;
329 ControlPartCode controlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
);
332 if ( cEvent
.GetParameter
<Boolean
>(kEventParamControlFocusEverything
, &focusEverything
) == noErr
)
337 if ( controlPart
== kControlFocusNoPart
)
340 if ( thisWindow
->GetCaret() )
341 thisWindow
->GetCaret()->OnKillFocus();
344 static bool inKillFocusEvent
= false ;
346 if ( !inKillFocusEvent
)
348 inKillFocusEvent
= true ;
349 wxFocusEvent
event( wxEVT_KILL_FOCUS
, thisWindow
->GetId());
350 event
.SetEventObject(thisWindow
);
351 thisWindow
->GetEventHandler()->ProcessEvent(event
) ;
352 inKillFocusEvent
= false ;
357 // panel wants to track the window which was the last to have focus in it
358 wxChildFocusEvent
eventFocus(thisWindow
);
359 thisWindow
->GetEventHandler()->ProcessEvent(eventFocus
);
362 if ( thisWindow
->GetCaret() )
363 thisWindow
->GetCaret()->OnSetFocus();
366 wxFocusEvent
event(wxEVT_SET_FOCUS
, thisWindow
->GetId());
367 event
.SetEventObject(thisWindow
);
368 thisWindow
->GetEventHandler()->ProcessEvent(event
) ;
371 if ( thisWindow
->MacIsUserPane() )
376 case kEventControlHit
:
377 result
= thisWindow
->MacControlHit( handler
, event
) ;
380 case kEventControlGetClickActivation
:
382 // fix to always have a proper activation for DataBrowser controls (stay in bkgnd otherwise)
383 WindowRef owner
= cEvent
.GetParameter
<WindowRef
>(kEventParamWindowRef
);
384 if ( !IsWindowActive(owner
) )
386 cEvent
.SetParameter(kEventParamClickActivation
,(UInt32
) kActivateAndIgnoreClick
) ;
399 static pascal OSStatus
wxMacWindowServiceEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
401 OSStatus result
= eventNotHandledErr
;
403 wxMacCarbonEvent
cEvent( event
) ;
405 ControlRef controlRef
;
406 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
407 wxTextCtrl
* textCtrl
= wxDynamicCast( thisWindow
, wxTextCtrl
) ;
408 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
410 switch ( GetEventKind( event
) )
412 case kEventServiceGetTypes
:
416 textCtrl
->GetSelection( &from
, &to
) ;
418 CFMutableArrayRef copyTypes
= 0 , pasteTypes
= 0;
420 copyTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServiceCopyTypes
, typeCFMutableArrayRef
) ;
421 if ( textCtrl
->IsEditable() )
422 pasteTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServicePasteTypes
, typeCFMutableArrayRef
) ;
424 static const OSType textDataTypes
[] = { kTXNTextData
/* , 'utxt', 'PICT', 'MooV', 'AIFF' */ };
425 for ( size_t i
= 0 ; i
< WXSIZEOF(textDataTypes
) ; ++i
)
427 CFStringRef typestring
= CreateTypeStringWithOSType(textDataTypes
[i
]);
431 CFArrayAppendValue(copyTypes
, typestring
) ;
433 CFArrayAppendValue(pasteTypes
, typestring
) ;
435 CFRelease( typestring
) ;
443 case kEventServiceCopy
:
448 textCtrl
->GetSelection( &from
, &to
) ;
449 wxString val
= textCtrl
->GetValue() ;
450 val
= val
.Mid( from
, to
- from
) ;
451 ScrapRef scrapRef
= cEvent
.GetParameter
< ScrapRef
> ( kEventParamScrapRef
, typeScrapRef
) ;
452 verify_noerr( ClearScrap( &scrapRef
) ) ;
453 verify_noerr( PutScrapFlavor( scrapRef
, kTXNTextData
, 0 , val
.length() , val
.c_str() ) ) ;
458 case kEventServicePaste
:
461 ScrapRef scrapRef
= cEvent
.GetParameter
< ScrapRef
> ( kEventParamScrapRef
, typeScrapRef
) ;
462 Size textSize
, pastedSize
;
463 verify_noerr( GetScrapFlavorSize(scrapRef
, kTXNTextData
, &textSize
) ) ;
465 char *content
= new char[textSize
] ;
466 GetScrapFlavorData(scrapRef
, kTXNTextData
, &pastedSize
, content
);
467 content
[textSize
- 1] = 0 ;
470 textCtrl
->WriteText( wxString( content
, wxConvLocal
) );
472 textCtrl
->WriteText( wxString( content
) ) ;
487 pascal OSStatus
wxMacUnicodeTextEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
489 OSStatus result
= eventNotHandledErr
;
490 wxWindowMac
* focus
= (wxWindowMac
*) data
;
492 wchar_t* uniChars
= NULL
;
493 UInt32 when
= EventTimeToTicks( GetEventTime( event
) ) ;
495 UniChar
* charBuf
= NULL
;
496 ByteCount dataSize
= 0 ;
499 if ( GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, 0 , &dataSize
, NULL
) == noErr
)
501 numChars
= dataSize
/ sizeof( UniChar
) + 1;
504 if ( (size_t) numChars
* 2 > sizeof(buf
) )
505 charBuf
= new UniChar
[ numChars
] ;
509 uniChars
= new wchar_t[ numChars
] ;
510 GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, dataSize
, NULL
, charBuf
) ;
511 charBuf
[ numChars
- 1 ] = 0;
512 #if SIZEOF_WCHAR_T == 2
513 uniChars
= (wchar_t*) charBuf
;
514 /* memcpy( uniChars , charBuf , numChars * 2 ) ;*/ // is there any point in copying charBuf over itself? (in fact, memcpy isn't even guaranteed to work correctly if the source and destination ranges overlap...)
516 // the resulting string will never have more chars than the utf16 version, so this is safe
517 wxMBConvUTF16 converter
;
518 numChars
= converter
.MB2WC( uniChars
, (const char*)charBuf
, numChars
) ;
522 switch ( GetEventKind( event
) )
524 case kEventTextInputUpdateActiveInputArea
:
526 // An IME input event may return several characters, but we need to send one char at a time to
528 for (int pos
=0 ; pos
< numChars
; pos
++)
530 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
531 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
532 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
534 UInt32 message
= uniChars
[pos
] < 128 ? (char)uniChars
[pos
] : '?';
536 NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
537 multiple times to update the active range during inline input, so this handler will often receive
538 uncommited text, which should usually not trigger side effects. It might be a good idea to check the
539 kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
540 On the other hand, it can be useful for some applications to react to uncommitted text (for example,
541 to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
542 should add new event types to support advanced text input. For now, I would keep things as they are.
544 However, the code that was being used caused additional problems:
545 UInt32 message = (0 << 8) + ((char)uniChars[pos] );
546 Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
547 input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
548 for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
549 (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
550 (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
551 Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
552 overlap with Unicode within the (7-bit) ASCII range.
553 But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
554 for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
555 characters as they are and replaces the rest with '?', ensuring that update events are triggered.
556 It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
557 I don't have time to look into that right now.
560 if ( wxTheApp
->MacSendCharEvent(
561 focus
, message
, 0 , when
, 0 , 0 , uniChars
[pos
] ) )
566 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
570 case kEventTextInputUnicodeForKeyEvent
:
572 UInt32 keyCode
, modifiers
;
575 unsigned char charCode
;
577 GetEventParameter( event
, kEventParamTextInputSendKeyboardEvent
, typeEventRef
, NULL
, sizeof(rawEvent
), NULL
, &rawEvent
) ;
578 GetEventParameter( rawEvent
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, sizeof(char), NULL
, &charCode
);
579 GetEventParameter( rawEvent
, kEventParamKeyCode
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
580 GetEventParameter( rawEvent
, kEventParamKeyModifiers
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &modifiers
);
581 GetEventParameter( rawEvent
, kEventParamMouseLocation
, typeQDPoint
, NULL
, sizeof(Point
), NULL
, &point
);
583 UInt32 message
= (keyCode
<< 8) + charCode
;
585 // An IME input event may return several characters, but we need to send one char at a time to
587 for (int pos
=0 ; pos
< numChars
; pos
++)
589 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
590 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
591 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
593 if ( wxTheApp
->MacSendCharEvent(
594 focus
, message
, modifiers
, when
, point
.h
, point
.v
, uniChars
[pos
] ) )
599 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
608 if ( charBuf
!= buf
)
614 static pascal OSStatus
wxMacWindowCommandEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
616 OSStatus result
= eventNotHandledErr
;
617 wxWindowMac
* focus
= (wxWindowMac
*) data
;
621 wxMacCarbonEvent
cEvent( event
) ;
622 cEvent
.GetParameter
<HICommand
>(kEventParamDirectObject
,typeHICommand
,&command
) ;
624 wxMenuItem
* item
= NULL
;
625 wxMenu
* itemMenu
= wxFindMenuFromMacCommand( command
, item
) ;
626 int id
= wxMacCommandToId( command
.commandID
) ;
630 wxASSERT( itemMenu
!= NULL
) ;
632 switch ( cEvent
.GetKind() )
634 case kEventProcessCommand
:
636 if (item
->IsCheckable())
637 item
->Check( !item
->IsChecked() ) ;
639 if ( itemMenu
->SendEvent( id
, item
->IsCheckable() ? item
->IsChecked() : -1 ) )
643 wxCommandEvent
event(wxEVT_COMMAND_MENU_SELECTED
, id
);
644 event
.SetEventObject(focus
);
645 event
.SetInt(item
->IsCheckable() ? item
->IsChecked() : -1);
647 if ( focus
->GetEventHandler()->ProcessEvent(event
) )
653 case kEventCommandUpdateStatus
:
655 wxUpdateUIEvent
event(id
);
656 event
.SetEventObject( itemMenu
);
658 bool processed
= false;
660 // Try the menu's event handler
662 wxEvtHandler
*handler
= itemMenu
->GetEventHandler();
664 processed
= handler
->ProcessEvent(event
);
667 // Try the window the menu was popped up from
668 // (and up through the hierarchy)
671 const wxMenuBase
*menu
= itemMenu
;
674 wxWindow
*win
= menu
->GetInvokingWindow();
677 processed
= win
->GetEventHandler()->ProcessEvent(event
);
681 menu
= menu
->GetParent();
687 processed
= focus
->GetEventHandler()->ProcessEvent(event
);
692 // if anything changed, update the changed attribute
693 if (event
.GetSetText())
694 itemMenu
->SetLabel(id
, event
.GetText());
695 if (event
.GetSetChecked())
696 itemMenu
->Check(id
, event
.GetChecked());
697 if (event
.GetSetEnabled())
698 itemMenu
->Enable(id
, event
.GetEnabled());
712 pascal OSStatus
wxMacWindowEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
714 EventRef formerEvent
= (EventRef
) wxTheApp
->MacGetCurrentEvent() ;
715 EventHandlerCallRef formerEventHandlerCallRef
= (EventHandlerCallRef
) wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
716 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
717 OSStatus result
= eventNotHandledErr
;
719 switch ( GetEventClass( event
) )
721 case kEventClassCommand
:
722 result
= wxMacWindowCommandEventHandler( handler
, event
, data
) ;
725 case kEventClassControl
:
726 result
= wxMacWindowControlEventHandler( handler
, event
, data
) ;
729 case kEventClassService
:
730 result
= wxMacWindowServiceEventHandler( handler
, event
, data
) ;
733 case kEventClassTextInput
:
734 result
= wxMacUnicodeTextEventHandler( handler
, event
, data
) ;
741 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerEventHandlerCallRef
) ;
746 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler
)
748 #if !TARGET_API_MAC_OSX
750 // ---------------------------------------------------------------------------
751 // UserPane events for non OSX builds
752 // ---------------------------------------------------------------------------
754 static pascal void wxMacControlUserPaneDrawProc(ControlRef control
, SInt16 part
)
756 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
758 win
->MacControlUserPaneDrawProc(part
) ;
760 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneDrawUPP
, wxMacControlUserPaneDrawProc
) ;
762 static pascal ControlPartCode
wxMacControlUserPaneHitTestProc(ControlRef control
, Point where
)
764 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
766 return win
->MacControlUserPaneHitTestProc(where
.h
, where
.v
) ;
768 return kControlNoPart
;
770 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneHitTestUPP
, wxMacControlUserPaneHitTestProc
) ;
772 static pascal ControlPartCode
wxMacControlUserPaneTrackingProc(ControlRef control
, Point startPt
, ControlActionUPP actionProc
)
774 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
776 return win
->MacControlUserPaneTrackingProc( startPt
.h
, startPt
.v
, (void*) actionProc
) ;
778 return kControlNoPart
;
780 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneTrackingUPP
, wxMacControlUserPaneTrackingProc
) ;
782 static pascal void wxMacControlUserPaneIdleProc(ControlRef control
)
784 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
786 win
->MacControlUserPaneIdleProc() ;
788 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneIdleUPP
, wxMacControlUserPaneIdleProc
) ;
790 static pascal ControlPartCode
wxMacControlUserPaneKeyDownProc(ControlRef control
, SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
)
792 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
794 return win
->MacControlUserPaneKeyDownProc(keyCode
,charCode
,modifiers
) ;
796 return kControlNoPart
;
798 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneKeyDownUPP
, wxMacControlUserPaneKeyDownProc
) ;
800 static pascal void wxMacControlUserPaneActivateProc(ControlRef control
, Boolean activating
)
802 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
804 win
->MacControlUserPaneActivateProc(activating
) ;
806 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneActivateUPP
, wxMacControlUserPaneActivateProc
) ;
808 static pascal ControlPartCode
wxMacControlUserPaneFocusProc(ControlRef control
, ControlFocusPart action
)
810 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
812 return win
->MacControlUserPaneFocusProc(action
) ;
814 return kControlNoPart
;
816 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneFocusUPP
, wxMacControlUserPaneFocusProc
) ;
818 static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control
, ControlBackgroundPtr info
)
820 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
822 win
->MacControlUserPaneBackgroundProc(info
) ;
824 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneBackgroundUPP
, wxMacControlUserPaneBackgroundProc
) ;
826 void wxWindowMac::MacControlUserPaneDrawProc(wxInt16 part
)
829 RgnHandle rgn
= NewRgn() ;
831 MacWindowToRootWindow( &x
, &y
) ;
832 OffsetRgn( rgn
, -x
, -y
) ;
833 wxMacWindowStateSaver
sv( this ) ;
834 SectRgn( rgn
, (RgnHandle
) MacGetVisibleRegion().GetWXHRGN() , rgn
) ;
835 MacDoRedraw( rgn
, 0 ) ;
839 wxInt16
wxWindowMac::MacControlUserPaneHitTestProc(wxInt16 x
, wxInt16 y
)
841 return kControlNoPart
;
844 wxInt16
wxWindowMac::MacControlUserPaneTrackingProc(wxInt16 x
, wxInt16 y
, void* actionProc
)
846 return kControlNoPart
;
849 void wxWindowMac::MacControlUserPaneIdleProc()
853 wxInt16
wxWindowMac::MacControlUserPaneKeyDownProc(wxInt16 keyCode
, wxInt16 charCode
, wxInt16 modifiers
)
855 return kControlNoPart
;
858 void wxWindowMac::MacControlUserPaneActivateProc(bool activating
)
862 wxInt16
wxWindowMac::MacControlUserPaneFocusProc(wxInt16 action
)
864 if ( AcceptsFocus() )
867 return kControlNoPart
;
870 void wxWindowMac::MacControlUserPaneBackgroundProc(void* info
)
876 // ---------------------------------------------------------------------------
877 // Scrollbar Tracking for all
878 // ---------------------------------------------------------------------------
880 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
) ;
881 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
)
885 wxWindow
* wx
= wxFindControlFromMacControl( control
) ;
887 wx
->MacHandleControlClick( (WXWidget
) control
, partCode
, true /* stillDown */ ) ;
890 wxMAC_DEFINE_PROC_GETTER( ControlActionUPP
, wxMacLiveScrollbarActionProc
) ;
892 // ===========================================================================
894 // ===========================================================================
896 WX_DECLARE_HASH_MAP(ControlRef
, wxWindow
*, wxPointerHash
, wxPointerEqual
, MacControlMap
);
898 static MacControlMap wxWinMacControlList
;
900 wxWindow
*wxFindControlFromMacControl(ControlRef inControl
)
902 MacControlMap::iterator node
= wxWinMacControlList
.find(inControl
);
904 return (node
== wxWinMacControlList
.end()) ? NULL
: node
->second
;
907 void wxAssociateControlWithMacControl(ControlRef inControl
, wxWindow
*control
)
909 // adding NULL ControlRef is (first) surely a result of an error and
910 // (secondly) breaks native event processing
911 wxCHECK_RET( inControl
!= (ControlRef
) NULL
, wxT("attempt to add a NULL WindowRef to window list") );
913 wxWinMacControlList
[inControl
] = control
;
916 void wxRemoveMacControlAssociation(wxWindow
*control
)
918 // iterate over all the elements in the class
919 // is the iterator stable ? as we might have two associations pointing to the same wxWindow
920 // we should go on...
926 MacControlMap::iterator it
;
927 for ( it
= wxWinMacControlList
.begin(); it
!= wxWinMacControlList
.end(); ++it
)
929 if ( it
->second
== control
)
931 wxWinMacControlList
.erase(it
);
939 // ----------------------------------------------------------------------------
940 // constructors and such
941 // ----------------------------------------------------------------------------
943 wxWindowMac::wxWindowMac()
948 wxWindowMac::wxWindowMac(wxWindowMac
*parent
,
953 const wxString
& name
)
956 Create(parent
, id
, pos
, size
, style
, name
);
959 void wxWindowMac::Init()
965 #if wxMAC_USE_CORE_GRAPHICS
966 m_cgContextRef
= NULL
;
969 // as all windows are created with WS_VISIBLE style...
972 m_hScrollBar
= NULL
;
973 m_vScrollBar
= NULL
;
974 m_macBackgroundBrush
= wxNullBrush
;
976 m_macIsUserPane
= true;
977 m_clipChildren
= false ;
978 m_cachedClippedRectValid
= false ;
980 // we need a valid font for the encodings
981 wxWindowBase::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
984 wxWindowMac::~wxWindowMac()
988 m_isBeingDeleted
= true;
990 MacInvalidateBorders() ;
992 #ifndef __WXUNIVERSAL__
993 // VS: make sure there's no wxFrame with last focus set to us:
994 for ( wxWindow
*win
= GetParent(); win
; win
= win
->GetParent() )
996 wxFrame
*frame
= wxDynamicCast(win
, wxFrame
);
999 if ( frame
->GetLastFocus() == this )
1000 frame
->SetLastFocus((wxWindow
*)NULL
);
1006 // destroy children before destroying this window itself
1009 // wxRemoveMacControlAssociation( this ) ;
1010 // If we delete an item, we should initialize the parent panel,
1011 // because it could now be invalid.
1012 wxTopLevelWindow
*tlw
= wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow
);
1015 if ( tlw
->GetDefaultItem() == (wxButton
*) this)
1016 tlw
->SetDefaultItem(NULL
);
1019 if ( m_peer
&& m_peer
->Ok() )
1021 // in case the callback might be called during destruction
1022 wxRemoveMacControlAssociation( this) ;
1023 ::RemoveEventHandler( (EventHandlerRef
) m_macControlEventHandler
) ;
1024 // we currently are not using this hook
1025 // ::SetControlColorProc( *m_peer , NULL ) ;
1029 if ( g_MacLastWindow
== this )
1030 g_MacLastWindow
= NULL
;
1032 wxFrame
* frame
= wxDynamicCast( wxGetTopLevelParent( this ) , wxFrame
) ;
1035 if ( frame
->GetLastFocus() == this )
1036 frame
->SetLastFocus( NULL
) ;
1039 // delete our drop target if we've got one
1040 #if wxUSE_DRAG_AND_DROP
1041 if ( m_dropTarget
!= NULL
)
1043 delete m_dropTarget
;
1044 m_dropTarget
= NULL
;
1051 WXWidget
wxWindowMac::GetHandle() const
1053 return (WXWidget
) m_peer
->GetControlRef() ;
1056 void wxWindowMac::MacInstallEventHandler( WXWidget control
)
1058 wxAssociateControlWithMacControl( (ControlRef
) control
, this ) ;
1059 InstallControlEventHandler( (ControlRef
)control
, GetwxMacWindowEventHandlerUPP(),
1060 GetEventTypeCount(eventList
), eventList
, this,
1061 (EventHandlerRef
*)&m_macControlEventHandler
);
1063 #if !TARGET_API_MAC_OSX
1064 if ( (ControlRef
) control
== m_peer
->GetControlRef() )
1066 m_peer
->SetData
<ControlUserPaneDrawUPP
>(kControlEntireControl
, kControlUserPaneDrawProcTag
, GetwxMacControlUserPaneDrawProc()) ;
1067 m_peer
->SetData
<ControlUserPaneHitTestUPP
>(kControlEntireControl
, kControlUserPaneHitTestProcTag
, GetwxMacControlUserPaneHitTestProc()) ;
1068 m_peer
->SetData
<ControlUserPaneTrackingUPP
>(kControlEntireControl
, kControlUserPaneTrackingProcTag
, GetwxMacControlUserPaneTrackingProc()) ;
1069 m_peer
->SetData
<ControlUserPaneIdleUPP
>(kControlEntireControl
, kControlUserPaneIdleProcTag
, GetwxMacControlUserPaneIdleProc()) ;
1070 m_peer
->SetData
<ControlUserPaneKeyDownUPP
>(kControlEntireControl
, kControlUserPaneKeyDownProcTag
, GetwxMacControlUserPaneKeyDownProc()) ;
1071 m_peer
->SetData
<ControlUserPaneActivateUPP
>(kControlEntireControl
, kControlUserPaneActivateProcTag
, GetwxMacControlUserPaneActivateProc()) ;
1072 m_peer
->SetData
<ControlUserPaneFocusUPP
>(kControlEntireControl
, kControlUserPaneFocusProcTag
, GetwxMacControlUserPaneFocusProc()) ;
1073 m_peer
->SetData
<ControlUserPaneBackgroundUPP
>(kControlEntireControl
, kControlUserPaneBackgroundProcTag
, GetwxMacControlUserPaneBackgroundProc()) ;
1079 bool wxWindowMac::Create(wxWindowMac
*parent
,
1084 const wxString
& name
)
1086 wxCHECK_MSG( parent
, false, wxT("can't create wxWindowMac without parent") );
1088 if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) )
1091 m_windowVariant
= parent
->GetWindowVariant() ;
1093 if ( m_macIsUserPane
)
1095 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
) ;
1098 | kControlSupportsEmbedding
1099 | kControlSupportsLiveFeedback
1100 | kControlGetsFocusOnClick
1101 // | kControlHasSpecialBackground
1102 // | kControlSupportsCalcBestRect
1103 | kControlHandlesTracking
1104 | kControlSupportsFocus
1105 | kControlWantsActivate
1106 | kControlWantsIdle
;
1108 m_peer
= new wxMacControl(this) ;
1109 OSStatus err
=::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds
, features
, m_peer
->GetControlRefAddr() );
1110 verify_noerr( err
);
1112 MacPostControlCreate(pos
, size
) ;
1115 #ifndef __WXUNIVERSAL__
1116 // Don't give scrollbars to wxControls unless they ask for them
1117 if ( (! IsKindOf(CLASSINFO(wxControl
)) && ! IsKindOf(CLASSINFO(wxStatusBar
)))
1118 || (IsKindOf(CLASSINFO(wxControl
)) && ((style
& wxHSCROLL
) || (style
& wxVSCROLL
))))
1120 MacCreateScrollBars( style
) ;
1124 wxWindowCreateEvent
event(this);
1125 GetEventHandler()->AddPendingEvent(event
);
1130 void wxWindowMac::MacChildAdded()
1133 m_vScrollBar
->Raise() ;
1135 m_hScrollBar
->Raise() ;
1138 void wxWindowMac::MacPostControlCreate(const wxPoint
& pos
, const wxSize
& size
)
1140 wxASSERT_MSG( m_peer
!= NULL
&& m_peer
->Ok() , wxT("No valid mac control") ) ;
1142 m_peer
->SetReference( (URefCon
) this ) ;
1143 GetParent()->AddChild( this );
1145 MacInstallEventHandler( (WXWidget
) m_peer
->GetControlRef() );
1147 ControlRef container
= (ControlRef
) GetParent()->GetHandle() ;
1148 wxASSERT_MSG( container
!= NULL
, wxT("No valid mac container control") ) ;
1149 ::EmbedControl( m_peer
->GetControlRef() , container
) ;
1150 GetParent()->MacChildAdded() ;
1152 // adjust font, controlsize etc
1153 DoSetWindowVariant( m_windowVariant
) ;
1155 m_peer
->SetLabel( wxStripMenuCodes(m_label
, wxStrip_Mnemonics
) ) ;
1157 if (!m_macIsUserPane
)
1158 SetInitialSize(size
);
1160 SetCursor( *wxSTANDARD_CURSOR
) ;
1163 void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant
)
1165 // Don't assert, in case we set the window variant before
1166 // the window is created
1167 // wxASSERT( m_peer->Ok() ) ;
1169 m_windowVariant
= variant
;
1171 if (m_peer
== NULL
|| !m_peer
->Ok())
1175 ThemeFontID themeFont
= kThemeSystemFont
;
1177 // we will get that from the settings later
1178 // and make this NORMAL later, but first
1179 // we have a few calculations that we must fix
1183 case wxWINDOW_VARIANT_NORMAL
:
1184 size
= kControlSizeNormal
;
1185 themeFont
= kThemeSystemFont
;
1188 case wxWINDOW_VARIANT_SMALL
:
1189 size
= kControlSizeSmall
;
1190 themeFont
= kThemeSmallSystemFont
;
1193 case wxWINDOW_VARIANT_MINI
:
1194 if (UMAGetSystemVersion() >= 0x1030 )
1196 // not always defined in the headers
1202 size
= kControlSizeSmall
;
1203 themeFont
= kThemeSmallSystemFont
;
1207 case wxWINDOW_VARIANT_LARGE
:
1208 size
= kControlSizeLarge
;
1209 themeFont
= kThemeSystemFont
;
1213 wxFAIL_MSG(_T("unexpected window variant"));
1217 m_peer
->SetData
<ControlSize
>(kControlEntireControl
, kControlSizeTag
, &size
) ;
1220 font
.MacCreateThemeFont( themeFont
) ;
1224 void wxWindowMac::MacUpdateControlFont()
1226 m_peer
->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ;
1230 bool wxWindowMac::SetFont(const wxFont
& font
)
1232 bool retval
= wxWindowBase::SetFont( font
);
1234 MacUpdateControlFont() ;
1239 bool wxWindowMac::SetForegroundColour(const wxColour
& col
)
1241 bool retval
= wxWindowBase::SetForegroundColour( col
);
1244 MacUpdateControlFont();
1249 bool wxWindowMac::SetBackgroundColour(const wxColour
& col
)
1251 if ( !wxWindowBase::SetBackgroundColour(col
) && m_hasBgCol
)
1255 wxColour
newCol(GetBackgroundColour());
1257 if ( newCol
== wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW
) )
1258 brush
.MacSetTheme( kThemeBrushDocumentWindowBackground
) ;
1259 else if ( newCol
== wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE
) )
1260 brush
.MacSetTheme( kThemeBrushDialogBackgroundActive
) ;
1262 brush
.SetColour( newCol
) ;
1264 MacSetBackgroundBrush( brush
) ;
1265 MacUpdateControlFont() ;
1270 void wxWindowMac::MacSetBackgroundBrush( const wxBrush
&brush
)
1272 m_macBackgroundBrush
= brush
;
1273 m_peer
->SetBackground( brush
) ;
1276 bool wxWindowMac::MacCanFocus() const
1278 // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so
1279 // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning,
1280 // but the value range is nowhere documented
1281 Boolean keyExistsAndHasValidFormat
;
1282 CFIndex fullKeyboardAccess
= CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) ,
1283 kCFPreferencesCurrentApplication
, &keyExistsAndHasValidFormat
);
1285 if ( keyExistsAndHasValidFormat
&& fullKeyboardAccess
> 0 )
1291 UInt32 features
= 0 ;
1292 m_peer
->GetFeatures( &features
) ;
1294 return features
& ( kControlSupportsFocus
| kControlGetsFocusOnClick
) ;
1298 void wxWindowMac::SetFocus()
1300 if ( !AcceptsFocus() )
1303 wxWindow
* former
= FindFocus() ;
1304 if ( former
== this )
1307 // as we cannot rely on the control features to find out whether we are in full keyboard mode,
1308 // we can only leave in case of an error
1309 OSStatus err
= m_peer
->SetFocus( kControlFocusNextPart
) ;
1310 if ( err
== errCouldntSetFocus
)
1313 SetUserFocusWindow( (WindowRef
)MacGetTopLevelWindowRef() );
1315 #if !TARGET_API_MAC_OSX
1316 // emulate carbon events when running under CarbonLib where they are not natively available
1319 EventRef evRef
= NULL
;
1321 err
= MacCreateEvent(
1322 NULL
, kEventClassControl
, kEventControlSetFocusPart
, TicksToEventTime( TickCount() ) ,
1323 kEventAttributeUserEvent
, &evRef
);
1324 verify_noerr( err
);
1326 wxMacCarbonEvent
cEvent( evRef
) ;
1327 cEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, (ControlRef
) former
->GetHandle() ) ;
1328 cEvent
.SetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
, kControlFocusNoPart
) ;
1330 wxMacWindowEventHandler( NULL
, evRef
, former
) ;
1331 ReleaseEvent( evRef
) ;
1334 // send new focus event
1336 EventRef evRef
= NULL
;
1338 err
= MacCreateEvent(
1339 NULL
, kEventClassControl
, kEventControlSetFocusPart
, TicksToEventTime( TickCount() ) ,
1340 kEventAttributeUserEvent
, &evRef
);
1341 verify_noerr( err
);
1343 wxMacCarbonEvent
cEvent( evRef
) ;
1344 cEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, (ControlRef
) GetHandle() ) ;
1345 cEvent
.SetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
, kControlFocusNextPart
) ;
1347 wxMacWindowEventHandler( NULL
, evRef
, this ) ;
1348 ReleaseEvent( evRef
) ;
1353 void wxWindowMac::DoCaptureMouse()
1355 wxApp::s_captureWindow
= this ;
1358 wxWindow
* wxWindowBase::GetCapture()
1360 return wxApp::s_captureWindow
;
1363 void wxWindowMac::DoReleaseMouse()
1365 wxApp::s_captureWindow
= NULL
;
1368 #if wxUSE_DRAG_AND_DROP
1370 void wxWindowMac::SetDropTarget(wxDropTarget
*pDropTarget
)
1372 if ( m_dropTarget
!= NULL
)
1373 delete m_dropTarget
;
1375 m_dropTarget
= pDropTarget
;
1376 if ( m_dropTarget
!= NULL
)
1384 // Old-style File Manager Drag & Drop
1385 void wxWindowMac::DragAcceptFiles(bool accept
)
1390 // Returns the size of the native control. In the case of the toplevel window
1391 // this is the content area root control
1393 void wxWindowMac::MacGetPositionAndSizeFromControl(int& x
, int& y
,
1394 int& w
, int& h
) const
1396 wxFAIL_MSG( wxT("Not currently supported") ) ;
1399 // From a wx position / size calculate the appropriate size of the native control
1401 bool wxWindowMac::MacGetBoundsForControl(
1405 int& w
, int& h
, bool adjustOrigin
) const
1407 // the desired size, minus the border pixels gives the correct size of the control
1411 // TODO: the default calls may be used as soon as PostCreateControl Is moved here
1412 w
= wxMax(size
.x
, 0) ; // WidthDefault( size.x );
1413 h
= wxMax(size
.y
, 0) ; // HeightDefault( size.y ) ;
1415 x
+= MacGetLeftBorderSize() ;
1416 y
+= MacGetTopBorderSize() ;
1417 w
-= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1418 h
-= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1421 AdjustForParentClientOrigin( x
, y
) ;
1423 // this is in window relative coordinate, as this parent may have a border, its physical position is offset by this border
1424 if ( !GetParent()->IsTopLevel() )
1426 x
-= GetParent()->MacGetLeftBorderSize() ;
1427 y
-= GetParent()->MacGetTopBorderSize() ;
1433 // Get window size (not client size)
1434 void wxWindowMac::DoGetSize(int *x
, int *y
) const
1437 m_peer
->GetRect( &bounds
) ;
1440 *x
= bounds
.right
- bounds
.left
+ MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1442 *y
= bounds
.bottom
- bounds
.top
+ MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1445 // get the position of the bounds of this window in client coordinates of its parent
1446 void wxWindowMac::DoGetPosition(int *x
, int *y
) const
1449 m_peer
->GetRect( &bounds
) ;
1451 int x1
= bounds
.left
;
1452 int y1
= bounds
.top
;
1454 // get the wx window position from the native one
1455 x1
-= MacGetLeftBorderSize() ;
1456 y1
-= MacGetTopBorderSize() ;
1458 if ( !IsTopLevel() )
1460 wxWindow
*parent
= GetParent();
1463 // we must first adjust it to be in window coordinates of the parent,
1464 // as otherwise it gets lost by the ClientAreaOrigin fix
1465 x1
+= parent
->MacGetLeftBorderSize() ;
1466 y1
+= parent
->MacGetTopBorderSize() ;
1468 // and now to client coordinates
1469 wxPoint
pt(parent
->GetClientAreaOrigin());
1481 void wxWindowMac::DoScreenToClient(int *x
, int *y
) const
1483 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
1484 wxCHECK_RET( window
, wxT("TopLevel Window missing") ) ;
1486 Point localwhere
= { 0, 0 } ;
1493 wxMacGlobalToLocal( window
, &localwhere
) ;
1500 MacRootWindowToWindow( x
, y
) ;
1502 wxPoint origin
= GetClientAreaOrigin() ;
1509 void wxWindowMac::DoClientToScreen(int *x
, int *y
) const
1511 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
1512 wxCHECK_RET( window
, wxT("TopLevel window missing") ) ;
1514 wxPoint origin
= GetClientAreaOrigin() ;
1520 MacWindowToRootWindow( x
, y
) ;
1522 Point localwhere
= { 0, 0 };
1528 wxMacLocalToGlobal( window
, &localwhere
) ;
1536 void wxWindowMac::MacClientToRootWindow( int *x
, int *y
) const
1538 wxPoint origin
= GetClientAreaOrigin() ;
1544 MacWindowToRootWindow( x
, y
) ;
1547 void wxWindowMac::MacRootWindowToClient( int *x
, int *y
) const
1549 MacRootWindowToWindow( x
, y
) ;
1551 wxPoint origin
= GetClientAreaOrigin() ;
1558 void wxWindowMac::MacWindowToRootWindow( int *x
, int *y
) const
1567 if ( !IsTopLevel() )
1569 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
1572 pt
.x
-= MacGetLeftBorderSize() ;
1573 pt
.y
-= MacGetTopBorderSize() ;
1574 wxMacControl::Convert( &pt
, m_peer
, top
->m_peer
) ;
1584 void wxWindowMac::MacWindowToRootWindow( short *x
, short *y
) const
1593 MacWindowToRootWindow( &x1
, &y1
) ;
1601 void wxWindowMac::MacRootWindowToWindow( int *x
, int *y
) const
1610 if ( !IsTopLevel() )
1612 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
1615 wxMacControl::Convert( &pt
, top
->m_peer
, m_peer
) ;
1616 pt
.x
+= MacGetLeftBorderSize() ;
1617 pt
.y
+= MacGetTopBorderSize() ;
1627 void wxWindowMac::MacRootWindowToWindow( short *x
, short *y
) const
1636 MacRootWindowToWindow( &x1
, &y1
) ;
1644 void wxWindowMac::MacGetContentAreaInset( int &left
, int &top
, int &right
, int &bottom
)
1646 RgnHandle rgn
= NewRgn() ;
1648 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1650 Rect structure
, content
;
1652 GetRegionBounds( rgn
, &content
) ;
1653 m_peer
->GetRect( &structure
) ;
1654 OffsetRect( &structure
, -structure
.left
, -structure
.top
) ;
1656 left
= content
.left
- structure
.left
;
1657 top
= content
.top
- structure
.top
;
1658 right
= structure
.right
- content
.right
;
1659 bottom
= structure
.bottom
- content
.bottom
;
1663 left
= top
= right
= bottom
= 0 ;
1669 wxSize
wxWindowMac::DoGetSizeFromClientSize( const wxSize
& size
) const
1671 wxSize sizeTotal
= size
;
1673 RgnHandle rgn
= NewRgn() ;
1674 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1676 Rect content
, structure
;
1677 GetRegionBounds( rgn
, &content
) ;
1678 m_peer
->GetRect( &structure
) ;
1680 // structure is in parent coordinates, but we only need width and height, so it's ok
1682 sizeTotal
.x
+= (structure
.right
- structure
.left
) - (content
.right
- content
.left
) ;
1683 sizeTotal
.y
+= (structure
.bottom
- structure
.top
) - (content
.bottom
- content
.top
) ;
1688 sizeTotal
.x
+= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1689 sizeTotal
.y
+= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1694 // Get size *available for subwindows* i.e. excluding menu bar etc.
1695 void wxWindowMac::DoGetClientSize( int *x
, int *y
) const
1699 RgnHandle rgn
= NewRgn() ;
1701 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1702 GetRegionBounds( rgn
, &content
) ;
1704 m_peer
->GetRect( &content
) ;
1707 ww
= content
.right
- content
.left
;
1708 hh
= content
.bottom
- content
.top
;
1710 if (m_hScrollBar
&& m_hScrollBar
->IsShown() )
1711 hh
-= m_hScrollBar
->GetSize().y
;
1713 if (m_vScrollBar
&& m_vScrollBar
->IsShown() )
1714 ww
-= m_vScrollBar
->GetSize().x
;
1722 bool wxWindowMac::SetCursor(const wxCursor
& cursor
)
1724 if (m_cursor
.IsSameAs(cursor
))
1729 if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR
) )
1734 if ( ! wxWindowBase::SetCursor( cursor
) )
1738 wxASSERT_MSG( m_cursor
.Ok(),
1739 wxT("cursor must be valid after call to the base version"));
1741 wxWindowMac
*mouseWin
= 0 ;
1743 wxTopLevelWindowMac
*tlw
= MacGetTopLevelWindow() ;
1744 WindowRef window
= (WindowRef
) ( tlw
? tlw
->MacGetWindowRef() : 0 ) ;
1746 ControlPartCode part
;
1747 ControlRef control
;
1749 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
1751 HIGetMousePosition(kHICoordSpaceWindow
, window
, &hiPoint
);
1756 Boolean swapped
= QDSwapPort( GetWindowPort( window
) , &savePort
) ;
1758 // TODO: If we ever get a GetCurrentEvent... replacement
1759 // for the mouse position, use it...
1764 control
= wxMacFindControlUnderMouse( tlw
, pt
, window
, &part
) ;
1766 mouseWin
= wxFindControlFromMacControl( control
) ;
1768 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
1770 QDSwapPort( savePort
, NULL
) ;
1774 if ( mouseWin
== this && !wxIsBusy() )
1775 m_cursor
.MacInstall() ;
1781 bool wxWindowMac::DoPopupMenu(wxMenu
*menu
, int x
, int y
)
1783 menu
->SetInvokingWindow(this);
1786 if ( x
== wxDefaultCoord
&& y
== wxDefaultCoord
)
1788 wxPoint mouse
= wxGetMousePosition();
1794 ClientToScreen( &x
, &y
) ;
1797 menu
->MacBeforeDisplay( true ) ;
1798 long menuResult
= ::PopUpMenuSelect((MenuHandle
) menu
->GetHMenu() , y
, x
, 0) ;
1799 if ( HiWord(menuResult
) != 0 )
1802 GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult
)) , LoWord(menuResult
) , &macid
);
1803 int id
= wxMacCommandToId( macid
);
1804 wxMenuItem
* item
= NULL
;
1806 item
= menu
->FindItem( id
, &realmenu
) ;
1809 if (item
->IsCheckable())
1810 item
->Check( !item
->IsChecked() ) ;
1812 menu
->SendEvent( id
, item
->IsCheckable() ? item
->IsChecked() : -1 ) ;
1816 menu
->MacAfterDisplay( true ) ;
1817 menu
->SetInvokingWindow( NULL
);
1823 // ----------------------------------------------------------------------------
1825 // ----------------------------------------------------------------------------
1829 void wxWindowMac::DoSetToolTip(wxToolTip
*tooltip
)
1831 wxWindowBase::DoSetToolTip(tooltip
);
1834 m_tooltip
->SetWindow(this);
1839 void wxWindowMac::MacInvalidateBorders()
1841 if ( m_peer
== NULL
)
1844 bool vis
= MacIsReallyShown() ;
1848 int outerBorder
= MacGetLeftBorderSize() ;
1849 if ( m_peer
->NeedsFocusRect() && m_peer
->HasFocus() )
1852 if ( outerBorder
== 0 )
1855 // now we know that we have something to do at all
1857 // as the borders are drawn on the parent we have to properly invalidate all these areas
1858 RgnHandle updateInner
, updateOuter
;
1861 // this rectangle is in HIViewCoordinates under OSX and in Window Coordinates under Carbon
1862 updateInner
= NewRgn() ;
1863 updateOuter
= NewRgn() ;
1865 m_peer
->GetRect( &rect
) ;
1866 RectRgn( updateInner
, &rect
) ;
1867 InsetRect( &rect
, -outerBorder
, -outerBorder
) ;
1868 RectRgn( updateOuter
, &rect
) ;
1869 DiffRgn( updateOuter
, updateInner
, updateOuter
) ;
1871 #ifdef __WXMAC_OSX__
1872 GetParent()->m_peer
->SetNeedsDisplay( updateOuter
) ;
1874 WindowRef tlw
= (WindowRef
) MacGetTopLevelWindowRef() ;
1876 InvalWindowRgn( tlw
, updateOuter
) ;
1879 DisposeRgn( updateOuter
) ;
1880 DisposeRgn( updateInner
) ;
1883 void wxWindowMac::DoMoveWindow(int x
, int y
, int width
, int height
)
1885 // this is never called for a toplevel window, so we know we have a parent
1886 int former_x
, former_y
, former_w
, former_h
;
1888 // Get true coordinates of former position
1889 DoGetPosition( &former_x
, &former_y
) ;
1890 DoGetSize( &former_w
, &former_h
) ;
1892 wxWindow
*parent
= GetParent();
1895 wxPoint
pt(parent
->GetClientAreaOrigin());
1900 int actualWidth
= width
;
1901 int actualHeight
= height
;
1905 if ((m_minWidth
!= -1) && (actualWidth
< m_minWidth
))
1906 actualWidth
= m_minWidth
;
1907 if ((m_minHeight
!= -1) && (actualHeight
< m_minHeight
))
1908 actualHeight
= m_minHeight
;
1909 if ((m_maxWidth
!= -1) && (actualWidth
> m_maxWidth
))
1910 actualWidth
= m_maxWidth
;
1911 if ((m_maxHeight
!= -1) && (actualHeight
> m_maxHeight
))
1912 actualHeight
= m_maxHeight
;
1914 bool doMove
= false, doResize
= false ;
1916 if ( actualX
!= former_x
|| actualY
!= former_y
)
1919 if ( actualWidth
!= former_w
|| actualHeight
!= former_h
)
1922 if ( doMove
|| doResize
)
1924 // as the borders are drawn outside the native control, we adjust now
1926 wxRect
bounds( wxPoint( actualX
+ MacGetLeftBorderSize() ,actualY
+ MacGetTopBorderSize() ),
1927 wxSize( actualWidth
- (MacGetLeftBorderSize() + MacGetRightBorderSize()) ,
1928 actualHeight
- (MacGetTopBorderSize() + MacGetBottomBorderSize()) ) ) ;
1931 wxMacRectToNative( &bounds
, &r
) ;
1933 if ( !GetParent()->IsTopLevel() )
1934 wxMacWindowToNative( GetParent() , &r
) ;
1936 MacInvalidateBorders() ;
1938 m_cachedClippedRectValid
= false ;
1939 m_peer
->SetRect( &r
) ;
1941 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
1943 MacInvalidateBorders() ;
1945 MacRepositionScrollBars() ;
1948 wxPoint
point(actualX
, actualY
);
1949 wxMoveEvent
event(point
, m_windowId
);
1950 event
.SetEventObject(this);
1951 GetEventHandler()->ProcessEvent(event
) ;
1956 MacRepositionScrollBars() ;
1957 wxSize
size(actualWidth
, actualHeight
);
1958 wxSizeEvent
event(size
, m_windowId
);
1959 event
.SetEventObject(this);
1960 GetEventHandler()->ProcessEvent(event
);
1965 wxSize
wxWindowMac::DoGetBestSize() const
1967 if ( m_macIsUserPane
|| IsTopLevel() )
1968 return wxWindowBase::DoGetBestSize() ;
1970 Rect bestsize
= { 0 , 0 , 0 , 0 } ;
1971 int bestWidth
, bestHeight
;
1973 m_peer
->GetBestRect( &bestsize
) ;
1974 if ( EmptyRect( &bestsize
) )
1979 bestsize
.bottom
= 16 ;
1981 if ( IsKindOf( CLASSINFO( wxScrollBar
) ) )
1983 bestsize
.bottom
= 16 ;
1986 else if ( IsKindOf( CLASSINFO( wxSpinButton
) ) )
1988 bestsize
.bottom
= 24 ;
1993 // return wxWindowBase::DoGetBestSize() ;
1997 bestWidth
= bestsize
.right
- bestsize
.left
;
1998 bestHeight
= bestsize
.bottom
- bestsize
.top
;
1999 if ( bestHeight
< 10 )
2002 return wxSize(bestWidth
, bestHeight
);
2005 // set the size of the window: if the dimensions are positive, just use them,
2006 // but if any of them is equal to -1, it means that we must find the value for
2007 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
2008 // which case -1 is a valid value for x and y)
2010 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
2011 // the width/height to best suit our contents, otherwise we reuse the current
2013 void wxWindowMac::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
2015 // get the current size and position...
2016 int currentX
, currentY
;
2017 int currentW
, currentH
;
2019 GetPosition(¤tX
, ¤tY
);
2020 GetSize(¤tW
, ¤tH
);
2022 // ... and don't do anything (avoiding flicker) if it's already ok
2023 if ( x
== currentX
&& y
== currentY
&&
2024 width
== currentW
&& height
== currentH
&& ( height
!= -1 && width
!= -1 ) )
2027 MacRepositionScrollBars() ; // we might have a real position shift
2032 if ( !(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) )
2034 if ( x
== wxDefaultCoord
)
2036 if ( y
== wxDefaultCoord
)
2040 AdjustForParentClientOrigin( x
, y
, sizeFlags
);
2042 wxSize size
= wxDefaultSize
;
2043 if ( width
== wxDefaultCoord
)
2045 if ( sizeFlags
& wxSIZE_AUTO_WIDTH
)
2047 size
= DoGetBestSize();
2052 // just take the current one
2057 if ( height
== wxDefaultCoord
)
2059 if ( sizeFlags
& wxSIZE_AUTO_HEIGHT
)
2061 if ( size
.x
== wxDefaultCoord
)
2062 size
= DoGetBestSize();
2063 // else: already called DoGetBestSize() above
2069 // just take the current one
2074 DoMoveWindow( x
, y
, width
, height
);
2077 wxPoint
wxWindowMac::GetClientAreaOrigin() const
2079 RgnHandle rgn
= NewRgn() ;
2081 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
2083 GetRegionBounds( rgn
, &content
) ;
2093 return wxPoint( content
.left
+ MacGetLeftBorderSize() , content
.top
+ MacGetTopBorderSize() );
2096 void wxWindowMac::DoSetClientSize(int clientwidth
, int clientheight
)
2098 if ( clientwidth
!= wxDefaultCoord
|| clientheight
!= wxDefaultCoord
)
2100 int currentclientwidth
, currentclientheight
;
2101 int currentwidth
, currentheight
;
2103 GetClientSize( ¤tclientwidth
, ¤tclientheight
) ;
2104 GetSize( ¤twidth
, ¤theight
) ;
2106 DoSetSize( wxDefaultCoord
, wxDefaultCoord
, currentwidth
+ clientwidth
- currentclientwidth
,
2107 currentheight
+ clientheight
- currentclientheight
, wxSIZE_USE_EXISTING
) ;
2111 void wxWindowMac::SetLabel(const wxString
& title
)
2113 m_label
= wxStripMenuCodes(title
, wxStrip_Mnemonics
) ;
2115 if ( m_peer
&& m_peer
->Ok() )
2116 m_peer
->SetLabel( m_label
) ;
2121 wxString
wxWindowMac::GetLabel() const
2126 bool wxWindowMac::Show(bool show
)
2128 bool former
= MacIsReallyShown() ;
2129 if ( !wxWindowBase::Show(show
) )
2132 // TODO: use visibilityChanged Carbon Event for OSX
2134 m_peer
->SetVisibility( show
, true ) ;
2136 if ( former
!= MacIsReallyShown() )
2137 MacPropagateVisibilityChanged() ;
2142 bool wxWindowMac::Enable(bool enable
)
2144 wxASSERT( m_peer
->Ok() ) ;
2145 bool former
= MacIsReallyEnabled() ;
2146 if ( !wxWindowBase::Enable(enable
) )
2149 m_peer
->Enable( enable
) ;
2151 if ( former
!= MacIsReallyEnabled() )
2152 MacPropagateEnabledStateChanged() ;
2158 // status change propagations (will be not necessary for OSX later )
2161 void wxWindowMac::MacPropagateVisibilityChanged()
2163 #if !TARGET_API_MAC_OSX
2164 MacVisibilityChanged() ;
2167 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
2170 child
= node
->GetData();
2171 if ( child
->IsShown() )
2172 child
->MacPropagateVisibilityChanged() ;
2174 node
= node
->GetNext();
2179 void wxWindowMac::MacPropagateEnabledStateChanged()
2181 #if !TARGET_API_MAC_OSX
2182 MacEnabledStateChanged() ;
2185 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
2188 child
= node
->GetData();
2189 if ( child
->IsEnabled() )
2190 child
->MacPropagateEnabledStateChanged() ;
2192 node
= node
->GetNext();
2197 void wxWindowMac::MacPropagateHiliteChanged()
2199 #if !TARGET_API_MAC_OSX
2200 MacHiliteChanged() ;
2203 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
2206 child
= node
->GetData();
2207 if (child
/* && child->IsEnabled() */)
2208 child
->MacPropagateHiliteChanged() ;
2210 node
= node
->GetNext();
2216 // status change notifications
2219 void wxWindowMac::MacVisibilityChanged()
2223 void wxWindowMac::MacHiliteChanged()
2227 void wxWindowMac::MacEnabledStateChanged()
2232 // status queries on the inherited window's state
2235 bool wxWindowMac::MacIsReallyShown()
2237 // only under OSX the visibility of the TLW is taken into account
2238 if ( m_isBeingDeleted
)
2241 #if TARGET_API_MAC_OSX
2242 if ( m_peer
&& m_peer
->Ok() )
2243 return m_peer
->IsVisible();
2246 wxWindow
* win
= this ;
2247 while ( win
->IsShown() )
2249 if ( win
->IsTopLevel() )
2252 win
= win
->GetParent() ;
2260 bool wxWindowMac::MacIsReallyEnabled()
2262 return m_peer
->IsEnabled() ;
2265 bool wxWindowMac::MacIsReallyHilited()
2267 return m_peer
->IsActive();
2270 void wxWindowMac::MacFlashInvalidAreas()
2272 #if TARGET_API_MAC_OSX
2273 HIViewFlashDirtyArea( (WindowRef
) MacGetTopLevelWindowRef() ) ;
2277 int wxWindowMac::GetCharHeight() const
2279 wxClientDC
dc( (wxWindowMac
*)this ) ;
2281 return dc
.GetCharHeight() ;
2284 int wxWindowMac::GetCharWidth() const
2286 wxClientDC
dc( (wxWindowMac
*)this ) ;
2288 return dc
.GetCharWidth() ;
2291 void wxWindowMac::GetTextExtent(const wxString
& string
, int *x
, int *y
,
2292 int *descent
, int *externalLeading
, const wxFont
*theFont
) const
2294 const wxFont
*fontToUse
= theFont
;
2296 fontToUse
= &m_font
;
2298 wxClientDC
dc( (wxWindowMac
*) this ) ;
2300 dc
.GetTextExtent( string
, &lx
, &ly
, &ld
, &le
, (wxFont
*)fontToUse
) ;
2301 if ( externalLeading
)
2302 *externalLeading
= le
;
2312 * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect
2313 * we always intersect with the entire window, not only with the client area
2316 void wxWindowMac::Refresh(bool eraseBack
, const wxRect
*rect
)
2318 if ( m_peer
== NULL
)
2321 if ( !MacIsReallyShown() )
2328 wxMacRectToNative( rect
, &r
) ;
2329 m_peer
->SetNeedsDisplay( &r
) ;
2333 m_peer
->SetNeedsDisplay() ;
2337 void wxWindowMac::Freeze()
2339 #if TARGET_API_MAC_OSX
2340 if ( !m_frozenness
++ )
2342 if ( m_peer
&& m_peer
->Ok() )
2343 m_peer
->SetDrawingEnabled( false ) ;
2348 void wxWindowMac::Thaw()
2350 #if TARGET_API_MAC_OSX
2351 wxASSERT_MSG( m_frozenness
> 0, wxT("Thaw() without matching Freeze()") );
2353 if ( !--m_frozenness
)
2355 if ( m_peer
&& m_peer
->Ok() )
2357 m_peer
->SetDrawingEnabled( true ) ;
2358 m_peer
->InvalidateWithChildren() ;
2364 bool wxWindowMac::IsFrozen() const
2366 return m_frozenness
!= 0;
2369 wxWindowMac
*wxGetActiveWindow()
2371 // actually this is a windows-only concept
2375 // Coordinates relative to the window
2376 void wxWindowMac::WarpPointer(int x_pos
, int y_pos
)
2378 // We really don't move the mouse programmatically under Mac.
2381 void wxWindowMac::OnEraseBackground(wxEraseEvent
& event
)
2383 if ( MacGetTopLevelWindow() == NULL
)
2386 #if TARGET_API_MAC_OSX
2387 if ( !m_macBackgroundBrush
.Ok() || m_macBackgroundBrush
.GetStyle() == wxTRANSPARENT
)
2394 event
.GetDC()->Clear() ;
2398 void wxWindowMac::OnNcPaint( wxNcPaintEvent
& event
)
2403 int wxWindowMac::GetScrollPos(int orient
) const
2405 if ( orient
== wxHORIZONTAL
)
2408 return m_hScrollBar
->GetThumbPosition() ;
2413 return m_vScrollBar
->GetThumbPosition() ;
2419 // This now returns the whole range, not just the number
2420 // of positions that we can scroll.
2421 int wxWindowMac::GetScrollRange(int orient
) const
2423 if ( orient
== wxHORIZONTAL
)
2426 return m_hScrollBar
->GetRange() ;
2431 return m_vScrollBar
->GetRange() ;
2437 int wxWindowMac::GetScrollThumb(int orient
) const
2439 if ( orient
== wxHORIZONTAL
)
2442 return m_hScrollBar
->GetThumbSize() ;
2447 return m_vScrollBar
->GetThumbSize() ;
2453 void wxWindowMac::SetScrollPos(int orient
, int pos
, bool refresh
)
2455 if ( orient
== wxHORIZONTAL
)
2458 m_hScrollBar
->SetThumbPosition( pos
) ;
2463 m_vScrollBar
->SetThumbPosition( pos
) ;
2468 // we draw borders and grow boxes, are already set up and clipped in the current port / cgContextRef
2469 // our own window origin is at leftOrigin/rightOrigin
2472 void wxWindowMac::MacPaintBorders( int leftOrigin
, int rightOrigin
)
2478 bool hasFocus
= m_peer
->NeedsFocusRect() && m_peer
->HasFocus() ;
2479 bool hasBothScrollbars
= (m_hScrollBar
&& m_hScrollBar
->IsShown()) && (m_vScrollBar
&& m_vScrollBar
->IsShown()) ;
2481 // back to the surrounding frame rectangle
2482 m_peer
->GetRect( &rect
) ;
2483 InsetRect( &rect
, -1 , -1 ) ;
2485 #if wxMAC_USE_CORE_GRAPHICS
2487 CGRect cgrect
= CGRectMake( rect
.left
, rect
.top
, rect
.right
- rect
.left
,
2488 rect
.bottom
- rect
.top
) ;
2490 HIThemeFrameDrawInfo info
;
2491 memset( &info
, 0 , sizeof(info
) ) ;
2495 info
.state
= IsEnabled() ? kThemeStateActive
: kThemeStateInactive
;
2496 info
.isFocused
= hasFocus
;
2498 CGContextRef cgContext
= (CGContextRef
) GetParent()->MacGetCGContextRef() ;
2499 wxASSERT( cgContext
) ;
2501 if ( HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
) )
2503 info
.kind
= kHIThemeFrameTextFieldSquare
;
2504 HIThemeDrawFrame( &cgrect
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2506 else if ( HasFlag(wxSIMPLE_BORDER
) )
2508 info
.kind
= kHIThemeFrameListBox
;
2509 HIThemeDrawFrame( &cgrect
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2511 else if ( hasFocus
)
2513 HIThemeDrawFocusRect( &cgrect
, true , cgContext
, kHIThemeOrientationNormal
) ;
2516 m_peer
->GetRect( &rect
) ;
2517 if ( hasBothScrollbars
)
2519 int size
= m_hScrollBar
->GetWindowVariant() == wxWINDOW_VARIANT_NORMAL
? 16 : 12 ;
2520 CGRect cgrect
= CGRectMake( rect
.right
- size
, rect
.bottom
- size
, size
, size
) ;
2521 CGPoint cgpoint
= CGPointMake( rect
.right
- size
, rect
.bottom
- size
) ;
2522 HIThemeGrowBoxDrawInfo info
;
2523 memset( &info
, 0, sizeof(info
) ) ;
2525 info
.state
= IsEnabled() ? kThemeStateActive
: kThemeStateInactive
;
2526 info
.kind
= kHIThemeGrowBoxKindNone
;
2527 info
.size
= kHIThemeGrowBoxSizeNormal
;
2528 info
.direction
= kThemeGrowRight
| kThemeGrowDown
;
2529 HIThemeDrawGrowBox( &cgpoint
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2534 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2538 wxMacControl::Convert( &pt
, GetParent()->m_peer
, top
->m_peer
) ;
2539 OffsetRect( &rect
, pt
.x
, pt
.y
) ;
2542 if ( HasFlag(wxRAISED_BORDER
) || HasFlag( wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
) )
2543 DrawThemeEditTextFrame( &rect
, IsEnabled() ? kThemeStateActive
: kThemeStateInactive
) ;
2544 else if ( HasFlag(wxSIMPLE_BORDER
) )
2545 DrawThemeListBoxFrame( &rect
, IsEnabled() ? kThemeStateActive
: kThemeStateInactive
) ;
2548 DrawThemeFocusRect( &rect
, true ) ;
2550 if ( hasBothScrollbars
)
2552 // GetThemeStandaloneGrowBoxBounds
2553 // DrawThemeStandaloneNoGrowBox
2559 void wxWindowMac::RemoveChild( wxWindowBase
*child
)
2561 if ( child
== m_hScrollBar
)
2562 m_hScrollBar
= NULL
;
2563 if ( child
== m_vScrollBar
)
2564 m_vScrollBar
= NULL
;
2566 wxWindowBase::RemoveChild( child
) ;
2569 // New function that will replace some of the above.
2570 void wxWindowMac::SetScrollbar(int orient
, int pos
, int thumbVisible
,
2571 int range
, bool refresh
)
2574 bool triggerSizeEvent
= false;
2576 if ( orient
== wxHORIZONTAL
)
2580 showScroller
= ((range
!= 0) && (range
> thumbVisible
));
2581 if ( m_hScrollBar
->IsShown() != showScroller
)
2583 m_hScrollBar
->Show( showScroller
);
2584 triggerSizeEvent
= true;
2587 m_hScrollBar
->SetScrollbar( pos
, thumbVisible
, range
, thumbVisible
, refresh
) ;
2594 showScroller
= ((range
!= 0) && (range
> thumbVisible
));
2595 if ( m_vScrollBar
->IsShown() != showScroller
)
2597 m_vScrollBar
->Show( showScroller
) ;
2598 triggerSizeEvent
= true;
2601 m_vScrollBar
->SetScrollbar( pos
, thumbVisible
, range
, thumbVisible
, refresh
) ;
2605 MacRepositionScrollBars() ;
2606 if ( triggerSizeEvent
)
2608 wxSizeEvent
event(GetSize(), m_windowId
);
2609 event
.SetEventObject(this);
2610 GetEventHandler()->ProcessEvent(event
);
2614 // Does a physical scroll
2615 void wxWindowMac::ScrollWindow(int dx
, int dy
, const wxRect
*rect
)
2617 if ( dx
== 0 && dy
== 0 )
2620 int width
, height
;
2621 GetClientSize( &width
, &height
) ;
2624 // note there currently is a bug in OSX which makes inefficient refreshes in case an entire control
2625 // area is scrolled, this does not occur if width and height are 2 pixels less,
2626 // TODO: write optimal workaround
2627 wxRect
scrollrect( MacGetLeftBorderSize() , MacGetTopBorderSize() , width
, height
) ;
2629 scrollrect
.Intersect( *rect
) ;
2631 if ( m_peer
->GetNeedsDisplay() )
2633 // because HIViewScrollRect does not scroll the already invalidated area we have two options:
2634 // either immediate redraw or full invalidate
2636 // is the better overall solution, as it does not slow down scrolling
2637 m_peer
->SetNeedsDisplay() ;
2639 // this would be the preferred version for fast drawing controls
2641 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
2642 if ( UMAGetSystemVersion() >= 0x1030 )
2643 HIViewRender(m_peer
->GetControlRef()) ;
2650 // as the native control might be not a 0/0 wx window coordinates, we have to offset
2651 scrollrect
.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ;
2652 m_peer
->ScrollRect( &scrollrect
, dx
, dy
) ;
2654 // becuase HIViewScrollRect does not scroll the already invalidated area we have two options
2655 // either immediate redraw or full invalidate
2657 // is the better overall solution, as it does not slow down scrolling
2658 m_peer
->SetNeedsDisplay() ;
2660 // this would be the preferred version for fast drawing controls
2662 HIViewRender(m_peer
->GetControlRef()) ;
2668 for (wxWindowList::compatibility_iterator node
= GetChildren().GetFirst(); node
; node
= node
->GetNext())
2670 child
= node
->GetData();
2673 if (child
== m_vScrollBar
)
2675 if (child
== m_hScrollBar
)
2677 if (child
->IsTopLevel())
2680 child
->GetPosition( &x
, &y
);
2681 child
->GetSize( &w
, &h
);
2684 wxRect
rc( x
, y
, w
, h
);
2685 if (rect
->Intersects( rc
))
2686 child
->SetSize( x
+ dx
, y
+ dy
, w
, h
);
2690 child
->SetSize( x
+ dx
, y
+ dy
, w
, h
);
2695 void wxWindowMac::MacOnScroll( wxScrollEvent
&event
)
2697 if ( event
.GetEventObject() == m_vScrollBar
|| event
.GetEventObject() == m_hScrollBar
)
2699 wxScrollWinEvent wevent
;
2700 wevent
.SetPosition(event
.GetPosition());
2701 wevent
.SetOrientation(event
.GetOrientation());
2702 wevent
.SetEventObject(this);
2704 if (event
.GetEventType() == wxEVT_SCROLL_TOP
)
2705 wevent
.SetEventType( wxEVT_SCROLLWIN_TOP
);
2706 else if (event
.GetEventType() == wxEVT_SCROLL_BOTTOM
)
2707 wevent
.SetEventType( wxEVT_SCROLLWIN_BOTTOM
);
2708 else if (event
.GetEventType() == wxEVT_SCROLL_LINEUP
)
2709 wevent
.SetEventType( wxEVT_SCROLLWIN_LINEUP
);
2710 else if (event
.GetEventType() == wxEVT_SCROLL_LINEDOWN
)
2711 wevent
.SetEventType( wxEVT_SCROLLWIN_LINEDOWN
);
2712 else if (event
.GetEventType() == wxEVT_SCROLL_PAGEUP
)
2713 wevent
.SetEventType( wxEVT_SCROLLWIN_PAGEUP
);
2714 else if (event
.GetEventType() == wxEVT_SCROLL_PAGEDOWN
)
2715 wevent
.SetEventType( wxEVT_SCROLLWIN_PAGEDOWN
);
2716 else if (event
.GetEventType() == wxEVT_SCROLL_THUMBTRACK
)
2717 wevent
.SetEventType( wxEVT_SCROLLWIN_THUMBTRACK
);
2718 else if (event
.GetEventType() == wxEVT_SCROLL_THUMBRELEASE
)
2719 wevent
.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE
);
2721 GetEventHandler()->ProcessEvent(wevent
);
2725 // Get the window with the focus
2726 wxWindowMac
*wxWindowBase::DoFindFocus()
2728 ControlRef control
;
2729 GetKeyboardFocus( GetUserFocusWindow() , &control
) ;
2730 return wxFindControlFromMacControl( control
) ;
2733 void wxWindowMac::OnSetFocus( wxFocusEvent
& event
)
2735 // panel wants to track the window which was the last to have focus in it,
2736 // so we want to set ourselves as the window which last had focus
2738 // notice that it's also important to do it upwards the tree because
2739 // otherwise when the top level panel gets focus, it won't set it back to
2740 // us, but to some other sibling
2742 // CS: don't know if this is still needed:
2743 //wxChildFocusEvent eventFocus(this);
2744 //(void)GetEventHandler()->ProcessEvent(eventFocus);
2746 if ( MacGetTopLevelWindow() && m_peer
->NeedsFocusRect() )
2748 #if wxMAC_USE_CORE_GRAPHICS
2749 GetParent()->Refresh() ;
2751 wxMacWindowStateSaver
sv( this ) ;
2754 m_peer
->GetRect( &rect
) ;
2755 // auf den umgebenden Rahmen zur\9fck
2756 InsetRect( &rect
, -1 , -1 ) ;
2758 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2762 wxMacControl::Convert( &pt
, GetParent()->m_peer
, top
->m_peer
) ;
2764 rect
.right
+= pt
.x
;
2766 rect
.bottom
+= pt
.y
;
2769 bool bIsFocusEvent
= (event
.GetEventType() == wxEVT_SET_FOCUS
);
2770 DrawThemeFocusRect( &rect
, bIsFocusEvent
) ;
2771 if ( !bIsFocusEvent
)
2773 // as this erases part of the frame we have to redraw borders
2774 // and because our z-ordering is not always correct (staticboxes)
2775 // we have to invalidate things, we cannot simple redraw
2776 MacInvalidateBorders() ;
2784 void wxWindowMac::OnInternalIdle()
2786 // This calls the UI-update mechanism (querying windows for
2787 // menu/toolbar/control state information)
2788 if (wxUpdateUIEvent::CanUpdate(this))
2789 UpdateWindowUI(wxUPDATE_UI_FROMIDLE
);
2792 // Raise the window to the top of the Z order
2793 void wxWindowMac::Raise()
2795 m_peer
->SetZOrder( true , NULL
) ;
2798 // Lower the window to the bottom of the Z order
2799 void wxWindowMac::Lower()
2801 m_peer
->SetZOrder( false , NULL
) ;
2804 // static wxWindow *gs_lastWhich = NULL;
2806 bool wxWindowMac::MacSetupCursor( const wxPoint
& pt
)
2808 // first trigger a set cursor event
2810 wxPoint clientorigin
= GetClientAreaOrigin() ;
2811 wxSize clientsize
= GetClientSize() ;
2813 if ( wxRect2DInt( clientorigin
.x
, clientorigin
.y
, clientsize
.x
, clientsize
.y
).Contains( wxPoint2DInt( pt
) ) )
2815 wxSetCursorEvent
event( pt
.x
, pt
.y
);
2817 bool processedEvtSetCursor
= GetEventHandler()->ProcessEvent(event
);
2818 if ( processedEvtSetCursor
&& event
.HasCursor() )
2820 cursor
= event
.GetCursor() ;
2824 // the test for processedEvtSetCursor is here to prevent using m_cursor
2825 // if the user code caught EVT_SET_CURSOR() and returned nothing from
2826 // it - this is a way to say that our cursor shouldn't be used for this
2828 if ( !processedEvtSetCursor
&& m_cursor
.Ok() )
2831 if ( !wxIsBusy() && !GetParent() )
2832 cursor
= *wxSTANDARD_CURSOR
;
2836 cursor
.MacInstall() ;
2839 return cursor
.Ok() ;
2842 wxString
wxWindowMac::MacGetToolTipString( wxPoint
&pt
)
2846 return m_tooltip
->GetTip() ;
2849 return wxEmptyString
;
2852 void wxWindowMac::ClearBackground()
2858 void wxWindowMac::Update()
2860 #if TARGET_API_MAC_OSX
2861 MacGetTopLevelWindow()->MacPerformUpdates() ;
2863 ::Draw1Control( m_peer
->GetControlRef() ) ;
2867 wxTopLevelWindowMac
* wxWindowMac::MacGetTopLevelWindow() const
2869 wxTopLevelWindowMac
* win
= NULL
;
2870 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
2872 win
= wxFindWinFromMacWindow( window
) ;
2877 const wxRect
& wxWindowMac::MacGetClippedClientRect() const
2879 MacUpdateClippedRects() ;
2881 return m_cachedClippedClientRect
;
2884 const wxRect
& wxWindowMac::MacGetClippedRect() const
2886 MacUpdateClippedRects() ;
2888 return m_cachedClippedRect
;
2891 const wxRect
&wxWindowMac:: MacGetClippedRectWithOuterStructure() const
2893 MacUpdateClippedRects() ;
2895 return m_cachedClippedRectWithOuterStructure
;
2898 const wxRegion
& wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures
)
2900 static wxRegion emptyrgn
;
2902 if ( !m_isBeingDeleted
&& MacIsReallyShown() /*m_peer->IsVisible() */ )
2904 MacUpdateClippedRects() ;
2905 if ( includeOuterStructures
)
2906 return m_cachedClippedRegionWithOuterStructure
;
2908 return m_cachedClippedRegion
;
2916 void wxWindowMac::MacUpdateClippedRects() const
2918 if ( m_cachedClippedRectValid
)
2921 // includeOuterStructures is true if we try to draw somthing like a focus ring etc.
2922 // also a window dc uses this, in this case we only clip in the hierarchy for hard
2923 // borders like a scrollwindow, splitter etc otherwise we end up in a paranoia having
2924 // to add focus borders everywhere
2926 Rect r
, rIncludingOuterStructures
;
2928 m_peer
->GetRect( &r
) ;
2929 r
.left
-= MacGetLeftBorderSize() ;
2930 r
.top
-= MacGetTopBorderSize() ;
2931 r
.bottom
+= MacGetBottomBorderSize() ;
2932 r
.right
+= MacGetRightBorderSize() ;
2939 rIncludingOuterStructures
= r
;
2940 InsetRect( &rIncludingOuterStructures
, -4 , -4 ) ;
2942 wxRect cl
= GetClientRect() ;
2943 Rect rClient
= { cl
.y
, cl
.x
, cl
.y
+ cl
.height
, cl
.x
+ cl
.width
} ;
2947 const wxWindow
* child
= this ;
2948 const wxWindow
* parent
= NULL
;
2950 while ( !child
->IsTopLevel() && ( parent
= child
->GetParent() ) != NULL
)
2952 if ( parent
->MacIsChildOfClientArea(child
) )
2954 size
= parent
->GetClientSize() ;
2955 wxPoint origin
= parent
->GetClientAreaOrigin() ;
2961 // this will be true for scrollbars, toolbars etc.
2962 size
= parent
->GetSize() ;
2963 y
= parent
->MacGetTopBorderSize() ;
2964 x
= parent
->MacGetLeftBorderSize() ;
2965 size
.x
-= parent
->MacGetLeftBorderSize() + parent
->MacGetRightBorderSize() ;
2966 size
.y
-= parent
->MacGetTopBorderSize() + parent
->MacGetBottomBorderSize() ;
2969 parent
->MacWindowToRootWindow( &x
, &y
) ;
2970 MacRootWindowToWindow( &x
, &y
) ;
2972 Rect rparent
= { y
, x
, y
+ size
.y
, x
+ size
.x
} ;
2974 // the wxwindow and client rects will always be clipped
2975 SectRect( &r
, &rparent
, &r
) ;
2976 SectRect( &rClient
, &rparent
, &rClient
) ;
2978 // the structure only at 'hard' borders
2979 if ( parent
->MacClipChildren() ||
2980 ( parent
->GetParent() && parent
->GetParent()->MacClipGrandChildren() ) )
2982 SectRect( &rIncludingOuterStructures
, &rparent
, &rIncludingOuterStructures
) ;
2988 m_cachedClippedRect
= wxRect( r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
- r
.top
) ;
2989 m_cachedClippedClientRect
= wxRect( rClient
.left
, rClient
.top
,
2990 rClient
.right
- rClient
.left
, rClient
.bottom
- rClient
.top
) ;
2991 m_cachedClippedRectWithOuterStructure
= wxRect(
2992 rIncludingOuterStructures
.left
, rIncludingOuterStructures
.top
,
2993 rIncludingOuterStructures
.right
- rIncludingOuterStructures
.left
,
2994 rIncludingOuterStructures
.bottom
- rIncludingOuterStructures
.top
) ;
2996 m_cachedClippedRegionWithOuterStructure
= wxRegion( m_cachedClippedRectWithOuterStructure
) ;
2997 m_cachedClippedRegion
= wxRegion( m_cachedClippedRect
) ;
2998 m_cachedClippedClientRegion
= wxRegion( m_cachedClippedClientRect
) ;
3000 m_cachedClippedRectValid
= true ;
3004 This function must not change the updatergn !
3006 bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr
, long time
)
3008 bool handled
= false ;
3010 RgnHandle updatergn
= (RgnHandle
) updatergnr
;
3011 GetRegionBounds( updatergn
, &updatebounds
) ;
3013 // wxLogDebug(wxT("update for %s bounds %d, %d, %d, %d"), wxString(GetClassInfo()->GetClassName()).c_str(), updatebounds.left, updatebounds.top , updatebounds.right , updatebounds.bottom ) ;
3015 if ( !EmptyRgn(updatergn
) )
3017 RgnHandle newupdate
= NewRgn() ;
3018 wxSize point
= GetClientSize() ;
3019 wxPoint origin
= GetClientAreaOrigin() ;
3020 SetRectRgn( newupdate
, origin
.x
, origin
.y
, origin
.x
+ point
.x
, origin
.y
+ point
.y
) ;
3021 SectRgn( newupdate
, updatergn
, newupdate
) ;
3023 // first send an erase event to the entire update area
3025 // for the toplevel window this really is the entire area
3026 // for all the others only their client area, otherwise they
3027 // might be drawing with full alpha and eg put blue into
3028 // the grow-box area of a scrolled window (scroll sample)
3029 wxDC
* dc
= new wxWindowDC(this);
3031 dc
->SetClippingRegion(wxRegion(updatergn
));
3033 dc
->SetClippingRegion(wxRegion(newupdate
));
3035 wxEraseEvent
eevent( GetId(), dc
);
3036 eevent
.SetEventObject( this );
3037 GetEventHandler()->ProcessEvent( eevent
);
3041 // calculate a client-origin version of the update rgn and set m_updateRegion to that
3042 OffsetRgn( newupdate
, -origin
.x
, -origin
.y
) ;
3043 m_updateRegion
= newupdate
;
3044 DisposeRgn( newupdate
) ;
3046 if ( !m_updateRegion
.Empty() )
3048 // paint the window itself
3051 event
.SetTimestamp(time
);
3052 event
.SetEventObject(this);
3053 GetEventHandler()->ProcessEvent(event
);
3057 // now we cannot rely on having its borders drawn by a window itself, as it does not
3058 // get the updateRgn wide enough to always do so, so we do it from the parent
3059 // this would also be the place to draw any custom backgrounds for native controls
3060 // in Composited windowing
3061 wxPoint clientOrigin
= GetClientAreaOrigin() ;
3065 for (wxWindowList::compatibility_iterator node
= GetChildren().GetFirst(); node
; node
= node
->GetNext())
3067 child
= node
->GetData();
3070 if (child
== m_vScrollBar
)
3072 if (child
== m_hScrollBar
)
3074 if (child
->IsTopLevel())
3076 if (!child
->IsShown())
3079 // only draw those in the update region (add a safety margin of 10 pixels for shadow effects
3081 child
->GetPosition( &x
, &y
);
3082 child
->GetSize( &w
, &h
);
3083 Rect childRect
= { y
, x
, y
+ h
, x
+ w
} ;
3084 OffsetRect( &childRect
, clientOrigin
.x
, clientOrigin
.y
) ;
3085 InsetRect( &childRect
, -10 , -10) ;
3087 if ( RectInRgn( &childRect
, updatergn
) )
3089 // paint custom borders
3090 wxNcPaintEvent
eventNc( child
->GetId() );
3091 eventNc
.SetEventObject( child
);
3092 if ( !child
->GetEventHandler()->ProcessEvent( eventNc
) )
3094 #if wxMAC_USE_CORE_GRAPHICS
3095 child
->MacPaintBorders(0, 0) ;
3098 wxWindowDC
dc(this) ;
3099 dc
.SetClippingRegion(wxRegion(updatergn
));
3100 wxMacPortSetter
helper(&dc
) ;
3101 child
->MacPaintBorders(0, 0) ;
3113 WXWindow
wxWindowMac::MacGetTopLevelWindowRef() const
3115 wxWindowMac
*iter
= (wxWindowMac
*)this ;
3119 if ( iter
->IsTopLevel() )
3120 return ((wxTopLevelWindow
*)iter
)->MacGetWindowRef() ;
3122 iter
= iter
->GetParent() ;
3128 void wxWindowMac::MacCreateScrollBars( long style
)
3130 wxASSERT_MSG( m_vScrollBar
== NULL
&& m_hScrollBar
== NULL
, wxT("attempt to create window twice") ) ;
3132 if ( style
& ( wxVSCROLL
| wxHSCROLL
) )
3134 bool hasBoth
= ( style
& wxVSCROLL
) && ( style
& wxHSCROLL
) ;
3135 int scrlsize
= MAC_SCROLLBAR_SIZE
;
3136 if ( GetWindowVariant() == wxWINDOW_VARIANT_SMALL
|| GetWindowVariant() == wxWINDOW_VARIANT_MINI
)
3138 scrlsize
= MAC_SMALL_SCROLLBAR_SIZE
;
3141 int adjust
= hasBoth
? scrlsize
- 1: 0 ;
3143 GetClientSize( &width
, &height
) ;
3145 wxPoint
vPoint(width
- scrlsize
, 0) ;
3146 wxSize
vSize(scrlsize
, height
- adjust
) ;
3147 wxPoint
hPoint(0, height
- scrlsize
) ;
3148 wxSize
hSize(width
- adjust
, scrlsize
) ;
3150 if ( style
& wxVSCROLL
)
3151 m_vScrollBar
= new wxScrollBar(this, wxID_ANY
, vPoint
, vSize
, wxVERTICAL
);
3153 if ( style
& wxHSCROLL
)
3154 m_hScrollBar
= new wxScrollBar(this, wxID_ANY
, hPoint
, hSize
, wxHORIZONTAL
);
3157 // because the create does not take into account the client area origin
3158 // we might have a real position shift
3159 MacRepositionScrollBars() ;
3162 bool wxWindowMac::MacIsChildOfClientArea( const wxWindow
* child
) const
3164 bool result
= ((child
== NULL
) || ((child
!= m_hScrollBar
) && (child
!= m_vScrollBar
)));
3169 void wxWindowMac::MacRepositionScrollBars()
3171 if ( !m_hScrollBar
&& !m_vScrollBar
)
3174 bool hasBoth
= (m_hScrollBar
&& m_hScrollBar
->IsShown()) && ( m_vScrollBar
&& m_vScrollBar
->IsShown()) ;
3175 int scrlsize
= m_hScrollBar
? m_hScrollBar
->GetSize().y
: ( m_vScrollBar
? m_vScrollBar
->GetSize().x
: MAC_SCROLLBAR_SIZE
) ;
3176 int adjust
= hasBoth
? scrlsize
- 1 : 0 ;
3178 // get real client area
3180 GetSize( &width
, &height
);
3182 width
-= MacGetLeftBorderSize() + MacGetRightBorderSize();
3183 height
-= MacGetTopBorderSize() + MacGetBottomBorderSize();
3185 wxPoint
vPoint( width
- scrlsize
, 0 ) ;
3186 wxSize
vSize( scrlsize
, height
- adjust
) ;
3187 wxPoint
hPoint( 0 , height
- scrlsize
) ;
3188 wxSize
hSize( width
- adjust
, scrlsize
) ;
3191 int x
= 0, y
= 0, w
, h
;
3192 GetSize( &w
, &h
) ;
3194 MacClientToRootWindow( &x
, &y
) ;
3195 MacClientToRootWindow( &w
, &h
) ;
3197 wxWindowMac
*iter
= (wxWindowMac
*)this ;
3199 int totW
= 10000 , totH
= 10000;
3202 if ( iter
->IsTopLevel() )
3204 iter
->GetSize( &totW
, &totH
) ;
3208 iter
= iter
->GetParent() ;
3222 if ( w
- x
>= totW
)
3227 if ( h
- y
>= totH
)
3235 m_vScrollBar
->SetSize( vPoint
.x
, vPoint
.y
, vSize
.x
, vSize
.y
, wxSIZE_ALLOW_MINUS_ONE
);
3237 m_hScrollBar
->SetSize( hPoint
.x
, hPoint
.y
, hSize
.x
, hSize
.y
, wxSIZE_ALLOW_MINUS_ONE
);
3240 bool wxWindowMac::AcceptsFocus() const
3242 return MacCanFocus() && wxWindowBase::AcceptsFocus();
3245 void wxWindowMac::MacSuperChangedPosition()
3247 // only window-absolute structures have to be moved i.e. controls
3249 m_cachedClippedRectValid
= false ;
3252 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
3255 child
= node
->GetData();
3256 child
->MacSuperChangedPosition() ;
3258 node
= node
->GetNext();
3262 void wxWindowMac::MacTopLevelWindowChangedPosition()
3264 // only screen-absolute structures have to be moved i.e. glcanvas
3267 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
3270 child
= node
->GetData();
3271 child
->MacTopLevelWindowChangedPosition() ;
3273 node
= node
->GetNext();
3277 long wxWindowMac::MacGetLeftBorderSize() const
3284 if (HasFlag(wxRAISED_BORDER
) || HasFlag( wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
))
3286 // this metric is only the 'outset' outside the simple frame rect
3287 GetThemeMetric( kThemeMetricEditTextFrameOutset
, &border
) ;
3290 else if (HasFlag(wxSIMPLE_BORDER
))
3292 // this metric is only the 'outset' outside the simple frame rect
3293 GetThemeMetric( kThemeMetricListBoxFrameOutset
, &border
) ;
3300 long wxWindowMac::MacGetRightBorderSize() const
3302 // they are all symmetric in mac themes
3303 return MacGetLeftBorderSize() ;
3306 long wxWindowMac::MacGetTopBorderSize() const
3308 // they are all symmetric in mac themes
3309 return MacGetLeftBorderSize() ;
3312 long wxWindowMac::MacGetBottomBorderSize() const
3314 // they are all symmetric in mac themes
3315 return MacGetLeftBorderSize() ;
3318 long wxWindowMac::MacRemoveBordersFromStyle( long style
)
3320 return style
& ~wxBORDER_MASK
;
3323 // Find the wxWindowMac at the current mouse position, returning the mouse
3325 wxWindowMac
* wxFindWindowAtPointer( wxPoint
& pt
)
3327 pt
= wxGetMousePosition();
3328 wxWindowMac
* found
= wxFindWindowAtPoint(pt
);
3333 // Get the current mouse position.
3334 wxPoint
wxGetMousePosition()
3338 wxGetMousePosition( &x
, &y
);
3340 return wxPoint(x
, y
);
3343 void wxWindowMac::OnMouseEvent( wxMouseEvent
&event
)
3345 if ( event
.GetEventType() == wxEVT_RIGHT_DOWN
)
3347 // copied from wxGTK : CS
3348 // VZ: shouldn't we move this to base class then?
3350 // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN
3353 // (a) it's a command event and so is propagated to the parent
3354 // (b) under MSW it can be generated from kbd too
3355 // (c) it uses screen coords (because of (a))
3356 wxContextMenuEvent
evtCtx(wxEVT_CONTEXT_MENU
,
3358 this->ClientToScreen(event
.GetPosition()));
3359 if ( ! GetEventHandler()->ProcessEvent(evtCtx
) )
3368 void wxWindowMac::OnPaint( wxPaintEvent
& event
)
3370 if ( wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
)
3371 CallNextEventHandler(
3372 (EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() ,
3373 (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
3376 void wxWindowMac::MacHandleControlClick( WXWidget control
, wxInt16 controlpart
, bool WXUNUSED( mouseStillDown
) )
3380 Rect
wxMacGetBoundsForControl( wxWindow
* window
, const wxPoint
& pos
, const wxSize
&size
, bool adjustForOrigin
)
3384 window
->MacGetBoundsForControl( pos
, size
, x
, y
, w
, h
, adjustForOrigin
) ;
3385 Rect bounds
= { y
, x
, y
+ h
, x
+ w
};
3390 wxInt32
wxWindowMac::MacControlHit(WXEVENTHANDLERREF
WXUNUSED(handler
) , WXEVENTREF
WXUNUSED(event
) )
3392 return eventNotHandledErr
;
3395 bool wxWindowMac::Reparent(wxWindowBase
*newParentBase
)
3397 wxWindowMac
*newParent
= (wxWindowMac
*)newParentBase
;
3398 if ( !wxWindowBase::Reparent(newParent
) )
3401 // copied from MacPostControlCreate
3402 ControlRef container
= (ControlRef
) GetParent()->GetHandle() ;
3404 wxASSERT_MSG( container
!= NULL
, wxT("No valid mac container control") ) ;
3406 ::EmbedControl( m_peer
->GetControlRef() , container
) ;
3411 bool wxWindowMac::SetTransparent(wxByte alpha
)
3413 #if wxMAC_USE_CORE_GRAPHICS
3414 if ( alpha
!= m_macAlpha
)
3416 m_macAlpha
= alpha
;
3426 bool wxWindowMac::CanSetTransparent()
3428 #if wxMAC_USE_CORE_GRAPHICS
3435 wxByte
wxWindowMac::GetTransparent() const