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"
57 #include "wx/popupwin.h"
60 #if wxUSE_DRAG_AND_DROP
64 #include "wx/mac/uma.h"
66 #define MAC_SCROLLBAR_SIZE 15
67 #define MAC_SMALL_SCROLLBAR_SIZE 11
71 #include <ToolUtils.h>
72 #include <MacTextEditor.h>
75 #if TARGET_API_MAC_OSX
77 #include <HIToolbox/HIView.h>
83 #ifdef __WXUNIVERSAL__
84 IMPLEMENT_ABSTRACT_CLASS(wxWindowMac
, wxWindowBase
)
86 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
89 BEGIN_EVENT_TABLE(wxWindowMac
, wxWindowBase
)
90 EVT_NC_PAINT(wxWindowMac::OnNcPaint
)
91 EVT_ERASE_BACKGROUND(wxWindowMac::OnEraseBackground
)
92 #if TARGET_API_MAC_OSX
93 EVT_PAINT(wxWindowMac::OnPaint
)
95 EVT_SET_FOCUS(wxWindowMac::OnSetFocus
)
96 EVT_KILL_FOCUS(wxWindowMac::OnSetFocus
)
97 EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent
)
100 #define wxMAC_DEBUG_REDRAW 0
101 #ifndef wxMAC_DEBUG_REDRAW
102 #define wxMAC_DEBUG_REDRAW 0
105 // ---------------------------------------------------------------------------
106 // Utility Routines to move between different coordinate systems
107 // ---------------------------------------------------------------------------
110 * Right now we have the following setup :
111 * a border that is not part of the native control is always outside the
112 * control's border (otherwise we loose all native intelligence, future ways
113 * may be to have a second embedding control responsible for drawing borders
114 * and backgrounds eventually)
115 * so all this border calculations have to be taken into account when calling
116 * native methods or getting native oriented data
117 * so we have three coordinate systems here
118 * wx client coordinates
119 * wx window coordinates (including window frames)
124 // originating from native control
128 void wxMacNativeToWindow( const wxWindow
* window
, RgnHandle handle
)
130 OffsetRgn( handle
, window
->MacGetLeftBorderSize() , window
->MacGetTopBorderSize() ) ;
133 void wxMacNativeToWindow( const wxWindow
* window
, Rect
*rect
)
135 OffsetRect( rect
, window
->MacGetLeftBorderSize() , window
->MacGetTopBorderSize() ) ;
139 // directed towards native control
142 void wxMacWindowToNative( const wxWindow
* window
, RgnHandle handle
)
144 OffsetRgn( handle
, -window
->MacGetLeftBorderSize() , -window
->MacGetTopBorderSize() );
147 void wxMacWindowToNative( const wxWindow
* window
, Rect
*rect
)
149 OffsetRect( rect
, -window
->MacGetLeftBorderSize() , -window
->MacGetTopBorderSize() ) ;
152 // ---------------------------------------------------------------------------
154 // ---------------------------------------------------------------------------
156 static const EventTypeSpec eventList
[] =
158 { kEventClassCommand
, kEventProcessCommand
} ,
159 { kEventClassCommand
, kEventCommandUpdateStatus
} ,
161 { kEventClassControl
, kEventControlGetClickActivation
} ,
162 { kEventClassControl
, kEventControlHit
} ,
164 { kEventClassTextInput
, kEventTextInputUnicodeForKeyEvent
} ,
165 { kEventClassTextInput
, kEventTextInputUpdateActiveInputArea
} ,
167 { kEventClassControl
, kEventControlDraw
} ,
168 #if TARGET_API_MAC_OSX
169 { kEventClassControl
, kEventControlVisibilityChanged
} ,
170 { kEventClassControl
, kEventControlEnabledStateChanged
} ,
171 { kEventClassControl
, kEventControlHiliteChanged
} ,
173 { kEventClassControl
, kEventControlActivate
} ,
174 { kEventClassControl
, kEventControlDeactivate
} ,
176 { kEventClassControl
, kEventControlSetFocusPart
} ,
178 { kEventClassService
, kEventServiceGetTypes
},
179 { kEventClassService
, kEventServiceCopy
},
180 { kEventClassService
, kEventServicePaste
},
182 // { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only
183 // { kEventClassControl , kEventControlBoundsChanged } ,
186 static pascal OSStatus
wxMacWindowControlEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
188 OSStatus result
= eventNotHandledErr
;
190 wxMacCarbonEvent
cEvent( event
) ;
192 ControlRef controlRef
;
193 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
195 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
197 switch ( GetEventKind( event
) )
199 #if TARGET_API_MAC_OSX
200 case kEventControlDraw
:
202 RgnHandle updateRgn
= NULL
;
203 RgnHandle allocatedRgn
= NULL
;
204 wxRegion visRegion
= thisWindow
->MacGetVisibleRegion() ;
206 if ( cEvent
.GetParameter
<RgnHandle
>(kEventParamRgnHandle
, &updateRgn
) != noErr
)
208 updateRgn
= (RgnHandle
) visRegion
.GetWXHRGN() ;
212 if ( thisWindow
->MacGetLeftBorderSize() != 0 || thisWindow
->MacGetTopBorderSize() != 0 )
214 // as this update region is in native window locals we must adapt it to wx window local
215 allocatedRgn
= NewRgn() ;
216 CopyRgn( updateRgn
, allocatedRgn
) ;
218 // hide the given region by the new region that must be shifted
219 wxMacNativeToWindow( thisWindow
, allocatedRgn
) ;
220 updateRgn
= allocatedRgn
;
225 GetRegionBounds( updateRgn
, &rgnBounds
) ;
227 #if wxMAC_DEBUG_REDRAW
228 if ( thisWindow
->MacIsUserPane() )
230 static float color
= 0.5 ;
233 CGContextRef cgContext
= cEvent
.GetParameter
<CGContextRef
>(kEventParamCGContextRef
) ;
235 HIViewGetBounds( controlRef
, &bounds
);
236 CGContextSetRGBFillColor( cgContext
, channel
== 0 ? color
: 0.5 ,
237 channel
== 1 ? color
: 0.5 , channel
== 2 ? color
: 0.5 , 1 );
238 CGContextFillRect( cgContext
, bounds
);
251 bool created
= false ;
252 CGContextRef cgContext
= NULL
;
253 OSStatus err
= cEvent
.GetParameter
<CGContextRef
>(kEventParamCGContextRef
, &cgContext
) ;
254 wxASSERT_MSG( err
== noErr
, wxT("Unable to retrieve CGContextRef") ) ;
255 thisWindow
->MacSetCGContextRef( cgContext
) ;
258 wxMacCGContextStateSaver
sg( cgContext
) ;
261 wxWindow
* iter
= thisWindow
;
264 alpha
*= (float) iter
->GetTransparent()/255.0 ;
265 if ( iter
->IsTopLevel() )
268 iter
= iter
->GetParent() ;
271 CGContextSetAlpha( cgContext
, alpha
) ;
273 if ( thisWindow
->GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT
)
276 HIViewGetBounds( controlRef
, &bounds
);
277 CGContextClearRect( cgContext
, bounds
);
280 if ( thisWindow
->MacDoRedraw( updateRgn
, cEvent
.GetTicks() ) )
283 thisWindow
->MacSetCGContextRef( NULL
) ;
287 CGContextRelease( cgContext
) ;
291 DisposeRgn( allocatedRgn
) ;
295 case kEventControlVisibilityChanged
:
296 thisWindow
->MacVisibilityChanged() ;
299 case kEventControlEnabledStateChanged
:
300 thisWindow
->MacEnabledStateChanged() ;
303 case kEventControlHiliteChanged
:
304 thisWindow
->MacHiliteChanged() ;
307 case kEventControlActivate
:
308 case kEventControlDeactivate
:
309 // FIXME: we should have a virtual function for this!
311 if ( thisWindow
->IsKindOf( CLASSINFO( wxTreeCtrl
) ) )
312 thisWindow
->Refresh();
315 if ( thisWindow
->IsKindOf( CLASSINFO( wxListCtrl
) ) )
316 thisWindow
->Refresh();
319 #endif // TARGET_API_MAC_OSX
321 // we emulate this event under Carbon CFM
322 case kEventControlSetFocusPart
:
324 Boolean focusEverything
= false ;
325 ControlPartCode controlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
);
327 if ( cEvent
.GetParameter
<Boolean
>(kEventParamControlFocusEverything
, &focusEverything
) == noErr
)
331 if ( thisWindow
->MacIsUserPane() )
334 if ( controlPart
== kControlFocusNoPart
)
337 if ( thisWindow
->GetCaret() )
338 thisWindow
->GetCaret()->OnKillFocus();
341 static bool inKillFocusEvent
= false ;
343 if ( !inKillFocusEvent
)
345 inKillFocusEvent
= true ;
346 wxFocusEvent
event( wxEVT_KILL_FOCUS
, thisWindow
->GetId());
347 event
.SetEventObject(thisWindow
);
348 thisWindow
->GetEventHandler()->ProcessEvent(event
) ;
349 inKillFocusEvent
= false ;
354 // panel wants to track the window which was the last to have focus in it
355 wxChildFocusEvent
eventFocus(thisWindow
);
356 thisWindow
->GetEventHandler()->ProcessEvent(eventFocus
);
359 if ( thisWindow
->GetCaret() )
360 thisWindow
->GetCaret()->OnSetFocus();
363 wxFocusEvent
event(wxEVT_SET_FOCUS
, thisWindow
->GetId());
364 event
.SetEventObject(thisWindow
);
365 thisWindow
->GetEventHandler()->ProcessEvent(event
) ;
370 case kEventControlHit
:
371 result
= thisWindow
->MacControlHit( handler
, event
) ;
374 case kEventControlGetClickActivation
:
376 // fix to always have a proper activation for DataBrowser controls (stay in bkgnd otherwise)
377 WindowRef owner
= cEvent
.GetParameter
<WindowRef
>(kEventParamWindowRef
);
378 if ( !IsWindowActive(owner
) )
380 cEvent
.SetParameter(kEventParamClickActivation
,(UInt32
) kActivateAndIgnoreClick
) ;
393 static pascal OSStatus
394 wxMacWindowServiceEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
398 OSStatus result
= eventNotHandledErr
;
400 wxMacCarbonEvent
cEvent( event
) ;
402 ControlRef controlRef
;
403 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
404 wxTextCtrl
* textCtrl
= wxDynamicCast( thisWindow
, wxTextCtrl
) ;
405 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
407 switch ( GetEventKind( event
) )
409 case kEventServiceGetTypes
:
413 textCtrl
->GetSelection( &from
, &to
) ;
415 CFMutableArrayRef copyTypes
= 0 , pasteTypes
= 0;
417 copyTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServiceCopyTypes
, typeCFMutableArrayRef
) ;
418 if ( textCtrl
->IsEditable() )
419 pasteTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServicePasteTypes
, typeCFMutableArrayRef
) ;
421 static const OSType textDataTypes
[] = { kTXNTextData
/* , 'utxt', 'PICT', 'MooV', 'AIFF' */ };
422 for ( size_t i
= 0 ; i
< WXSIZEOF(textDataTypes
) ; ++i
)
424 CFStringRef typestring
= CreateTypeStringWithOSType(textDataTypes
[i
]);
428 CFArrayAppendValue(copyTypes
, typestring
) ;
430 CFArrayAppendValue(pasteTypes
, typestring
) ;
432 CFRelease( typestring
) ;
440 case kEventServiceCopy
:
445 textCtrl
->GetSelection( &from
, &to
) ;
446 wxString val
= textCtrl
->GetValue() ;
447 val
= val
.Mid( from
, to
- from
) ;
448 PasteboardRef pasteboard
= cEvent
.GetParameter
<PasteboardRef
>( kEventParamPasteboardRef
, typePasteboardRef
);
449 verify_noerr( PasteboardClear( pasteboard
) ) ;
450 PasteboardSynchronize( pasteboard
);
451 // TODO add proper conversion
452 CFDataRef data
= CFDataCreate( kCFAllocatorDefault
, (const UInt8
*)val
.c_str(), val
.length() );
453 PasteboardPutItemFlavor( pasteboard
, (PasteboardItemID
) 1, CFSTR("com.apple.traditional-mac-plain-text"), data
, 0);
459 case kEventServicePaste
:
462 PasteboardRef pasteboard
= cEvent
.GetParameter
<PasteboardRef
>( kEventParamPasteboardRef
, typePasteboardRef
);
463 PasteboardSynchronize( pasteboard
);
465 verify_noerr( PasteboardGetItemCount( pasteboard
, &itemCount
) );
466 for( UInt32 itemIndex
= 1; itemIndex
<= itemCount
; itemIndex
++ )
468 PasteboardItemID itemID
;
469 if ( PasteboardGetItemIdentifier( pasteboard
, itemIndex
, &itemID
) == noErr
)
471 CFDataRef flavorData
= NULL
;
472 if ( PasteboardCopyItemFlavorData( pasteboard
, itemID
, CFSTR("com.apple.traditional-mac-plain-text"), &flavorData
) == noErr
)
474 CFIndex flavorDataSize
= CFDataGetLength( flavorData
);
475 char *content
= new char[flavorDataSize
+1] ;
476 memcpy( content
, CFDataGetBytePtr( flavorData
), flavorDataSize
);
477 content
[flavorDataSize
]=0;
478 CFRelease( flavorData
);
480 textCtrl
->WriteText( wxString( content
, wxConvLocal
) );
482 textCtrl
->WriteText( wxString( content
) ) ;
500 pascal OSStatus
wxMacUnicodeTextEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
502 OSStatus result
= eventNotHandledErr
;
503 wxWindowMac
* focus
= (wxWindowMac
*) data
;
505 wchar_t* uniChars
= NULL
;
506 UInt32 when
= EventTimeToTicks( GetEventTime( event
) ) ;
508 UniChar
* charBuf
= NULL
;
509 ByteCount dataSize
= 0 ;
512 if ( GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, 0 , &dataSize
, NULL
) == noErr
)
514 numChars
= dataSize
/ sizeof( UniChar
) + 1;
517 if ( (size_t) numChars
* 2 > sizeof(buf
) )
518 charBuf
= new UniChar
[ numChars
] ;
522 uniChars
= new wchar_t[ numChars
] ;
523 GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, dataSize
, NULL
, charBuf
) ;
524 charBuf
[ numChars
- 1 ] = 0;
525 #if SIZEOF_WCHAR_T == 2
526 uniChars
= (wchar_t*) charBuf
;
527 /* memcpy( uniChars , charBuf , numChars * 2 ) ;*/ // is there any point in copying charBuf over itself? (in fact, memcpy isn't even guaranteed to work correctly if the source and destination ranges overlap...)
529 // the resulting string will never have more chars than the utf16 version, so this is safe
530 wxMBConvUTF16 converter
;
531 numChars
= converter
.MB2WC( uniChars
, (const char*)charBuf
, numChars
) ;
535 switch ( GetEventKind( event
) )
537 case kEventTextInputUpdateActiveInputArea
:
539 // An IME input event may return several characters, but we need to send one char at a time to
541 for (int pos
=0 ; pos
< numChars
; pos
++)
543 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
544 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
545 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
547 UInt32 message
= uniChars
[pos
] < 128 ? (char)uniChars
[pos
] : '?';
549 NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
550 multiple times to update the active range during inline input, so this handler will often receive
551 uncommited text, which should usually not trigger side effects. It might be a good idea to check the
552 kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
553 On the other hand, it can be useful for some applications to react to uncommitted text (for example,
554 to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
555 should add new event types to support advanced text input. For now, I would keep things as they are.
557 However, the code that was being used caused additional problems:
558 UInt32 message = (0 << 8) + ((char)uniChars[pos] );
559 Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
560 input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
561 for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
562 (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
563 (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
564 Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
565 overlap with Unicode within the (7-bit) ASCII range.
566 But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
567 for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
568 characters as they are and replaces the rest with '?', ensuring that update events are triggered.
569 It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
570 I don't have time to look into that right now.
573 if ( wxTheApp
->MacSendCharEvent(
574 focus
, message
, 0 , when
, 0 , 0 , uniChars
[pos
] ) )
579 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
583 case kEventTextInputUnicodeForKeyEvent
:
585 UInt32 keyCode
, modifiers
;
588 unsigned char charCode
;
590 GetEventParameter( event
, kEventParamTextInputSendKeyboardEvent
, typeEventRef
, NULL
, sizeof(rawEvent
), NULL
, &rawEvent
) ;
591 GetEventParameter( rawEvent
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, sizeof(char), NULL
, &charCode
);
592 GetEventParameter( rawEvent
, kEventParamKeyCode
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
593 GetEventParameter( rawEvent
, kEventParamKeyModifiers
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &modifiers
);
594 GetEventParameter( rawEvent
, kEventParamMouseLocation
, typeQDPoint
, NULL
, sizeof(Point
), NULL
, &point
);
596 UInt32 message
= (keyCode
<< 8) + charCode
;
598 // An IME input event may return several characters, but we need to send one char at a time to
600 for (int pos
=0 ; pos
< numChars
; pos
++)
602 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
603 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
604 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
606 if ( wxTheApp
->MacSendCharEvent(
607 focus
, message
, modifiers
, when
, point
.h
, point
.v
, uniChars
[pos
] ) )
612 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
621 if ( charBuf
!= buf
)
627 static pascal OSStatus
628 wxMacWindowCommandEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
632 OSStatus result
= eventNotHandledErr
;
633 wxWindowMac
* focus
= (wxWindowMac
*) data
;
637 wxMacCarbonEvent
cEvent( event
) ;
638 cEvent
.GetParameter
<HICommand
>(kEventParamDirectObject
,typeHICommand
,&command
) ;
640 wxMenuItem
* item
= NULL
;
641 wxMenu
* itemMenu
= wxFindMenuFromMacCommand( command
, item
) ;
642 int id
= wxMacCommandToId( command
.commandID
) ;
646 wxASSERT( itemMenu
!= NULL
) ;
648 switch ( cEvent
.GetKind() )
650 case kEventProcessCommand
:
651 result
= itemMenu
->MacHandleCommandProcess( item
, id
, focus
);
654 case kEventCommandUpdateStatus
:
655 result
= itemMenu
->MacHandleCommandUpdateStatus( item
, id
, focus
);
665 pascal OSStatus
wxMacWindowEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
667 EventRef formerEvent
= (EventRef
) wxTheApp
->MacGetCurrentEvent() ;
668 EventHandlerCallRef formerEventHandlerCallRef
= (EventHandlerCallRef
) wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
669 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
670 OSStatus result
= eventNotHandledErr
;
672 switch ( GetEventClass( event
) )
674 case kEventClassCommand
:
675 result
= wxMacWindowCommandEventHandler( handler
, event
, data
) ;
678 case kEventClassControl
:
679 result
= wxMacWindowControlEventHandler( handler
, event
, data
) ;
682 case kEventClassService
:
683 result
= wxMacWindowServiceEventHandler( handler
, event
, data
) ;
686 case kEventClassTextInput
:
687 result
= wxMacUnicodeTextEventHandler( handler
, event
, data
) ;
694 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerEventHandlerCallRef
) ;
699 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler
)
701 #if !TARGET_API_MAC_OSX
703 // ---------------------------------------------------------------------------
704 // UserPane events for non OSX builds
705 // ---------------------------------------------------------------------------
707 static pascal void wxMacControlUserPaneDrawProc(ControlRef control
, SInt16 part
)
709 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
711 win
->MacControlUserPaneDrawProc(part
) ;
713 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneDrawUPP
, wxMacControlUserPaneDrawProc
) ;
715 static pascal ControlPartCode
wxMacControlUserPaneHitTestProc(ControlRef control
, Point where
)
717 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
719 return win
->MacControlUserPaneHitTestProc(where
.h
, where
.v
) ;
721 return kControlNoPart
;
723 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneHitTestUPP
, wxMacControlUserPaneHitTestProc
) ;
725 static pascal ControlPartCode
wxMacControlUserPaneTrackingProc(ControlRef control
, Point startPt
, ControlActionUPP actionProc
)
727 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
729 return win
->MacControlUserPaneTrackingProc( startPt
.h
, startPt
.v
, (void*) actionProc
) ;
731 return kControlNoPart
;
733 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneTrackingUPP
, wxMacControlUserPaneTrackingProc
) ;
735 static pascal void wxMacControlUserPaneIdleProc(ControlRef control
)
737 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
739 win
->MacControlUserPaneIdleProc() ;
741 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneIdleUPP
, wxMacControlUserPaneIdleProc
) ;
743 static pascal ControlPartCode
wxMacControlUserPaneKeyDownProc(ControlRef control
, SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
)
745 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
747 return win
->MacControlUserPaneKeyDownProc(keyCode
,charCode
,modifiers
) ;
749 return kControlNoPart
;
751 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneKeyDownUPP
, wxMacControlUserPaneKeyDownProc
) ;
753 static pascal void wxMacControlUserPaneActivateProc(ControlRef control
, Boolean activating
)
755 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
757 win
->MacControlUserPaneActivateProc(activating
) ;
759 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneActivateUPP
, wxMacControlUserPaneActivateProc
) ;
761 static pascal ControlPartCode
wxMacControlUserPaneFocusProc(ControlRef control
, ControlFocusPart action
)
763 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
765 return win
->MacControlUserPaneFocusProc(action
) ;
767 return kControlNoPart
;
769 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneFocusUPP
, wxMacControlUserPaneFocusProc
) ;
771 static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control
, ControlBackgroundPtr info
)
773 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
775 win
->MacControlUserPaneBackgroundProc(info
) ;
777 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneBackgroundUPP
, wxMacControlUserPaneBackgroundProc
) ;
779 void wxWindowMac::MacControlUserPaneDrawProc(wxInt16 part
)
782 RgnHandle rgn
= NewRgn() ;
784 MacWindowToRootWindow( &x
, &y
) ;
785 OffsetRgn( rgn
, -x
, -y
) ;
786 wxMacWindowStateSaver
sv( this ) ;
787 SectRgn( rgn
, (RgnHandle
) MacGetVisibleRegion().GetWXHRGN() , rgn
) ;
788 MacDoRedraw( rgn
, 0 ) ;
792 wxInt16
wxWindowMac::MacControlUserPaneHitTestProc(wxInt16 x
, wxInt16 y
)
794 return kControlNoPart
;
797 wxInt16
wxWindowMac::MacControlUserPaneTrackingProc(wxInt16 x
, wxInt16 y
, void* actionProc
)
799 return kControlNoPart
;
802 void wxWindowMac::MacControlUserPaneIdleProc()
806 wxInt16
wxWindowMac::MacControlUserPaneKeyDownProc(wxInt16 keyCode
, wxInt16 charCode
, wxInt16 modifiers
)
808 return kControlNoPart
;
811 void wxWindowMac::MacControlUserPaneActivateProc(bool activating
)
815 wxInt16
wxWindowMac::MacControlUserPaneFocusProc(wxInt16 action
)
817 if ( AcceptsFocus() )
820 return kControlNoPart
;
823 void wxWindowMac::MacControlUserPaneBackgroundProc(void* info
)
829 // ---------------------------------------------------------------------------
830 // Scrollbar Tracking for all
831 // ---------------------------------------------------------------------------
833 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
) ;
834 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
)
838 wxWindow
* wx
= wxFindControlFromMacControl( control
) ;
840 wx
->MacHandleControlClick( (WXWidget
) control
, partCode
, true /* stillDown */ ) ;
843 wxMAC_DEFINE_PROC_GETTER( ControlActionUPP
, wxMacLiveScrollbarActionProc
) ;
845 // ===========================================================================
847 // ===========================================================================
849 WX_DECLARE_HASH_MAP(ControlRef
, wxWindow
*, wxPointerHash
, wxPointerEqual
, MacControlMap
);
851 static MacControlMap wxWinMacControlList
;
853 wxWindow
*wxFindControlFromMacControl(ControlRef inControl
)
855 MacControlMap::iterator node
= wxWinMacControlList
.find(inControl
);
857 return (node
== wxWinMacControlList
.end()) ? NULL
: node
->second
;
860 void wxAssociateControlWithMacControl(ControlRef inControl
, wxWindow
*control
)
862 // adding NULL ControlRef is (first) surely a result of an error and
863 // (secondly) breaks native event processing
864 wxCHECK_RET( inControl
!= (ControlRef
) NULL
, wxT("attempt to add a NULL WindowRef to window list") );
866 wxWinMacControlList
[inControl
] = control
;
869 void wxRemoveMacControlAssociation(wxWindow
*control
)
871 // iterate over all the elements in the class
872 // is the iterator stable ? as we might have two associations pointing to the same wxWindow
873 // we should go on...
879 MacControlMap::iterator it
;
880 for ( it
= wxWinMacControlList
.begin(); it
!= wxWinMacControlList
.end(); ++it
)
882 if ( it
->second
== control
)
884 wxWinMacControlList
.erase(it
);
892 // ----------------------------------------------------------------------------
893 // constructors and such
894 // ----------------------------------------------------------------------------
896 wxWindowMac::wxWindowMac()
901 wxWindowMac::wxWindowMac(wxWindowMac
*parent
,
906 const wxString
& name
)
909 Create(parent
, id
, pos
, size
, style
, name
);
912 void wxWindowMac::Init()
917 m_cgContextRef
= NULL
;
919 // as all windows are created with WS_VISIBLE style...
922 m_hScrollBar
= NULL
;
923 m_vScrollBar
= NULL
;
924 m_hScrollBarAlwaysShown
= false;
925 m_vScrollBarAlwaysShown
= false;
927 m_macIsUserPane
= true;
928 m_clipChildren
= false ;
929 m_cachedClippedRectValid
= false ;
931 // we need a valid font for the encodings
932 wxWindowBase::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
935 wxWindowMac::~wxWindowMac()
939 m_isBeingDeleted
= true;
941 MacInvalidateBorders() ;
943 #ifndef __WXUNIVERSAL__
944 // VS: make sure there's no wxFrame with last focus set to us:
945 for ( wxWindow
*win
= GetParent(); win
; win
= win
->GetParent() )
947 wxFrame
*frame
= wxDynamicCast(win
, wxFrame
);
950 if ( frame
->GetLastFocus() == this )
951 frame
->SetLastFocus((wxWindow
*)NULL
);
957 // destroy children before destroying this window itself
960 // wxRemoveMacControlAssociation( this ) ;
961 // If we delete an item, we should initialize the parent panel,
962 // because it could now be invalid.
963 wxTopLevelWindow
*tlw
= wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow
);
966 if ( tlw
->GetDefaultItem() == (wxButton
*) this)
967 tlw
->SetDefaultItem(NULL
);
970 if ( m_peer
&& m_peer
->Ok() )
972 // in case the callback might be called during destruction
973 wxRemoveMacControlAssociation( this) ;
974 ::RemoveEventHandler( (EventHandlerRef
) m_macControlEventHandler
) ;
975 // we currently are not using this hook
976 // ::SetControlColorProc( *m_peer , NULL ) ;
980 if ( g_MacLastWindow
== this )
981 g_MacLastWindow
= NULL
;
983 #ifndef __WXUNIVERSAL__
984 wxFrame
* frame
= wxDynamicCast( wxGetTopLevelParent( (wxWindow
*)this ) , wxFrame
) ;
987 if ( frame
->GetLastFocus() == this )
988 frame
->SetLastFocus( NULL
) ;
992 // delete our drop target if we've got one
993 #if wxUSE_DRAG_AND_DROP
994 if ( m_dropTarget
!= NULL
)
1004 WXWidget
wxWindowMac::GetHandle() const
1006 return (WXWidget
) m_peer
->GetControlRef() ;
1009 void wxWindowMac::MacInstallEventHandler( WXWidget control
)
1011 wxAssociateControlWithMacControl( (ControlRef
) control
, this ) ;
1012 InstallControlEventHandler( (ControlRef
)control
, GetwxMacWindowEventHandlerUPP(),
1013 GetEventTypeCount(eventList
), eventList
, this,
1014 (EventHandlerRef
*)&m_macControlEventHandler
);
1016 #if !TARGET_API_MAC_OSX
1017 if ( (ControlRef
) control
== m_peer
->GetControlRef() )
1019 m_peer
->SetData
<ControlUserPaneDrawUPP
>(kControlEntireControl
, kControlUserPaneDrawProcTag
, GetwxMacControlUserPaneDrawProc()) ;
1020 m_peer
->SetData
<ControlUserPaneHitTestUPP
>(kControlEntireControl
, kControlUserPaneHitTestProcTag
, GetwxMacControlUserPaneHitTestProc()) ;
1021 m_peer
->SetData
<ControlUserPaneTrackingUPP
>(kControlEntireControl
, kControlUserPaneTrackingProcTag
, GetwxMacControlUserPaneTrackingProc()) ;
1022 m_peer
->SetData
<ControlUserPaneIdleUPP
>(kControlEntireControl
, kControlUserPaneIdleProcTag
, GetwxMacControlUserPaneIdleProc()) ;
1023 m_peer
->SetData
<ControlUserPaneKeyDownUPP
>(kControlEntireControl
, kControlUserPaneKeyDownProcTag
, GetwxMacControlUserPaneKeyDownProc()) ;
1024 m_peer
->SetData
<ControlUserPaneActivateUPP
>(kControlEntireControl
, kControlUserPaneActivateProcTag
, GetwxMacControlUserPaneActivateProc()) ;
1025 m_peer
->SetData
<ControlUserPaneFocusUPP
>(kControlEntireControl
, kControlUserPaneFocusProcTag
, GetwxMacControlUserPaneFocusProc()) ;
1026 m_peer
->SetData
<ControlUserPaneBackgroundUPP
>(kControlEntireControl
, kControlUserPaneBackgroundProcTag
, GetwxMacControlUserPaneBackgroundProc()) ;
1032 bool wxWindowMac::Create(wxWindowMac
*parent
,
1037 const wxString
& name
)
1039 wxCHECK_MSG( parent
, false, wxT("can't create wxWindowMac without parent") );
1041 if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) )
1044 m_windowVariant
= parent
->GetWindowVariant() ;
1046 if ( m_macIsUserPane
)
1048 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
) ;
1051 | kControlSupportsEmbedding
1052 | kControlSupportsLiveFeedback
1053 | kControlGetsFocusOnClick
1054 // | kControlHasSpecialBackground
1055 // | kControlSupportsCalcBestRect
1056 | kControlHandlesTracking
1057 | kControlSupportsFocus
1058 | kControlWantsActivate
1059 | kControlWantsIdle
;
1061 m_peer
= new wxMacControl(this) ;
1062 OSStatus err
=::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds
, features
, m_peer
->GetControlRefAddr() );
1063 verify_noerr( err
);
1065 MacPostControlCreate(pos
, size
) ;
1068 #ifndef __WXUNIVERSAL__
1069 // Don't give scrollbars to wxControls unless they ask for them
1070 if ( (! IsKindOf(CLASSINFO(wxControl
)) && ! IsKindOf(CLASSINFO(wxStatusBar
)))
1071 || (IsKindOf(CLASSINFO(wxControl
)) && ((style
& wxHSCROLL
) || (style
& wxVSCROLL
))))
1073 MacCreateScrollBars( style
) ;
1077 wxWindowCreateEvent
event(this);
1078 GetEventHandler()->AddPendingEvent(event
);
1083 void wxWindowMac::MacChildAdded()
1086 m_vScrollBar
->Raise() ;
1088 m_hScrollBar
->Raise() ;
1091 void wxWindowMac::MacPostControlCreate(const wxPoint
& WXUNUSED(pos
), const wxSize
& size
)
1093 wxASSERT_MSG( m_peer
!= NULL
&& m_peer
->Ok() , wxT("No valid mac control") ) ;
1095 m_peer
->SetReference( (URefCon
) this ) ;
1096 GetParent()->AddChild( this );
1098 MacInstallEventHandler( (WXWidget
) m_peer
->GetControlRef() );
1100 ControlRef container
= (ControlRef
) GetParent()->GetHandle() ;
1101 wxASSERT_MSG( container
!= NULL
, wxT("No valid mac container control") ) ;
1102 ::EmbedControl( m_peer
->GetControlRef() , container
) ;
1103 GetParent()->MacChildAdded() ;
1105 // adjust font, controlsize etc
1106 DoSetWindowVariant( m_windowVariant
) ;
1108 m_peer
->SetLabel( wxStripMenuCodes(m_label
, wxStrip_Mnemonics
) ) ;
1110 if (!m_macIsUserPane
)
1111 SetInitialSize(size
);
1113 SetCursor( *wxSTANDARD_CURSOR
) ;
1116 void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant
)
1118 // Don't assert, in case we set the window variant before
1119 // the window is created
1120 // wxASSERT( m_peer->Ok() ) ;
1122 m_windowVariant
= variant
;
1124 if (m_peer
== NULL
|| !m_peer
->Ok())
1128 ThemeFontID themeFont
= kThemeSystemFont
;
1130 // we will get that from the settings later
1131 // and make this NORMAL later, but first
1132 // we have a few calculations that we must fix
1136 case wxWINDOW_VARIANT_NORMAL
:
1137 size
= kControlSizeNormal
;
1138 themeFont
= kThemeSystemFont
;
1141 case wxWINDOW_VARIANT_SMALL
:
1142 size
= kControlSizeSmall
;
1143 themeFont
= kThemeSmallSystemFont
;
1146 case wxWINDOW_VARIANT_MINI
:
1147 // not always defined in the headers
1152 case wxWINDOW_VARIANT_LARGE
:
1153 size
= kControlSizeLarge
;
1154 themeFont
= kThemeSystemFont
;
1158 wxFAIL_MSG(_T("unexpected window variant"));
1162 m_peer
->SetData
<ControlSize
>(kControlEntireControl
, kControlSizeTag
, &size
) ;
1165 font
.MacCreateThemeFont( themeFont
) ;
1169 void wxWindowMac::MacUpdateControlFont()
1171 m_peer
->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ;
1172 // do not trigger refreshes upon invisible and possible partly created objects
1173 if ( MacIsReallyShown() )
1177 bool wxWindowMac::SetFont(const wxFont
& font
)
1179 bool retval
= wxWindowBase::SetFont( font
);
1181 MacUpdateControlFont() ;
1186 bool wxWindowMac::SetForegroundColour(const wxColour
& col
)
1188 bool retval
= wxWindowBase::SetForegroundColour( col
);
1191 MacUpdateControlFont();
1196 bool wxWindowMac::SetBackgroundColour(const wxColour
& col
)
1198 if ( !wxWindowBase::SetBackgroundColour(col
) && m_hasBgCol
)
1201 m_peer
->SetBackgroundColour( col
) ;
1206 bool wxWindowMac::MacCanFocus() const
1208 // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so
1209 // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning,
1210 // but the value range is nowhere documented
1211 Boolean keyExistsAndHasValidFormat
;
1212 CFIndex fullKeyboardAccess
= CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) ,
1213 kCFPreferencesCurrentApplication
, &keyExistsAndHasValidFormat
);
1215 if ( keyExistsAndHasValidFormat
&& fullKeyboardAccess
> 0 )
1221 UInt32 features
= 0 ;
1222 m_peer
->GetFeatures( &features
) ;
1224 return features
& ( kControlSupportsFocus
| kControlGetsFocusOnClick
) ;
1228 void wxWindowMac::SetFocus()
1230 if ( !AcceptsFocus() )
1233 wxWindow
* former
= FindFocus() ;
1234 if ( former
== this )
1237 // as we cannot rely on the control features to find out whether we are in full keyboard mode,
1238 // we can only leave in case of an error
1239 OSStatus err
= m_peer
->SetFocus( kControlFocusNextPart
) ;
1240 if ( err
== errCouldntSetFocus
)
1243 SetUserFocusWindow( (WindowRef
)MacGetTopLevelWindowRef() );
1245 #if !TARGET_API_MAC_OSX
1246 // emulate carbon events when running under CarbonLib where they are not natively available
1249 EventRef evRef
= NULL
;
1251 err
= MacCreateEvent(
1252 NULL
, kEventClassControl
, kEventControlSetFocusPart
, TicksToEventTime( TickCount() ) ,
1253 kEventAttributeUserEvent
, &evRef
);
1254 verify_noerr( err
);
1256 wxMacCarbonEvent
cEvent( evRef
) ;
1257 cEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, (ControlRef
) former
->GetHandle() ) ;
1258 cEvent
.SetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
, kControlFocusNoPart
) ;
1260 wxMacWindowEventHandler( NULL
, evRef
, former
) ;
1261 ReleaseEvent( evRef
) ;
1264 // send new focus event
1266 EventRef evRef
= NULL
;
1268 err
= MacCreateEvent(
1269 NULL
, kEventClassControl
, kEventControlSetFocusPart
, TicksToEventTime( TickCount() ) ,
1270 kEventAttributeUserEvent
, &evRef
);
1271 verify_noerr( err
);
1273 wxMacCarbonEvent
cEvent( evRef
) ;
1274 cEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, (ControlRef
) GetHandle() ) ;
1275 cEvent
.SetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
, kControlFocusNextPart
) ;
1277 wxMacWindowEventHandler( NULL
, evRef
, this ) ;
1278 ReleaseEvent( evRef
) ;
1283 void wxWindowMac::DoCaptureMouse()
1285 wxApp::s_captureWindow
= this ;
1288 wxWindow
* wxWindowBase::GetCapture()
1290 return wxApp::s_captureWindow
;
1293 void wxWindowMac::DoReleaseMouse()
1295 wxApp::s_captureWindow
= NULL
;
1298 #if wxUSE_DRAG_AND_DROP
1300 void wxWindowMac::SetDropTarget(wxDropTarget
*pDropTarget
)
1302 if ( m_dropTarget
!= NULL
)
1303 delete m_dropTarget
;
1305 m_dropTarget
= pDropTarget
;
1306 if ( m_dropTarget
!= NULL
)
1314 // Old-style File Manager Drag & Drop
1315 void wxWindowMac::DragAcceptFiles(bool WXUNUSED(accept
))
1320 // Returns the size of the native control. In the case of the toplevel window
1321 // this is the content area root control
1323 void wxWindowMac::MacGetPositionAndSizeFromControl(int& WXUNUSED(x
),
1326 int& WXUNUSED(h
)) const
1328 wxFAIL_MSG( wxT("Not currently supported") ) ;
1331 // From a wx position / size calculate the appropriate size of the native control
1333 bool wxWindowMac::MacGetBoundsForControl(
1337 int& w
, int& h
, bool adjustOrigin
) const
1339 // the desired size, minus the border pixels gives the correct size of the control
1343 // TODO: the default calls may be used as soon as PostCreateControl Is moved here
1344 w
= wxMax(size
.x
, 0) ; // WidthDefault( size.x );
1345 h
= wxMax(size
.y
, 0) ; // HeightDefault( size.y ) ;
1347 x
+= MacGetLeftBorderSize() ;
1348 y
+= MacGetTopBorderSize() ;
1349 w
-= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1350 h
-= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1353 AdjustForParentClientOrigin( x
, y
) ;
1355 // this is in window relative coordinate, as this parent may have a border, its physical position is offset by this border
1356 if ( !GetParent()->IsTopLevel() )
1358 x
-= GetParent()->MacGetLeftBorderSize() ;
1359 y
-= GetParent()->MacGetTopBorderSize() ;
1365 // Get window size (not client size)
1366 void wxWindowMac::DoGetSize(int *x
, int *y
) const
1369 m_peer
->GetRect( &bounds
) ;
1372 *x
= bounds
.right
- bounds
.left
+ MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1374 *y
= bounds
.bottom
- bounds
.top
+ MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1377 // get the position of the bounds of this window in client coordinates of its parent
1378 void wxWindowMac::DoGetPosition(int *x
, int *y
) const
1381 m_peer
->GetRect( &bounds
) ;
1383 int x1
= bounds
.left
;
1384 int y1
= bounds
.top
;
1386 // get the wx window position from the native one
1387 x1
-= MacGetLeftBorderSize() ;
1388 y1
-= MacGetTopBorderSize() ;
1390 if ( !IsTopLevel() )
1392 wxWindow
*parent
= GetParent();
1395 // we must first adjust it to be in window coordinates of the parent,
1396 // as otherwise it gets lost by the ClientAreaOrigin fix
1397 x1
+= parent
->MacGetLeftBorderSize() ;
1398 y1
+= parent
->MacGetTopBorderSize() ;
1400 // and now to client coordinates
1401 wxPoint
pt(parent
->GetClientAreaOrigin());
1413 void wxWindowMac::DoScreenToClient(int *x
, int *y
) const
1415 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
1416 wxCHECK_RET( window
, wxT("TopLevel Window missing") ) ;
1418 Point localwhere
= { 0, 0 } ;
1425 wxMacGlobalToLocal( window
, &localwhere
) ;
1432 MacRootWindowToWindow( x
, y
) ;
1434 wxPoint origin
= GetClientAreaOrigin() ;
1441 void wxWindowMac::DoClientToScreen(int *x
, int *y
) const
1443 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
1444 wxCHECK_RET( window
, wxT("TopLevel window missing") ) ;
1446 wxPoint origin
= GetClientAreaOrigin() ;
1452 MacWindowToRootWindow( x
, y
) ;
1454 Point localwhere
= { 0, 0 };
1460 wxMacLocalToGlobal( window
, &localwhere
) ;
1468 void wxWindowMac::MacClientToRootWindow( int *x
, int *y
) const
1470 wxPoint origin
= GetClientAreaOrigin() ;
1476 MacWindowToRootWindow( x
, y
) ;
1479 void wxWindowMac::MacRootWindowToClient( int *x
, int *y
) const
1481 MacRootWindowToWindow( x
, y
) ;
1483 wxPoint origin
= GetClientAreaOrigin() ;
1490 void wxWindowMac::MacWindowToRootWindow( int *x
, int *y
) const
1499 if ( !IsTopLevel() )
1501 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
1504 pt
.x
-= MacGetLeftBorderSize() ;
1505 pt
.y
-= MacGetTopBorderSize() ;
1506 wxMacControl::Convert( &pt
, m_peer
, top
->m_peer
) ;
1516 void wxWindowMac::MacWindowToRootWindow( short *x
, short *y
) const
1525 MacWindowToRootWindow( &x1
, &y1
) ;
1533 void wxWindowMac::MacRootWindowToWindow( int *x
, int *y
) const
1542 if ( !IsTopLevel() )
1544 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
1547 wxMacControl::Convert( &pt
, top
->m_peer
, m_peer
) ;
1548 pt
.x
+= MacGetLeftBorderSize() ;
1549 pt
.y
+= MacGetTopBorderSize() ;
1559 void wxWindowMac::MacRootWindowToWindow( short *x
, short *y
) const
1568 MacRootWindowToWindow( &x1
, &y1
) ;
1576 void wxWindowMac::MacGetContentAreaInset( int &left
, int &top
, int &right
, int &bottom
)
1578 RgnHandle rgn
= NewRgn() ;
1580 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1582 Rect structure
, content
;
1584 GetRegionBounds( rgn
, &content
) ;
1585 m_peer
->GetRect( &structure
) ;
1586 OffsetRect( &structure
, -structure
.left
, -structure
.top
) ;
1588 left
= content
.left
- structure
.left
;
1589 top
= content
.top
- structure
.top
;
1590 right
= structure
.right
- content
.right
;
1591 bottom
= structure
.bottom
- content
.bottom
;
1595 left
= top
= right
= bottom
= 0 ;
1601 wxSize
wxWindowMac::DoGetSizeFromClientSize( const wxSize
& size
) const
1603 wxSize sizeTotal
= size
;
1605 RgnHandle rgn
= NewRgn() ;
1606 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1608 Rect content
, structure
;
1609 GetRegionBounds( rgn
, &content
) ;
1610 m_peer
->GetRect( &structure
) ;
1612 // structure is in parent coordinates, but we only need width and height, so it's ok
1614 sizeTotal
.x
+= (structure
.right
- structure
.left
) - (content
.right
- content
.left
) ;
1615 sizeTotal
.y
+= (structure
.bottom
- structure
.top
) - (content
.bottom
- content
.top
) ;
1620 sizeTotal
.x
+= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1621 sizeTotal
.y
+= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1626 // Get size *available for subwindows* i.e. excluding menu bar etc.
1627 void wxWindowMac::DoGetClientSize( int *x
, int *y
) const
1631 RgnHandle rgn
= NewRgn() ;
1633 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1634 GetRegionBounds( rgn
, &content
) ;
1636 m_peer
->GetRect( &content
) ;
1639 ww
= content
.right
- content
.left
;
1640 hh
= content
.bottom
- content
.top
;
1642 if (m_hScrollBar
&& m_hScrollBar
->IsShown() )
1643 hh
-= m_hScrollBar
->GetSize().y
;
1645 if (m_vScrollBar
&& m_vScrollBar
->IsShown() )
1646 ww
-= m_vScrollBar
->GetSize().x
;
1654 bool wxWindowMac::SetCursor(const wxCursor
& cursor
)
1656 if (m_cursor
.IsSameAs(cursor
))
1661 if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR
) )
1666 if ( ! wxWindowBase::SetCursor( cursor
) )
1670 wxASSERT_MSG( m_cursor
.Ok(),
1671 wxT("cursor must be valid after call to the base version"));
1673 wxWindowMac
*mouseWin
= 0 ;
1675 wxTopLevelWindowMac
*tlw
= MacGetTopLevelWindow() ;
1676 WindowRef window
= (WindowRef
) ( tlw
? tlw
->MacGetWindowRef() : 0 ) ;
1678 ControlPartCode part
;
1679 ControlRef control
;
1681 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
1683 HIGetMousePosition(kHICoordSpaceWindow
, window
, &hiPoint
);
1688 Boolean swapped
= QDSwapPort( GetWindowPort( window
) , &savePort
) ;
1690 // TODO: If we ever get a GetCurrentEvent... replacement
1691 // for the mouse position, use it...
1696 control
= FindControlUnderMouse( pt
, window
, &part
) ;
1698 mouseWin
= wxFindControlFromMacControl( control
) ;
1700 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
1702 QDSwapPort( savePort
, NULL
) ;
1706 if ( mouseWin
== this && !wxIsBusy() )
1707 m_cursor
.MacInstall() ;
1713 bool wxWindowMac::DoPopupMenu(wxMenu
*menu
, int x
, int y
)
1715 #ifndef __WXUNIVERSAL__
1716 menu
->SetInvokingWindow((wxWindow
*)this);
1719 if ( x
== wxDefaultCoord
&& y
== wxDefaultCoord
)
1721 wxPoint mouse
= wxGetMousePosition();
1727 ClientToScreen( &x
, &y
) ;
1730 menu
->MacBeforeDisplay( true ) ;
1731 long menuResult
= ::PopUpMenuSelect((MenuHandle
) menu
->GetHMenu() , y
, x
, 0) ;
1732 if ( HiWord(menuResult
) != 0 )
1735 GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult
)) , LoWord(menuResult
) , &macid
);
1736 int id
= wxMacCommandToId( macid
);
1737 wxMenuItem
* item
= NULL
;
1739 item
= menu
->FindItem( id
, &realmenu
) ;
1742 if (item
->IsCheckable())
1743 item
->Check( !item
->IsChecked() ) ;
1745 menu
->SendEvent( id
, item
->IsCheckable() ? item
->IsChecked() : -1 ) ;
1749 menu
->MacAfterDisplay( true ) ;
1750 menu
->SetInvokingWindow( NULL
);
1754 // actually this shouldn't be called, because universal is having its own implementation
1760 // ----------------------------------------------------------------------------
1762 // ----------------------------------------------------------------------------
1766 void wxWindowMac::DoSetToolTip(wxToolTip
*tooltip
)
1768 wxWindowBase::DoSetToolTip(tooltip
);
1771 m_tooltip
->SetWindow(this);
1776 void wxWindowMac::MacInvalidateBorders()
1778 if ( m_peer
== NULL
)
1781 bool vis
= MacIsReallyShown() ;
1785 int outerBorder
= MacGetLeftBorderSize() ;
1786 if ( m_peer
->NeedsFocusRect() && m_peer
->HasFocus() )
1789 if ( outerBorder
== 0 )
1792 // now we know that we have something to do at all
1794 // as the borders are drawn on the parent we have to properly invalidate all these areas
1795 RgnHandle updateInner
, updateOuter
;
1798 // this rectangle is in HIViewCoordinates under OSX and in Window Coordinates under Carbon
1799 updateInner
= NewRgn() ;
1800 updateOuter
= NewRgn() ;
1802 m_peer
->GetRect( &rect
) ;
1803 RectRgn( updateInner
, &rect
) ;
1804 InsetRect( &rect
, -outerBorder
, -outerBorder
) ;
1805 RectRgn( updateOuter
, &rect
) ;
1806 DiffRgn( updateOuter
, updateInner
, updateOuter
) ;
1808 GetParent()->m_peer
->SetNeedsDisplay( updateOuter
) ;
1810 DisposeRgn( updateOuter
) ;
1811 DisposeRgn( updateInner
) ;
1814 void wxWindowMac::DoMoveWindow(int x
, int y
, int width
, int height
)
1816 // this is never called for a toplevel window, so we know we have a parent
1817 int former_x
, former_y
, former_w
, former_h
;
1819 // Get true coordinates of former position
1820 DoGetPosition( &former_x
, &former_y
) ;
1821 DoGetSize( &former_w
, &former_h
) ;
1823 wxWindow
*parent
= GetParent();
1826 wxPoint
pt(parent
->GetClientAreaOrigin());
1831 int actualWidth
= width
;
1832 int actualHeight
= height
;
1836 if ((m_minWidth
!= -1) && (actualWidth
< m_minWidth
))
1837 actualWidth
= m_minWidth
;
1838 if ((m_minHeight
!= -1) && (actualHeight
< m_minHeight
))
1839 actualHeight
= m_minHeight
;
1840 if ((m_maxWidth
!= -1) && (actualWidth
> m_maxWidth
))
1841 actualWidth
= m_maxWidth
;
1842 if ((m_maxHeight
!= -1) && (actualHeight
> m_maxHeight
))
1843 actualHeight
= m_maxHeight
;
1845 bool doMove
= false, doResize
= false ;
1847 if ( actualX
!= former_x
|| actualY
!= former_y
)
1850 if ( actualWidth
!= former_w
|| actualHeight
!= former_h
)
1853 if ( doMove
|| doResize
)
1855 // as the borders are drawn outside the native control, we adjust now
1857 wxRect
bounds( wxPoint( actualX
+ MacGetLeftBorderSize() ,actualY
+ MacGetTopBorderSize() ),
1858 wxSize( actualWidth
- (MacGetLeftBorderSize() + MacGetRightBorderSize()) ,
1859 actualHeight
- (MacGetTopBorderSize() + MacGetBottomBorderSize()) ) ) ;
1862 wxMacRectToNative( &bounds
, &r
) ;
1864 if ( !GetParent()->IsTopLevel() )
1865 wxMacWindowToNative( GetParent() , &r
) ;
1867 MacInvalidateBorders() ;
1869 m_cachedClippedRectValid
= false ;
1870 m_peer
->SetRect( &r
) ;
1872 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
1874 MacInvalidateBorders() ;
1876 MacRepositionScrollBars() ;
1879 wxPoint
point(actualX
, actualY
);
1880 wxMoveEvent
event(point
, m_windowId
);
1881 event
.SetEventObject(this);
1882 GetEventHandler()->ProcessEvent(event
) ;
1887 MacRepositionScrollBars() ;
1888 wxSize
size(actualWidth
, actualHeight
);
1889 wxSizeEvent
event(size
, m_windowId
);
1890 event
.SetEventObject(this);
1891 GetEventHandler()->ProcessEvent(event
);
1896 wxSize
wxWindowMac::DoGetBestSize() const
1898 if ( m_macIsUserPane
|| IsTopLevel() )
1899 return wxWindowBase::DoGetBestSize() ;
1901 Rect bestsize
= { 0 , 0 , 0 , 0 } ;
1902 int bestWidth
, bestHeight
;
1904 m_peer
->GetBestRect( &bestsize
) ;
1905 if ( EmptyRect( &bestsize
) )
1910 bestsize
.bottom
= 16 ;
1912 if ( IsKindOf( CLASSINFO( wxScrollBar
) ) )
1914 bestsize
.bottom
= 16 ;
1917 else if ( IsKindOf( CLASSINFO( wxSpinButton
) ) )
1919 bestsize
.bottom
= 24 ;
1924 // return wxWindowBase::DoGetBestSize() ;
1928 bestWidth
= bestsize
.right
- bestsize
.left
;
1929 bestHeight
= bestsize
.bottom
- bestsize
.top
;
1930 if ( bestHeight
< 10 )
1933 return wxSize(bestWidth
, bestHeight
);
1936 // set the size of the window: if the dimensions are positive, just use them,
1937 // but if any of them is equal to -1, it means that we must find the value for
1938 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
1939 // which case -1 is a valid value for x and y)
1941 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
1942 // the width/height to best suit our contents, otherwise we reuse the current
1944 void wxWindowMac::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
1946 // get the current size and position...
1947 int currentX
, currentY
;
1948 int currentW
, currentH
;
1950 GetPosition(¤tX
, ¤tY
);
1951 GetSize(¤tW
, ¤tH
);
1953 // ... and don't do anything (avoiding flicker) if it's already ok
1954 if ( x
== currentX
&& y
== currentY
&&
1955 width
== currentW
&& height
== currentH
&& ( height
!= -1 && width
!= -1 ) )
1958 MacRepositionScrollBars() ; // we might have a real position shift
1963 if ( !(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) )
1965 if ( x
== wxDefaultCoord
)
1967 if ( y
== wxDefaultCoord
)
1971 AdjustForParentClientOrigin( x
, y
, sizeFlags
);
1973 wxSize size
= wxDefaultSize
;
1974 if ( width
== wxDefaultCoord
)
1976 if ( sizeFlags
& wxSIZE_AUTO_WIDTH
)
1978 size
= DoGetBestSize();
1983 // just take the current one
1988 if ( height
== wxDefaultCoord
)
1990 if ( sizeFlags
& wxSIZE_AUTO_HEIGHT
)
1992 if ( size
.x
== wxDefaultCoord
)
1993 size
= DoGetBestSize();
1994 // else: already called DoGetBestSize() above
2000 // just take the current one
2005 DoMoveWindow( x
, y
, width
, height
);
2008 wxPoint
wxWindowMac::GetClientAreaOrigin() const
2010 RgnHandle rgn
= NewRgn() ;
2012 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
2014 GetRegionBounds( rgn
, &content
) ;
2024 return wxPoint( content
.left
+ MacGetLeftBorderSize() , content
.top
+ MacGetTopBorderSize() );
2027 void wxWindowMac::DoSetClientSize(int clientwidth
, int clientheight
)
2029 if ( clientwidth
!= wxDefaultCoord
|| clientheight
!= wxDefaultCoord
)
2031 int currentclientwidth
, currentclientheight
;
2032 int currentwidth
, currentheight
;
2034 GetClientSize( ¤tclientwidth
, ¤tclientheight
) ;
2035 GetSize( ¤twidth
, ¤theight
) ;
2037 DoSetSize( wxDefaultCoord
, wxDefaultCoord
, currentwidth
+ clientwidth
- currentclientwidth
,
2038 currentheight
+ clientheight
- currentclientheight
, wxSIZE_USE_EXISTING
) ;
2042 void wxWindowMac::SetLabel(const wxString
& title
)
2046 if ( m_peer
&& m_peer
->Ok() )
2047 m_peer
->SetLabel( wxStripMenuCodes(m_label
, wxStrip_Mnemonics
) ) ;
2049 // do not trigger refreshes upon invisible and possible partly created objects
2050 if ( MacIsReallyShown() )
2054 wxString
wxWindowMac::GetLabel() const
2059 bool wxWindowMac::Show(bool show
)
2061 bool former
= MacIsReallyShown() ;
2062 if ( !wxWindowBase::Show(show
) )
2065 // TODO: use visibilityChanged Carbon Event for OSX
2067 m_peer
->SetVisibility( show
, true ) ;
2069 if ( former
!= MacIsReallyShown() )
2070 MacPropagateVisibilityChanged() ;
2075 void wxWindowMac::DoEnable(bool enable
)
2077 m_peer
->Enable( enable
) ;
2081 // status change propagations (will be not necessary for OSX later )
2084 void wxWindowMac::MacPropagateVisibilityChanged()
2086 #if !TARGET_API_MAC_OSX
2087 MacVisibilityChanged() ;
2090 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
2093 child
= node
->GetData();
2094 if ( child
->IsShown() )
2095 child
->MacPropagateVisibilityChanged() ;
2097 node
= node
->GetNext();
2102 void wxWindowMac::OnEnabled(bool WXUNUSED(enabled
))
2104 #if !TARGET_API_MAC_OSX
2105 MacEnabledStateChanged() ;
2109 void wxWindowMac::MacPropagateHiliteChanged()
2111 #if !TARGET_API_MAC_OSX
2112 MacHiliteChanged() ;
2115 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
2118 child
= node
->GetData();
2119 if (child
/* && child->IsEnabled() */)
2120 child
->MacPropagateHiliteChanged() ;
2122 node
= node
->GetNext();
2128 // status change notifications
2131 void wxWindowMac::MacVisibilityChanged()
2135 void wxWindowMac::MacHiliteChanged()
2139 void wxWindowMac::MacEnabledStateChanged()
2144 // status queries on the inherited window's state
2147 bool wxWindowMac::MacIsReallyShown()
2149 // only under OSX the visibility of the TLW is taken into account
2150 if ( m_isBeingDeleted
)
2153 #if TARGET_API_MAC_OSX
2154 if ( m_peer
&& m_peer
->Ok() )
2155 return m_peer
->IsVisible();
2158 wxWindow
* win
= this ;
2159 while ( win
->IsShown() )
2161 if ( win
->IsTopLevel() )
2164 win
= win
->GetParent() ;
2172 bool wxWindowMac::MacIsReallyEnabled()
2174 return m_peer
->IsEnabled() ;
2177 bool wxWindowMac::MacIsReallyHilited()
2179 return m_peer
->IsActive();
2182 void wxWindowMac::MacFlashInvalidAreas()
2184 #if TARGET_API_MAC_OSX
2185 HIViewFlashDirtyArea( (WindowRef
) MacGetTopLevelWindowRef() ) ;
2189 int wxWindowMac::GetCharHeight() const
2191 wxClientDC
dc( (wxWindowMac
*)this ) ;
2193 return dc
.GetCharHeight() ;
2196 int wxWindowMac::GetCharWidth() const
2198 wxClientDC
dc( (wxWindowMac
*)this ) ;
2200 return dc
.GetCharWidth() ;
2203 void wxWindowMac::GetTextExtent(const wxString
& string
, int *x
, int *y
,
2204 int *descent
, int *externalLeading
, const wxFont
*theFont
) const
2206 const wxFont
*fontToUse
= theFont
;
2208 fontToUse
= &m_font
;
2210 wxClientDC
dc( (wxWindowMac
*) this ) ;
2211 wxCoord lx
,ly
,ld
,le
;
2212 dc
.GetTextExtent( string
, &lx
, &ly
, &ld
, &le
, (wxFont
*)fontToUse
) ;
2213 if ( externalLeading
)
2214 *externalLeading
= le
;
2224 * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect
2225 * we always intersect with the entire window, not only with the client area
2228 void wxWindowMac::Refresh(bool WXUNUSED(eraseBack
), const wxRect
*rect
)
2230 if ( m_peer
== NULL
)
2233 if ( !MacIsReallyShown() )
2240 wxMacRectToNative( rect
, &r
) ;
2241 m_peer
->SetNeedsDisplay( &r
) ;
2245 m_peer
->SetNeedsDisplay() ;
2249 void wxWindowMac::Freeze()
2251 #if TARGET_API_MAC_OSX
2252 if ( !m_frozenness
++ )
2254 if ( m_peer
&& m_peer
->Ok() )
2255 m_peer
->SetDrawingEnabled( false ) ;
2260 void wxWindowMac::Thaw()
2262 #if TARGET_API_MAC_OSX
2263 wxASSERT_MSG( m_frozenness
> 0, wxT("Thaw() without matching Freeze()") );
2265 if ( !--m_frozenness
)
2267 if ( m_peer
&& m_peer
->Ok() )
2269 m_peer
->SetDrawingEnabled( true ) ;
2270 m_peer
->InvalidateWithChildren() ;
2276 bool wxWindowMac::IsFrozen() const
2278 return m_frozenness
!= 0;
2281 wxWindowMac
*wxGetActiveWindow()
2283 // actually this is a windows-only concept
2287 // Coordinates relative to the window
2288 void wxWindowMac::WarpPointer(int WXUNUSED(x_pos
), int WXUNUSED(y_pos
))
2290 // We really don't move the mouse programmatically under Mac.
2293 void wxWindowMac::OnEraseBackground(wxEraseEvent
& event
)
2295 if ( MacGetTopLevelWindow() == NULL
)
2298 #if TARGET_API_MAC_OSX
2299 if ( !m_backgroundColour
.Ok() || GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT
)
2306 event
.GetDC()->Clear() ;
2310 void wxWindowMac::OnNcPaint( wxNcPaintEvent
& event
)
2315 int wxWindowMac::GetScrollPos(int orient
) const
2317 if ( orient
== wxHORIZONTAL
)
2320 return m_hScrollBar
->GetThumbPosition() ;
2325 return m_vScrollBar
->GetThumbPosition() ;
2331 // This now returns the whole range, not just the number
2332 // of positions that we can scroll.
2333 int wxWindowMac::GetScrollRange(int orient
) const
2335 if ( orient
== wxHORIZONTAL
)
2338 return m_hScrollBar
->GetRange() ;
2343 return m_vScrollBar
->GetRange() ;
2349 int wxWindowMac::GetScrollThumb(int orient
) const
2351 if ( orient
== wxHORIZONTAL
)
2354 return m_hScrollBar
->GetThumbSize() ;
2359 return m_vScrollBar
->GetThumbSize() ;
2365 void wxWindowMac::SetScrollPos(int orient
, int pos
, bool WXUNUSED(refresh
))
2367 if ( orient
== wxHORIZONTAL
)
2370 m_hScrollBar
->SetThumbPosition( pos
) ;
2375 m_vScrollBar
->SetThumbPosition( pos
) ;
2380 wxWindowMac::AlwaysShowScrollbars(bool hflag
, bool vflag
)
2382 bool needVisibilityUpdate
= false;
2384 if ( m_hScrollBarAlwaysShown
!= hflag
)
2386 m_hScrollBarAlwaysShown
= hflag
;
2387 needVisibilityUpdate
= true;
2390 if ( m_vScrollBarAlwaysShown
!= vflag
)
2392 m_vScrollBarAlwaysShown
= vflag
;
2393 needVisibilityUpdate
= true;
2396 if ( needVisibilityUpdate
)
2397 DoUpdateScrollbarVisibility();
2401 // we draw borders and grow boxes, are already set up and clipped in the current port / cgContextRef
2402 // our own window origin is at leftOrigin/rightOrigin
2405 void wxWindowMac::MacPaintGrowBox()
2410 if ( MacHasScrollBarCorner() )
2414 CGContextRef cgContext
= (CGContextRef
) MacGetCGContextRef() ;
2415 wxASSERT( cgContext
) ;
2417 m_peer
->GetRect( &rect
) ;
2419 int size
= m_hScrollBar
? m_hScrollBar
->GetSize().y
: ( m_vScrollBar
? m_vScrollBar
->GetSize().x
: MAC_SCROLLBAR_SIZE
) ;
2420 CGRect cgrect
= CGRectMake( rect
.right
- size
, rect
.bottom
- size
, size
, size
) ;
2421 CGPoint cgpoint
= CGPointMake( rect
.right
- size
, rect
.bottom
- size
) ;
2422 CGContextSaveGState( cgContext
);
2424 if ( m_backgroundColour
.Ok() )
2426 CGContextSetFillColorWithColor( cgContext
, m_backgroundColour
.GetCGColor() );
2430 CGContextSetRGBFillColor( cgContext
, 1.0, 1.0 , 1.0 , 1.0 );
2432 CGContextFillRect( cgContext
, cgrect
);
2433 CGContextRestoreGState( cgContext
);
2437 void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin
) , int WXUNUSED(rightOrigin
) )
2443 bool hasFocus
= m_peer
->NeedsFocusRect() && m_peer
->HasFocus() ;
2445 // back to the surrounding frame rectangle
2446 m_peer
->GetRect( &rect
) ;
2447 InsetRect( &rect
, -1 , -1 ) ;
2450 CGRect cgrect
= CGRectMake( rect
.left
, rect
.top
, rect
.right
- rect
.left
,
2451 rect
.bottom
- rect
.top
) ;
2453 HIThemeFrameDrawInfo info
;
2454 memset( &info
, 0 , sizeof(info
) ) ;
2458 info
.state
= IsEnabled() ? kThemeStateActive
: kThemeStateInactive
;
2459 info
.isFocused
= hasFocus
;
2461 CGContextRef cgContext
= (CGContextRef
) GetParent()->MacGetCGContextRef() ;
2462 wxASSERT( cgContext
) ;
2464 if ( HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
) )
2466 info
.kind
= kHIThemeFrameTextFieldSquare
;
2467 HIThemeDrawFrame( &cgrect
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2469 else if ( HasFlag(wxSIMPLE_BORDER
) )
2471 info
.kind
= kHIThemeFrameListBox
;
2472 HIThemeDrawFrame( &cgrect
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2474 else if ( hasFocus
)
2476 HIThemeDrawFocusRect( &cgrect
, true , cgContext
, kHIThemeOrientationNormal
) ;
2478 #if 0 // TODO REMOVE now done in a separate call earlier in drawing the window itself
2479 m_peer
->GetRect( &rect
) ;
2480 if ( MacHasScrollBarCorner() )
2482 int variant
= (m_hScrollBar
== NULL
? m_vScrollBar
: m_hScrollBar
) ->GetWindowVariant();
2483 int size
= m_hScrollBar
? m_hScrollBar
->GetSize().y
: ( m_vScrollBar
? m_vScrollBar
->GetSize().x
: MAC_SCROLLBAR_SIZE
) ;
2484 CGRect cgrect
= CGRectMake( rect
.right
- size
, rect
.bottom
- size
, size
, size
) ;
2485 CGPoint cgpoint
= CGPointMake( rect
.right
- size
, rect
.bottom
- size
) ;
2486 HIThemeGrowBoxDrawInfo info
;
2487 memset( &info
, 0, sizeof(info
) ) ;
2489 info
.state
= IsEnabled() ? kThemeStateActive
: kThemeStateInactive
;
2490 info
.kind
= kHIThemeGrowBoxKindNone
;
2491 // contrary to the docs ...SizeSmall does not work
2492 info
.size
= kHIThemeGrowBoxSizeNormal
;
2493 info
.direction
= 0 ;
2494 HIThemeDrawGrowBox( &cgpoint
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2500 void wxWindowMac::RemoveChild( wxWindowBase
*child
)
2502 if ( child
== m_hScrollBar
)
2503 m_hScrollBar
= NULL
;
2504 if ( child
== m_vScrollBar
)
2505 m_vScrollBar
= NULL
;
2507 wxWindowBase::RemoveChild( child
) ;
2510 void wxWindowMac::DoUpdateScrollbarVisibility()
2512 bool triggerSizeEvent
= false;
2516 bool showHScrollBar
= m_hScrollBarAlwaysShown
|| m_hScrollBar
->IsNeeded();
2518 if ( m_hScrollBar
->IsShown() != showHScrollBar
)
2520 m_hScrollBar
->Show( showHScrollBar
);
2521 triggerSizeEvent
= true;
2527 bool showVScrollBar
= m_vScrollBarAlwaysShown
|| m_vScrollBar
->IsNeeded();
2529 if ( m_vScrollBar
->IsShown() != showVScrollBar
)
2531 m_vScrollBar
->Show( showVScrollBar
) ;
2532 triggerSizeEvent
= true;
2536 MacRepositionScrollBars() ;
2537 if ( triggerSizeEvent
)
2539 wxSizeEvent
event(GetSize(), m_windowId
);
2540 event
.SetEventObject(this);
2541 GetEventHandler()->ProcessEvent(event
);
2545 // New function that will replace some of the above.
2546 void wxWindowMac::SetScrollbar(int orient
, int pos
, int thumb
,
2547 int range
, bool refresh
)
2549 if ( orient
== wxHORIZONTAL
&& m_hScrollBar
)
2550 m_hScrollBar
->SetScrollbar(pos
, thumb
, range
, thumb
, refresh
);
2551 else if ( orient
== wxVERTICAL
&& m_vScrollBar
)
2552 m_vScrollBar
->SetScrollbar(pos
, thumb
, range
, thumb
, refresh
);
2554 DoUpdateScrollbarVisibility();
2557 // Does a physical scroll
2558 void wxWindowMac::ScrollWindow(int dx
, int dy
, const wxRect
*rect
)
2560 if ( dx
== 0 && dy
== 0 )
2563 int width
, height
;
2564 GetClientSize( &width
, &height
) ;
2567 // note there currently is a bug in OSX which makes inefficient refreshes in case an entire control
2568 // area is scrolled, this does not occur if width and height are 2 pixels less,
2569 // TODO: write optimal workaround
2570 wxRect
scrollrect( MacGetLeftBorderSize() , MacGetTopBorderSize() , width
, height
) ;
2572 scrollrect
.Intersect( *rect
) ;
2574 if ( m_peer
->GetNeedsDisplay() )
2576 // because HIViewScrollRect does not scroll the already invalidated area we have two options:
2577 // in case there is already a pending redraw on that area
2578 // either immediate redraw or full invalidate
2580 // is the better overall solution, as it does not slow down scrolling
2581 m_peer
->SetNeedsDisplay() ;
2583 // this would be the preferred version for fast drawing controls
2584 HIViewRender(m_peer
->GetControlRef()) ;
2588 // as the native control might be not a 0/0 wx window coordinates, we have to offset
2589 scrollrect
.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ;
2590 m_peer
->ScrollRect( &scrollrect
, dx
, dy
) ;
2593 // this would be the preferred version for fast drawing controls
2594 HIViewRender(m_peer
->GetControlRef()) ;
2600 for (wxWindowList::compatibility_iterator node
= GetChildren().GetFirst(); node
; node
= node
->GetNext())
2602 child
= node
->GetData();
2605 if (child
== m_vScrollBar
)
2607 if (child
== m_hScrollBar
)
2609 if (child
->IsTopLevel())
2612 child
->GetPosition( &x
, &y
);
2613 child
->GetSize( &w
, &h
);
2616 wxRect
rc( x
, y
, w
, h
);
2617 if (rect
->Intersects( rc
))
2618 child
->SetSize( x
+ dx
, y
+ dy
, w
, h
, wxSIZE_AUTO
|wxSIZE_ALLOW_MINUS_ONE
);
2622 child
->SetSize( x
+ dx
, y
+ dy
, w
, h
, wxSIZE_AUTO
|wxSIZE_ALLOW_MINUS_ONE
);
2627 void wxWindowMac::MacOnScroll( wxScrollEvent
&event
)
2629 if ( event
.GetEventObject() == m_vScrollBar
|| event
.GetEventObject() == m_hScrollBar
)
2631 wxScrollWinEvent wevent
;
2632 wevent
.SetPosition(event
.GetPosition());
2633 wevent
.SetOrientation(event
.GetOrientation());
2634 wevent
.SetEventObject(this);
2636 if (event
.GetEventType() == wxEVT_SCROLL_TOP
)
2637 wevent
.SetEventType( wxEVT_SCROLLWIN_TOP
);
2638 else if (event
.GetEventType() == wxEVT_SCROLL_BOTTOM
)
2639 wevent
.SetEventType( wxEVT_SCROLLWIN_BOTTOM
);
2640 else if (event
.GetEventType() == wxEVT_SCROLL_LINEUP
)
2641 wevent
.SetEventType( wxEVT_SCROLLWIN_LINEUP
);
2642 else if (event
.GetEventType() == wxEVT_SCROLL_LINEDOWN
)
2643 wevent
.SetEventType( wxEVT_SCROLLWIN_LINEDOWN
);
2644 else if (event
.GetEventType() == wxEVT_SCROLL_PAGEUP
)
2645 wevent
.SetEventType( wxEVT_SCROLLWIN_PAGEUP
);
2646 else if (event
.GetEventType() == wxEVT_SCROLL_PAGEDOWN
)
2647 wevent
.SetEventType( wxEVT_SCROLLWIN_PAGEDOWN
);
2648 else if (event
.GetEventType() == wxEVT_SCROLL_THUMBTRACK
)
2649 wevent
.SetEventType( wxEVT_SCROLLWIN_THUMBTRACK
);
2650 else if (event
.GetEventType() == wxEVT_SCROLL_THUMBRELEASE
)
2651 wevent
.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE
);
2653 GetEventHandler()->ProcessEvent(wevent
);
2657 // Get the window with the focus
2658 wxWindowMac
*wxWindowBase::DoFindFocus()
2660 ControlRef control
;
2661 GetKeyboardFocus( GetUserFocusWindow() , &control
) ;
2662 return wxFindControlFromMacControl( control
) ;
2665 void wxWindowMac::OnSetFocus( wxFocusEvent
& event
)
2667 // panel wants to track the window which was the last to have focus in it,
2668 // so we want to set ourselves as the window which last had focus
2670 // notice that it's also important to do it upwards the tree because
2671 // otherwise when the top level panel gets focus, it won't set it back to
2672 // us, but to some other sibling
2674 // CS: don't know if this is still needed:
2675 //wxChildFocusEvent eventFocus(this);
2676 //(void)GetEventHandler()->ProcessEvent(eventFocus);
2678 if ( MacGetTopLevelWindow() && m_peer
->NeedsFocusRect() )
2680 GetParent()->Refresh() ;
2681 wxMacWindowStateSaver
sv( this ) ;
2684 m_peer
->GetRect( &rect
) ;
2685 // auf den umgebenden Rahmen zurチᅡ゚ck
2686 InsetRect( &rect
, -1 , -1 ) ;
2688 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2692 wxMacControl::Convert( &pt
, GetParent()->m_peer
, top
->m_peer
) ;
2694 rect
.right
+= pt
.x
;
2696 rect
.bottom
+= pt
.y
;
2699 bool bIsFocusEvent
= (event
.GetEventType() == wxEVT_SET_FOCUS
);
2700 DrawThemeFocusRect( &rect
, bIsFocusEvent
) ;
2701 if ( !bIsFocusEvent
)
2703 // as this erases part of the frame we have to redraw borders
2704 // and because our z-ordering is not always correct (staticboxes)
2705 // we have to invalidate things, we cannot simple redraw
2706 MacInvalidateBorders() ;
2713 void wxWindowMac::OnInternalIdle()
2715 // This calls the UI-update mechanism (querying windows for
2716 // menu/toolbar/control state information)
2717 if (wxUpdateUIEvent::CanUpdate(this) && IsShown())
2718 UpdateWindowUI(wxUPDATE_UI_FROMIDLE
);
2721 // Raise the window to the top of the Z order
2722 void wxWindowMac::Raise()
2724 m_peer
->SetZOrder( true , NULL
) ;
2727 // Lower the window to the bottom of the Z order
2728 void wxWindowMac::Lower()
2730 m_peer
->SetZOrder( false , NULL
) ;
2733 // static wxWindow *gs_lastWhich = NULL;
2735 bool wxWindowMac::MacSetupCursor( const wxPoint
& pt
)
2737 // first trigger a set cursor event
2739 wxPoint clientorigin
= GetClientAreaOrigin() ;
2740 wxSize clientsize
= GetClientSize() ;
2742 if ( wxRect2DInt( clientorigin
.x
, clientorigin
.y
, clientsize
.x
, clientsize
.y
).Contains( wxPoint2DInt( pt
) ) )
2744 wxSetCursorEvent
event( pt
.x
, pt
.y
);
2746 bool processedEvtSetCursor
= GetEventHandler()->ProcessEvent(event
);
2747 if ( processedEvtSetCursor
&& event
.HasCursor() )
2749 cursor
= event
.GetCursor() ;
2753 // the test for processedEvtSetCursor is here to prevent using m_cursor
2754 // if the user code caught EVT_SET_CURSOR() and returned nothing from
2755 // it - this is a way to say that our cursor shouldn't be used for this
2757 if ( !processedEvtSetCursor
&& m_cursor
.Ok() )
2760 if ( !wxIsBusy() && !GetParent() )
2761 cursor
= *wxSTANDARD_CURSOR
;
2765 cursor
.MacInstall() ;
2768 return cursor
.Ok() ;
2771 wxString
wxWindowMac::MacGetToolTipString( wxPoint
&WXUNUSED(pt
) )
2775 return m_tooltip
->GetTip() ;
2778 return wxEmptyString
;
2781 void wxWindowMac::ClearBackground()
2787 void wxWindowMac::Update()
2789 #if TARGET_API_MAC_OSX
2790 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2792 top
->MacPerformUpdates() ;
2794 ::Draw1Control( m_peer
->GetControlRef() ) ;
2798 wxTopLevelWindowMac
* wxWindowMac::MacGetTopLevelWindow() const
2800 wxTopLevelWindowMac
* win
= NULL
;
2801 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
2803 win
= wxFindWinFromMacWindow( window
) ;
2808 const wxRect
& wxWindowMac::MacGetClippedClientRect() const
2810 MacUpdateClippedRects() ;
2812 return m_cachedClippedClientRect
;
2815 const wxRect
& wxWindowMac::MacGetClippedRect() const
2817 MacUpdateClippedRects() ;
2819 return m_cachedClippedRect
;
2822 const wxRect
&wxWindowMac:: MacGetClippedRectWithOuterStructure() const
2824 MacUpdateClippedRects() ;
2826 return m_cachedClippedRectWithOuterStructure
;
2829 const wxRegion
& wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures
)
2831 static wxRegion emptyrgn
;
2833 if ( !m_isBeingDeleted
&& MacIsReallyShown() /*m_peer->IsVisible() */ )
2835 MacUpdateClippedRects() ;
2836 if ( includeOuterStructures
)
2837 return m_cachedClippedRegionWithOuterStructure
;
2839 return m_cachedClippedRegion
;
2847 void wxWindowMac::MacUpdateClippedRects() const
2849 if ( m_cachedClippedRectValid
)
2852 // includeOuterStructures is true if we try to draw somthing like a focus ring etc.
2853 // also a window dc uses this, in this case we only clip in the hierarchy for hard
2854 // borders like a scrollwindow, splitter etc otherwise we end up in a paranoia having
2855 // to add focus borders everywhere
2857 Rect r
, rIncludingOuterStructures
;
2859 m_peer
->GetRect( &r
) ;
2860 r
.left
-= MacGetLeftBorderSize() ;
2861 r
.top
-= MacGetTopBorderSize() ;
2862 r
.bottom
+= MacGetBottomBorderSize() ;
2863 r
.right
+= MacGetRightBorderSize() ;
2870 rIncludingOuterStructures
= r
;
2871 InsetRect( &rIncludingOuterStructures
, -4 , -4 ) ;
2873 wxRect cl
= GetClientRect() ;
2874 Rect rClient
= { cl
.y
, cl
.x
, cl
.y
+ cl
.height
, cl
.x
+ cl
.width
} ;
2878 const wxWindow
* child
= this ;
2879 const wxWindow
* parent
= NULL
;
2881 while ( !child
->IsTopLevel() && ( parent
= child
->GetParent() ) != NULL
)
2883 if ( parent
->MacIsChildOfClientArea(child
) )
2885 size
= parent
->GetClientSize() ;
2886 wxPoint origin
= parent
->GetClientAreaOrigin() ;
2892 // this will be true for scrollbars, toolbars etc.
2893 size
= parent
->GetSize() ;
2894 y
= parent
->MacGetTopBorderSize() ;
2895 x
= parent
->MacGetLeftBorderSize() ;
2896 size
.x
-= parent
->MacGetLeftBorderSize() + parent
->MacGetRightBorderSize() ;
2897 size
.y
-= parent
->MacGetTopBorderSize() + parent
->MacGetBottomBorderSize() ;
2900 parent
->MacWindowToRootWindow( &x
, &y
) ;
2901 MacRootWindowToWindow( &x
, &y
) ;
2903 Rect rparent
= { y
, x
, y
+ size
.y
, x
+ size
.x
} ;
2905 // the wxwindow and client rects will always be clipped
2906 SectRect( &r
, &rparent
, &r
) ;
2907 SectRect( &rClient
, &rparent
, &rClient
) ;
2909 // the structure only at 'hard' borders
2910 if ( parent
->MacClipChildren() ||
2911 ( parent
->GetParent() && parent
->GetParent()->MacClipGrandChildren() ) )
2913 SectRect( &rIncludingOuterStructures
, &rparent
, &rIncludingOuterStructures
) ;
2919 m_cachedClippedRect
= wxRect( r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
- r
.top
) ;
2920 m_cachedClippedClientRect
= wxRect( rClient
.left
, rClient
.top
,
2921 rClient
.right
- rClient
.left
, rClient
.bottom
- rClient
.top
) ;
2922 m_cachedClippedRectWithOuterStructure
= wxRect(
2923 rIncludingOuterStructures
.left
, rIncludingOuterStructures
.top
,
2924 rIncludingOuterStructures
.right
- rIncludingOuterStructures
.left
,
2925 rIncludingOuterStructures
.bottom
- rIncludingOuterStructures
.top
) ;
2927 m_cachedClippedRegionWithOuterStructure
= wxRegion( m_cachedClippedRectWithOuterStructure
) ;
2928 m_cachedClippedRegion
= wxRegion( m_cachedClippedRect
) ;
2929 m_cachedClippedClientRegion
= wxRegion( m_cachedClippedClientRect
) ;
2931 m_cachedClippedRectValid
= true ;
2935 This function must not change the updatergn !
2937 bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr
, long time
)
2939 bool handled
= false ;
2941 RgnHandle updatergn
= (RgnHandle
) updatergnr
;
2942 GetRegionBounds( updatergn
, &updatebounds
) ;
2944 // wxLogDebug(wxT("update for %s bounds %d, %d, %d, %d"), wxString(GetClassInfo()->GetClassName()).c_str(), updatebounds.left, updatebounds.top , updatebounds.right , updatebounds.bottom ) ;
2946 if ( !EmptyRgn(updatergn
) )
2948 RgnHandle newupdate
= NewRgn() ;
2949 wxSize point
= GetClientSize() ;
2950 wxPoint origin
= GetClientAreaOrigin() ;
2951 SetRectRgn( newupdate
, origin
.x
, origin
.y
, origin
.x
+ point
.x
, origin
.y
+ point
.y
) ;
2952 SectRgn( newupdate
, updatergn
, newupdate
) ;
2954 // first send an erase event to the entire update area
2956 // for the toplevel window this really is the entire area
2957 // for all the others only their client area, otherwise they
2958 // might be drawing with full alpha and eg put blue into
2959 // the grow-box area of a scrolled window (scroll sample)
2960 wxDC
* dc
= new wxWindowDC(this);
2962 dc
->SetClippingRegion(wxRegion(updatergn
));
2964 dc
->SetClippingRegion(wxRegion(newupdate
));
2966 wxEraseEvent
eevent( GetId(), dc
);
2967 eevent
.SetEventObject( this );
2968 GetEventHandler()->ProcessEvent( eevent
);
2974 // calculate a client-origin version of the update rgn and set m_updateRegion to that
2975 OffsetRgn( newupdate
, -origin
.x
, -origin
.y
) ;
2976 m_updateRegion
= newupdate
;
2977 DisposeRgn( newupdate
) ;
2979 if ( !m_updateRegion
.Empty() )
2981 // paint the window itself
2984 event
.SetTimestamp(time
);
2985 event
.SetEventObject(this);
2986 GetEventHandler()->ProcessEvent(event
);
2990 // now we cannot rely on having its borders drawn by a window itself, as it does not
2991 // get the updateRgn wide enough to always do so, so we do it from the parent
2992 // this would also be the place to draw any custom backgrounds for native controls
2993 // in Composited windowing
2994 wxPoint clientOrigin
= GetClientAreaOrigin() ;
2998 for (wxWindowList::compatibility_iterator node
= GetChildren().GetFirst(); node
; node
= node
->GetNext())
3000 child
= node
->GetData();
3003 if (child
== m_vScrollBar
)
3005 if (child
== m_hScrollBar
)
3007 if (child
->IsTopLevel())
3009 if (!child
->IsShown())
3012 // only draw those in the update region (add a safety margin of 10 pixels for shadow effects
3014 child
->GetPosition( &x
, &y
);
3015 child
->GetSize( &w
, &h
);
3016 Rect childRect
= { y
, x
, y
+ h
, x
+ w
} ;
3017 OffsetRect( &childRect
, clientOrigin
.x
, clientOrigin
.y
) ;
3018 InsetRect( &childRect
, -10 , -10) ;
3020 if ( RectInRgn( &childRect
, updatergn
) )
3022 // paint custom borders
3023 wxNcPaintEvent
eventNc( child
->GetId() );
3024 eventNc
.SetEventObject( child
);
3025 if ( !child
->GetEventHandler()->ProcessEvent( eventNc
) )
3027 child
->MacPaintBorders(0, 0) ;
3037 WXWindow
wxWindowMac::MacGetTopLevelWindowRef() const
3039 wxWindowMac
*iter
= (wxWindowMac
*)this ;
3043 if ( iter
->IsTopLevel() )
3045 wxTopLevelWindow
* toplevel
= wxDynamicCast(iter
,wxTopLevelWindow
);
3047 return toplevel
->MacGetWindowRef();
3049 wxPopupWindow
* popupwin
= wxDynamicCast(iter
,wxPopupWindow
);
3051 return popupwin
->MacGetPopupWindowRef();
3054 iter
= iter
->GetParent() ;
3060 bool wxWindowMac::MacHasScrollBarCorner() const
3062 /* Returns whether the scroll bars in a wxScrolledWindow should be
3063 * shortened. Scroll bars should be shortened if either:
3065 * - both scroll bars are visible, or
3067 * - there is a resize box in the parent frame's corner and this
3068 * window shares the bottom and right edge with the parent
3072 if ( m_hScrollBar
== NULL
&& m_vScrollBar
== NULL
)
3075 if ( ( m_hScrollBar
&& m_hScrollBar
->IsShown() )
3076 && ( m_vScrollBar
&& m_vScrollBar
->IsShown() ) )
3078 // Both scroll bars visible
3083 wxPoint thisWindowBottomRight
= GetScreenRect().GetBottomRight();
3085 for ( const wxWindow
*win
= this; win
; win
= win
->GetParent() )
3087 const wxFrame
*frame
= wxDynamicCast( win
, wxFrame
) ;
3090 if ( frame
->GetWindowStyleFlag() & wxRESIZE_BORDER
)
3092 // Parent frame has resize handle
3093 wxPoint frameBottomRight
= frame
->GetScreenRect().GetBottomRight();
3095 // Note: allow for some wiggle room here as wxMac's
3096 // window rect calculations seem to be imprecise
3097 if ( abs( thisWindowBottomRight
.x
- frameBottomRight
.x
) <= 2
3098 && abs( thisWindowBottomRight
.y
- frameBottomRight
.y
) <= 2 )
3100 // Parent frame has resize handle and shares
3101 // right bottom corner
3106 // Parent frame has resize handle but doesn't
3107 // share right bottom corner
3113 // Parent frame doesn't have resize handle
3119 // No parent frame found
3124 void wxWindowMac::MacCreateScrollBars( long style
)
3126 wxASSERT_MSG( m_vScrollBar
== NULL
&& m_hScrollBar
== NULL
, wxT("attempt to create window twice") ) ;
3128 if ( style
& ( wxVSCROLL
| wxHSCROLL
) )
3130 int scrlsize
= MAC_SCROLLBAR_SIZE
;
3131 if ( GetWindowVariant() == wxWINDOW_VARIANT_SMALL
|| GetWindowVariant() == wxWINDOW_VARIANT_MINI
)
3133 scrlsize
= MAC_SMALL_SCROLLBAR_SIZE
;
3136 int adjust
= MacHasScrollBarCorner() ? scrlsize
- 1: 0 ;
3138 GetClientSize( &width
, &height
) ;
3140 wxPoint
vPoint(width
- scrlsize
, 0) ;
3141 wxSize
vSize(scrlsize
, height
- adjust
) ;
3142 wxPoint
hPoint(0, height
- scrlsize
) ;
3143 wxSize
hSize(width
- adjust
, scrlsize
) ;
3145 // we have to set the min size to a smaller value, otherwise they cannot get smaller (InitialSize sets MinSize)
3146 if ( style
& wxVSCROLL
)
3148 m_vScrollBar
= new wxScrollBar((wxWindow
*)this, wxID_ANY
, vPoint
, vSize
, wxVERTICAL
);
3149 m_vScrollBar
->SetMinSize( wxDefaultSize
);
3152 if ( style
& wxHSCROLL
)
3154 m_hScrollBar
= new wxScrollBar((wxWindow
*)this, wxID_ANY
, hPoint
, hSize
, wxHORIZONTAL
);
3155 m_hScrollBar
->SetMinSize( wxDefaultSize
);
3159 // because the create does not take into account the client area origin
3160 // we might have a real position shift
3161 MacRepositionScrollBars() ;
3164 bool wxWindowMac::MacIsChildOfClientArea( const wxWindow
* child
) const
3166 bool result
= ((child
== NULL
) || ((child
!= m_hScrollBar
) && (child
!= m_vScrollBar
)));
3171 void wxWindowMac::MacRepositionScrollBars()
3173 if ( !m_hScrollBar
&& !m_vScrollBar
)
3176 int scrlsize
= m_hScrollBar
? m_hScrollBar
->GetSize().y
: ( m_vScrollBar
? m_vScrollBar
->GetSize().x
: MAC_SCROLLBAR_SIZE
) ;
3177 int adjust
= MacHasScrollBarCorner() ? scrlsize
- 1 : 0 ;
3179 // get real client area
3181 GetSize( &width
, &height
);
3183 width
-= MacGetLeftBorderSize() + MacGetRightBorderSize();
3184 height
-= MacGetTopBorderSize() + MacGetBottomBorderSize();
3186 wxPoint
vPoint( width
- scrlsize
, 0 ) ;
3187 wxSize
vSize( scrlsize
, height
- adjust
) ;
3188 wxPoint
hPoint( 0 , height
- scrlsize
) ;
3189 wxSize
hSize( width
- adjust
, scrlsize
) ;
3192 int x
= 0, y
= 0, w
, h
;
3193 GetSize( &w
, &h
) ;
3195 MacClientToRootWindow( &x
, &y
) ;
3196 MacClientToRootWindow( &w
, &h
) ;
3198 wxWindowMac
*iter
= (wxWindowMac
*)this ;
3200 int totW
= 10000 , totH
= 10000;
3203 if ( iter
->IsTopLevel() )
3205 iter
->GetSize( &totW
, &totH
) ;
3209 iter
= iter
->GetParent() ;
3223 if ( w
- x
>= totW
)
3228 if ( h
- y
>= totH
)
3236 m_vScrollBar
->SetSize( vPoint
.x
, vPoint
.y
, vSize
.x
, vSize
.y
, wxSIZE_ALLOW_MINUS_ONE
);
3238 m_hScrollBar
->SetSize( hPoint
.x
, hPoint
.y
, hSize
.x
, hSize
.y
, wxSIZE_ALLOW_MINUS_ONE
);
3241 bool wxWindowMac::AcceptsFocus() const
3243 return MacCanFocus() && wxWindowBase::AcceptsFocus();
3246 void wxWindowMac::MacSuperChangedPosition()
3248 // only window-absolute structures have to be moved i.e. controls
3250 m_cachedClippedRectValid
= false ;
3253 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
3256 child
= node
->GetData();
3257 child
->MacSuperChangedPosition() ;
3259 node
= node
->GetNext();
3263 void wxWindowMac::MacTopLevelWindowChangedPosition()
3265 // only screen-absolute structures have to be moved i.e. glcanvas
3268 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
3271 child
= node
->GetData();
3272 child
->MacTopLevelWindowChangedPosition() ;
3274 node
= node
->GetNext();
3278 long wxWindowMac::MacGetLeftBorderSize() const
3285 if (HasFlag(wxRAISED_BORDER
) || HasFlag( wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
))
3287 // this metric is only the 'outset' outside the simple frame rect
3288 GetThemeMetric( kThemeMetricEditTextFrameOutset
, &border
) ;
3291 else if (HasFlag(wxSIMPLE_BORDER
))
3293 // this metric is only the 'outset' outside the simple frame rect
3294 GetThemeMetric( kThemeMetricListBoxFrameOutset
, &border
) ;
3301 long wxWindowMac::MacGetRightBorderSize() const
3303 // they are all symmetric in mac themes
3304 return MacGetLeftBorderSize() ;
3307 long wxWindowMac::MacGetTopBorderSize() const
3309 // they are all symmetric in mac themes
3310 return MacGetLeftBorderSize() ;
3313 long wxWindowMac::MacGetBottomBorderSize() const
3315 // they are all symmetric in mac themes
3316 return MacGetLeftBorderSize() ;
3319 long wxWindowMac::MacRemoveBordersFromStyle( long style
)
3321 return style
& ~wxBORDER_MASK
;
3324 // Find the wxWindowMac at the current mouse position, returning the mouse
3326 wxWindowMac
* wxFindWindowAtPointer( wxPoint
& pt
)
3328 pt
= wxGetMousePosition();
3329 wxWindowMac
* found
= wxFindWindowAtPoint(pt
);
3334 // Get the current mouse position.
3335 wxPoint
wxGetMousePosition()
3339 wxGetMousePosition( &x
, &y
);
3341 return wxPoint(x
, y
);
3344 void wxWindowMac::OnMouseEvent( wxMouseEvent
&event
)
3346 if ( event
.GetEventType() == wxEVT_RIGHT_DOWN
)
3348 // copied from wxGTK : CS
3349 // VZ: shouldn't we move this to base class then?
3351 // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN
3354 // (a) it's a command event and so is propagated to the parent
3355 // (b) under MSW it can be generated from kbd too
3356 // (c) it uses screen coords (because of (a))
3357 wxContextMenuEvent
evtCtx(wxEVT_CONTEXT_MENU
,
3359 this->ClientToScreen(event
.GetPosition()));
3360 if ( ! GetEventHandler()->ProcessEvent(evtCtx
) )
3369 void wxWindowMac::OnPaint( wxPaintEvent
& WXUNUSED(event
) )
3371 if ( wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
3372 && GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT
)
3373 CallNextEventHandler(
3374 (EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() ,
3375 (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
3378 void wxWindowMac::MacHandleControlClick(WXWidget
WXUNUSED(control
),
3379 wxInt16
WXUNUSED(controlpart
),
3380 bool WXUNUSED(mouseStillDown
))
3384 Rect
wxMacGetBoundsForControl( wxWindow
* window
, const wxPoint
& pos
, const wxSize
&size
, bool adjustForOrigin
)
3388 window
->MacGetBoundsForControl( pos
, size
, x
, y
, w
, h
, adjustForOrigin
) ;
3389 Rect bounds
= { y
, x
, y
+ h
, x
+ w
};
3394 wxInt32
wxWindowMac::MacControlHit(WXEVENTHANDLERREF
WXUNUSED(handler
) , WXEVENTREF
WXUNUSED(event
) )
3396 return eventNotHandledErr
;
3399 bool wxWindowMac::Reparent(wxWindowBase
*newParentBase
)
3401 wxWindowMac
*newParent
= (wxWindowMac
*)newParentBase
;
3402 if ( !wxWindowBase::Reparent(newParent
) )
3405 // copied from MacPostControlCreate
3406 ControlRef container
= (ControlRef
) GetParent()->GetHandle() ;
3408 wxASSERT_MSG( container
!= NULL
, wxT("No valid mac container control") ) ;
3410 ::EmbedControl( m_peer
->GetControlRef() , container
) ;
3415 bool wxWindowMac::SetTransparent(wxByte alpha
)
3417 SetBackgroundStyle(wxBG_STYLE_TRANSPARENT
);
3419 if ( alpha
!= m_macAlpha
)
3421 m_macAlpha
= alpha
;
3428 bool wxWindowMac::CanSetTransparent()
3433 wxByte
wxWindowMac::GetTransparent() const