1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/carbon/window.cpp
3 // Purpose: wxWindowMac
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
14 #include "wx/window.h"
23 #include "wx/dcclient.h"
24 #include "wx/button.h"
26 #include "wx/dialog.h"
27 #include "wx/settings.h"
28 #include "wx/msgdlg.h"
29 #include "wx/scrolbar.h"
30 #include "wx/statbox.h"
31 #include "wx/textctrl.h"
32 #include "wx/toolbar.h"
33 #include "wx/layout.h"
34 #include "wx/statusbr.h"
35 #include "wx/menuitem.h"
36 #include "wx/treectrl.h"
37 #include "wx/listctrl.h"
40 #include "wx/tooltip.h"
41 #include "wx/spinctrl.h"
42 #include "wx/geometry.h"
45 #include "wx/listctrl.h"
49 #include "wx/treectrl.h"
56 #if wxUSE_DRAG_AND_DROP
60 #include "wx/mac/uma.h"
62 #define MAC_SCROLLBAR_SIZE 15
63 #define MAC_SMALL_SCROLLBAR_SIZE 11
67 #include <ToolUtils.h>
69 #include <MacTextEditor.h>
72 #if TARGET_API_MAC_OSX
74 #include <HIToolbox/HIView.h>
80 #ifdef __WXUNIVERSAL__
81 IMPLEMENT_ABSTRACT_CLASS(wxWindowMac
, wxWindowBase
)
83 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
86 BEGIN_EVENT_TABLE(wxWindowMac
, wxWindowBase
)
87 EVT_NC_PAINT(wxWindowMac::OnNcPaint
)
88 EVT_ERASE_BACKGROUND(wxWindowMac::OnEraseBackground
)
89 #if TARGET_API_MAC_OSX
90 EVT_PAINT(wxWindowMac::OnPaint
)
92 EVT_SET_FOCUS(wxWindowMac::OnSetFocus
)
93 EVT_KILL_FOCUS(wxWindowMac::OnSetFocus
)
94 EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent
)
97 #define wxMAC_DEBUG_REDRAW 0
98 #ifndef wxMAC_DEBUG_REDRAW
99 #define wxMAC_DEBUG_REDRAW 0
102 // ---------------------------------------------------------------------------
103 // Utility Routines to move between different coordinate systems
104 // ---------------------------------------------------------------------------
107 * Right now we have the following setup :
108 * a border that is not part of the native control is always outside the
109 * control's border (otherwise we loose all native intelligence, future ways
110 * may be to have a second embedding control responsible for drawing borders
111 * and backgrounds eventually)
112 * so all this border calculations have to be taken into account when calling
113 * native methods or getting native oriented data
114 * so we have three coordinate systems here
115 * wx client coordinates
116 * wx window coordinates (including window frames)
121 // originating from native control
125 void wxMacNativeToWindow( const wxWindow
* window
, RgnHandle handle
)
127 OffsetRgn( handle
, window
->MacGetLeftBorderSize() , window
->MacGetTopBorderSize() ) ;
130 void wxMacNativeToWindow( const wxWindow
* window
, Rect
*rect
)
132 OffsetRect( rect
, window
->MacGetLeftBorderSize() , window
->MacGetTopBorderSize() ) ;
136 // directed towards native control
139 void wxMacWindowToNative( const wxWindow
* window
, RgnHandle handle
)
141 OffsetRgn( handle
, -window
->MacGetLeftBorderSize() , -window
->MacGetTopBorderSize() );
144 void wxMacWindowToNative( const wxWindow
* window
, Rect
*rect
)
146 OffsetRect( rect
, -window
->MacGetLeftBorderSize() , -window
->MacGetTopBorderSize() ) ;
149 // ---------------------------------------------------------------------------
151 // ---------------------------------------------------------------------------
153 #if TARGET_API_MAC_OSX
155 #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3
158 kEventControlVisibilityChanged
= 157
164 static const EventTypeSpec eventList
[] =
166 { kEventClassCommand
, kEventProcessCommand
} ,
167 { kEventClassCommand
, kEventCommandUpdateStatus
} ,
169 { kEventClassControl
, kEventControlGetClickActivation
} ,
170 { kEventClassControl
, kEventControlHit
} ,
172 { kEventClassTextInput
, kEventTextInputUnicodeForKeyEvent
} ,
173 { kEventClassTextInput
, kEventTextInputUpdateActiveInputArea
} ,
175 { kEventClassControl
, kEventControlDraw
} ,
176 #if TARGET_API_MAC_OSX
177 { kEventClassControl
, kEventControlVisibilityChanged
} ,
178 { kEventClassControl
, kEventControlEnabledStateChanged
} ,
179 { kEventClassControl
, kEventControlHiliteChanged
} ,
181 { kEventClassControl
, kEventControlActivate
} ,
182 { kEventClassControl
, kEventControlDeactivate
} ,
184 { kEventClassControl
, kEventControlSetFocusPart
} ,
186 { kEventClassService
, kEventServiceGetTypes
},
187 { kEventClassService
, kEventServiceCopy
},
188 { kEventClassService
, kEventServicePaste
},
190 // { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only
191 // { kEventClassControl , kEventControlBoundsChanged } ,
194 static pascal OSStatus
wxMacWindowControlEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
196 OSStatus result
= eventNotHandledErr
;
198 wxMacCarbonEvent
cEvent( event
) ;
200 ControlRef controlRef
;
201 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
203 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
205 switch ( GetEventKind( event
) )
207 #if TARGET_API_MAC_OSX
208 case kEventControlDraw
:
210 RgnHandle updateRgn
= NULL
;
211 RgnHandle allocatedRgn
= NULL
;
212 wxRegion visRegion
= thisWindow
->MacGetVisibleRegion() ;
214 if ( cEvent
.GetParameter
<RgnHandle
>(kEventParamRgnHandle
, &updateRgn
) != noErr
)
216 updateRgn
= (RgnHandle
) visRegion
.GetWXHRGN() ;
220 if ( thisWindow
->MacGetLeftBorderSize() != 0 || thisWindow
->MacGetTopBorderSize() != 0 )
222 // as this update region is in native window locals we must adapt it to wx window local
223 allocatedRgn
= NewRgn() ;
224 CopyRgn( updateRgn
, allocatedRgn
) ;
226 // hide the given region by the new region that must be shifted
227 wxMacNativeToWindow( thisWindow
, allocatedRgn
) ;
228 updateRgn
= allocatedRgn
;
233 GetRegionBounds( updateRgn
, &rgnBounds
) ;
235 #if wxMAC_DEBUG_REDRAW
236 if ( thisWindow
->MacIsUserPane() )
238 static float color
= 0.5 ;
241 CGContextRef cgContext
= cEvent
.GetParameter
<CGContextRef
>(kEventParamCGContextRef
) ;
243 HIViewGetBounds( controlRef
, &bounds
);
244 CGContextSetRGBFillColor( cgContext
, channel
== 0 ? color
: 0.5 ,
245 channel
== 1 ? color
: 0.5 , channel
== 2 ? color
: 0.5 , 1 );
246 CGContextFillRect( cgContext
, bounds
);
259 #if wxMAC_USE_CORE_GRAPHICS
260 bool created
= false ;
261 CGContextRef cgContext
= NULL
;
262 OSStatus err
= cEvent
.GetParameter
<CGContextRef
>(kEventParamCGContextRef
, &cgContext
) ;
263 wxASSERT_MSG( err
== noErr
, wxT("Unable to retrieve CGContextRef") ) ;
264 thisWindow
->MacSetCGContextRef( cgContext
) ;
267 wxMacCGContextStateSaver
sg( cgContext
) ;
270 wxWindow
* iter
= thisWindow
;
273 alpha
*= (float) iter
->GetTransparent()/255.0 ;
274 if ( iter
->IsTopLevel() )
277 iter
= iter
->GetParent() ;
280 CGContextSetAlpha( cgContext
, alpha
) ;
282 if ( thisWindow
->GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT
)
285 HIViewGetBounds( controlRef
, &bounds
);
286 CGContextClearRect( cgContext
, bounds
);
291 if ( thisWindow
->MacDoRedraw( updateRgn
, cEvent
.GetTicks() ) )
294 #if wxMAC_USE_CORE_GRAPHICS
295 thisWindow
->MacSetCGContextRef( NULL
) ;
299 CGContextRelease( cgContext
) ;
304 DisposeRgn( allocatedRgn
) ;
308 case kEventControlVisibilityChanged
:
309 thisWindow
->MacVisibilityChanged() ;
312 case kEventControlEnabledStateChanged
:
313 thisWindow
->MacEnabledStateChanged() ;
316 case kEventControlHiliteChanged
:
317 thisWindow
->MacHiliteChanged() ;
320 case kEventControlActivate
:
321 case kEventControlDeactivate
:
322 // FIXME: we should have a virtual function for this!
324 if ( thisWindow
->IsKindOf( CLASSINFO( wxTreeCtrl
) ) )
325 thisWindow
->Refresh();
328 if ( thisWindow
->IsKindOf( CLASSINFO( wxListCtrl
) ) )
329 thisWindow
->Refresh();
332 #endif // TARGET_API_MAC_OSX
334 // we emulate this event under Carbon CFM
335 case kEventControlSetFocusPart
:
337 Boolean focusEverything
= false ;
338 ControlPartCode controlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
);
341 if ( cEvent
.GetParameter
<Boolean
>(kEventParamControlFocusEverything
, &focusEverything
) == noErr
)
346 if ( thisWindow
->MacIsUserPane() )
349 if ( controlPart
== kControlFocusNoPart
)
352 if ( thisWindow
->GetCaret() )
353 thisWindow
->GetCaret()->OnKillFocus();
356 static bool inKillFocusEvent
= false ;
358 if ( !inKillFocusEvent
)
360 inKillFocusEvent
= true ;
361 wxFocusEvent
event( wxEVT_KILL_FOCUS
, thisWindow
->GetId());
362 event
.SetEventObject(thisWindow
);
363 thisWindow
->GetEventHandler()->ProcessEvent(event
) ;
364 inKillFocusEvent
= false ;
369 // panel wants to track the window which was the last to have focus in it
370 wxChildFocusEvent
eventFocus(thisWindow
);
371 thisWindow
->GetEventHandler()->ProcessEvent(eventFocus
);
374 if ( thisWindow
->GetCaret() )
375 thisWindow
->GetCaret()->OnSetFocus();
378 wxFocusEvent
event(wxEVT_SET_FOCUS
, thisWindow
->GetId());
379 event
.SetEventObject(thisWindow
);
380 thisWindow
->GetEventHandler()->ProcessEvent(event
) ;
385 case kEventControlHit
:
386 result
= thisWindow
->MacControlHit( handler
, event
) ;
389 case kEventControlGetClickActivation
:
391 // fix to always have a proper activation for DataBrowser controls (stay in bkgnd otherwise)
392 WindowRef owner
= cEvent
.GetParameter
<WindowRef
>(kEventParamWindowRef
);
393 if ( !IsWindowActive(owner
) )
395 cEvent
.SetParameter(kEventParamClickActivation
,(UInt32
) kActivateAndIgnoreClick
) ;
408 static pascal OSStatus
409 wxMacWindowServiceEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
413 OSStatus result
= eventNotHandledErr
;
415 wxMacCarbonEvent
cEvent( event
) ;
417 ControlRef controlRef
;
418 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
419 wxTextCtrl
* textCtrl
= wxDynamicCast( thisWindow
, wxTextCtrl
) ;
420 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
422 switch ( GetEventKind( event
) )
424 case kEventServiceGetTypes
:
428 textCtrl
->GetSelection( &from
, &to
) ;
430 CFMutableArrayRef copyTypes
= 0 , pasteTypes
= 0;
432 copyTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServiceCopyTypes
, typeCFMutableArrayRef
) ;
433 if ( textCtrl
->IsEditable() )
434 pasteTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServicePasteTypes
, typeCFMutableArrayRef
) ;
436 static const OSType textDataTypes
[] = { kTXNTextData
/* , 'utxt', 'PICT', 'MooV', 'AIFF' */ };
437 for ( size_t i
= 0 ; i
< WXSIZEOF(textDataTypes
) ; ++i
)
439 CFStringRef typestring
= CreateTypeStringWithOSType(textDataTypes
[i
]);
443 CFArrayAppendValue(copyTypes
, typestring
) ;
445 CFArrayAppendValue(pasteTypes
, typestring
) ;
447 CFRelease( typestring
) ;
455 case kEventServiceCopy
:
460 textCtrl
->GetSelection( &from
, &to
) ;
461 wxString val
= textCtrl
->GetValue() ;
462 val
= val
.Mid( from
, to
- from
) ;
463 ScrapRef scrapRef
= cEvent
.GetParameter
< ScrapRef
> ( kEventParamScrapRef
, typeScrapRef
) ;
464 verify_noerr( ClearScrap( &scrapRef
) ) ;
465 verify_noerr( PutScrapFlavor( scrapRef
, kTXNTextData
, 0 , val
.length() , val
.c_str() ) ) ;
470 case kEventServicePaste
:
473 ScrapRef scrapRef
= cEvent
.GetParameter
< ScrapRef
> ( kEventParamScrapRef
, typeScrapRef
) ;
474 Size textSize
, pastedSize
;
475 verify_noerr( GetScrapFlavorSize(scrapRef
, kTXNTextData
, &textSize
) ) ;
477 char *content
= new char[textSize
] ;
478 GetScrapFlavorData(scrapRef
, kTXNTextData
, &pastedSize
, content
);
479 content
[textSize
- 1] = 0 ;
482 textCtrl
->WriteText( wxString( content
, wxConvLocal
) );
484 textCtrl
->WriteText( wxString( content
) ) ;
499 pascal OSStatus
wxMacUnicodeTextEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
501 OSStatus result
= eventNotHandledErr
;
502 wxWindowMac
* focus
= (wxWindowMac
*) data
;
504 wchar_t* uniChars
= NULL
;
505 UInt32 when
= EventTimeToTicks( GetEventTime( event
) ) ;
507 UniChar
* charBuf
= NULL
;
508 ByteCount dataSize
= 0 ;
511 if ( GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, 0 , &dataSize
, NULL
) == noErr
)
513 numChars
= dataSize
/ sizeof( UniChar
) + 1;
516 if ( (size_t) numChars
* 2 > sizeof(buf
) )
517 charBuf
= new UniChar
[ numChars
] ;
521 uniChars
= new wchar_t[ numChars
] ;
522 GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, dataSize
, NULL
, charBuf
) ;
523 charBuf
[ numChars
- 1 ] = 0;
524 #if SIZEOF_WCHAR_T == 2
525 uniChars
= (wchar_t*) charBuf
;
526 /* 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...)
528 // the resulting string will never have more chars than the utf16 version, so this is safe
529 wxMBConvUTF16 converter
;
530 numChars
= converter
.MB2WC( uniChars
, (const char*)charBuf
, numChars
) ;
534 switch ( GetEventKind( event
) )
536 case kEventTextInputUpdateActiveInputArea
:
538 // An IME input event may return several characters, but we need to send one char at a time to
540 for (int pos
=0 ; pos
< numChars
; pos
++)
542 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
543 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
544 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
546 UInt32 message
= uniChars
[pos
] < 128 ? (char)uniChars
[pos
] : '?';
548 NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
549 multiple times to update the active range during inline input, so this handler will often receive
550 uncommited text, which should usually not trigger side effects. It might be a good idea to check the
551 kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
552 On the other hand, it can be useful for some applications to react to uncommitted text (for example,
553 to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
554 should add new event types to support advanced text input. For now, I would keep things as they are.
556 However, the code that was being used caused additional problems:
557 UInt32 message = (0 << 8) + ((char)uniChars[pos] );
558 Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
559 input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
560 for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
561 (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
562 (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
563 Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
564 overlap with Unicode within the (7-bit) ASCII range.
565 But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
566 for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
567 characters as they are and replaces the rest with '?', ensuring that update events are triggered.
568 It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
569 I don't have time to look into that right now.
572 if ( wxTheApp
->MacSendCharEvent(
573 focus
, message
, 0 , when
, 0 , 0 , uniChars
[pos
] ) )
578 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
582 case kEventTextInputUnicodeForKeyEvent
:
584 UInt32 keyCode
, modifiers
;
587 unsigned char charCode
;
589 GetEventParameter( event
, kEventParamTextInputSendKeyboardEvent
, typeEventRef
, NULL
, sizeof(rawEvent
), NULL
, &rawEvent
) ;
590 GetEventParameter( rawEvent
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, sizeof(char), NULL
, &charCode
);
591 GetEventParameter( rawEvent
, kEventParamKeyCode
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
592 GetEventParameter( rawEvent
, kEventParamKeyModifiers
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &modifiers
);
593 GetEventParameter( rawEvent
, kEventParamMouseLocation
, typeQDPoint
, NULL
, sizeof(Point
), NULL
, &point
);
595 UInt32 message
= (keyCode
<< 8) + charCode
;
597 // An IME input event may return several characters, but we need to send one char at a time to
599 for (int pos
=0 ; pos
< numChars
; pos
++)
601 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
602 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
603 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
605 if ( wxTheApp
->MacSendCharEvent(
606 focus
, message
, modifiers
, when
, point
.h
, point
.v
, uniChars
[pos
] ) )
611 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
620 if ( charBuf
!= buf
)
626 static pascal OSStatus
627 wxMacWindowCommandEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
631 OSStatus result
= eventNotHandledErr
;
632 wxWindowMac
* focus
= (wxWindowMac
*) data
;
636 wxMacCarbonEvent
cEvent( event
) ;
637 cEvent
.GetParameter
<HICommand
>(kEventParamDirectObject
,typeHICommand
,&command
) ;
639 wxMenuItem
* item
= NULL
;
640 wxMenu
* itemMenu
= wxFindMenuFromMacCommand( command
, item
) ;
641 int id
= wxMacCommandToId( command
.commandID
) ;
645 wxASSERT( itemMenu
!= NULL
) ;
647 switch ( cEvent
.GetKind() )
649 case kEventProcessCommand
:
651 if (item
->IsCheckable())
652 item
->Check( !item
->IsChecked() ) ;
654 if ( itemMenu
->SendEvent( id
, item
->IsCheckable() ? item
->IsChecked() : -1 ) )
658 wxCommandEvent
event(wxEVT_COMMAND_MENU_SELECTED
, id
);
659 event
.SetEventObject(focus
);
660 event
.SetInt(item
->IsCheckable() ? item
->IsChecked() : -1);
662 if ( focus
->GetEventHandler()->ProcessEvent(event
) )
668 case kEventCommandUpdateStatus
:
670 wxUpdateUIEvent
event(id
);
671 event
.SetEventObject( itemMenu
);
673 bool processed
= false;
675 // Try the menu's event handler
677 wxEvtHandler
*handler
= itemMenu
->GetEventHandler();
679 processed
= handler
->ProcessEvent(event
);
682 // Try the window the menu was popped up from
683 // (and up through the hierarchy)
686 const wxMenuBase
*menu
= itemMenu
;
689 wxWindow
*win
= menu
->GetInvokingWindow();
692 processed
= win
->GetEventHandler()->ProcessEvent(event
);
696 menu
= menu
->GetParent();
702 processed
= focus
->GetEventHandler()->ProcessEvent(event
);
707 // if anything changed, update the changed attribute
708 if (event
.GetSetText())
709 itemMenu
->SetLabel(id
, event
.GetText());
710 if (event
.GetSetChecked())
711 itemMenu
->Check(id
, event
.GetChecked());
712 if (event
.GetSetEnabled())
713 itemMenu
->Enable(id
, event
.GetEnabled());
727 pascal OSStatus
wxMacWindowEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
729 EventRef formerEvent
= (EventRef
) wxTheApp
->MacGetCurrentEvent() ;
730 EventHandlerCallRef formerEventHandlerCallRef
= (EventHandlerCallRef
) wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
731 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
732 OSStatus result
= eventNotHandledErr
;
734 switch ( GetEventClass( event
) )
736 case kEventClassCommand
:
737 result
= wxMacWindowCommandEventHandler( handler
, event
, data
) ;
740 case kEventClassControl
:
741 result
= wxMacWindowControlEventHandler( handler
, event
, data
) ;
744 case kEventClassService
:
745 result
= wxMacWindowServiceEventHandler( handler
, event
, data
) ;
748 case kEventClassTextInput
:
749 result
= wxMacUnicodeTextEventHandler( handler
, event
, data
) ;
756 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerEventHandlerCallRef
) ;
761 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler
)
763 #if !TARGET_API_MAC_OSX
765 // ---------------------------------------------------------------------------
766 // UserPane events for non OSX builds
767 // ---------------------------------------------------------------------------
769 static pascal void wxMacControlUserPaneDrawProc(ControlRef control
, SInt16 part
)
771 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
773 win
->MacControlUserPaneDrawProc(part
) ;
775 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneDrawUPP
, wxMacControlUserPaneDrawProc
) ;
777 static pascal ControlPartCode
wxMacControlUserPaneHitTestProc(ControlRef control
, Point where
)
779 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
781 return win
->MacControlUserPaneHitTestProc(where
.h
, where
.v
) ;
783 return kControlNoPart
;
785 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneHitTestUPP
, wxMacControlUserPaneHitTestProc
) ;
787 static pascal ControlPartCode
wxMacControlUserPaneTrackingProc(ControlRef control
, Point startPt
, ControlActionUPP actionProc
)
789 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
791 return win
->MacControlUserPaneTrackingProc( startPt
.h
, startPt
.v
, (void*) actionProc
) ;
793 return kControlNoPart
;
795 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneTrackingUPP
, wxMacControlUserPaneTrackingProc
) ;
797 static pascal void wxMacControlUserPaneIdleProc(ControlRef control
)
799 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
801 win
->MacControlUserPaneIdleProc() ;
803 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneIdleUPP
, wxMacControlUserPaneIdleProc
) ;
805 static pascal ControlPartCode
wxMacControlUserPaneKeyDownProc(ControlRef control
, SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
)
807 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
809 return win
->MacControlUserPaneKeyDownProc(keyCode
,charCode
,modifiers
) ;
811 return kControlNoPart
;
813 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneKeyDownUPP
, wxMacControlUserPaneKeyDownProc
) ;
815 static pascal void wxMacControlUserPaneActivateProc(ControlRef control
, Boolean activating
)
817 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
819 win
->MacControlUserPaneActivateProc(activating
) ;
821 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneActivateUPP
, wxMacControlUserPaneActivateProc
) ;
823 static pascal ControlPartCode
wxMacControlUserPaneFocusProc(ControlRef control
, ControlFocusPart action
)
825 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
827 return win
->MacControlUserPaneFocusProc(action
) ;
829 return kControlNoPart
;
831 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneFocusUPP
, wxMacControlUserPaneFocusProc
) ;
833 static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control
, ControlBackgroundPtr info
)
835 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
837 win
->MacControlUserPaneBackgroundProc(info
) ;
839 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneBackgroundUPP
, wxMacControlUserPaneBackgroundProc
) ;
841 void wxWindowMac::MacControlUserPaneDrawProc(wxInt16 part
)
844 RgnHandle rgn
= NewRgn() ;
846 MacWindowToRootWindow( &x
, &y
) ;
847 OffsetRgn( rgn
, -x
, -y
) ;
848 wxMacWindowStateSaver
sv( this ) ;
849 SectRgn( rgn
, (RgnHandle
) MacGetVisibleRegion().GetWXHRGN() , rgn
) ;
850 MacDoRedraw( rgn
, 0 ) ;
854 wxInt16
wxWindowMac::MacControlUserPaneHitTestProc(wxInt16 x
, wxInt16 y
)
856 return kControlNoPart
;
859 wxInt16
wxWindowMac::MacControlUserPaneTrackingProc(wxInt16 x
, wxInt16 y
, void* actionProc
)
861 return kControlNoPart
;
864 void wxWindowMac::MacControlUserPaneIdleProc()
868 wxInt16
wxWindowMac::MacControlUserPaneKeyDownProc(wxInt16 keyCode
, wxInt16 charCode
, wxInt16 modifiers
)
870 return kControlNoPart
;
873 void wxWindowMac::MacControlUserPaneActivateProc(bool activating
)
877 wxInt16
wxWindowMac::MacControlUserPaneFocusProc(wxInt16 action
)
879 if ( AcceptsFocus() )
882 return kControlNoPart
;
885 void wxWindowMac::MacControlUserPaneBackgroundProc(void* info
)
891 // ---------------------------------------------------------------------------
892 // Scrollbar Tracking for all
893 // ---------------------------------------------------------------------------
895 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
) ;
896 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
)
900 wxWindow
* wx
= wxFindControlFromMacControl( control
) ;
902 wx
->MacHandleControlClick( (WXWidget
) control
, partCode
, true /* stillDown */ ) ;
905 wxMAC_DEFINE_PROC_GETTER( ControlActionUPP
, wxMacLiveScrollbarActionProc
) ;
907 // ===========================================================================
909 // ===========================================================================
911 WX_DECLARE_HASH_MAP(ControlRef
, wxWindow
*, wxPointerHash
, wxPointerEqual
, MacControlMap
);
913 static MacControlMap wxWinMacControlList
;
915 wxWindow
*wxFindControlFromMacControl(ControlRef inControl
)
917 MacControlMap::iterator node
= wxWinMacControlList
.find(inControl
);
919 return (node
== wxWinMacControlList
.end()) ? NULL
: node
->second
;
922 void wxAssociateControlWithMacControl(ControlRef inControl
, wxWindow
*control
)
924 // adding NULL ControlRef is (first) surely a result of an error and
925 // (secondly) breaks native event processing
926 wxCHECK_RET( inControl
!= (ControlRef
) NULL
, wxT("attempt to add a NULL WindowRef to window list") );
928 wxWinMacControlList
[inControl
] = control
;
931 void wxRemoveMacControlAssociation(wxWindow
*control
)
933 // iterate over all the elements in the class
934 // is the iterator stable ? as we might have two associations pointing to the same wxWindow
935 // we should go on...
941 MacControlMap::iterator it
;
942 for ( it
= wxWinMacControlList
.begin(); it
!= wxWinMacControlList
.end(); ++it
)
944 if ( it
->second
== control
)
946 wxWinMacControlList
.erase(it
);
954 // ----------------------------------------------------------------------------
955 // constructors and such
956 // ----------------------------------------------------------------------------
958 wxWindowMac::wxWindowMac()
963 wxWindowMac::wxWindowMac(wxWindowMac
*parent
,
968 const wxString
& name
)
971 Create(parent
, id
, pos
, size
, style
, name
);
974 void wxWindowMac::Init()
980 #if wxMAC_USE_CORE_GRAPHICS
981 m_cgContextRef
= NULL
;
984 // as all windows are created with WS_VISIBLE style...
987 m_hScrollBar
= NULL
;
988 m_vScrollBar
= NULL
;
989 m_hScrollBarAlwaysShown
= false;
990 m_vScrollBarAlwaysShown
= false;
992 m_macBackgroundBrush
= wxNullBrush
;
994 m_macIsUserPane
= true;
995 m_clipChildren
= false ;
996 m_cachedClippedRectValid
= false ;
998 // we need a valid font for the encodings
999 wxWindowBase::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
1002 wxWindowMac::~wxWindowMac()
1006 m_isBeingDeleted
= true;
1008 MacInvalidateBorders() ;
1010 #ifndef __WXUNIVERSAL__
1011 // VS: make sure there's no wxFrame with last focus set to us:
1012 for ( wxWindow
*win
= GetParent(); win
; win
= win
->GetParent() )
1014 wxFrame
*frame
= wxDynamicCast(win
, wxFrame
);
1017 if ( frame
->GetLastFocus() == this )
1018 frame
->SetLastFocus((wxWindow
*)NULL
);
1024 // destroy children before destroying this window itself
1027 // wxRemoveMacControlAssociation( this ) ;
1028 // If we delete an item, we should initialize the parent panel,
1029 // because it could now be invalid.
1030 wxTopLevelWindow
*tlw
= wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow
);
1033 if ( tlw
->GetDefaultItem() == (wxButton
*) this)
1034 tlw
->SetDefaultItem(NULL
);
1037 if ( m_peer
&& m_peer
->Ok() )
1039 // in case the callback might be called during destruction
1040 wxRemoveMacControlAssociation( this) ;
1041 ::RemoveEventHandler( (EventHandlerRef
) m_macControlEventHandler
) ;
1042 // we currently are not using this hook
1043 // ::SetControlColorProc( *m_peer , NULL ) ;
1047 if ( g_MacLastWindow
== this )
1048 g_MacLastWindow
= NULL
;
1050 wxFrame
* frame
= wxDynamicCast( wxGetTopLevelParent( this ) , wxFrame
) ;
1053 if ( frame
->GetLastFocus() == this )
1054 frame
->SetLastFocus( NULL
) ;
1057 // delete our drop target if we've got one
1058 #if wxUSE_DRAG_AND_DROP
1059 if ( m_dropTarget
!= NULL
)
1061 delete m_dropTarget
;
1062 m_dropTarget
= NULL
;
1069 WXWidget
wxWindowMac::GetHandle() const
1071 return (WXWidget
) m_peer
->GetControlRef() ;
1074 void wxWindowMac::MacInstallEventHandler( WXWidget control
)
1076 wxAssociateControlWithMacControl( (ControlRef
) control
, this ) ;
1077 InstallControlEventHandler( (ControlRef
)control
, GetwxMacWindowEventHandlerUPP(),
1078 GetEventTypeCount(eventList
), eventList
, this,
1079 (EventHandlerRef
*)&m_macControlEventHandler
);
1081 #if !TARGET_API_MAC_OSX
1082 if ( (ControlRef
) control
== m_peer
->GetControlRef() )
1084 m_peer
->SetData
<ControlUserPaneDrawUPP
>(kControlEntireControl
, kControlUserPaneDrawProcTag
, GetwxMacControlUserPaneDrawProc()) ;
1085 m_peer
->SetData
<ControlUserPaneHitTestUPP
>(kControlEntireControl
, kControlUserPaneHitTestProcTag
, GetwxMacControlUserPaneHitTestProc()) ;
1086 m_peer
->SetData
<ControlUserPaneTrackingUPP
>(kControlEntireControl
, kControlUserPaneTrackingProcTag
, GetwxMacControlUserPaneTrackingProc()) ;
1087 m_peer
->SetData
<ControlUserPaneIdleUPP
>(kControlEntireControl
, kControlUserPaneIdleProcTag
, GetwxMacControlUserPaneIdleProc()) ;
1088 m_peer
->SetData
<ControlUserPaneKeyDownUPP
>(kControlEntireControl
, kControlUserPaneKeyDownProcTag
, GetwxMacControlUserPaneKeyDownProc()) ;
1089 m_peer
->SetData
<ControlUserPaneActivateUPP
>(kControlEntireControl
, kControlUserPaneActivateProcTag
, GetwxMacControlUserPaneActivateProc()) ;
1090 m_peer
->SetData
<ControlUserPaneFocusUPP
>(kControlEntireControl
, kControlUserPaneFocusProcTag
, GetwxMacControlUserPaneFocusProc()) ;
1091 m_peer
->SetData
<ControlUserPaneBackgroundUPP
>(kControlEntireControl
, kControlUserPaneBackgroundProcTag
, GetwxMacControlUserPaneBackgroundProc()) ;
1097 bool wxWindowMac::Create(wxWindowMac
*parent
,
1102 const wxString
& name
)
1104 wxCHECK_MSG( parent
, false, wxT("can't create wxWindowMac without parent") );
1106 if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) )
1109 m_windowVariant
= parent
->GetWindowVariant() ;
1111 if ( m_macIsUserPane
)
1113 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
) ;
1116 | kControlSupportsEmbedding
1117 | kControlSupportsLiveFeedback
1118 | kControlGetsFocusOnClick
1119 // | kControlHasSpecialBackground
1120 // | kControlSupportsCalcBestRect
1121 | kControlHandlesTracking
1122 | kControlSupportsFocus
1123 | kControlWantsActivate
1124 | kControlWantsIdle
;
1126 m_peer
= new wxMacControl(this) ;
1127 OSStatus err
=::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds
, features
, m_peer
->GetControlRefAddr() );
1128 verify_noerr( err
);
1130 MacPostControlCreate(pos
, size
) ;
1133 #ifndef __WXUNIVERSAL__
1134 // Don't give scrollbars to wxControls unless they ask for them
1135 if ( (! IsKindOf(CLASSINFO(wxControl
)) && ! IsKindOf(CLASSINFO(wxStatusBar
)))
1136 || (IsKindOf(CLASSINFO(wxControl
)) && ((style
& wxHSCROLL
) || (style
& wxVSCROLL
))))
1138 MacCreateScrollBars( style
) ;
1142 wxWindowCreateEvent
event(this);
1143 GetEventHandler()->AddPendingEvent(event
);
1148 void wxWindowMac::MacChildAdded()
1151 m_vScrollBar
->Raise() ;
1153 m_hScrollBar
->Raise() ;
1156 void wxWindowMac::MacPostControlCreate(const wxPoint
& WXUNUSED(pos
), const wxSize
& size
)
1158 wxASSERT_MSG( m_peer
!= NULL
&& m_peer
->Ok() , wxT("No valid mac control") ) ;
1160 m_peer
->SetReference( (URefCon
) this ) ;
1161 GetParent()->AddChild( this );
1163 MacInstallEventHandler( (WXWidget
) m_peer
->GetControlRef() );
1165 ControlRef container
= (ControlRef
) GetParent()->GetHandle() ;
1166 wxASSERT_MSG( container
!= NULL
, wxT("No valid mac container control") ) ;
1167 ::EmbedControl( m_peer
->GetControlRef() , container
) ;
1168 GetParent()->MacChildAdded() ;
1170 // adjust font, controlsize etc
1171 DoSetWindowVariant( m_windowVariant
) ;
1173 m_peer
->SetLabel( wxStripMenuCodes(m_label
, wxStrip_Mnemonics
) ) ;
1175 if (!m_macIsUserPane
)
1176 SetInitialSize(size
);
1178 SetCursor( *wxSTANDARD_CURSOR
) ;
1181 void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant
)
1183 // Don't assert, in case we set the window variant before
1184 // the window is created
1185 // wxASSERT( m_peer->Ok() ) ;
1187 m_windowVariant
= variant
;
1189 if (m_peer
== NULL
|| !m_peer
->Ok())
1193 ThemeFontID themeFont
= kThemeSystemFont
;
1195 // we will get that from the settings later
1196 // and make this NORMAL later, but first
1197 // we have a few calculations that we must fix
1201 case wxWINDOW_VARIANT_NORMAL
:
1202 size
= kControlSizeNormal
;
1203 themeFont
= kThemeSystemFont
;
1206 case wxWINDOW_VARIANT_SMALL
:
1207 size
= kControlSizeSmall
;
1208 themeFont
= kThemeSmallSystemFont
;
1211 case wxWINDOW_VARIANT_MINI
:
1212 if (UMAGetSystemVersion() >= 0x1030 )
1214 // not always defined in the headers
1220 size
= kControlSizeSmall
;
1221 themeFont
= kThemeSmallSystemFont
;
1225 case wxWINDOW_VARIANT_LARGE
:
1226 size
= kControlSizeLarge
;
1227 themeFont
= kThemeSystemFont
;
1231 wxFAIL_MSG(_T("unexpected window variant"));
1235 m_peer
->SetData
<ControlSize
>(kControlEntireControl
, kControlSizeTag
, &size
) ;
1238 font
.MacCreateThemeFont( themeFont
) ;
1242 void wxWindowMac::MacUpdateControlFont()
1244 m_peer
->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ;
1248 bool wxWindowMac::SetFont(const wxFont
& font
)
1250 bool retval
= wxWindowBase::SetFont( font
);
1252 MacUpdateControlFont() ;
1257 bool wxWindowMac::SetForegroundColour(const wxColour
& col
)
1259 bool retval
= wxWindowBase::SetForegroundColour( col
);
1262 MacUpdateControlFont();
1267 bool wxWindowMac::SetBackgroundColour(const wxColour
& col
)
1269 if ( !wxWindowBase::SetBackgroundColour(col
) && m_hasBgCol
)
1273 wxColour
newCol(GetBackgroundColour());
1275 if ( newCol
== wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW
) )
1276 brush
.MacSetTheme( kThemeBrushDocumentWindowBackground
) ;
1277 else if ( newCol
== wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE
) )
1278 brush
.MacSetTheme( kThemeBrushDialogBackgroundActive
) ;
1280 brush
.SetColour( newCol
) ;
1282 MacSetBackgroundBrush( brush
) ;
1283 MacUpdateControlFont() ;
1288 void wxWindowMac::MacSetBackgroundBrush( const wxBrush
&brush
)
1290 m_macBackgroundBrush
= brush
;
1291 m_peer
->SetBackground( brush
) ;
1294 bool wxWindowMac::MacCanFocus() const
1296 // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so
1297 // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning,
1298 // but the value range is nowhere documented
1299 Boolean keyExistsAndHasValidFormat
;
1300 CFIndex fullKeyboardAccess
= CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) ,
1301 kCFPreferencesCurrentApplication
, &keyExistsAndHasValidFormat
);
1303 if ( keyExistsAndHasValidFormat
&& fullKeyboardAccess
> 0 )
1309 UInt32 features
= 0 ;
1310 m_peer
->GetFeatures( &features
) ;
1312 return features
& ( kControlSupportsFocus
| kControlGetsFocusOnClick
) ;
1316 void wxWindowMac::SetFocus()
1318 if ( !AcceptsFocus() )
1321 wxWindow
* former
= FindFocus() ;
1322 if ( former
== this )
1325 // as we cannot rely on the control features to find out whether we are in full keyboard mode,
1326 // we can only leave in case of an error
1327 OSStatus err
= m_peer
->SetFocus( kControlFocusNextPart
) ;
1328 if ( err
== errCouldntSetFocus
)
1331 SetUserFocusWindow( (WindowRef
)MacGetTopLevelWindowRef() );
1333 #if !TARGET_API_MAC_OSX
1334 // emulate carbon events when running under CarbonLib where they are not natively available
1337 EventRef evRef
= NULL
;
1339 err
= MacCreateEvent(
1340 NULL
, kEventClassControl
, kEventControlSetFocusPart
, TicksToEventTime( TickCount() ) ,
1341 kEventAttributeUserEvent
, &evRef
);
1342 verify_noerr( err
);
1344 wxMacCarbonEvent
cEvent( evRef
) ;
1345 cEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, (ControlRef
) former
->GetHandle() ) ;
1346 cEvent
.SetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
, kControlFocusNoPart
) ;
1348 wxMacWindowEventHandler( NULL
, evRef
, former
) ;
1349 ReleaseEvent( evRef
) ;
1352 // send new focus event
1354 EventRef evRef
= NULL
;
1356 err
= MacCreateEvent(
1357 NULL
, kEventClassControl
, kEventControlSetFocusPart
, TicksToEventTime( TickCount() ) ,
1358 kEventAttributeUserEvent
, &evRef
);
1359 verify_noerr( err
);
1361 wxMacCarbonEvent
cEvent( evRef
) ;
1362 cEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, (ControlRef
) GetHandle() ) ;
1363 cEvent
.SetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
, kControlFocusNextPart
) ;
1365 wxMacWindowEventHandler( NULL
, evRef
, this ) ;
1366 ReleaseEvent( evRef
) ;
1371 void wxWindowMac::DoCaptureMouse()
1373 wxApp::s_captureWindow
= this ;
1376 wxWindow
* wxWindowBase::GetCapture()
1378 return wxApp::s_captureWindow
;
1381 void wxWindowMac::DoReleaseMouse()
1383 wxApp::s_captureWindow
= NULL
;
1386 #if wxUSE_DRAG_AND_DROP
1388 void wxWindowMac::SetDropTarget(wxDropTarget
*pDropTarget
)
1390 if ( m_dropTarget
!= NULL
)
1391 delete m_dropTarget
;
1393 m_dropTarget
= pDropTarget
;
1394 if ( m_dropTarget
!= NULL
)
1402 // Old-style File Manager Drag & Drop
1403 void wxWindowMac::DragAcceptFiles(bool WXUNUSED(accept
))
1408 // Returns the size of the native control. In the case of the toplevel window
1409 // this is the content area root control
1411 void wxWindowMac::MacGetPositionAndSizeFromControl(int& WXUNUSED(x
),
1414 int& WXUNUSED(h
)) const
1416 wxFAIL_MSG( wxT("Not currently supported") ) ;
1419 // From a wx position / size calculate the appropriate size of the native control
1421 bool wxWindowMac::MacGetBoundsForControl(
1425 int& w
, int& h
, bool adjustOrigin
) const
1427 // the desired size, minus the border pixels gives the correct size of the control
1431 // TODO: the default calls may be used as soon as PostCreateControl Is moved here
1432 w
= wxMax(size
.x
, 0) ; // WidthDefault( size.x );
1433 h
= wxMax(size
.y
, 0) ; // HeightDefault( size.y ) ;
1435 x
+= MacGetLeftBorderSize() ;
1436 y
+= MacGetTopBorderSize() ;
1437 w
-= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1438 h
-= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1441 AdjustForParentClientOrigin( x
, y
) ;
1443 // this is in window relative coordinate, as this parent may have a border, its physical position is offset by this border
1444 if ( !GetParent()->IsTopLevel() )
1446 x
-= GetParent()->MacGetLeftBorderSize() ;
1447 y
-= GetParent()->MacGetTopBorderSize() ;
1453 // Get window size (not client size)
1454 void wxWindowMac::DoGetSize(int *x
, int *y
) const
1457 m_peer
->GetRect( &bounds
) ;
1460 *x
= bounds
.right
- bounds
.left
+ MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1462 *y
= bounds
.bottom
- bounds
.top
+ MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1465 // get the position of the bounds of this window in client coordinates of its parent
1466 void wxWindowMac::DoGetPosition(int *x
, int *y
) const
1469 m_peer
->GetRect( &bounds
) ;
1471 int x1
= bounds
.left
;
1472 int y1
= bounds
.top
;
1474 // get the wx window position from the native one
1475 x1
-= MacGetLeftBorderSize() ;
1476 y1
-= MacGetTopBorderSize() ;
1478 if ( !IsTopLevel() )
1480 wxWindow
*parent
= GetParent();
1483 // we must first adjust it to be in window coordinates of the parent,
1484 // as otherwise it gets lost by the ClientAreaOrigin fix
1485 x1
+= parent
->MacGetLeftBorderSize() ;
1486 y1
+= parent
->MacGetTopBorderSize() ;
1488 // and now to client coordinates
1489 wxPoint
pt(parent
->GetClientAreaOrigin());
1501 void wxWindowMac::DoScreenToClient(int *x
, int *y
) const
1503 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
1504 wxCHECK_RET( window
, wxT("TopLevel Window missing") ) ;
1506 Point localwhere
= { 0, 0 } ;
1513 wxMacGlobalToLocal( window
, &localwhere
) ;
1520 MacRootWindowToWindow( x
, y
) ;
1522 wxPoint origin
= GetClientAreaOrigin() ;
1529 void wxWindowMac::DoClientToScreen(int *x
, int *y
) const
1531 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
1532 wxCHECK_RET( window
, wxT("TopLevel window missing") ) ;
1534 wxPoint origin
= GetClientAreaOrigin() ;
1540 MacWindowToRootWindow( x
, y
) ;
1542 Point localwhere
= { 0, 0 };
1548 wxMacLocalToGlobal( window
, &localwhere
) ;
1556 void wxWindowMac::MacClientToRootWindow( int *x
, int *y
) const
1558 wxPoint origin
= GetClientAreaOrigin() ;
1564 MacWindowToRootWindow( x
, y
) ;
1567 void wxWindowMac::MacRootWindowToClient( int *x
, int *y
) const
1569 MacRootWindowToWindow( x
, y
) ;
1571 wxPoint origin
= GetClientAreaOrigin() ;
1578 void wxWindowMac::MacWindowToRootWindow( int *x
, int *y
) const
1587 if ( !IsTopLevel() )
1589 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
1592 pt
.x
-= MacGetLeftBorderSize() ;
1593 pt
.y
-= MacGetTopBorderSize() ;
1594 wxMacControl::Convert( &pt
, m_peer
, top
->m_peer
) ;
1604 void wxWindowMac::MacWindowToRootWindow( short *x
, short *y
) const
1613 MacWindowToRootWindow( &x1
, &y1
) ;
1621 void wxWindowMac::MacRootWindowToWindow( int *x
, int *y
) const
1630 if ( !IsTopLevel() )
1632 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
1635 wxMacControl::Convert( &pt
, top
->m_peer
, m_peer
) ;
1636 pt
.x
+= MacGetLeftBorderSize() ;
1637 pt
.y
+= MacGetTopBorderSize() ;
1647 void wxWindowMac::MacRootWindowToWindow( short *x
, short *y
) const
1656 MacRootWindowToWindow( &x1
, &y1
) ;
1664 void wxWindowMac::MacGetContentAreaInset( int &left
, int &top
, int &right
, int &bottom
)
1666 RgnHandle rgn
= NewRgn() ;
1668 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1670 Rect structure
, content
;
1672 GetRegionBounds( rgn
, &content
) ;
1673 m_peer
->GetRect( &structure
) ;
1674 OffsetRect( &structure
, -structure
.left
, -structure
.top
) ;
1676 left
= content
.left
- structure
.left
;
1677 top
= content
.top
- structure
.top
;
1678 right
= structure
.right
- content
.right
;
1679 bottom
= structure
.bottom
- content
.bottom
;
1683 left
= top
= right
= bottom
= 0 ;
1689 wxSize
wxWindowMac::DoGetSizeFromClientSize( const wxSize
& size
) const
1691 wxSize sizeTotal
= size
;
1693 RgnHandle rgn
= NewRgn() ;
1694 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1696 Rect content
, structure
;
1697 GetRegionBounds( rgn
, &content
) ;
1698 m_peer
->GetRect( &structure
) ;
1700 // structure is in parent coordinates, but we only need width and height, so it's ok
1702 sizeTotal
.x
+= (structure
.right
- structure
.left
) - (content
.right
- content
.left
) ;
1703 sizeTotal
.y
+= (structure
.bottom
- structure
.top
) - (content
.bottom
- content
.top
) ;
1708 sizeTotal
.x
+= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1709 sizeTotal
.y
+= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1714 // Get size *available for subwindows* i.e. excluding menu bar etc.
1715 void wxWindowMac::DoGetClientSize( int *x
, int *y
) const
1719 RgnHandle rgn
= NewRgn() ;
1721 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1722 GetRegionBounds( rgn
, &content
) ;
1724 m_peer
->GetRect( &content
) ;
1727 ww
= content
.right
- content
.left
;
1728 hh
= content
.bottom
- content
.top
;
1730 if (m_hScrollBar
&& m_hScrollBar
->IsShown() )
1731 hh
-= m_hScrollBar
->GetSize().y
;
1733 if (m_vScrollBar
&& m_vScrollBar
->IsShown() )
1734 ww
-= m_vScrollBar
->GetSize().x
;
1742 bool wxWindowMac::SetCursor(const wxCursor
& cursor
)
1744 if (m_cursor
.IsSameAs(cursor
))
1749 if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR
) )
1754 if ( ! wxWindowBase::SetCursor( cursor
) )
1758 wxASSERT_MSG( m_cursor
.Ok(),
1759 wxT("cursor must be valid after call to the base version"));
1761 wxWindowMac
*mouseWin
= 0 ;
1763 wxTopLevelWindowMac
*tlw
= MacGetTopLevelWindow() ;
1764 WindowRef window
= (WindowRef
) ( tlw
? tlw
->MacGetWindowRef() : 0 ) ;
1766 ControlPartCode part
;
1767 ControlRef control
;
1769 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
1771 HIGetMousePosition(kHICoordSpaceWindow
, window
, &hiPoint
);
1776 Boolean swapped
= QDSwapPort( GetWindowPort( window
) , &savePort
) ;
1778 // TODO: If we ever get a GetCurrentEvent... replacement
1779 // for the mouse position, use it...
1784 control
= wxMacFindControlUnderMouse( tlw
, pt
, window
, &part
) ;
1786 mouseWin
= wxFindControlFromMacControl( control
) ;
1788 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
1790 QDSwapPort( savePort
, NULL
) ;
1794 if ( mouseWin
== this && !wxIsBusy() )
1795 m_cursor
.MacInstall() ;
1801 bool wxWindowMac::DoPopupMenu(wxMenu
*menu
, int x
, int y
)
1803 menu
->SetInvokingWindow(this);
1806 if ( x
== wxDefaultCoord
&& y
== wxDefaultCoord
)
1808 wxPoint mouse
= wxGetMousePosition();
1814 ClientToScreen( &x
, &y
) ;
1817 menu
->MacBeforeDisplay( true ) ;
1818 long menuResult
= ::PopUpMenuSelect((MenuHandle
) menu
->GetHMenu() , y
, x
, 0) ;
1819 if ( HiWord(menuResult
) != 0 )
1822 GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult
)) , LoWord(menuResult
) , &macid
);
1823 int id
= wxMacCommandToId( macid
);
1824 wxMenuItem
* item
= NULL
;
1826 item
= menu
->FindItem( id
, &realmenu
) ;
1829 if (item
->IsCheckable())
1830 item
->Check( !item
->IsChecked() ) ;
1832 menu
->SendEvent( id
, item
->IsCheckable() ? item
->IsChecked() : -1 ) ;
1836 menu
->MacAfterDisplay( true ) ;
1837 menu
->SetInvokingWindow( NULL
);
1843 // ----------------------------------------------------------------------------
1845 // ----------------------------------------------------------------------------
1849 void wxWindowMac::DoSetToolTip(wxToolTip
*tooltip
)
1851 wxWindowBase::DoSetToolTip(tooltip
);
1854 m_tooltip
->SetWindow(this);
1859 void wxWindowMac::MacInvalidateBorders()
1861 if ( m_peer
== NULL
)
1864 bool vis
= MacIsReallyShown() ;
1868 int outerBorder
= MacGetLeftBorderSize() ;
1869 if ( m_peer
->NeedsFocusRect() && m_peer
->HasFocus() )
1872 if ( outerBorder
== 0 )
1875 // now we know that we have something to do at all
1877 // as the borders are drawn on the parent we have to properly invalidate all these areas
1878 RgnHandle updateInner
, updateOuter
;
1881 // this rectangle is in HIViewCoordinates under OSX and in Window Coordinates under Carbon
1882 updateInner
= NewRgn() ;
1883 updateOuter
= NewRgn() ;
1885 m_peer
->GetRect( &rect
) ;
1886 RectRgn( updateInner
, &rect
) ;
1887 InsetRect( &rect
, -outerBorder
, -outerBorder
) ;
1888 RectRgn( updateOuter
, &rect
) ;
1889 DiffRgn( updateOuter
, updateInner
, updateOuter
) ;
1891 #ifdef __WXMAC_OSX__
1892 GetParent()->m_peer
->SetNeedsDisplay( updateOuter
) ;
1894 WindowRef tlw
= (WindowRef
) MacGetTopLevelWindowRef() ;
1896 InvalWindowRgn( tlw
, updateOuter
) ;
1899 DisposeRgn( updateOuter
) ;
1900 DisposeRgn( updateInner
) ;
1903 void wxWindowMac::DoMoveWindow(int x
, int y
, int width
, int height
)
1905 // this is never called for a toplevel window, so we know we have a parent
1906 int former_x
, former_y
, former_w
, former_h
;
1908 // Get true coordinates of former position
1909 DoGetPosition( &former_x
, &former_y
) ;
1910 DoGetSize( &former_w
, &former_h
) ;
1912 wxWindow
*parent
= GetParent();
1915 wxPoint
pt(parent
->GetClientAreaOrigin());
1920 int actualWidth
= width
;
1921 int actualHeight
= height
;
1925 if ((m_minWidth
!= -1) && (actualWidth
< m_minWidth
))
1926 actualWidth
= m_minWidth
;
1927 if ((m_minHeight
!= -1) && (actualHeight
< m_minHeight
))
1928 actualHeight
= m_minHeight
;
1929 if ((m_maxWidth
!= -1) && (actualWidth
> m_maxWidth
))
1930 actualWidth
= m_maxWidth
;
1931 if ((m_maxHeight
!= -1) && (actualHeight
> m_maxHeight
))
1932 actualHeight
= m_maxHeight
;
1934 bool doMove
= false, doResize
= false ;
1936 if ( actualX
!= former_x
|| actualY
!= former_y
)
1939 if ( actualWidth
!= former_w
|| actualHeight
!= former_h
)
1942 if ( doMove
|| doResize
)
1944 // as the borders are drawn outside the native control, we adjust now
1946 wxRect
bounds( wxPoint( actualX
+ MacGetLeftBorderSize() ,actualY
+ MacGetTopBorderSize() ),
1947 wxSize( actualWidth
- (MacGetLeftBorderSize() + MacGetRightBorderSize()) ,
1948 actualHeight
- (MacGetTopBorderSize() + MacGetBottomBorderSize()) ) ) ;
1951 wxMacRectToNative( &bounds
, &r
) ;
1953 if ( !GetParent()->IsTopLevel() )
1954 wxMacWindowToNative( GetParent() , &r
) ;
1956 MacInvalidateBorders() ;
1958 m_cachedClippedRectValid
= false ;
1959 m_peer
->SetRect( &r
) ;
1961 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
1963 MacInvalidateBorders() ;
1965 MacRepositionScrollBars() ;
1968 wxPoint
point(actualX
, actualY
);
1969 wxMoveEvent
event(point
, m_windowId
);
1970 event
.SetEventObject(this);
1971 GetEventHandler()->ProcessEvent(event
) ;
1976 MacRepositionScrollBars() ;
1977 wxSize
size(actualWidth
, actualHeight
);
1978 wxSizeEvent
event(size
, m_windowId
);
1979 event
.SetEventObject(this);
1980 GetEventHandler()->ProcessEvent(event
);
1985 wxSize
wxWindowMac::DoGetBestSize() const
1987 if ( m_macIsUserPane
|| IsTopLevel() )
1988 return wxWindowBase::DoGetBestSize() ;
1990 Rect bestsize
= { 0 , 0 , 0 , 0 } ;
1991 int bestWidth
, bestHeight
;
1993 m_peer
->GetBestRect( &bestsize
) ;
1994 if ( EmptyRect( &bestsize
) )
1999 bestsize
.bottom
= 16 ;
2001 if ( IsKindOf( CLASSINFO( wxScrollBar
) ) )
2003 bestsize
.bottom
= 16 ;
2006 else if ( IsKindOf( CLASSINFO( wxSpinButton
) ) )
2008 bestsize
.bottom
= 24 ;
2013 // return wxWindowBase::DoGetBestSize() ;
2017 bestWidth
= bestsize
.right
- bestsize
.left
;
2018 bestHeight
= bestsize
.bottom
- bestsize
.top
;
2019 if ( bestHeight
< 10 )
2022 return wxSize(bestWidth
, bestHeight
);
2025 // set the size of the window: if the dimensions are positive, just use them,
2026 // but if any of them is equal to -1, it means that we must find the value for
2027 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
2028 // which case -1 is a valid value for x and y)
2030 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
2031 // the width/height to best suit our contents, otherwise we reuse the current
2033 void wxWindowMac::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
2035 // get the current size and position...
2036 int currentX
, currentY
;
2037 int currentW
, currentH
;
2039 GetPosition(¤tX
, ¤tY
);
2040 GetSize(¤tW
, ¤tH
);
2042 // ... and don't do anything (avoiding flicker) if it's already ok
2043 if ( x
== currentX
&& y
== currentY
&&
2044 width
== currentW
&& height
== currentH
&& ( height
!= -1 && width
!= -1 ) )
2047 MacRepositionScrollBars() ; // we might have a real position shift
2052 if ( !(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) )
2054 if ( x
== wxDefaultCoord
)
2056 if ( y
== wxDefaultCoord
)
2060 AdjustForParentClientOrigin( x
, y
, sizeFlags
);
2062 wxSize size
= wxDefaultSize
;
2063 if ( width
== wxDefaultCoord
)
2065 if ( sizeFlags
& wxSIZE_AUTO_WIDTH
)
2067 size
= DoGetBestSize();
2072 // just take the current one
2077 if ( height
== wxDefaultCoord
)
2079 if ( sizeFlags
& wxSIZE_AUTO_HEIGHT
)
2081 if ( size
.x
== wxDefaultCoord
)
2082 size
= DoGetBestSize();
2083 // else: already called DoGetBestSize() above
2089 // just take the current one
2094 DoMoveWindow( x
, y
, width
, height
);
2097 wxPoint
wxWindowMac::GetClientAreaOrigin() const
2099 RgnHandle rgn
= NewRgn() ;
2101 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
2103 GetRegionBounds( rgn
, &content
) ;
2113 return wxPoint( content
.left
+ MacGetLeftBorderSize() , content
.top
+ MacGetTopBorderSize() );
2116 void wxWindowMac::DoSetClientSize(int clientwidth
, int clientheight
)
2118 if ( clientwidth
!= wxDefaultCoord
|| clientheight
!= wxDefaultCoord
)
2120 int currentclientwidth
, currentclientheight
;
2121 int currentwidth
, currentheight
;
2123 GetClientSize( ¤tclientwidth
, ¤tclientheight
) ;
2124 GetSize( ¤twidth
, ¤theight
) ;
2126 DoSetSize( wxDefaultCoord
, wxDefaultCoord
, currentwidth
+ clientwidth
- currentclientwidth
,
2127 currentheight
+ clientheight
- currentclientheight
, wxSIZE_USE_EXISTING
) ;
2131 void wxWindowMac::SetLabel(const wxString
& title
)
2133 m_label
= wxStripMenuCodes(title
, wxStrip_Mnemonics
) ;
2135 if ( m_peer
&& m_peer
->Ok() )
2136 m_peer
->SetLabel( m_label
) ;
2141 wxString
wxWindowMac::GetLabel() const
2146 bool wxWindowMac::Show(bool show
)
2148 bool former
= MacIsReallyShown() ;
2149 if ( !wxWindowBase::Show(show
) )
2152 // TODO: use visibilityChanged Carbon Event for OSX
2154 m_peer
->SetVisibility( show
, true ) ;
2156 if ( former
!= MacIsReallyShown() )
2157 MacPropagateVisibilityChanged() ;
2162 void wxWindowMac::DoEnable(bool enable
)
2164 m_peer
->Enable( enable
) ;
2168 // status change propagations (will be not necessary for OSX later )
2171 void wxWindowMac::MacPropagateVisibilityChanged()
2173 #if !TARGET_API_MAC_OSX
2174 MacVisibilityChanged() ;
2177 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
2180 child
= node
->GetData();
2181 if ( child
->IsShown() )
2182 child
->MacPropagateVisibilityChanged() ;
2184 node
= node
->GetNext();
2189 void wxWindowMac::OnEnabled(bool WXUNUSED(enabled
))
2191 #if !TARGET_API_MAC_OSX
2192 MacEnabledStateChanged() ;
2196 void wxWindowMac::MacPropagateHiliteChanged()
2198 #if !TARGET_API_MAC_OSX
2199 MacHiliteChanged() ;
2202 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
2205 child
= node
->GetData();
2206 if (child
/* && child->IsEnabled() */)
2207 child
->MacPropagateHiliteChanged() ;
2209 node
= node
->GetNext();
2215 // status change notifications
2218 void wxWindowMac::MacVisibilityChanged()
2222 void wxWindowMac::MacHiliteChanged()
2226 void wxWindowMac::MacEnabledStateChanged()
2231 // status queries on the inherited window's state
2234 bool wxWindowMac::MacIsReallyShown()
2236 // only under OSX the visibility of the TLW is taken into account
2237 if ( m_isBeingDeleted
)
2240 #if TARGET_API_MAC_OSX
2241 if ( m_peer
&& m_peer
->Ok() )
2242 return m_peer
->IsVisible();
2245 wxWindow
* win
= this ;
2246 while ( win
->IsShown() )
2248 if ( win
->IsTopLevel() )
2251 win
= win
->GetParent() ;
2259 bool wxWindowMac::MacIsReallyEnabled()
2261 return m_peer
->IsEnabled() ;
2264 bool wxWindowMac::MacIsReallyHilited()
2266 return m_peer
->IsActive();
2269 void wxWindowMac::MacFlashInvalidAreas()
2271 #if TARGET_API_MAC_OSX
2272 HIViewFlashDirtyArea( (WindowRef
) MacGetTopLevelWindowRef() ) ;
2276 int wxWindowMac::GetCharHeight() const
2278 wxClientDC
dc( (wxWindowMac
*)this ) ;
2280 return dc
.GetCharHeight() ;
2283 int wxWindowMac::GetCharWidth() const
2285 wxClientDC
dc( (wxWindowMac
*)this ) ;
2287 return dc
.GetCharWidth() ;
2290 void wxWindowMac::GetTextExtent(const wxString
& string
, int *x
, int *y
,
2291 int *descent
, int *externalLeading
, const wxFont
*theFont
) const
2293 const wxFont
*fontToUse
= theFont
;
2295 fontToUse
= &m_font
;
2297 wxClientDC
dc( (wxWindowMac
*) this ) ;
2298 wxCoord lx
,ly
,ld
,le
;
2299 dc
.GetTextExtent( string
, &lx
, &ly
, &ld
, &le
, (wxFont
*)fontToUse
) ;
2300 if ( externalLeading
)
2301 *externalLeading
= le
;
2311 * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect
2312 * we always intersect with the entire window, not only with the client area
2315 void wxWindowMac::Refresh(bool WXUNUSED(eraseBack
), const wxRect
*rect
)
2317 if ( m_peer
== NULL
)
2320 if ( !MacIsReallyShown() )
2327 wxMacRectToNative( rect
, &r
) ;
2328 m_peer
->SetNeedsDisplay( &r
) ;
2332 m_peer
->SetNeedsDisplay() ;
2336 void wxWindowMac::Freeze()
2338 #if TARGET_API_MAC_OSX
2339 if ( !m_frozenness
++ )
2341 if ( m_peer
&& m_peer
->Ok() )
2342 m_peer
->SetDrawingEnabled( false ) ;
2347 void wxWindowMac::Thaw()
2349 #if TARGET_API_MAC_OSX
2350 wxASSERT_MSG( m_frozenness
> 0, wxT("Thaw() without matching Freeze()") );
2352 if ( !--m_frozenness
)
2354 if ( m_peer
&& m_peer
->Ok() )
2356 m_peer
->SetDrawingEnabled( true ) ;
2357 m_peer
->InvalidateWithChildren() ;
2363 bool wxWindowMac::IsFrozen() const
2365 return m_frozenness
!= 0;
2368 wxWindowMac
*wxGetActiveWindow()
2370 // actually this is a windows-only concept
2374 // Coordinates relative to the window
2375 void wxWindowMac::WarpPointer(int WXUNUSED(x_pos
), int WXUNUSED(y_pos
))
2377 // We really don't move the mouse programmatically under Mac.
2380 void wxWindowMac::OnEraseBackground(wxEraseEvent
& event
)
2382 if ( MacGetTopLevelWindow() == NULL
)
2385 #if TARGET_API_MAC_OSX
2386 if ( !m_macBackgroundBrush
.Ok() || m_macBackgroundBrush
.GetStyle() == wxTRANSPARENT
2387 || GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT
)
2394 event
.GetDC()->Clear() ;
2398 void wxWindowMac::OnNcPaint( wxNcPaintEvent
& event
)
2403 int wxWindowMac::GetScrollPos(int orient
) const
2405 if ( orient
== wxHORIZONTAL
)
2408 return m_hScrollBar
->GetThumbPosition() ;
2413 return m_vScrollBar
->GetThumbPosition() ;
2419 // This now returns the whole range, not just the number
2420 // of positions that we can scroll.
2421 int wxWindowMac::GetScrollRange(int orient
) const
2423 if ( orient
== wxHORIZONTAL
)
2426 return m_hScrollBar
->GetRange() ;
2431 return m_vScrollBar
->GetRange() ;
2437 int wxWindowMac::GetScrollThumb(int orient
) const
2439 if ( orient
== wxHORIZONTAL
)
2442 return m_hScrollBar
->GetThumbSize() ;
2447 return m_vScrollBar
->GetThumbSize() ;
2453 void wxWindowMac::SetScrollPos(int orient
, int pos
, bool WXUNUSED(refresh
))
2455 if ( orient
== wxHORIZONTAL
)
2458 m_hScrollBar
->SetThumbPosition( pos
) ;
2463 m_vScrollBar
->SetThumbPosition( pos
) ;
2468 wxWindowMac::AlwaysShowScrollbars(bool hflag
, bool vflag
)
2470 bool needVisibilityUpdate
= false;
2472 if ( m_hScrollBarAlwaysShown
!= hflag
)
2474 m_hScrollBarAlwaysShown
= hflag
;
2475 needVisibilityUpdate
= true;
2478 if ( m_vScrollBarAlwaysShown
!= vflag
)
2480 m_vScrollBarAlwaysShown
= vflag
;
2481 needVisibilityUpdate
= true;
2484 if ( needVisibilityUpdate
)
2485 DoUpdateScrollbarVisibility();
2488 // we draw borders and grow boxes, are already set up and clipped in the current port / cgContextRef
2489 // our own window origin is at leftOrigin/rightOrigin
2492 void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin
) , int WXUNUSED(rightOrigin
) )
2498 bool hasFocus
= m_peer
->NeedsFocusRect() && m_peer
->HasFocus() ;
2499 bool hasBothScrollbars
= (m_hScrollBar
&& m_hScrollBar
->IsShown()) && (m_vScrollBar
&& m_vScrollBar
->IsShown()) ;
2501 // back to the surrounding frame rectangle
2502 m_peer
->GetRect( &rect
) ;
2503 InsetRect( &rect
, -1 , -1 ) ;
2505 #if wxMAC_USE_CORE_GRAPHICS
2507 CGRect cgrect
= CGRectMake( rect
.left
, rect
.top
, rect
.right
- rect
.left
,
2508 rect
.bottom
- rect
.top
) ;
2510 HIThemeFrameDrawInfo info
;
2511 memset( &info
, 0 , sizeof(info
) ) ;
2515 info
.state
= IsEnabled() ? kThemeStateActive
: kThemeStateInactive
;
2516 info
.isFocused
= hasFocus
;
2518 CGContextRef cgContext
= (CGContextRef
) GetParent()->MacGetCGContextRef() ;
2519 wxASSERT( cgContext
) ;
2521 if ( HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
) )
2523 info
.kind
= kHIThemeFrameTextFieldSquare
;
2524 HIThemeDrawFrame( &cgrect
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2526 else if ( HasFlag(wxSIMPLE_BORDER
) )
2528 info
.kind
= kHIThemeFrameListBox
;
2529 HIThemeDrawFrame( &cgrect
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2531 else if ( hasFocus
)
2533 HIThemeDrawFocusRect( &cgrect
, true , cgContext
, kHIThemeOrientationNormal
) ;
2536 m_peer
->GetRect( &rect
) ;
2537 if ( hasBothScrollbars
)
2539 int size
= m_hScrollBar
->GetWindowVariant() == wxWINDOW_VARIANT_NORMAL
? 16 : 12 ;
2540 CGRect cgrect
= CGRectMake( rect
.right
- size
, rect
.bottom
- size
, size
, size
) ;
2541 CGPoint cgpoint
= CGPointMake( rect
.right
- size
, rect
.bottom
- size
) ;
2542 HIThemeGrowBoxDrawInfo info
;
2543 memset( &info
, 0, sizeof(info
) ) ;
2545 info
.state
= IsEnabled() ? kThemeStateActive
: kThemeStateInactive
;
2546 info
.kind
= kHIThemeGrowBoxKindNone
;
2547 info
.size
= kHIThemeGrowBoxSizeNormal
;
2548 info
.direction
= kThemeGrowRight
| kThemeGrowDown
;
2549 HIThemeDrawGrowBox( &cgpoint
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2554 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2558 wxMacControl::Convert( &pt
, GetParent()->m_peer
, top
->m_peer
) ;
2559 OffsetRect( &rect
, pt
.x
, pt
.y
) ;
2562 if ( HasFlag(wxRAISED_BORDER
) || HasFlag( wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
) )
2563 DrawThemeEditTextFrame( &rect
, IsEnabled() ? kThemeStateActive
: kThemeStateInactive
) ;
2564 else if ( HasFlag(wxSIMPLE_BORDER
) )
2565 DrawThemeListBoxFrame( &rect
, IsEnabled() ? kThemeStateActive
: kThemeStateInactive
) ;
2568 DrawThemeFocusRect( &rect
, true ) ;
2570 if ( hasBothScrollbars
)
2572 // GetThemeStandaloneGrowBoxBounds
2573 // DrawThemeStandaloneNoGrowBox
2579 void wxWindowMac::RemoveChild( wxWindowBase
*child
)
2581 if ( child
== m_hScrollBar
)
2582 m_hScrollBar
= NULL
;
2583 if ( child
== m_vScrollBar
)
2584 m_vScrollBar
= NULL
;
2586 wxWindowBase::RemoveChild( child
) ;
2589 void wxWindowMac::DoUpdateScrollbarVisibility()
2591 bool triggerSizeEvent
= false;
2595 bool showHScrollBar
= m_hScrollBarAlwaysShown
|| m_hScrollBar
->IsNeeded();
2597 if ( m_hScrollBar
->IsShown() != showHScrollBar
)
2599 m_hScrollBar
->Show( showHScrollBar
);
2600 triggerSizeEvent
= true;
2606 bool showVScrollBar
= m_vScrollBarAlwaysShown
|| m_vScrollBar
->IsNeeded();
2608 if ( m_vScrollBar
->IsShown() != showVScrollBar
)
2610 m_vScrollBar
->Show( showVScrollBar
) ;
2611 triggerSizeEvent
= true;
2615 MacRepositionScrollBars() ;
2616 if ( triggerSizeEvent
)
2618 wxSizeEvent
event(GetSize(), m_windowId
);
2619 event
.SetEventObject(this);
2620 GetEventHandler()->ProcessEvent(event
);
2624 // New function that will replace some of the above.
2625 void wxWindowMac::SetScrollbar(int orient
, int pos
, int thumb
,
2626 int range
, bool refresh
)
2628 if ( orient
== wxHORIZONTAL
&& m_hScrollBar
)
2629 m_hScrollBar
->SetScrollbar(pos
, thumb
, range
, thumb
, refresh
);
2630 else if ( orient
== wxVERTICAL
&& m_vScrollBar
)
2631 m_vScrollBar
->SetScrollbar(pos
, thumb
, range
, thumb
, refresh
);
2633 DoUpdateScrollbarVisibility();
2636 // Does a physical scroll
2637 void wxWindowMac::ScrollWindow(int dx
, int dy
, const wxRect
*rect
)
2639 if ( dx
== 0 && dy
== 0 )
2642 int width
, height
;
2643 GetClientSize( &width
, &height
) ;
2646 // note there currently is a bug in OSX which makes inefficient refreshes in case an entire control
2647 // area is scrolled, this does not occur if width and height are 2 pixels less,
2648 // TODO: write optimal workaround
2649 wxRect
scrollrect( MacGetLeftBorderSize() , MacGetTopBorderSize() , width
, height
) ;
2651 scrollrect
.Intersect( *rect
) ;
2653 if ( m_peer
->GetNeedsDisplay() )
2655 // because HIViewScrollRect does not scroll the already invalidated area we have two options:
2656 // in case there is already a pending redraw on that area
2657 // either immediate redraw or full invalidate
2659 // is the better overall solution, as it does not slow down scrolling
2660 m_peer
->SetNeedsDisplay() ;
2662 // this would be the preferred version for fast drawing controls
2664 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
2665 if ( UMAGetSystemVersion() >= 0x1030 )
2666 HIViewRender(m_peer
->GetControlRef()) ;
2673 // as the native control might be not a 0/0 wx window coordinates, we have to offset
2674 scrollrect
.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ;
2675 m_peer
->ScrollRect( &scrollrect
, dx
, dy
) ;
2678 // this would be the preferred version for fast drawing controls
2679 HIViewRender(m_peer
->GetControlRef()) ;
2685 for (wxWindowList::compatibility_iterator node
= GetChildren().GetFirst(); node
; node
= node
->GetNext())
2687 child
= node
->GetData();
2690 if (child
== m_vScrollBar
)
2692 if (child
== m_hScrollBar
)
2694 if (child
->IsTopLevel())
2697 child
->GetPosition( &x
, &y
);
2698 child
->GetSize( &w
, &h
);
2701 wxRect
rc( x
, y
, w
, h
);
2702 if (rect
->Intersects( rc
))
2703 child
->SetSize( x
+ dx
, y
+ dy
, w
, h
, wxSIZE_AUTO
|wxSIZE_ALLOW_MINUS_ONE
);
2707 child
->SetSize( x
+ dx
, y
+ dy
, w
, h
, wxSIZE_AUTO
|wxSIZE_ALLOW_MINUS_ONE
);
2712 void wxWindowMac::MacOnScroll( wxScrollEvent
&event
)
2714 if ( event
.GetEventObject() == m_vScrollBar
|| event
.GetEventObject() == m_hScrollBar
)
2716 wxScrollWinEvent wevent
;
2717 wevent
.SetPosition(event
.GetPosition());
2718 wevent
.SetOrientation(event
.GetOrientation());
2719 wevent
.SetEventObject(this);
2721 if (event
.GetEventType() == wxEVT_SCROLL_TOP
)
2722 wevent
.SetEventType( wxEVT_SCROLLWIN_TOP
);
2723 else if (event
.GetEventType() == wxEVT_SCROLL_BOTTOM
)
2724 wevent
.SetEventType( wxEVT_SCROLLWIN_BOTTOM
);
2725 else if (event
.GetEventType() == wxEVT_SCROLL_LINEUP
)
2726 wevent
.SetEventType( wxEVT_SCROLLWIN_LINEUP
);
2727 else if (event
.GetEventType() == wxEVT_SCROLL_LINEDOWN
)
2728 wevent
.SetEventType( wxEVT_SCROLLWIN_LINEDOWN
);
2729 else if (event
.GetEventType() == wxEVT_SCROLL_PAGEUP
)
2730 wevent
.SetEventType( wxEVT_SCROLLWIN_PAGEUP
);
2731 else if (event
.GetEventType() == wxEVT_SCROLL_PAGEDOWN
)
2732 wevent
.SetEventType( wxEVT_SCROLLWIN_PAGEDOWN
);
2733 else if (event
.GetEventType() == wxEVT_SCROLL_THUMBTRACK
)
2734 wevent
.SetEventType( wxEVT_SCROLLWIN_THUMBTRACK
);
2735 else if (event
.GetEventType() == wxEVT_SCROLL_THUMBRELEASE
)
2736 wevent
.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE
);
2738 GetEventHandler()->ProcessEvent(wevent
);
2742 // Get the window with the focus
2743 wxWindowMac
*wxWindowBase::DoFindFocus()
2745 ControlRef control
;
2746 GetKeyboardFocus( GetUserFocusWindow() , &control
) ;
2747 return wxFindControlFromMacControl( control
) ;
2750 void wxWindowMac::OnSetFocus( wxFocusEvent
& event
)
2752 // panel wants to track the window which was the last to have focus in it,
2753 // so we want to set ourselves as the window which last had focus
2755 // notice that it's also important to do it upwards the tree because
2756 // otherwise when the top level panel gets focus, it won't set it back to
2757 // us, but to some other sibling
2759 // CS: don't know if this is still needed:
2760 //wxChildFocusEvent eventFocus(this);
2761 //(void)GetEventHandler()->ProcessEvent(eventFocus);
2763 if ( MacGetTopLevelWindow() && m_peer
->NeedsFocusRect() )
2765 #if wxMAC_USE_CORE_GRAPHICS
2766 GetParent()->Refresh() ;
2768 wxMacWindowStateSaver
sv( this ) ;
2771 m_peer
->GetRect( &rect
) ;
2772 // auf den umgebenden Rahmen zur\81Â\9fck
2773 InsetRect( &rect
, -1 , -1 ) ;
2775 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2779 wxMacControl::Convert( &pt
, GetParent()->m_peer
, top
->m_peer
) ;
2781 rect
.right
+= pt
.x
;
2783 rect
.bottom
+= pt
.y
;
2786 bool bIsFocusEvent
= (event
.GetEventType() == wxEVT_SET_FOCUS
);
2787 DrawThemeFocusRect( &rect
, bIsFocusEvent
) ;
2788 if ( !bIsFocusEvent
)
2790 // as this erases part of the frame we have to redraw borders
2791 // and because our z-ordering is not always correct (staticboxes)
2792 // we have to invalidate things, we cannot simple redraw
2793 MacInvalidateBorders() ;
2801 void wxWindowMac::OnInternalIdle()
2803 // This calls the UI-update mechanism (querying windows for
2804 // menu/toolbar/control state information)
2805 if (wxUpdateUIEvent::CanUpdate(this))
2806 UpdateWindowUI(wxUPDATE_UI_FROMIDLE
);
2809 // Raise the window to the top of the Z order
2810 void wxWindowMac::Raise()
2812 m_peer
->SetZOrder( true , NULL
) ;
2815 // Lower the window to the bottom of the Z order
2816 void wxWindowMac::Lower()
2818 m_peer
->SetZOrder( false , NULL
) ;
2821 // static wxWindow *gs_lastWhich = NULL;
2823 bool wxWindowMac::MacSetupCursor( const wxPoint
& pt
)
2825 // first trigger a set cursor event
2827 wxPoint clientorigin
= GetClientAreaOrigin() ;
2828 wxSize clientsize
= GetClientSize() ;
2830 if ( wxRect2DInt( clientorigin
.x
, clientorigin
.y
, clientsize
.x
, clientsize
.y
).Contains( wxPoint2DInt( pt
) ) )
2832 wxSetCursorEvent
event( pt
.x
, pt
.y
);
2834 bool processedEvtSetCursor
= GetEventHandler()->ProcessEvent(event
);
2835 if ( processedEvtSetCursor
&& event
.HasCursor() )
2837 cursor
= event
.GetCursor() ;
2841 // the test for processedEvtSetCursor is here to prevent using m_cursor
2842 // if the user code caught EVT_SET_CURSOR() and returned nothing from
2843 // it - this is a way to say that our cursor shouldn't be used for this
2845 if ( !processedEvtSetCursor
&& m_cursor
.Ok() )
2848 if ( !wxIsBusy() && !GetParent() )
2849 cursor
= *wxSTANDARD_CURSOR
;
2853 cursor
.MacInstall() ;
2856 return cursor
.Ok() ;
2859 wxString
wxWindowMac::MacGetToolTipString( wxPoint
&WXUNUSED(pt
) )
2863 return m_tooltip
->GetTip() ;
2866 return wxEmptyString
;
2869 void wxWindowMac::ClearBackground()
2875 void wxWindowMac::Update()
2877 #if TARGET_API_MAC_OSX
2878 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2880 top
->MacPerformUpdates() ;
2882 ::Draw1Control( m_peer
->GetControlRef() ) ;
2886 wxTopLevelWindowMac
* wxWindowMac::MacGetTopLevelWindow() const
2888 wxTopLevelWindowMac
* win
= NULL
;
2889 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
2891 win
= wxFindWinFromMacWindow( window
) ;
2896 const wxRect
& wxWindowMac::MacGetClippedClientRect() const
2898 MacUpdateClippedRects() ;
2900 return m_cachedClippedClientRect
;
2903 const wxRect
& wxWindowMac::MacGetClippedRect() const
2905 MacUpdateClippedRects() ;
2907 return m_cachedClippedRect
;
2910 const wxRect
&wxWindowMac:: MacGetClippedRectWithOuterStructure() const
2912 MacUpdateClippedRects() ;
2914 return m_cachedClippedRectWithOuterStructure
;
2917 const wxRegion
& wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures
)
2919 static wxRegion emptyrgn
;
2921 if ( !m_isBeingDeleted
&& MacIsReallyShown() /*m_peer->IsVisible() */ )
2923 MacUpdateClippedRects() ;
2924 if ( includeOuterStructures
)
2925 return m_cachedClippedRegionWithOuterStructure
;
2927 return m_cachedClippedRegion
;
2935 void wxWindowMac::MacUpdateClippedRects() const
2937 if ( m_cachedClippedRectValid
)
2940 // includeOuterStructures is true if we try to draw somthing like a focus ring etc.
2941 // also a window dc uses this, in this case we only clip in the hierarchy for hard
2942 // borders like a scrollwindow, splitter etc otherwise we end up in a paranoia having
2943 // to add focus borders everywhere
2945 Rect r
, rIncludingOuterStructures
;
2947 m_peer
->GetRect( &r
) ;
2948 r
.left
-= MacGetLeftBorderSize() ;
2949 r
.top
-= MacGetTopBorderSize() ;
2950 r
.bottom
+= MacGetBottomBorderSize() ;
2951 r
.right
+= MacGetRightBorderSize() ;
2958 rIncludingOuterStructures
= r
;
2959 InsetRect( &rIncludingOuterStructures
, -4 , -4 ) ;
2961 wxRect cl
= GetClientRect() ;
2962 Rect rClient
= { cl
.y
, cl
.x
, cl
.y
+ cl
.height
, cl
.x
+ cl
.width
} ;
2966 const wxWindow
* child
= this ;
2967 const wxWindow
* parent
= NULL
;
2969 while ( !child
->IsTopLevel() && ( parent
= child
->GetParent() ) != NULL
)
2971 if ( parent
->MacIsChildOfClientArea(child
) )
2973 size
= parent
->GetClientSize() ;
2974 wxPoint origin
= parent
->GetClientAreaOrigin() ;
2980 // this will be true for scrollbars, toolbars etc.
2981 size
= parent
->GetSize() ;
2982 y
= parent
->MacGetTopBorderSize() ;
2983 x
= parent
->MacGetLeftBorderSize() ;
2984 size
.x
-= parent
->MacGetLeftBorderSize() + parent
->MacGetRightBorderSize() ;
2985 size
.y
-= parent
->MacGetTopBorderSize() + parent
->MacGetBottomBorderSize() ;
2988 parent
->MacWindowToRootWindow( &x
, &y
) ;
2989 MacRootWindowToWindow( &x
, &y
) ;
2991 Rect rparent
= { y
, x
, y
+ size
.y
, x
+ size
.x
} ;
2993 // the wxwindow and client rects will always be clipped
2994 SectRect( &r
, &rparent
, &r
) ;
2995 SectRect( &rClient
, &rparent
, &rClient
) ;
2997 // the structure only at 'hard' borders
2998 if ( parent
->MacClipChildren() ||
2999 ( parent
->GetParent() && parent
->GetParent()->MacClipGrandChildren() ) )
3001 SectRect( &rIncludingOuterStructures
, &rparent
, &rIncludingOuterStructures
) ;
3007 m_cachedClippedRect
= wxRect( r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
- r
.top
) ;
3008 m_cachedClippedClientRect
= wxRect( rClient
.left
, rClient
.top
,
3009 rClient
.right
- rClient
.left
, rClient
.bottom
- rClient
.top
) ;
3010 m_cachedClippedRectWithOuterStructure
= wxRect(
3011 rIncludingOuterStructures
.left
, rIncludingOuterStructures
.top
,
3012 rIncludingOuterStructures
.right
- rIncludingOuterStructures
.left
,
3013 rIncludingOuterStructures
.bottom
- rIncludingOuterStructures
.top
) ;
3015 m_cachedClippedRegionWithOuterStructure
= wxRegion( m_cachedClippedRectWithOuterStructure
) ;
3016 m_cachedClippedRegion
= wxRegion( m_cachedClippedRect
) ;
3017 m_cachedClippedClientRegion
= wxRegion( m_cachedClippedClientRect
) ;
3019 m_cachedClippedRectValid
= true ;
3023 This function must not change the updatergn !
3025 bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr
, long time
)
3027 bool handled
= false ;
3029 RgnHandle updatergn
= (RgnHandle
) updatergnr
;
3030 GetRegionBounds( updatergn
, &updatebounds
) ;
3032 // wxLogDebug(wxT("update for %s bounds %d, %d, %d, %d"), wxString(GetClassInfo()->GetClassName()).c_str(), updatebounds.left, updatebounds.top , updatebounds.right , updatebounds.bottom ) ;
3034 if ( !EmptyRgn(updatergn
) )
3036 RgnHandle newupdate
= NewRgn() ;
3037 wxSize point
= GetClientSize() ;
3038 wxPoint origin
= GetClientAreaOrigin() ;
3039 SetRectRgn( newupdate
, origin
.x
, origin
.y
, origin
.x
+ point
.x
, origin
.y
+ point
.y
) ;
3040 SectRgn( newupdate
, updatergn
, newupdate
) ;
3042 // first send an erase event to the entire update area
3044 // for the toplevel window this really is the entire area
3045 // for all the others only their client area, otherwise they
3046 // might be drawing with full alpha and eg put blue into
3047 // the grow-box area of a scrolled window (scroll sample)
3048 wxDC
* dc
= new wxWindowDC(this);
3050 dc
->SetClippingRegion(wxRegion(updatergn
));
3052 dc
->SetClippingRegion(wxRegion(newupdate
));
3054 wxEraseEvent
eevent( GetId(), dc
);
3055 eevent
.SetEventObject( this );
3056 GetEventHandler()->ProcessEvent( eevent
);
3060 // calculate a client-origin version of the update rgn and set m_updateRegion to that
3061 OffsetRgn( newupdate
, -origin
.x
, -origin
.y
) ;
3062 m_updateRegion
= newupdate
;
3063 DisposeRgn( newupdate
) ;
3065 if ( !m_updateRegion
.Empty() )
3067 // paint the window itself
3070 event
.SetTimestamp(time
);
3071 event
.SetEventObject(this);
3072 GetEventHandler()->ProcessEvent(event
);
3076 // now we cannot rely on having its borders drawn by a window itself, as it does not
3077 // get the updateRgn wide enough to always do so, so we do it from the parent
3078 // this would also be the place to draw any custom backgrounds for native controls
3079 // in Composited windowing
3080 wxPoint clientOrigin
= GetClientAreaOrigin() ;
3084 for (wxWindowList::compatibility_iterator node
= GetChildren().GetFirst(); node
; node
= node
->GetNext())
3086 child
= node
->GetData();
3089 if (child
== m_vScrollBar
)
3091 if (child
== m_hScrollBar
)
3093 if (child
->IsTopLevel())
3095 if (!child
->IsShown())
3098 // only draw those in the update region (add a safety margin of 10 pixels for shadow effects
3100 child
->GetPosition( &x
, &y
);
3101 child
->GetSize( &w
, &h
);
3102 Rect childRect
= { y
, x
, y
+ h
, x
+ w
} ;
3103 OffsetRect( &childRect
, clientOrigin
.x
, clientOrigin
.y
) ;
3104 InsetRect( &childRect
, -10 , -10) ;
3106 if ( RectInRgn( &childRect
, updatergn
) )
3108 // paint custom borders
3109 wxNcPaintEvent
eventNc( child
->GetId() );
3110 eventNc
.SetEventObject( child
);
3111 if ( !child
->GetEventHandler()->ProcessEvent( eventNc
) )
3113 #if wxMAC_USE_CORE_GRAPHICS
3114 child
->MacPaintBorders(0, 0) ;
3117 wxWindowDC
dc(this) ;
3118 dc
.SetClippingRegion(wxRegion(updatergn
));
3119 wxMacPortSetter
helper(&dc
) ;
3120 child
->MacPaintBorders(0, 0) ;
3132 WXWindow
wxWindowMac::MacGetTopLevelWindowRef() const
3134 wxWindowMac
*iter
= (wxWindowMac
*)this ;
3138 if ( iter
->IsTopLevel() )
3139 return ((wxTopLevelWindow
*)iter
)->MacGetWindowRef() ;
3141 iter
= iter
->GetParent() ;
3147 void wxWindowMac::MacCreateScrollBars( long style
)
3149 wxASSERT_MSG( m_vScrollBar
== NULL
&& m_hScrollBar
== NULL
, wxT("attempt to create window twice") ) ;
3151 if ( style
& ( wxVSCROLL
| wxHSCROLL
) )
3153 bool hasBoth
= ( style
& wxVSCROLL
) && ( style
& wxHSCROLL
) ;
3154 int scrlsize
= MAC_SCROLLBAR_SIZE
;
3155 if ( GetWindowVariant() == wxWINDOW_VARIANT_SMALL
|| GetWindowVariant() == wxWINDOW_VARIANT_MINI
)
3157 scrlsize
= MAC_SMALL_SCROLLBAR_SIZE
;
3160 int adjust
= hasBoth
? scrlsize
- 1: 0 ;
3162 GetClientSize( &width
, &height
) ;
3164 wxPoint
vPoint(width
- scrlsize
, 0) ;
3165 wxSize
vSize(scrlsize
, height
- adjust
) ;
3166 wxPoint
hPoint(0, height
- scrlsize
) ;
3167 wxSize
hSize(width
- adjust
, scrlsize
) ;
3169 if ( style
& wxVSCROLL
)
3170 m_vScrollBar
= new wxScrollBar(this, wxID_ANY
, vPoint
, vSize
, wxVERTICAL
);
3172 if ( style
& wxHSCROLL
)
3173 m_hScrollBar
= new wxScrollBar(this, wxID_ANY
, hPoint
, hSize
, wxHORIZONTAL
);
3176 // because the create does not take into account the client area origin
3177 // we might have a real position shift
3178 MacRepositionScrollBars() ;
3181 bool wxWindowMac::MacIsChildOfClientArea( const wxWindow
* child
) const
3183 bool result
= ((child
== NULL
) || ((child
!= m_hScrollBar
) && (child
!= m_vScrollBar
)));
3188 void wxWindowMac::MacRepositionScrollBars()
3190 if ( !m_hScrollBar
&& !m_vScrollBar
)
3193 bool hasBoth
= (m_hScrollBar
&& m_hScrollBar
->IsShown()) && ( m_vScrollBar
&& m_vScrollBar
->IsShown()) ;
3194 int scrlsize
= m_hScrollBar
? m_hScrollBar
->GetSize().y
: ( m_vScrollBar
? m_vScrollBar
->GetSize().x
: MAC_SCROLLBAR_SIZE
) ;
3195 int adjust
= hasBoth
? scrlsize
- 1 : 0 ;
3197 // get real client area
3199 GetSize( &width
, &height
);
3201 width
-= MacGetLeftBorderSize() + MacGetRightBorderSize();
3202 height
-= MacGetTopBorderSize() + MacGetBottomBorderSize();
3204 wxPoint
vPoint( width
- scrlsize
, 0 ) ;
3205 wxSize
vSize( scrlsize
, height
- adjust
) ;
3206 wxPoint
hPoint( 0 , height
- scrlsize
) ;
3207 wxSize
hSize( width
- adjust
, scrlsize
) ;
3210 int x
= 0, y
= 0, w
, h
;
3211 GetSize( &w
, &h
) ;
3213 MacClientToRootWindow( &x
, &y
) ;
3214 MacClientToRootWindow( &w
, &h
) ;
3216 wxWindowMac
*iter
= (wxWindowMac
*)this ;
3218 int totW
= 10000 , totH
= 10000;
3221 if ( iter
->IsTopLevel() )
3223 iter
->GetSize( &totW
, &totH
) ;
3227 iter
= iter
->GetParent() ;
3241 if ( w
- x
>= totW
)
3246 if ( h
- y
>= totH
)
3254 m_vScrollBar
->SetSize( vPoint
.x
, vPoint
.y
, vSize
.x
, vSize
.y
, wxSIZE_ALLOW_MINUS_ONE
);
3256 m_hScrollBar
->SetSize( hPoint
.x
, hPoint
.y
, hSize
.x
, hSize
.y
, wxSIZE_ALLOW_MINUS_ONE
);
3259 bool wxWindowMac::AcceptsFocus() const
3261 return MacCanFocus() && wxWindowBase::AcceptsFocus();
3264 void wxWindowMac::MacSuperChangedPosition()
3266 // only window-absolute structures have to be moved i.e. controls
3268 m_cachedClippedRectValid
= false ;
3271 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
3274 child
= node
->GetData();
3275 child
->MacSuperChangedPosition() ;
3277 node
= node
->GetNext();
3281 void wxWindowMac::MacTopLevelWindowChangedPosition()
3283 // only screen-absolute structures have to be moved i.e. glcanvas
3286 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
3289 child
= node
->GetData();
3290 child
->MacTopLevelWindowChangedPosition() ;
3292 node
= node
->GetNext();
3296 long wxWindowMac::MacGetLeftBorderSize() const
3303 if (HasFlag(wxRAISED_BORDER
) || HasFlag( wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
))
3305 // this metric is only the 'outset' outside the simple frame rect
3306 GetThemeMetric( kThemeMetricEditTextFrameOutset
, &border
) ;
3309 else if (HasFlag(wxSIMPLE_BORDER
))
3311 // this metric is only the 'outset' outside the simple frame rect
3312 GetThemeMetric( kThemeMetricListBoxFrameOutset
, &border
) ;
3319 long wxWindowMac::MacGetRightBorderSize() const
3321 // they are all symmetric in mac themes
3322 return MacGetLeftBorderSize() ;
3325 long wxWindowMac::MacGetTopBorderSize() const
3327 // they are all symmetric in mac themes
3328 return MacGetLeftBorderSize() ;
3331 long wxWindowMac::MacGetBottomBorderSize() const
3333 // they are all symmetric in mac themes
3334 return MacGetLeftBorderSize() ;
3337 long wxWindowMac::MacRemoveBordersFromStyle( long style
)
3339 return style
& ~wxBORDER_MASK
;
3342 // Find the wxWindowMac at the current mouse position, returning the mouse
3344 wxWindowMac
* wxFindWindowAtPointer( wxPoint
& pt
)
3346 pt
= wxGetMousePosition();
3347 wxWindowMac
* found
= wxFindWindowAtPoint(pt
);
3352 // Get the current mouse position.
3353 wxPoint
wxGetMousePosition()
3357 wxGetMousePosition( &x
, &y
);
3359 return wxPoint(x
, y
);
3362 void wxWindowMac::OnMouseEvent( wxMouseEvent
&event
)
3364 if ( event
.GetEventType() == wxEVT_RIGHT_DOWN
)
3366 // copied from wxGTK : CS
3367 // VZ: shouldn't we move this to base class then?
3369 // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN
3372 // (a) it's a command event and so is propagated to the parent
3373 // (b) under MSW it can be generated from kbd too
3374 // (c) it uses screen coords (because of (a))
3375 wxContextMenuEvent
evtCtx(wxEVT_CONTEXT_MENU
,
3377 this->ClientToScreen(event
.GetPosition()));
3378 if ( ! GetEventHandler()->ProcessEvent(evtCtx
) )
3387 void wxWindowMac::OnPaint( wxPaintEvent
& WXUNUSED(event
) )
3389 if ( wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
3390 && GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT
)
3391 CallNextEventHandler(
3392 (EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() ,
3393 (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
3396 void wxWindowMac::MacHandleControlClick(WXWidget
WXUNUSED(control
),
3397 wxInt16
WXUNUSED(controlpart
),
3398 bool WXUNUSED(mouseStillDown
))
3402 Rect
wxMacGetBoundsForControl( wxWindow
* window
, const wxPoint
& pos
, const wxSize
&size
, bool adjustForOrigin
)
3406 window
->MacGetBoundsForControl( pos
, size
, x
, y
, w
, h
, adjustForOrigin
) ;
3407 Rect bounds
= { y
, x
, y
+ h
, x
+ w
};
3412 wxInt32
wxWindowMac::MacControlHit(WXEVENTHANDLERREF
WXUNUSED(handler
) , WXEVENTREF
WXUNUSED(event
) )
3414 return eventNotHandledErr
;
3417 bool wxWindowMac::Reparent(wxWindowBase
*newParentBase
)
3419 wxWindowMac
*newParent
= (wxWindowMac
*)newParentBase
;
3420 if ( !wxWindowBase::Reparent(newParent
) )
3423 // copied from MacPostControlCreate
3424 ControlRef container
= (ControlRef
) GetParent()->GetHandle() ;
3426 wxASSERT_MSG( container
!= NULL
, wxT("No valid mac container control") ) ;
3428 ::EmbedControl( m_peer
->GetControlRef() , container
) ;
3433 bool wxWindowMac::SetTransparent(wxByte alpha
)
3435 #if wxMAC_USE_CORE_GRAPHICS
3436 SetBackgroundStyle(wxBG_STYLE_TRANSPARENT
);
3438 if ( alpha
!= m_macAlpha
)
3440 m_macAlpha
= alpha
;
3450 bool wxWindowMac::CanSetTransparent()
3452 #if wxMAC_USE_CORE_GRAPHICS
3459 wxByte
wxWindowMac::GetTransparent() const