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_macBackgroundBrush
= wxNullBrush
;
929 m_macIsUserPane
= true;
930 m_clipChildren
= false ;
931 m_cachedClippedRectValid
= false ;
933 // we need a valid font for the encodings
934 wxWindowBase::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
937 wxWindowMac::~wxWindowMac()
941 m_isBeingDeleted
= true;
943 MacInvalidateBorders() ;
945 #ifndef __WXUNIVERSAL__
946 // VS: make sure there's no wxFrame with last focus set to us:
947 for ( wxWindow
*win
= GetParent(); win
; win
= win
->GetParent() )
949 wxFrame
*frame
= wxDynamicCast(win
, wxFrame
);
952 if ( frame
->GetLastFocus() == this )
953 frame
->SetLastFocus((wxWindow
*)NULL
);
959 // destroy children before destroying this window itself
962 // wxRemoveMacControlAssociation( this ) ;
963 // If we delete an item, we should initialize the parent panel,
964 // because it could now be invalid.
965 wxTopLevelWindow
*tlw
= wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow
);
968 if ( tlw
->GetDefaultItem() == (wxButton
*) this)
969 tlw
->SetDefaultItem(NULL
);
972 if ( m_peer
&& m_peer
->Ok() )
974 // in case the callback might be called during destruction
975 wxRemoveMacControlAssociation( this) ;
976 ::RemoveEventHandler( (EventHandlerRef
) m_macControlEventHandler
) ;
977 // we currently are not using this hook
978 // ::SetControlColorProc( *m_peer , NULL ) ;
982 if ( g_MacLastWindow
== this )
983 g_MacLastWindow
= NULL
;
985 #ifndef __WXUNIVERSAL__
986 wxFrame
* frame
= wxDynamicCast( wxGetTopLevelParent( (wxWindow
*)this ) , wxFrame
) ;
989 if ( frame
->GetLastFocus() == this )
990 frame
->SetLastFocus( NULL
) ;
994 // delete our drop target if we've got one
995 #if wxUSE_DRAG_AND_DROP
996 if ( m_dropTarget
!= NULL
)
1006 WXWidget
wxWindowMac::GetHandle() const
1008 return (WXWidget
) m_peer
->GetControlRef() ;
1011 void wxWindowMac::MacInstallEventHandler( WXWidget control
)
1013 wxAssociateControlWithMacControl( (ControlRef
) control
, this ) ;
1014 InstallControlEventHandler( (ControlRef
)control
, GetwxMacWindowEventHandlerUPP(),
1015 GetEventTypeCount(eventList
), eventList
, this,
1016 (EventHandlerRef
*)&m_macControlEventHandler
);
1018 #if !TARGET_API_MAC_OSX
1019 if ( (ControlRef
) control
== m_peer
->GetControlRef() )
1021 m_peer
->SetData
<ControlUserPaneDrawUPP
>(kControlEntireControl
, kControlUserPaneDrawProcTag
, GetwxMacControlUserPaneDrawProc()) ;
1022 m_peer
->SetData
<ControlUserPaneHitTestUPP
>(kControlEntireControl
, kControlUserPaneHitTestProcTag
, GetwxMacControlUserPaneHitTestProc()) ;
1023 m_peer
->SetData
<ControlUserPaneTrackingUPP
>(kControlEntireControl
, kControlUserPaneTrackingProcTag
, GetwxMacControlUserPaneTrackingProc()) ;
1024 m_peer
->SetData
<ControlUserPaneIdleUPP
>(kControlEntireControl
, kControlUserPaneIdleProcTag
, GetwxMacControlUserPaneIdleProc()) ;
1025 m_peer
->SetData
<ControlUserPaneKeyDownUPP
>(kControlEntireControl
, kControlUserPaneKeyDownProcTag
, GetwxMacControlUserPaneKeyDownProc()) ;
1026 m_peer
->SetData
<ControlUserPaneActivateUPP
>(kControlEntireControl
, kControlUserPaneActivateProcTag
, GetwxMacControlUserPaneActivateProc()) ;
1027 m_peer
->SetData
<ControlUserPaneFocusUPP
>(kControlEntireControl
, kControlUserPaneFocusProcTag
, GetwxMacControlUserPaneFocusProc()) ;
1028 m_peer
->SetData
<ControlUserPaneBackgroundUPP
>(kControlEntireControl
, kControlUserPaneBackgroundProcTag
, GetwxMacControlUserPaneBackgroundProc()) ;
1034 bool wxWindowMac::Create(wxWindowMac
*parent
,
1039 const wxString
& name
)
1041 wxCHECK_MSG( parent
, false, wxT("can't create wxWindowMac without parent") );
1043 if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) )
1046 m_windowVariant
= parent
->GetWindowVariant() ;
1048 if ( m_macIsUserPane
)
1050 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
) ;
1053 | kControlSupportsEmbedding
1054 | kControlSupportsLiveFeedback
1055 | kControlGetsFocusOnClick
1056 // | kControlHasSpecialBackground
1057 // | kControlSupportsCalcBestRect
1058 | kControlHandlesTracking
1059 | kControlSupportsFocus
1060 | kControlWantsActivate
1061 | kControlWantsIdle
;
1063 m_peer
= new wxMacControl(this) ;
1064 OSStatus err
=::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds
, features
, m_peer
->GetControlRefAddr() );
1065 verify_noerr( err
);
1067 MacPostControlCreate(pos
, size
) ;
1070 #ifndef __WXUNIVERSAL__
1071 // Don't give scrollbars to wxControls unless they ask for them
1072 if ( (! IsKindOf(CLASSINFO(wxControl
)) && ! IsKindOf(CLASSINFO(wxStatusBar
)))
1073 || (IsKindOf(CLASSINFO(wxControl
)) && ((style
& wxHSCROLL
) || (style
& wxVSCROLL
))))
1075 MacCreateScrollBars( style
) ;
1079 wxWindowCreateEvent
event(this);
1080 GetEventHandler()->AddPendingEvent(event
);
1085 void wxWindowMac::MacChildAdded()
1088 m_vScrollBar
->Raise() ;
1090 m_hScrollBar
->Raise() ;
1093 void wxWindowMac::MacPostControlCreate(const wxPoint
& WXUNUSED(pos
), const wxSize
& size
)
1095 wxASSERT_MSG( m_peer
!= NULL
&& m_peer
->Ok() , wxT("No valid mac control") ) ;
1097 m_peer
->SetReference( (URefCon
) this ) ;
1098 GetParent()->AddChild( this );
1100 MacInstallEventHandler( (WXWidget
) m_peer
->GetControlRef() );
1102 ControlRef container
= (ControlRef
) GetParent()->GetHandle() ;
1103 wxASSERT_MSG( container
!= NULL
, wxT("No valid mac container control") ) ;
1104 ::EmbedControl( m_peer
->GetControlRef() , container
) ;
1105 GetParent()->MacChildAdded() ;
1107 // adjust font, controlsize etc
1108 DoSetWindowVariant( m_windowVariant
) ;
1110 m_peer
->SetLabel( wxStripMenuCodes(m_label
, wxStrip_Mnemonics
) ) ;
1112 if (!m_macIsUserPane
)
1113 SetInitialSize(size
);
1115 SetCursor( *wxSTANDARD_CURSOR
) ;
1118 void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant
)
1120 // Don't assert, in case we set the window variant before
1121 // the window is created
1122 // wxASSERT( m_peer->Ok() ) ;
1124 m_windowVariant
= variant
;
1126 if (m_peer
== NULL
|| !m_peer
->Ok())
1130 ThemeFontID themeFont
= kThemeSystemFont
;
1132 // we will get that from the settings later
1133 // and make this NORMAL later, but first
1134 // we have a few calculations that we must fix
1138 case wxWINDOW_VARIANT_NORMAL
:
1139 size
= kControlSizeNormal
;
1140 themeFont
= kThemeSystemFont
;
1143 case wxWINDOW_VARIANT_SMALL
:
1144 size
= kControlSizeSmall
;
1145 themeFont
= kThemeSmallSystemFont
;
1148 case wxWINDOW_VARIANT_MINI
:
1149 // not always defined in the headers
1154 case wxWINDOW_VARIANT_LARGE
:
1155 size
= kControlSizeLarge
;
1156 themeFont
= kThemeSystemFont
;
1160 wxFAIL_MSG(_T("unexpected window variant"));
1164 m_peer
->SetData
<ControlSize
>(kControlEntireControl
, kControlSizeTag
, &size
) ;
1167 font
.MacCreateThemeFont( themeFont
) ;
1171 void wxWindowMac::MacUpdateControlFont()
1173 m_peer
->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ;
1174 // do not trigger refreshes upon invisible and possible partly created objects
1175 if ( MacIsReallyShown() )
1179 bool wxWindowMac::SetFont(const wxFont
& font
)
1181 bool retval
= wxWindowBase::SetFont( font
);
1183 MacUpdateControlFont() ;
1188 bool wxWindowMac::SetForegroundColour(const wxColour
& col
)
1190 bool retval
= wxWindowBase::SetForegroundColour( col
);
1193 MacUpdateControlFont();
1198 bool wxWindowMac::SetBackgroundColour(const wxColour
& col
)
1200 if ( !wxWindowBase::SetBackgroundColour(col
) && m_hasBgCol
)
1204 wxColour
newCol(GetBackgroundColour());
1206 if ( newCol
== wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW
) )
1207 brush
.MacSetTheme( kThemeBrushDocumentWindowBackground
) ;
1208 else if ( newCol
== wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE
) )
1209 brush
.MacSetTheme( kThemeBrushDialogBackgroundActive
) ;
1211 brush
.SetColour( newCol
) ;
1213 MacSetBackgroundBrush( brush
) ;
1214 MacUpdateControlFont() ;
1219 void wxWindowMac::MacSetBackgroundBrush( const wxBrush
&brush
)
1221 m_macBackgroundBrush
= brush
;
1222 m_peer
->SetBackground( brush
) ;
1225 bool wxWindowMac::MacCanFocus() const
1227 // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so
1228 // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning,
1229 // but the value range is nowhere documented
1230 Boolean keyExistsAndHasValidFormat
;
1231 CFIndex fullKeyboardAccess
= CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) ,
1232 kCFPreferencesCurrentApplication
, &keyExistsAndHasValidFormat
);
1234 if ( keyExistsAndHasValidFormat
&& fullKeyboardAccess
> 0 )
1240 UInt32 features
= 0 ;
1241 m_peer
->GetFeatures( &features
) ;
1243 return features
& ( kControlSupportsFocus
| kControlGetsFocusOnClick
) ;
1247 void wxWindowMac::SetFocus()
1249 if ( !AcceptsFocus() )
1252 wxWindow
* former
= FindFocus() ;
1253 if ( former
== this )
1256 // as we cannot rely on the control features to find out whether we are in full keyboard mode,
1257 // we can only leave in case of an error
1258 OSStatus err
= m_peer
->SetFocus( kControlFocusNextPart
) ;
1259 if ( err
== errCouldntSetFocus
)
1262 SetUserFocusWindow( (WindowRef
)MacGetTopLevelWindowRef() );
1264 #if !TARGET_API_MAC_OSX
1265 // emulate carbon events when running under CarbonLib where they are not natively available
1268 EventRef evRef
= NULL
;
1270 err
= MacCreateEvent(
1271 NULL
, kEventClassControl
, kEventControlSetFocusPart
, TicksToEventTime( TickCount() ) ,
1272 kEventAttributeUserEvent
, &evRef
);
1273 verify_noerr( err
);
1275 wxMacCarbonEvent
cEvent( evRef
) ;
1276 cEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, (ControlRef
) former
->GetHandle() ) ;
1277 cEvent
.SetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
, kControlFocusNoPart
) ;
1279 wxMacWindowEventHandler( NULL
, evRef
, former
) ;
1280 ReleaseEvent( evRef
) ;
1283 // send new focus event
1285 EventRef evRef
= NULL
;
1287 err
= MacCreateEvent(
1288 NULL
, kEventClassControl
, kEventControlSetFocusPart
, TicksToEventTime( TickCount() ) ,
1289 kEventAttributeUserEvent
, &evRef
);
1290 verify_noerr( err
);
1292 wxMacCarbonEvent
cEvent( evRef
) ;
1293 cEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, (ControlRef
) GetHandle() ) ;
1294 cEvent
.SetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
, kControlFocusNextPart
) ;
1296 wxMacWindowEventHandler( NULL
, evRef
, this ) ;
1297 ReleaseEvent( evRef
) ;
1302 void wxWindowMac::DoCaptureMouse()
1304 wxApp::s_captureWindow
= this ;
1307 wxWindow
* wxWindowBase::GetCapture()
1309 return wxApp::s_captureWindow
;
1312 void wxWindowMac::DoReleaseMouse()
1314 wxApp::s_captureWindow
= NULL
;
1317 #if wxUSE_DRAG_AND_DROP
1319 void wxWindowMac::SetDropTarget(wxDropTarget
*pDropTarget
)
1321 if ( m_dropTarget
!= NULL
)
1322 delete m_dropTarget
;
1324 m_dropTarget
= pDropTarget
;
1325 if ( m_dropTarget
!= NULL
)
1333 // Old-style File Manager Drag & Drop
1334 void wxWindowMac::DragAcceptFiles(bool WXUNUSED(accept
))
1339 // Returns the size of the native control. In the case of the toplevel window
1340 // this is the content area root control
1342 void wxWindowMac::MacGetPositionAndSizeFromControl(int& WXUNUSED(x
),
1345 int& WXUNUSED(h
)) const
1347 wxFAIL_MSG( wxT("Not currently supported") ) ;
1350 // From a wx position / size calculate the appropriate size of the native control
1352 bool wxWindowMac::MacGetBoundsForControl(
1356 int& w
, int& h
, bool adjustOrigin
) const
1358 // the desired size, minus the border pixels gives the correct size of the control
1362 // TODO: the default calls may be used as soon as PostCreateControl Is moved here
1363 w
= wxMax(size
.x
, 0) ; // WidthDefault( size.x );
1364 h
= wxMax(size
.y
, 0) ; // HeightDefault( size.y ) ;
1366 x
+= MacGetLeftBorderSize() ;
1367 y
+= MacGetTopBorderSize() ;
1368 w
-= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1369 h
-= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1372 AdjustForParentClientOrigin( x
, y
) ;
1374 // this is in window relative coordinate, as this parent may have a border, its physical position is offset by this border
1375 if ( !GetParent()->IsTopLevel() )
1377 x
-= GetParent()->MacGetLeftBorderSize() ;
1378 y
-= GetParent()->MacGetTopBorderSize() ;
1384 // Get window size (not client size)
1385 void wxWindowMac::DoGetSize(int *x
, int *y
) const
1388 m_peer
->GetRect( &bounds
) ;
1391 *x
= bounds
.right
- bounds
.left
+ MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1393 *y
= bounds
.bottom
- bounds
.top
+ MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1396 // get the position of the bounds of this window in client coordinates of its parent
1397 void wxWindowMac::DoGetPosition(int *x
, int *y
) const
1400 m_peer
->GetRect( &bounds
) ;
1402 int x1
= bounds
.left
;
1403 int y1
= bounds
.top
;
1405 // get the wx window position from the native one
1406 x1
-= MacGetLeftBorderSize() ;
1407 y1
-= MacGetTopBorderSize() ;
1409 if ( !IsTopLevel() )
1411 wxWindow
*parent
= GetParent();
1414 // we must first adjust it to be in window coordinates of the parent,
1415 // as otherwise it gets lost by the ClientAreaOrigin fix
1416 x1
+= parent
->MacGetLeftBorderSize() ;
1417 y1
+= parent
->MacGetTopBorderSize() ;
1419 // and now to client coordinates
1420 wxPoint
pt(parent
->GetClientAreaOrigin());
1432 void wxWindowMac::DoScreenToClient(int *x
, int *y
) const
1434 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
1435 wxCHECK_RET( window
, wxT("TopLevel Window missing") ) ;
1437 Point localwhere
= { 0, 0 } ;
1444 wxMacGlobalToLocal( window
, &localwhere
) ;
1451 MacRootWindowToWindow( x
, y
) ;
1453 wxPoint origin
= GetClientAreaOrigin() ;
1460 void wxWindowMac::DoClientToScreen(int *x
, int *y
) const
1462 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
1463 wxCHECK_RET( window
, wxT("TopLevel window missing") ) ;
1465 wxPoint origin
= GetClientAreaOrigin() ;
1471 MacWindowToRootWindow( x
, y
) ;
1473 Point localwhere
= { 0, 0 };
1479 wxMacLocalToGlobal( window
, &localwhere
) ;
1487 void wxWindowMac::MacClientToRootWindow( int *x
, int *y
) const
1489 wxPoint origin
= GetClientAreaOrigin() ;
1495 MacWindowToRootWindow( x
, y
) ;
1498 void wxWindowMac::MacRootWindowToClient( int *x
, int *y
) const
1500 MacRootWindowToWindow( x
, y
) ;
1502 wxPoint origin
= GetClientAreaOrigin() ;
1509 void wxWindowMac::MacWindowToRootWindow( int *x
, int *y
) const
1518 if ( !IsTopLevel() )
1520 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
1523 pt
.x
-= MacGetLeftBorderSize() ;
1524 pt
.y
-= MacGetTopBorderSize() ;
1525 wxMacControl::Convert( &pt
, m_peer
, top
->m_peer
) ;
1535 void wxWindowMac::MacWindowToRootWindow( short *x
, short *y
) const
1544 MacWindowToRootWindow( &x1
, &y1
) ;
1552 void wxWindowMac::MacRootWindowToWindow( int *x
, int *y
) const
1561 if ( !IsTopLevel() )
1563 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
1566 wxMacControl::Convert( &pt
, top
->m_peer
, m_peer
) ;
1567 pt
.x
+= MacGetLeftBorderSize() ;
1568 pt
.y
+= MacGetTopBorderSize() ;
1578 void wxWindowMac::MacRootWindowToWindow( short *x
, short *y
) const
1587 MacRootWindowToWindow( &x1
, &y1
) ;
1595 void wxWindowMac::MacGetContentAreaInset( int &left
, int &top
, int &right
, int &bottom
)
1597 RgnHandle rgn
= NewRgn() ;
1599 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1601 Rect structure
, content
;
1603 GetRegionBounds( rgn
, &content
) ;
1604 m_peer
->GetRect( &structure
) ;
1605 OffsetRect( &structure
, -structure
.left
, -structure
.top
) ;
1607 left
= content
.left
- structure
.left
;
1608 top
= content
.top
- structure
.top
;
1609 right
= structure
.right
- content
.right
;
1610 bottom
= structure
.bottom
- content
.bottom
;
1614 left
= top
= right
= bottom
= 0 ;
1620 wxSize
wxWindowMac::DoGetSizeFromClientSize( const wxSize
& size
) const
1622 wxSize sizeTotal
= size
;
1624 RgnHandle rgn
= NewRgn() ;
1625 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1627 Rect content
, structure
;
1628 GetRegionBounds( rgn
, &content
) ;
1629 m_peer
->GetRect( &structure
) ;
1631 // structure is in parent coordinates, but we only need width and height, so it's ok
1633 sizeTotal
.x
+= (structure
.right
- structure
.left
) - (content
.right
- content
.left
) ;
1634 sizeTotal
.y
+= (structure
.bottom
- structure
.top
) - (content
.bottom
- content
.top
) ;
1639 sizeTotal
.x
+= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1640 sizeTotal
.y
+= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1645 // Get size *available for subwindows* i.e. excluding menu bar etc.
1646 void wxWindowMac::DoGetClientSize( int *x
, int *y
) const
1650 RgnHandle rgn
= NewRgn() ;
1652 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1653 GetRegionBounds( rgn
, &content
) ;
1655 m_peer
->GetRect( &content
) ;
1658 ww
= content
.right
- content
.left
;
1659 hh
= content
.bottom
- content
.top
;
1661 if (m_hScrollBar
&& m_hScrollBar
->IsShown() )
1662 hh
-= m_hScrollBar
->GetSize().y
;
1664 if (m_vScrollBar
&& m_vScrollBar
->IsShown() )
1665 ww
-= m_vScrollBar
->GetSize().x
;
1673 bool wxWindowMac::SetCursor(const wxCursor
& cursor
)
1675 if (m_cursor
.IsSameAs(cursor
))
1680 if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR
) )
1685 if ( ! wxWindowBase::SetCursor( cursor
) )
1689 wxASSERT_MSG( m_cursor
.Ok(),
1690 wxT("cursor must be valid after call to the base version"));
1692 wxWindowMac
*mouseWin
= 0 ;
1694 wxTopLevelWindowMac
*tlw
= MacGetTopLevelWindow() ;
1695 WindowRef window
= (WindowRef
) ( tlw
? tlw
->MacGetWindowRef() : 0 ) ;
1697 ControlPartCode part
;
1698 ControlRef control
;
1700 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
1702 HIGetMousePosition(kHICoordSpaceWindow
, window
, &hiPoint
);
1707 Boolean swapped
= QDSwapPort( GetWindowPort( window
) , &savePort
) ;
1709 // TODO: If we ever get a GetCurrentEvent... replacement
1710 // for the mouse position, use it...
1715 control
= FindControlUnderMouse( pt
, window
, &part
) ;
1717 mouseWin
= wxFindControlFromMacControl( control
) ;
1719 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
1721 QDSwapPort( savePort
, NULL
) ;
1725 if ( mouseWin
== this && !wxIsBusy() )
1726 m_cursor
.MacInstall() ;
1732 bool wxWindowMac::DoPopupMenu(wxMenu
*menu
, int x
, int y
)
1734 #ifndef __WXUNIVERSAL__
1735 menu
->SetInvokingWindow((wxWindow
*)this);
1738 if ( x
== wxDefaultCoord
&& y
== wxDefaultCoord
)
1740 wxPoint mouse
= wxGetMousePosition();
1746 ClientToScreen( &x
, &y
) ;
1749 menu
->MacBeforeDisplay( true ) ;
1750 long menuResult
= ::PopUpMenuSelect((MenuHandle
) menu
->GetHMenu() , y
, x
, 0) ;
1751 if ( HiWord(menuResult
) != 0 )
1754 GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult
)) , LoWord(menuResult
) , &macid
);
1755 int id
= wxMacCommandToId( macid
);
1756 wxMenuItem
* item
= NULL
;
1758 item
= menu
->FindItem( id
, &realmenu
) ;
1761 if (item
->IsCheckable())
1762 item
->Check( !item
->IsChecked() ) ;
1764 menu
->SendEvent( id
, item
->IsCheckable() ? item
->IsChecked() : -1 ) ;
1768 menu
->MacAfterDisplay( true ) ;
1769 menu
->SetInvokingWindow( NULL
);
1773 // actually this shouldn't be called, because universal is having its own implementation
1779 // ----------------------------------------------------------------------------
1781 // ----------------------------------------------------------------------------
1785 void wxWindowMac::DoSetToolTip(wxToolTip
*tooltip
)
1787 wxWindowBase::DoSetToolTip(tooltip
);
1790 m_tooltip
->SetWindow(this);
1795 void wxWindowMac::MacInvalidateBorders()
1797 if ( m_peer
== NULL
)
1800 bool vis
= MacIsReallyShown() ;
1804 int outerBorder
= MacGetLeftBorderSize() ;
1805 if ( m_peer
->NeedsFocusRect() && m_peer
->HasFocus() )
1808 if ( outerBorder
== 0 )
1811 // now we know that we have something to do at all
1813 // as the borders are drawn on the parent we have to properly invalidate all these areas
1814 RgnHandle updateInner
, updateOuter
;
1817 // this rectangle is in HIViewCoordinates under OSX and in Window Coordinates under Carbon
1818 updateInner
= NewRgn() ;
1819 updateOuter
= NewRgn() ;
1821 m_peer
->GetRect( &rect
) ;
1822 RectRgn( updateInner
, &rect
) ;
1823 InsetRect( &rect
, -outerBorder
, -outerBorder
) ;
1824 RectRgn( updateOuter
, &rect
) ;
1825 DiffRgn( updateOuter
, updateInner
, updateOuter
) ;
1827 GetParent()->m_peer
->SetNeedsDisplay( updateOuter
) ;
1829 DisposeRgn( updateOuter
) ;
1830 DisposeRgn( updateInner
) ;
1833 void wxWindowMac::DoMoveWindow(int x
, int y
, int width
, int height
)
1835 // this is never called for a toplevel window, so we know we have a parent
1836 int former_x
, former_y
, former_w
, former_h
;
1838 // Get true coordinates of former position
1839 DoGetPosition( &former_x
, &former_y
) ;
1840 DoGetSize( &former_w
, &former_h
) ;
1842 wxWindow
*parent
= GetParent();
1845 wxPoint
pt(parent
->GetClientAreaOrigin());
1850 int actualWidth
= width
;
1851 int actualHeight
= height
;
1855 if ((m_minWidth
!= -1) && (actualWidth
< m_minWidth
))
1856 actualWidth
= m_minWidth
;
1857 if ((m_minHeight
!= -1) && (actualHeight
< m_minHeight
))
1858 actualHeight
= m_minHeight
;
1859 if ((m_maxWidth
!= -1) && (actualWidth
> m_maxWidth
))
1860 actualWidth
= m_maxWidth
;
1861 if ((m_maxHeight
!= -1) && (actualHeight
> m_maxHeight
))
1862 actualHeight
= m_maxHeight
;
1864 bool doMove
= false, doResize
= false ;
1866 if ( actualX
!= former_x
|| actualY
!= former_y
)
1869 if ( actualWidth
!= former_w
|| actualHeight
!= former_h
)
1872 if ( doMove
|| doResize
)
1874 // as the borders are drawn outside the native control, we adjust now
1876 wxRect
bounds( wxPoint( actualX
+ MacGetLeftBorderSize() ,actualY
+ MacGetTopBorderSize() ),
1877 wxSize( actualWidth
- (MacGetLeftBorderSize() + MacGetRightBorderSize()) ,
1878 actualHeight
- (MacGetTopBorderSize() + MacGetBottomBorderSize()) ) ) ;
1881 wxMacRectToNative( &bounds
, &r
) ;
1883 if ( !GetParent()->IsTopLevel() )
1884 wxMacWindowToNative( GetParent() , &r
) ;
1886 MacInvalidateBorders() ;
1888 m_cachedClippedRectValid
= false ;
1889 m_peer
->SetRect( &r
) ;
1891 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
1893 MacInvalidateBorders() ;
1895 MacRepositionScrollBars() ;
1898 wxPoint
point(actualX
, actualY
);
1899 wxMoveEvent
event(point
, m_windowId
);
1900 event
.SetEventObject(this);
1901 GetEventHandler()->ProcessEvent(event
) ;
1906 MacRepositionScrollBars() ;
1907 wxSize
size(actualWidth
, actualHeight
);
1908 wxSizeEvent
event(size
, m_windowId
);
1909 event
.SetEventObject(this);
1910 GetEventHandler()->ProcessEvent(event
);
1915 wxSize
wxWindowMac::DoGetBestSize() const
1917 if ( m_macIsUserPane
|| IsTopLevel() )
1918 return wxWindowBase::DoGetBestSize() ;
1920 Rect bestsize
= { 0 , 0 , 0 , 0 } ;
1921 int bestWidth
, bestHeight
;
1923 m_peer
->GetBestRect( &bestsize
) ;
1924 if ( EmptyRect( &bestsize
) )
1929 bestsize
.bottom
= 16 ;
1931 if ( IsKindOf( CLASSINFO( wxScrollBar
) ) )
1933 bestsize
.bottom
= 16 ;
1936 else if ( IsKindOf( CLASSINFO( wxSpinButton
) ) )
1938 bestsize
.bottom
= 24 ;
1943 // return wxWindowBase::DoGetBestSize() ;
1947 bestWidth
= bestsize
.right
- bestsize
.left
;
1948 bestHeight
= bestsize
.bottom
- bestsize
.top
;
1949 if ( bestHeight
< 10 )
1952 return wxSize(bestWidth
, bestHeight
);
1955 // set the size of the window: if the dimensions are positive, just use them,
1956 // but if any of them is equal to -1, it means that we must find the value for
1957 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
1958 // which case -1 is a valid value for x and y)
1960 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
1961 // the width/height to best suit our contents, otherwise we reuse the current
1963 void wxWindowMac::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
1965 // get the current size and position...
1966 int currentX
, currentY
;
1967 int currentW
, currentH
;
1969 GetPosition(¤tX
, ¤tY
);
1970 GetSize(¤tW
, ¤tH
);
1972 // ... and don't do anything (avoiding flicker) if it's already ok
1973 if ( x
== currentX
&& y
== currentY
&&
1974 width
== currentW
&& height
== currentH
&& ( height
!= -1 && width
!= -1 ) )
1977 MacRepositionScrollBars() ; // we might have a real position shift
1982 if ( !(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) )
1984 if ( x
== wxDefaultCoord
)
1986 if ( y
== wxDefaultCoord
)
1990 AdjustForParentClientOrigin( x
, y
, sizeFlags
);
1992 wxSize size
= wxDefaultSize
;
1993 if ( width
== wxDefaultCoord
)
1995 if ( sizeFlags
& wxSIZE_AUTO_WIDTH
)
1997 size
= DoGetBestSize();
2002 // just take the current one
2007 if ( height
== wxDefaultCoord
)
2009 if ( sizeFlags
& wxSIZE_AUTO_HEIGHT
)
2011 if ( size
.x
== wxDefaultCoord
)
2012 size
= DoGetBestSize();
2013 // else: already called DoGetBestSize() above
2019 // just take the current one
2024 DoMoveWindow( x
, y
, width
, height
);
2027 wxPoint
wxWindowMac::GetClientAreaOrigin() const
2029 RgnHandle rgn
= NewRgn() ;
2031 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
2033 GetRegionBounds( rgn
, &content
) ;
2043 return wxPoint( content
.left
+ MacGetLeftBorderSize() , content
.top
+ MacGetTopBorderSize() );
2046 void wxWindowMac::DoSetClientSize(int clientwidth
, int clientheight
)
2048 if ( clientwidth
!= wxDefaultCoord
|| clientheight
!= wxDefaultCoord
)
2050 int currentclientwidth
, currentclientheight
;
2051 int currentwidth
, currentheight
;
2053 GetClientSize( ¤tclientwidth
, ¤tclientheight
) ;
2054 GetSize( ¤twidth
, ¤theight
) ;
2056 DoSetSize( wxDefaultCoord
, wxDefaultCoord
, currentwidth
+ clientwidth
- currentclientwidth
,
2057 currentheight
+ clientheight
- currentclientheight
, wxSIZE_USE_EXISTING
) ;
2061 void wxWindowMac::SetLabel(const wxString
& title
)
2065 if ( m_peer
&& m_peer
->Ok() )
2066 m_peer
->SetLabel( wxStripMenuCodes(m_label
, wxStrip_Mnemonics
) ) ;
2068 // do not trigger refreshes upon invisible and possible partly created objects
2069 if ( MacIsReallyShown() )
2073 wxString
wxWindowMac::GetLabel() const
2078 bool wxWindowMac::Show(bool show
)
2080 bool former
= MacIsReallyShown() ;
2081 if ( !wxWindowBase::Show(show
) )
2084 // TODO: use visibilityChanged Carbon Event for OSX
2086 m_peer
->SetVisibility( show
, true ) ;
2088 if ( former
!= MacIsReallyShown() )
2089 MacPropagateVisibilityChanged() ;
2094 void wxWindowMac::DoEnable(bool enable
)
2096 m_peer
->Enable( enable
) ;
2100 // status change propagations (will be not necessary for OSX later )
2103 void wxWindowMac::MacPropagateVisibilityChanged()
2105 #if !TARGET_API_MAC_OSX
2106 MacVisibilityChanged() ;
2109 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
2112 child
= node
->GetData();
2113 if ( child
->IsShown() )
2114 child
->MacPropagateVisibilityChanged() ;
2116 node
= node
->GetNext();
2121 void wxWindowMac::OnEnabled(bool WXUNUSED(enabled
))
2123 #if !TARGET_API_MAC_OSX
2124 MacEnabledStateChanged() ;
2128 void wxWindowMac::MacPropagateHiliteChanged()
2130 #if !TARGET_API_MAC_OSX
2131 MacHiliteChanged() ;
2134 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
2137 child
= node
->GetData();
2138 if (child
/* && child->IsEnabled() */)
2139 child
->MacPropagateHiliteChanged() ;
2141 node
= node
->GetNext();
2147 // status change notifications
2150 void wxWindowMac::MacVisibilityChanged()
2154 void wxWindowMac::MacHiliteChanged()
2158 void wxWindowMac::MacEnabledStateChanged()
2163 // status queries on the inherited window's state
2166 bool wxWindowMac::MacIsReallyShown()
2168 // only under OSX the visibility of the TLW is taken into account
2169 if ( m_isBeingDeleted
)
2172 #if TARGET_API_MAC_OSX
2173 if ( m_peer
&& m_peer
->Ok() )
2174 return m_peer
->IsVisible();
2177 wxWindow
* win
= this ;
2178 while ( win
->IsShown() )
2180 if ( win
->IsTopLevel() )
2183 win
= win
->GetParent() ;
2191 bool wxWindowMac::MacIsReallyEnabled()
2193 return m_peer
->IsEnabled() ;
2196 bool wxWindowMac::MacIsReallyHilited()
2198 return m_peer
->IsActive();
2201 void wxWindowMac::MacFlashInvalidAreas()
2203 #if TARGET_API_MAC_OSX
2204 HIViewFlashDirtyArea( (WindowRef
) MacGetTopLevelWindowRef() ) ;
2208 int wxWindowMac::GetCharHeight() const
2210 wxClientDC
dc( (wxWindowMac
*)this ) ;
2212 return dc
.GetCharHeight() ;
2215 int wxWindowMac::GetCharWidth() const
2217 wxClientDC
dc( (wxWindowMac
*)this ) ;
2219 return dc
.GetCharWidth() ;
2222 void wxWindowMac::GetTextExtent(const wxString
& string
, int *x
, int *y
,
2223 int *descent
, int *externalLeading
, const wxFont
*theFont
) const
2225 const wxFont
*fontToUse
= theFont
;
2227 fontToUse
= &m_font
;
2229 wxClientDC
dc( (wxWindowMac
*) this ) ;
2230 wxCoord lx
,ly
,ld
,le
;
2231 dc
.GetTextExtent( string
, &lx
, &ly
, &ld
, &le
, (wxFont
*)fontToUse
) ;
2232 if ( externalLeading
)
2233 *externalLeading
= le
;
2243 * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect
2244 * we always intersect with the entire window, not only with the client area
2247 void wxWindowMac::Refresh(bool WXUNUSED(eraseBack
), const wxRect
*rect
)
2249 if ( m_peer
== NULL
)
2252 if ( !MacIsReallyShown() )
2259 wxMacRectToNative( rect
, &r
) ;
2260 m_peer
->SetNeedsDisplay( &r
) ;
2264 m_peer
->SetNeedsDisplay() ;
2268 void wxWindowMac::Freeze()
2270 #if TARGET_API_MAC_OSX
2271 if ( !m_frozenness
++ )
2273 if ( m_peer
&& m_peer
->Ok() )
2274 m_peer
->SetDrawingEnabled( false ) ;
2279 void wxWindowMac::Thaw()
2281 #if TARGET_API_MAC_OSX
2282 wxASSERT_MSG( m_frozenness
> 0, wxT("Thaw() without matching Freeze()") );
2284 if ( !--m_frozenness
)
2286 if ( m_peer
&& m_peer
->Ok() )
2288 m_peer
->SetDrawingEnabled( true ) ;
2289 m_peer
->InvalidateWithChildren() ;
2295 bool wxWindowMac::IsFrozen() const
2297 return m_frozenness
!= 0;
2300 wxWindowMac
*wxGetActiveWindow()
2302 // actually this is a windows-only concept
2306 // Coordinates relative to the window
2307 void wxWindowMac::WarpPointer(int WXUNUSED(x_pos
), int WXUNUSED(y_pos
))
2309 // We really don't move the mouse programmatically under Mac.
2312 void wxWindowMac::OnEraseBackground(wxEraseEvent
& event
)
2314 if ( MacGetTopLevelWindow() == NULL
)
2317 #if TARGET_API_MAC_OSX
2318 if ( !m_macBackgroundBrush
.Ok() || m_macBackgroundBrush
.GetStyle() == wxTRANSPARENT
2319 || GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT
)
2326 event
.GetDC()->Clear() ;
2330 void wxWindowMac::OnNcPaint( wxNcPaintEvent
& event
)
2335 int wxWindowMac::GetScrollPos(int orient
) const
2337 if ( orient
== wxHORIZONTAL
)
2340 return m_hScrollBar
->GetThumbPosition() ;
2345 return m_vScrollBar
->GetThumbPosition() ;
2351 // This now returns the whole range, not just the number
2352 // of positions that we can scroll.
2353 int wxWindowMac::GetScrollRange(int orient
) const
2355 if ( orient
== wxHORIZONTAL
)
2358 return m_hScrollBar
->GetRange() ;
2363 return m_vScrollBar
->GetRange() ;
2369 int wxWindowMac::GetScrollThumb(int orient
) const
2371 if ( orient
== wxHORIZONTAL
)
2374 return m_hScrollBar
->GetThumbSize() ;
2379 return m_vScrollBar
->GetThumbSize() ;
2385 void wxWindowMac::SetScrollPos(int orient
, int pos
, bool WXUNUSED(refresh
))
2387 if ( orient
== wxHORIZONTAL
)
2390 m_hScrollBar
->SetThumbPosition( pos
) ;
2395 m_vScrollBar
->SetThumbPosition( pos
) ;
2400 wxWindowMac::AlwaysShowScrollbars(bool hflag
, bool vflag
)
2402 bool needVisibilityUpdate
= false;
2404 if ( m_hScrollBarAlwaysShown
!= hflag
)
2406 m_hScrollBarAlwaysShown
= hflag
;
2407 needVisibilityUpdate
= true;
2410 if ( m_vScrollBarAlwaysShown
!= vflag
)
2412 m_vScrollBarAlwaysShown
= vflag
;
2413 needVisibilityUpdate
= true;
2416 if ( needVisibilityUpdate
)
2417 DoUpdateScrollbarVisibility();
2421 // we draw borders and grow boxes, are already set up and clipped in the current port / cgContextRef
2422 // our own window origin is at leftOrigin/rightOrigin
2425 void wxWindowMac::MacPaintGrowBox()
2430 if ( MacHasScrollBarCorner() )
2434 CGContextRef cgContext
= (CGContextRef
) MacGetCGContextRef() ;
2435 wxASSERT( cgContext
) ;
2437 m_peer
->GetRect( &rect
) ;
2439 int size
= m_hScrollBar
? m_hScrollBar
->GetSize().y
: ( m_vScrollBar
? m_vScrollBar
->GetSize().x
: MAC_SCROLLBAR_SIZE
) ;
2440 CGRect cgrect
= CGRectMake( rect
.right
- size
, rect
.bottom
- size
, size
, size
) ;
2441 CGPoint cgpoint
= CGPointMake( rect
.right
- size
, rect
.bottom
- size
) ;
2442 CGContextSaveGState( cgContext
);
2444 if ( m_macBackgroundBrush
.Ok() && m_macBackgroundBrush
.GetStyle() != wxTRANSPARENT
)
2446 wxMacCoreGraphicsColour
bkgnd( m_macBackgroundBrush
) ;
2447 bkgnd
.Apply( cgContext
);
2451 CGContextSetRGBFillColor( cgContext
, 1.0, 1.0 , 1.0 , 1.0 );
2453 CGContextFillRect( cgContext
, cgrect
);
2454 CGContextRestoreGState( cgContext
);
2458 void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin
) , int WXUNUSED(rightOrigin
) )
2464 bool hasFocus
= m_peer
->NeedsFocusRect() && m_peer
->HasFocus() ;
2466 // back to the surrounding frame rectangle
2467 m_peer
->GetRect( &rect
) ;
2468 InsetRect( &rect
, -1 , -1 ) ;
2471 CGRect cgrect
= CGRectMake( rect
.left
, rect
.top
, rect
.right
- rect
.left
,
2472 rect
.bottom
- rect
.top
) ;
2474 HIThemeFrameDrawInfo info
;
2475 memset( &info
, 0 , sizeof(info
) ) ;
2479 info
.state
= IsEnabled() ? kThemeStateActive
: kThemeStateInactive
;
2480 info
.isFocused
= hasFocus
;
2482 CGContextRef cgContext
= (CGContextRef
) GetParent()->MacGetCGContextRef() ;
2483 wxASSERT( cgContext
) ;
2485 if ( HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
) )
2487 info
.kind
= kHIThemeFrameTextFieldSquare
;
2488 HIThemeDrawFrame( &cgrect
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2490 else if ( HasFlag(wxSIMPLE_BORDER
) )
2492 info
.kind
= kHIThemeFrameListBox
;
2493 HIThemeDrawFrame( &cgrect
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2495 else if ( hasFocus
)
2497 HIThemeDrawFocusRect( &cgrect
, true , cgContext
, kHIThemeOrientationNormal
) ;
2499 #if 0 // TODO REMOVE now done in a separate call earlier in drawing the window itself
2500 m_peer
->GetRect( &rect
) ;
2501 if ( MacHasScrollBarCorner() )
2503 int variant
= (m_hScrollBar
== NULL
? m_vScrollBar
: m_hScrollBar
) ->GetWindowVariant();
2504 int size
= m_hScrollBar
? m_hScrollBar
->GetSize().y
: ( m_vScrollBar
? m_vScrollBar
->GetSize().x
: MAC_SCROLLBAR_SIZE
) ;
2505 CGRect cgrect
= CGRectMake( rect
.right
- size
, rect
.bottom
- size
, size
, size
) ;
2506 CGPoint cgpoint
= CGPointMake( rect
.right
- size
, rect
.bottom
- size
) ;
2507 HIThemeGrowBoxDrawInfo info
;
2508 memset( &info
, 0, sizeof(info
) ) ;
2510 info
.state
= IsEnabled() ? kThemeStateActive
: kThemeStateInactive
;
2511 info
.kind
= kHIThemeGrowBoxKindNone
;
2512 // contrary to the docs ...SizeSmall does not work
2513 info
.size
= kHIThemeGrowBoxSizeNormal
;
2514 info
.direction
= 0 ;
2515 HIThemeDrawGrowBox( &cgpoint
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2521 void wxWindowMac::RemoveChild( wxWindowBase
*child
)
2523 if ( child
== m_hScrollBar
)
2524 m_hScrollBar
= NULL
;
2525 if ( child
== m_vScrollBar
)
2526 m_vScrollBar
= NULL
;
2528 wxWindowBase::RemoveChild( child
) ;
2531 void wxWindowMac::DoUpdateScrollbarVisibility()
2533 bool triggerSizeEvent
= false;
2537 bool showHScrollBar
= m_hScrollBarAlwaysShown
|| m_hScrollBar
->IsNeeded();
2539 if ( m_hScrollBar
->IsShown() != showHScrollBar
)
2541 m_hScrollBar
->Show( showHScrollBar
);
2542 triggerSizeEvent
= true;
2548 bool showVScrollBar
= m_vScrollBarAlwaysShown
|| m_vScrollBar
->IsNeeded();
2550 if ( m_vScrollBar
->IsShown() != showVScrollBar
)
2552 m_vScrollBar
->Show( showVScrollBar
) ;
2553 triggerSizeEvent
= true;
2557 MacRepositionScrollBars() ;
2558 if ( triggerSizeEvent
)
2560 wxSizeEvent
event(GetSize(), m_windowId
);
2561 event
.SetEventObject(this);
2562 GetEventHandler()->ProcessEvent(event
);
2566 // New function that will replace some of the above.
2567 void wxWindowMac::SetScrollbar(int orient
, int pos
, int thumb
,
2568 int range
, bool refresh
)
2570 if ( orient
== wxHORIZONTAL
&& m_hScrollBar
)
2571 m_hScrollBar
->SetScrollbar(pos
, thumb
, range
, thumb
, refresh
);
2572 else if ( orient
== wxVERTICAL
&& m_vScrollBar
)
2573 m_vScrollBar
->SetScrollbar(pos
, thumb
, range
, thumb
, refresh
);
2575 DoUpdateScrollbarVisibility();
2578 // Does a physical scroll
2579 void wxWindowMac::ScrollWindow(int dx
, int dy
, const wxRect
*rect
)
2581 if ( dx
== 0 && dy
== 0 )
2584 int width
, height
;
2585 GetClientSize( &width
, &height
) ;
2588 // note there currently is a bug in OSX which makes inefficient refreshes in case an entire control
2589 // area is scrolled, this does not occur if width and height are 2 pixels less,
2590 // TODO: write optimal workaround
2591 wxRect
scrollrect( MacGetLeftBorderSize() , MacGetTopBorderSize() , width
, height
) ;
2593 scrollrect
.Intersect( *rect
) ;
2595 if ( m_peer
->GetNeedsDisplay() )
2597 // because HIViewScrollRect does not scroll the already invalidated area we have two options:
2598 // in case there is already a pending redraw on that area
2599 // either immediate redraw or full invalidate
2601 // is the better overall solution, as it does not slow down scrolling
2602 m_peer
->SetNeedsDisplay() ;
2604 // this would be the preferred version for fast drawing controls
2605 HIViewRender(m_peer
->GetControlRef()) ;
2609 // as the native control might be not a 0/0 wx window coordinates, we have to offset
2610 scrollrect
.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ;
2611 m_peer
->ScrollRect( &scrollrect
, dx
, dy
) ;
2614 // this would be the preferred version for fast drawing controls
2615 HIViewRender(m_peer
->GetControlRef()) ;
2621 for (wxWindowList::compatibility_iterator node
= GetChildren().GetFirst(); node
; node
= node
->GetNext())
2623 child
= node
->GetData();
2626 if (child
== m_vScrollBar
)
2628 if (child
== m_hScrollBar
)
2630 if (child
->IsTopLevel())
2633 child
->GetPosition( &x
, &y
);
2634 child
->GetSize( &w
, &h
);
2637 wxRect
rc( x
, y
, w
, h
);
2638 if (rect
->Intersects( rc
))
2639 child
->SetSize( x
+ dx
, y
+ dy
, w
, h
, wxSIZE_AUTO
|wxSIZE_ALLOW_MINUS_ONE
);
2643 child
->SetSize( x
+ dx
, y
+ dy
, w
, h
, wxSIZE_AUTO
|wxSIZE_ALLOW_MINUS_ONE
);
2648 void wxWindowMac::MacOnScroll( wxScrollEvent
&event
)
2650 if ( event
.GetEventObject() == m_vScrollBar
|| event
.GetEventObject() == m_hScrollBar
)
2652 wxScrollWinEvent wevent
;
2653 wevent
.SetPosition(event
.GetPosition());
2654 wevent
.SetOrientation(event
.GetOrientation());
2655 wevent
.SetEventObject(this);
2657 if (event
.GetEventType() == wxEVT_SCROLL_TOP
)
2658 wevent
.SetEventType( wxEVT_SCROLLWIN_TOP
);
2659 else if (event
.GetEventType() == wxEVT_SCROLL_BOTTOM
)
2660 wevent
.SetEventType( wxEVT_SCROLLWIN_BOTTOM
);
2661 else if (event
.GetEventType() == wxEVT_SCROLL_LINEUP
)
2662 wevent
.SetEventType( wxEVT_SCROLLWIN_LINEUP
);
2663 else if (event
.GetEventType() == wxEVT_SCROLL_LINEDOWN
)
2664 wevent
.SetEventType( wxEVT_SCROLLWIN_LINEDOWN
);
2665 else if (event
.GetEventType() == wxEVT_SCROLL_PAGEUP
)
2666 wevent
.SetEventType( wxEVT_SCROLLWIN_PAGEUP
);
2667 else if (event
.GetEventType() == wxEVT_SCROLL_PAGEDOWN
)
2668 wevent
.SetEventType( wxEVT_SCROLLWIN_PAGEDOWN
);
2669 else if (event
.GetEventType() == wxEVT_SCROLL_THUMBTRACK
)
2670 wevent
.SetEventType( wxEVT_SCROLLWIN_THUMBTRACK
);
2671 else if (event
.GetEventType() == wxEVT_SCROLL_THUMBRELEASE
)
2672 wevent
.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE
);
2674 GetEventHandler()->ProcessEvent(wevent
);
2678 // Get the window with the focus
2679 wxWindowMac
*wxWindowBase::DoFindFocus()
2681 ControlRef control
;
2682 GetKeyboardFocus( GetUserFocusWindow() , &control
) ;
2683 return wxFindControlFromMacControl( control
) ;
2686 void wxWindowMac::OnSetFocus( wxFocusEvent
& event
)
2688 // panel wants to track the window which was the last to have focus in it,
2689 // so we want to set ourselves as the window which last had focus
2691 // notice that it's also important to do it upwards the tree because
2692 // otherwise when the top level panel gets focus, it won't set it back to
2693 // us, but to some other sibling
2695 // CS: don't know if this is still needed:
2696 //wxChildFocusEvent eventFocus(this);
2697 //(void)GetEventHandler()->ProcessEvent(eventFocus);
2699 if ( MacGetTopLevelWindow() && m_peer
->NeedsFocusRect() )
2701 GetParent()->Refresh() ;
2702 wxMacWindowStateSaver
sv( this ) ;
2705 m_peer
->GetRect( &rect
) ;
2706 // auf den umgebenden Rahmen zurチᅡ゚ck
2707 InsetRect( &rect
, -1 , -1 ) ;
2709 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2713 wxMacControl::Convert( &pt
, GetParent()->m_peer
, top
->m_peer
) ;
2715 rect
.right
+= pt
.x
;
2717 rect
.bottom
+= pt
.y
;
2720 bool bIsFocusEvent
= (event
.GetEventType() == wxEVT_SET_FOCUS
);
2721 DrawThemeFocusRect( &rect
, bIsFocusEvent
) ;
2722 if ( !bIsFocusEvent
)
2724 // as this erases part of the frame we have to redraw borders
2725 // and because our z-ordering is not always correct (staticboxes)
2726 // we have to invalidate things, we cannot simple redraw
2727 MacInvalidateBorders() ;
2734 void wxWindowMac::OnInternalIdle()
2736 // This calls the UI-update mechanism (querying windows for
2737 // menu/toolbar/control state information)
2738 if (wxUpdateUIEvent::CanUpdate(this) && IsShown())
2739 UpdateWindowUI(wxUPDATE_UI_FROMIDLE
);
2742 // Raise the window to the top of the Z order
2743 void wxWindowMac::Raise()
2745 m_peer
->SetZOrder( true , NULL
) ;
2748 // Lower the window to the bottom of the Z order
2749 void wxWindowMac::Lower()
2751 m_peer
->SetZOrder( false , NULL
) ;
2754 // static wxWindow *gs_lastWhich = NULL;
2756 bool wxWindowMac::MacSetupCursor( const wxPoint
& pt
)
2758 // first trigger a set cursor event
2760 wxPoint clientorigin
= GetClientAreaOrigin() ;
2761 wxSize clientsize
= GetClientSize() ;
2763 if ( wxRect2DInt( clientorigin
.x
, clientorigin
.y
, clientsize
.x
, clientsize
.y
).Contains( wxPoint2DInt( pt
) ) )
2765 wxSetCursorEvent
event( pt
.x
, pt
.y
);
2767 bool processedEvtSetCursor
= GetEventHandler()->ProcessEvent(event
);
2768 if ( processedEvtSetCursor
&& event
.HasCursor() )
2770 cursor
= event
.GetCursor() ;
2774 // the test for processedEvtSetCursor is here to prevent using m_cursor
2775 // if the user code caught EVT_SET_CURSOR() and returned nothing from
2776 // it - this is a way to say that our cursor shouldn't be used for this
2778 if ( !processedEvtSetCursor
&& m_cursor
.Ok() )
2781 if ( !wxIsBusy() && !GetParent() )
2782 cursor
= *wxSTANDARD_CURSOR
;
2786 cursor
.MacInstall() ;
2789 return cursor
.Ok() ;
2792 wxString
wxWindowMac::MacGetToolTipString( wxPoint
&WXUNUSED(pt
) )
2796 return m_tooltip
->GetTip() ;
2799 return wxEmptyString
;
2802 void wxWindowMac::ClearBackground()
2808 void wxWindowMac::Update()
2810 #if TARGET_API_MAC_OSX
2811 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2813 top
->MacPerformUpdates() ;
2815 ::Draw1Control( m_peer
->GetControlRef() ) ;
2819 wxTopLevelWindowMac
* wxWindowMac::MacGetTopLevelWindow() const
2821 wxTopLevelWindowMac
* win
= NULL
;
2822 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
2824 win
= wxFindWinFromMacWindow( window
) ;
2829 const wxRect
& wxWindowMac::MacGetClippedClientRect() const
2831 MacUpdateClippedRects() ;
2833 return m_cachedClippedClientRect
;
2836 const wxRect
& wxWindowMac::MacGetClippedRect() const
2838 MacUpdateClippedRects() ;
2840 return m_cachedClippedRect
;
2843 const wxRect
&wxWindowMac:: MacGetClippedRectWithOuterStructure() const
2845 MacUpdateClippedRects() ;
2847 return m_cachedClippedRectWithOuterStructure
;
2850 const wxRegion
& wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures
)
2852 static wxRegion emptyrgn
;
2854 if ( !m_isBeingDeleted
&& MacIsReallyShown() /*m_peer->IsVisible() */ )
2856 MacUpdateClippedRects() ;
2857 if ( includeOuterStructures
)
2858 return m_cachedClippedRegionWithOuterStructure
;
2860 return m_cachedClippedRegion
;
2868 void wxWindowMac::MacUpdateClippedRects() const
2870 if ( m_cachedClippedRectValid
)
2873 // includeOuterStructures is true if we try to draw somthing like a focus ring etc.
2874 // also a window dc uses this, in this case we only clip in the hierarchy for hard
2875 // borders like a scrollwindow, splitter etc otherwise we end up in a paranoia having
2876 // to add focus borders everywhere
2878 Rect r
, rIncludingOuterStructures
;
2880 m_peer
->GetRect( &r
) ;
2881 r
.left
-= MacGetLeftBorderSize() ;
2882 r
.top
-= MacGetTopBorderSize() ;
2883 r
.bottom
+= MacGetBottomBorderSize() ;
2884 r
.right
+= MacGetRightBorderSize() ;
2891 rIncludingOuterStructures
= r
;
2892 InsetRect( &rIncludingOuterStructures
, -4 , -4 ) ;
2894 wxRect cl
= GetClientRect() ;
2895 Rect rClient
= { cl
.y
, cl
.x
, cl
.y
+ cl
.height
, cl
.x
+ cl
.width
} ;
2899 const wxWindow
* child
= this ;
2900 const wxWindow
* parent
= NULL
;
2902 while ( !child
->IsTopLevel() && ( parent
= child
->GetParent() ) != NULL
)
2904 if ( parent
->MacIsChildOfClientArea(child
) )
2906 size
= parent
->GetClientSize() ;
2907 wxPoint origin
= parent
->GetClientAreaOrigin() ;
2913 // this will be true for scrollbars, toolbars etc.
2914 size
= parent
->GetSize() ;
2915 y
= parent
->MacGetTopBorderSize() ;
2916 x
= parent
->MacGetLeftBorderSize() ;
2917 size
.x
-= parent
->MacGetLeftBorderSize() + parent
->MacGetRightBorderSize() ;
2918 size
.y
-= parent
->MacGetTopBorderSize() + parent
->MacGetBottomBorderSize() ;
2921 parent
->MacWindowToRootWindow( &x
, &y
) ;
2922 MacRootWindowToWindow( &x
, &y
) ;
2924 Rect rparent
= { y
, x
, y
+ size
.y
, x
+ size
.x
} ;
2926 // the wxwindow and client rects will always be clipped
2927 SectRect( &r
, &rparent
, &r
) ;
2928 SectRect( &rClient
, &rparent
, &rClient
) ;
2930 // the structure only at 'hard' borders
2931 if ( parent
->MacClipChildren() ||
2932 ( parent
->GetParent() && parent
->GetParent()->MacClipGrandChildren() ) )
2934 SectRect( &rIncludingOuterStructures
, &rparent
, &rIncludingOuterStructures
) ;
2940 m_cachedClippedRect
= wxRect( r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
- r
.top
) ;
2941 m_cachedClippedClientRect
= wxRect( rClient
.left
, rClient
.top
,
2942 rClient
.right
- rClient
.left
, rClient
.bottom
- rClient
.top
) ;
2943 m_cachedClippedRectWithOuterStructure
= wxRect(
2944 rIncludingOuterStructures
.left
, rIncludingOuterStructures
.top
,
2945 rIncludingOuterStructures
.right
- rIncludingOuterStructures
.left
,
2946 rIncludingOuterStructures
.bottom
- rIncludingOuterStructures
.top
) ;
2948 m_cachedClippedRegionWithOuterStructure
= wxRegion( m_cachedClippedRectWithOuterStructure
) ;
2949 m_cachedClippedRegion
= wxRegion( m_cachedClippedRect
) ;
2950 m_cachedClippedClientRegion
= wxRegion( m_cachedClippedClientRect
) ;
2952 m_cachedClippedRectValid
= true ;
2956 This function must not change the updatergn !
2958 bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr
, long time
)
2960 bool handled
= false ;
2962 RgnHandle updatergn
= (RgnHandle
) updatergnr
;
2963 GetRegionBounds( updatergn
, &updatebounds
) ;
2965 // wxLogDebug(wxT("update for %s bounds %d, %d, %d, %d"), wxString(GetClassInfo()->GetClassName()).c_str(), updatebounds.left, updatebounds.top , updatebounds.right , updatebounds.bottom ) ;
2967 if ( !EmptyRgn(updatergn
) )
2969 RgnHandle newupdate
= NewRgn() ;
2970 wxSize point
= GetClientSize() ;
2971 wxPoint origin
= GetClientAreaOrigin() ;
2972 SetRectRgn( newupdate
, origin
.x
, origin
.y
, origin
.x
+ point
.x
, origin
.y
+ point
.y
) ;
2973 SectRgn( newupdate
, updatergn
, newupdate
) ;
2975 // first send an erase event to the entire update area
2977 // for the toplevel window this really is the entire area
2978 // for all the others only their client area, otherwise they
2979 // might be drawing with full alpha and eg put blue into
2980 // the grow-box area of a scrolled window (scroll sample)
2981 wxDC
* dc
= new wxWindowDC(this);
2983 dc
->SetClippingRegion(wxRegion(updatergn
));
2985 dc
->SetClippingRegion(wxRegion(newupdate
));
2987 wxEraseEvent
eevent( GetId(), dc
);
2988 eevent
.SetEventObject( this );
2989 GetEventHandler()->ProcessEvent( eevent
);
2995 // calculate a client-origin version of the update rgn and set m_updateRegion to that
2996 OffsetRgn( newupdate
, -origin
.x
, -origin
.y
) ;
2997 m_updateRegion
= newupdate
;
2998 DisposeRgn( newupdate
) ;
3000 if ( !m_updateRegion
.Empty() )
3002 // paint the window itself
3005 event
.SetTimestamp(time
);
3006 event
.SetEventObject(this);
3007 GetEventHandler()->ProcessEvent(event
);
3011 // now we cannot rely on having its borders drawn by a window itself, as it does not
3012 // get the updateRgn wide enough to always do so, so we do it from the parent
3013 // this would also be the place to draw any custom backgrounds for native controls
3014 // in Composited windowing
3015 wxPoint clientOrigin
= GetClientAreaOrigin() ;
3019 for (wxWindowList::compatibility_iterator node
= GetChildren().GetFirst(); node
; node
= node
->GetNext())
3021 child
= node
->GetData();
3024 if (child
== m_vScrollBar
)
3026 if (child
== m_hScrollBar
)
3028 if (child
->IsTopLevel())
3030 if (!child
->IsShown())
3033 // only draw those in the update region (add a safety margin of 10 pixels for shadow effects
3035 child
->GetPosition( &x
, &y
);
3036 child
->GetSize( &w
, &h
);
3037 Rect childRect
= { y
, x
, y
+ h
, x
+ w
} ;
3038 OffsetRect( &childRect
, clientOrigin
.x
, clientOrigin
.y
) ;
3039 InsetRect( &childRect
, -10 , -10) ;
3041 if ( RectInRgn( &childRect
, updatergn
) )
3043 // paint custom borders
3044 wxNcPaintEvent
eventNc( child
->GetId() );
3045 eventNc
.SetEventObject( child
);
3046 if ( !child
->GetEventHandler()->ProcessEvent( eventNc
) )
3048 child
->MacPaintBorders(0, 0) ;
3058 WXWindow
wxWindowMac::MacGetTopLevelWindowRef() const
3060 wxWindowMac
*iter
= (wxWindowMac
*)this ;
3064 if ( iter
->IsTopLevel() )
3066 wxTopLevelWindow
* toplevel
= wxDynamicCast(iter
,wxTopLevelWindow
);
3068 return toplevel
->MacGetWindowRef();
3070 wxPopupWindow
* popupwin
= wxDynamicCast(iter
,wxPopupWindow
);
3072 return popupwin
->MacGetPopupWindowRef();
3075 iter
= iter
->GetParent() ;
3081 bool wxWindowMac::MacHasScrollBarCorner() const
3083 /* Returns whether the scroll bars in a wxScrolledWindow should be
3084 * shortened. Scroll bars should be shortened if either:
3086 * - both scroll bars are visible, or
3088 * - there is a resize box in the parent frame's corner and this
3089 * window shares the bottom and right edge with the parent
3093 if ( m_hScrollBar
== NULL
&& m_vScrollBar
== NULL
)
3096 if ( ( m_hScrollBar
&& m_hScrollBar
->IsShown() )
3097 && ( m_vScrollBar
&& m_vScrollBar
->IsShown() ) )
3099 // Both scroll bars visible
3104 wxPoint thisWindowBottomRight
= GetScreenRect().GetBottomRight();
3106 for ( const wxWindow
*win
= this; win
; win
= win
->GetParent() )
3108 const wxFrame
*frame
= wxDynamicCast( win
, wxFrame
) ;
3111 if ( frame
->GetWindowStyleFlag() & wxRESIZE_BORDER
)
3113 // Parent frame has resize handle
3114 wxPoint frameBottomRight
= frame
->GetScreenRect().GetBottomRight();
3116 // Note: allow for some wiggle room here as wxMac's
3117 // window rect calculations seem to be imprecise
3118 if ( abs( thisWindowBottomRight
.x
- frameBottomRight
.x
) <= 2
3119 && abs( thisWindowBottomRight
.y
- frameBottomRight
.y
) <= 2 )
3121 // Parent frame has resize handle and shares
3122 // right bottom corner
3127 // Parent frame has resize handle but doesn't
3128 // share right bottom corner
3134 // Parent frame doesn't have resize handle
3140 // No parent frame found
3145 void wxWindowMac::MacCreateScrollBars( long style
)
3147 wxASSERT_MSG( m_vScrollBar
== NULL
&& m_hScrollBar
== NULL
, wxT("attempt to create window twice") ) ;
3149 if ( style
& ( wxVSCROLL
| wxHSCROLL
) )
3151 int scrlsize
= MAC_SCROLLBAR_SIZE
;
3152 if ( GetWindowVariant() == wxWINDOW_VARIANT_SMALL
|| GetWindowVariant() == wxWINDOW_VARIANT_MINI
)
3154 scrlsize
= MAC_SMALL_SCROLLBAR_SIZE
;
3157 int adjust
= MacHasScrollBarCorner() ? scrlsize
- 1: 0 ;
3159 GetClientSize( &width
, &height
) ;
3161 wxPoint
vPoint(width
- scrlsize
, 0) ;
3162 wxSize
vSize(scrlsize
, height
- adjust
) ;
3163 wxPoint
hPoint(0, height
- scrlsize
) ;
3164 wxSize
hSize(width
- adjust
, scrlsize
) ;
3166 // we have to set the min size to a smaller value, otherwise they cannot get smaller (InitialSize sets MinSize)
3167 if ( style
& wxVSCROLL
)
3169 m_vScrollBar
= new wxScrollBar((wxWindow
*)this, wxID_ANY
, vPoint
, vSize
, wxVERTICAL
);
3170 m_vScrollBar
->SetMinSize( wxDefaultSize
);
3173 if ( style
& wxHSCROLL
)
3175 m_hScrollBar
= new wxScrollBar((wxWindow
*)this, wxID_ANY
, hPoint
, hSize
, wxHORIZONTAL
);
3176 m_hScrollBar
->SetMinSize( wxDefaultSize
);
3180 // because the create does not take into account the client area origin
3181 // we might have a real position shift
3182 MacRepositionScrollBars() ;
3185 bool wxWindowMac::MacIsChildOfClientArea( const wxWindow
* child
) const
3187 bool result
= ((child
== NULL
) || ((child
!= m_hScrollBar
) && (child
!= m_vScrollBar
)));
3192 void wxWindowMac::MacRepositionScrollBars()
3194 if ( !m_hScrollBar
&& !m_vScrollBar
)
3197 int scrlsize
= m_hScrollBar
? m_hScrollBar
->GetSize().y
: ( m_vScrollBar
? m_vScrollBar
->GetSize().x
: MAC_SCROLLBAR_SIZE
) ;
3198 int adjust
= MacHasScrollBarCorner() ? scrlsize
- 1 : 0 ;
3200 // get real client area
3202 GetSize( &width
, &height
);
3204 width
-= MacGetLeftBorderSize() + MacGetRightBorderSize();
3205 height
-= MacGetTopBorderSize() + MacGetBottomBorderSize();
3207 wxPoint
vPoint( width
- scrlsize
, 0 ) ;
3208 wxSize
vSize( scrlsize
, height
- adjust
) ;
3209 wxPoint
hPoint( 0 , height
- scrlsize
) ;
3210 wxSize
hSize( width
- adjust
, scrlsize
) ;
3213 int x
= 0, y
= 0, w
, h
;
3214 GetSize( &w
, &h
) ;
3216 MacClientToRootWindow( &x
, &y
) ;
3217 MacClientToRootWindow( &w
, &h
) ;
3219 wxWindowMac
*iter
= (wxWindowMac
*)this ;
3221 int totW
= 10000 , totH
= 10000;
3224 if ( iter
->IsTopLevel() )
3226 iter
->GetSize( &totW
, &totH
) ;
3230 iter
= iter
->GetParent() ;
3244 if ( w
- x
>= totW
)
3249 if ( h
- y
>= totH
)
3257 m_vScrollBar
->SetSize( vPoint
.x
, vPoint
.y
, vSize
.x
, vSize
.y
, wxSIZE_ALLOW_MINUS_ONE
);
3259 m_hScrollBar
->SetSize( hPoint
.x
, hPoint
.y
, hSize
.x
, hSize
.y
, wxSIZE_ALLOW_MINUS_ONE
);
3262 bool wxWindowMac::AcceptsFocus() const
3264 return MacCanFocus() && wxWindowBase::AcceptsFocus();
3267 void wxWindowMac::MacSuperChangedPosition()
3269 // only window-absolute structures have to be moved i.e. controls
3271 m_cachedClippedRectValid
= false ;
3274 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
3277 child
= node
->GetData();
3278 child
->MacSuperChangedPosition() ;
3280 node
= node
->GetNext();
3284 void wxWindowMac::MacTopLevelWindowChangedPosition()
3286 // only screen-absolute structures have to be moved i.e. glcanvas
3289 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
3292 child
= node
->GetData();
3293 child
->MacTopLevelWindowChangedPosition() ;
3295 node
= node
->GetNext();
3299 long wxWindowMac::MacGetLeftBorderSize() const
3306 if (HasFlag(wxRAISED_BORDER
) || HasFlag( wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
))
3308 // this metric is only the 'outset' outside the simple frame rect
3309 GetThemeMetric( kThemeMetricEditTextFrameOutset
, &border
) ;
3312 else if (HasFlag(wxSIMPLE_BORDER
))
3314 // this metric is only the 'outset' outside the simple frame rect
3315 GetThemeMetric( kThemeMetricListBoxFrameOutset
, &border
) ;
3322 long wxWindowMac::MacGetRightBorderSize() const
3324 // they are all symmetric in mac themes
3325 return MacGetLeftBorderSize() ;
3328 long wxWindowMac::MacGetTopBorderSize() const
3330 // they are all symmetric in mac themes
3331 return MacGetLeftBorderSize() ;
3334 long wxWindowMac::MacGetBottomBorderSize() const
3336 // they are all symmetric in mac themes
3337 return MacGetLeftBorderSize() ;
3340 long wxWindowMac::MacRemoveBordersFromStyle( long style
)
3342 return style
& ~wxBORDER_MASK
;
3345 // Find the wxWindowMac at the current mouse position, returning the mouse
3347 wxWindowMac
* wxFindWindowAtPointer( wxPoint
& pt
)
3349 pt
= wxGetMousePosition();
3350 wxWindowMac
* found
= wxFindWindowAtPoint(pt
);
3355 // Get the current mouse position.
3356 wxPoint
wxGetMousePosition()
3360 wxGetMousePosition( &x
, &y
);
3362 return wxPoint(x
, y
);
3365 void wxWindowMac::OnMouseEvent( wxMouseEvent
&event
)
3367 if ( event
.GetEventType() == wxEVT_RIGHT_DOWN
)
3369 // copied from wxGTK : CS
3370 // VZ: shouldn't we move this to base class then?
3372 // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN
3375 // (a) it's a command event and so is propagated to the parent
3376 // (b) under MSW it can be generated from kbd too
3377 // (c) it uses screen coords (because of (a))
3378 wxContextMenuEvent
evtCtx(wxEVT_CONTEXT_MENU
,
3380 this->ClientToScreen(event
.GetPosition()));
3381 if ( ! GetEventHandler()->ProcessEvent(evtCtx
) )
3390 void wxWindowMac::OnPaint( wxPaintEvent
& WXUNUSED(event
) )
3392 if ( wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
3393 && GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT
)
3394 CallNextEventHandler(
3395 (EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() ,
3396 (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
3399 void wxWindowMac::MacHandleControlClick(WXWidget
WXUNUSED(control
),
3400 wxInt16
WXUNUSED(controlpart
),
3401 bool WXUNUSED(mouseStillDown
))
3405 Rect
wxMacGetBoundsForControl( wxWindow
* window
, const wxPoint
& pos
, const wxSize
&size
, bool adjustForOrigin
)
3409 window
->MacGetBoundsForControl( pos
, size
, x
, y
, w
, h
, adjustForOrigin
) ;
3410 Rect bounds
= { y
, x
, y
+ h
, x
+ w
};
3415 wxInt32
wxWindowMac::MacControlHit(WXEVENTHANDLERREF
WXUNUSED(handler
) , WXEVENTREF
WXUNUSED(event
) )
3417 return eventNotHandledErr
;
3420 bool wxWindowMac::Reparent(wxWindowBase
*newParentBase
)
3422 wxWindowMac
*newParent
= (wxWindowMac
*)newParentBase
;
3423 if ( !wxWindowBase::Reparent(newParent
) )
3426 // copied from MacPostControlCreate
3427 ControlRef container
= (ControlRef
) GetParent()->GetHandle() ;
3429 wxASSERT_MSG( container
!= NULL
, wxT("No valid mac container control") ) ;
3431 ::EmbedControl( m_peer
->GetControlRef() , container
) ;
3436 bool wxWindowMac::SetTransparent(wxByte alpha
)
3438 SetBackgroundStyle(wxBG_STYLE_TRANSPARENT
);
3440 if ( alpha
!= m_macAlpha
)
3442 m_macAlpha
= alpha
;
3449 bool wxWindowMac::CanSetTransparent()
3454 wxByte
wxWindowMac::GetTransparent() const