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
wxMacWindowServiceEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
410 OSStatus result
= eventNotHandledErr
;
412 wxMacCarbonEvent
cEvent( event
) ;
414 ControlRef controlRef
;
415 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
416 wxTextCtrl
* textCtrl
= wxDynamicCast( thisWindow
, wxTextCtrl
) ;
417 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
419 switch ( GetEventKind( event
) )
421 case kEventServiceGetTypes
:
425 textCtrl
->GetSelection( &from
, &to
) ;
427 CFMutableArrayRef copyTypes
= 0 , pasteTypes
= 0;
429 copyTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServiceCopyTypes
, typeCFMutableArrayRef
) ;
430 if ( textCtrl
->IsEditable() )
431 pasteTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServicePasteTypes
, typeCFMutableArrayRef
) ;
433 static const OSType textDataTypes
[] = { kTXNTextData
/* , 'utxt', 'PICT', 'MooV', 'AIFF' */ };
434 for ( size_t i
= 0 ; i
< WXSIZEOF(textDataTypes
) ; ++i
)
436 CFStringRef typestring
= CreateTypeStringWithOSType(textDataTypes
[i
]);
440 CFArrayAppendValue(copyTypes
, typestring
) ;
442 CFArrayAppendValue(pasteTypes
, typestring
) ;
444 CFRelease( typestring
) ;
452 case kEventServiceCopy
:
457 textCtrl
->GetSelection( &from
, &to
) ;
458 wxString val
= textCtrl
->GetValue() ;
459 val
= val
.Mid( from
, to
- from
) ;
460 ScrapRef scrapRef
= cEvent
.GetParameter
< ScrapRef
> ( kEventParamScrapRef
, typeScrapRef
) ;
461 verify_noerr( ClearScrap( &scrapRef
) ) ;
462 verify_noerr( PutScrapFlavor( scrapRef
, kTXNTextData
, 0 , val
.length() , val
.c_str() ) ) ;
467 case kEventServicePaste
:
470 ScrapRef scrapRef
= cEvent
.GetParameter
< ScrapRef
> ( kEventParamScrapRef
, typeScrapRef
) ;
471 Size textSize
, pastedSize
;
472 verify_noerr( GetScrapFlavorSize(scrapRef
, kTXNTextData
, &textSize
) ) ;
474 char *content
= new char[textSize
] ;
475 GetScrapFlavorData(scrapRef
, kTXNTextData
, &pastedSize
, content
);
476 content
[textSize
- 1] = 0 ;
479 textCtrl
->WriteText( wxString( content
, wxConvLocal
) );
481 textCtrl
->WriteText( wxString( content
) ) ;
496 pascal OSStatus
wxMacUnicodeTextEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
498 OSStatus result
= eventNotHandledErr
;
499 wxWindowMac
* focus
= (wxWindowMac
*) data
;
501 wchar_t* uniChars
= NULL
;
502 UInt32 when
= EventTimeToTicks( GetEventTime( event
) ) ;
504 UniChar
* charBuf
= NULL
;
505 ByteCount dataSize
= 0 ;
508 if ( GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, 0 , &dataSize
, NULL
) == noErr
)
510 numChars
= dataSize
/ sizeof( UniChar
) + 1;
513 if ( (size_t) numChars
* 2 > sizeof(buf
) )
514 charBuf
= new UniChar
[ numChars
] ;
518 uniChars
= new wchar_t[ numChars
] ;
519 GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, dataSize
, NULL
, charBuf
) ;
520 charBuf
[ numChars
- 1 ] = 0;
521 #if SIZEOF_WCHAR_T == 2
522 uniChars
= (wchar_t*) charBuf
;
523 /* memcpy( uniChars , charBuf , numChars * 2 ) ;*/ // is there any point in copying charBuf over itself? (in fact, memcpy isn't even guaranteed to work correctly if the source and destination ranges overlap...)
525 // the resulting string will never have more chars than the utf16 version, so this is safe
526 wxMBConvUTF16 converter
;
527 numChars
= converter
.MB2WC( uniChars
, (const char*)charBuf
, numChars
) ;
531 switch ( GetEventKind( event
) )
533 case kEventTextInputUpdateActiveInputArea
:
535 // An IME input event may return several characters, but we need to send one char at a time to
537 for (int pos
=0 ; pos
< numChars
; pos
++)
539 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
540 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
541 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
543 UInt32 message
= uniChars
[pos
] < 128 ? (char)uniChars
[pos
] : '?';
545 NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
546 multiple times to update the active range during inline input, so this handler will often receive
547 uncommited text, which should usually not trigger side effects. It might be a good idea to check the
548 kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
549 On the other hand, it can be useful for some applications to react to uncommitted text (for example,
550 to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
551 should add new event types to support advanced text input. For now, I would keep things as they are.
553 However, the code that was being used caused additional problems:
554 UInt32 message = (0 << 8) + ((char)uniChars[pos] );
555 Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
556 input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
557 for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
558 (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
559 (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
560 Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
561 overlap with Unicode within the (7-bit) ASCII range.
562 But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
563 for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
564 characters as they are and replaces the rest with '?', ensuring that update events are triggered.
565 It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
566 I don't have time to look into that right now.
569 if ( wxTheApp
->MacSendCharEvent(
570 focus
, message
, 0 , when
, 0 , 0 , uniChars
[pos
] ) )
575 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
579 case kEventTextInputUnicodeForKeyEvent
:
581 UInt32 keyCode
, modifiers
;
584 unsigned char charCode
;
586 GetEventParameter( event
, kEventParamTextInputSendKeyboardEvent
, typeEventRef
, NULL
, sizeof(rawEvent
), NULL
, &rawEvent
) ;
587 GetEventParameter( rawEvent
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, sizeof(char), NULL
, &charCode
);
588 GetEventParameter( rawEvent
, kEventParamKeyCode
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
589 GetEventParameter( rawEvent
, kEventParamKeyModifiers
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &modifiers
);
590 GetEventParameter( rawEvent
, kEventParamMouseLocation
, typeQDPoint
, NULL
, sizeof(Point
), NULL
, &point
);
592 UInt32 message
= (keyCode
<< 8) + charCode
;
594 // An IME input event may return several characters, but we need to send one char at a time to
596 for (int pos
=0 ; pos
< numChars
; pos
++)
598 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
599 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
600 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
602 if ( wxTheApp
->MacSendCharEvent(
603 focus
, message
, modifiers
, when
, point
.h
, point
.v
, uniChars
[pos
] ) )
608 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
617 if ( charBuf
!= buf
)
623 static pascal OSStatus
wxMacWindowCommandEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
625 OSStatus result
= eventNotHandledErr
;
626 wxWindowMac
* focus
= (wxWindowMac
*) data
;
630 wxMacCarbonEvent
cEvent( event
) ;
631 cEvent
.GetParameter
<HICommand
>(kEventParamDirectObject
,typeHICommand
,&command
) ;
633 wxMenuItem
* item
= NULL
;
634 wxMenu
* itemMenu
= wxFindMenuFromMacCommand( command
, item
) ;
635 int id
= wxMacCommandToId( command
.commandID
) ;
639 wxASSERT( itemMenu
!= NULL
) ;
641 switch ( cEvent
.GetKind() )
643 case kEventProcessCommand
:
645 if (item
->IsCheckable())
646 item
->Check( !item
->IsChecked() ) ;
648 if ( itemMenu
->SendEvent( id
, item
->IsCheckable() ? item
->IsChecked() : -1 ) )
652 wxCommandEvent
event(wxEVT_COMMAND_MENU_SELECTED
, id
);
653 event
.SetEventObject(focus
);
654 event
.SetInt(item
->IsCheckable() ? item
->IsChecked() : -1);
656 if ( focus
->GetEventHandler()->ProcessEvent(event
) )
662 case kEventCommandUpdateStatus
:
664 wxUpdateUIEvent
event(id
);
665 event
.SetEventObject( itemMenu
);
667 bool processed
= false;
669 // Try the menu's event handler
671 wxEvtHandler
*handler
= itemMenu
->GetEventHandler();
673 processed
= handler
->ProcessEvent(event
);
676 // Try the window the menu was popped up from
677 // (and up through the hierarchy)
680 const wxMenuBase
*menu
= itemMenu
;
683 wxWindow
*win
= menu
->GetInvokingWindow();
686 processed
= win
->GetEventHandler()->ProcessEvent(event
);
690 menu
= menu
->GetParent();
696 processed
= focus
->GetEventHandler()->ProcessEvent(event
);
701 // if anything changed, update the changed attribute
702 if (event
.GetSetText())
703 itemMenu
->SetLabel(id
, event
.GetText());
704 if (event
.GetSetChecked())
705 itemMenu
->Check(id
, event
.GetChecked());
706 if (event
.GetSetEnabled())
707 itemMenu
->Enable(id
, event
.GetEnabled());
721 pascal OSStatus
wxMacWindowEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
723 EventRef formerEvent
= (EventRef
) wxTheApp
->MacGetCurrentEvent() ;
724 EventHandlerCallRef formerEventHandlerCallRef
= (EventHandlerCallRef
) wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
725 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
726 OSStatus result
= eventNotHandledErr
;
728 switch ( GetEventClass( event
) )
730 case kEventClassCommand
:
731 result
= wxMacWindowCommandEventHandler( handler
, event
, data
) ;
734 case kEventClassControl
:
735 result
= wxMacWindowControlEventHandler( handler
, event
, data
) ;
738 case kEventClassService
:
739 result
= wxMacWindowServiceEventHandler( handler
, event
, data
) ;
742 case kEventClassTextInput
:
743 result
= wxMacUnicodeTextEventHandler( handler
, event
, data
) ;
750 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerEventHandlerCallRef
) ;
755 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler
)
757 #if !TARGET_API_MAC_OSX
759 // ---------------------------------------------------------------------------
760 // UserPane events for non OSX builds
761 // ---------------------------------------------------------------------------
763 static pascal void wxMacControlUserPaneDrawProc(ControlRef control
, SInt16 part
)
765 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
767 win
->MacControlUserPaneDrawProc(part
) ;
769 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneDrawUPP
, wxMacControlUserPaneDrawProc
) ;
771 static pascal ControlPartCode
wxMacControlUserPaneHitTestProc(ControlRef control
, Point where
)
773 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
775 return win
->MacControlUserPaneHitTestProc(where
.h
, where
.v
) ;
777 return kControlNoPart
;
779 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneHitTestUPP
, wxMacControlUserPaneHitTestProc
) ;
781 static pascal ControlPartCode
wxMacControlUserPaneTrackingProc(ControlRef control
, Point startPt
, ControlActionUPP actionProc
)
783 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
785 return win
->MacControlUserPaneTrackingProc( startPt
.h
, startPt
.v
, (void*) actionProc
) ;
787 return kControlNoPart
;
789 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneTrackingUPP
, wxMacControlUserPaneTrackingProc
) ;
791 static pascal void wxMacControlUserPaneIdleProc(ControlRef control
)
793 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
795 win
->MacControlUserPaneIdleProc() ;
797 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneIdleUPP
, wxMacControlUserPaneIdleProc
) ;
799 static pascal ControlPartCode
wxMacControlUserPaneKeyDownProc(ControlRef control
, SInt16 keyCode
, SInt16 charCode
, SInt16 modifiers
)
801 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
803 return win
->MacControlUserPaneKeyDownProc(keyCode
,charCode
,modifiers
) ;
805 return kControlNoPart
;
807 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneKeyDownUPP
, wxMacControlUserPaneKeyDownProc
) ;
809 static pascal void wxMacControlUserPaneActivateProc(ControlRef control
, Boolean activating
)
811 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
813 win
->MacControlUserPaneActivateProc(activating
) ;
815 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneActivateUPP
, wxMacControlUserPaneActivateProc
) ;
817 static pascal ControlPartCode
wxMacControlUserPaneFocusProc(ControlRef control
, ControlFocusPart action
)
819 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
821 return win
->MacControlUserPaneFocusProc(action
) ;
823 return kControlNoPart
;
825 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneFocusUPP
, wxMacControlUserPaneFocusProc
) ;
827 static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control
, ControlBackgroundPtr info
)
829 wxWindow
* win
= wxFindControlFromMacControl(control
) ;
831 win
->MacControlUserPaneBackgroundProc(info
) ;
833 wxMAC_DEFINE_PROC_GETTER( ControlUserPaneBackgroundUPP
, wxMacControlUserPaneBackgroundProc
) ;
835 void wxWindowMac::MacControlUserPaneDrawProc(wxInt16 part
)
838 RgnHandle rgn
= NewRgn() ;
840 MacWindowToRootWindow( &x
, &y
) ;
841 OffsetRgn( rgn
, -x
, -y
) ;
842 wxMacWindowStateSaver
sv( this ) ;
843 SectRgn( rgn
, (RgnHandle
) MacGetVisibleRegion().GetWXHRGN() , rgn
) ;
844 MacDoRedraw( rgn
, 0 ) ;
848 wxInt16
wxWindowMac::MacControlUserPaneHitTestProc(wxInt16 x
, wxInt16 y
)
850 return kControlNoPart
;
853 wxInt16
wxWindowMac::MacControlUserPaneTrackingProc(wxInt16 x
, wxInt16 y
, void* actionProc
)
855 return kControlNoPart
;
858 void wxWindowMac::MacControlUserPaneIdleProc()
862 wxInt16
wxWindowMac::MacControlUserPaneKeyDownProc(wxInt16 keyCode
, wxInt16 charCode
, wxInt16 modifiers
)
864 return kControlNoPart
;
867 void wxWindowMac::MacControlUserPaneActivateProc(bool activating
)
871 wxInt16
wxWindowMac::MacControlUserPaneFocusProc(wxInt16 action
)
873 if ( AcceptsFocus() )
876 return kControlNoPart
;
879 void wxWindowMac::MacControlUserPaneBackgroundProc(void* info
)
885 // ---------------------------------------------------------------------------
886 // Scrollbar Tracking for all
887 // ---------------------------------------------------------------------------
889 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
) ;
890 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
)
894 wxWindow
* wx
= wxFindControlFromMacControl( control
) ;
896 wx
->MacHandleControlClick( (WXWidget
) control
, partCode
, true /* stillDown */ ) ;
899 wxMAC_DEFINE_PROC_GETTER( ControlActionUPP
, wxMacLiveScrollbarActionProc
) ;
901 // ===========================================================================
903 // ===========================================================================
905 WX_DECLARE_HASH_MAP(ControlRef
, wxWindow
*, wxPointerHash
, wxPointerEqual
, MacControlMap
);
907 static MacControlMap wxWinMacControlList
;
909 wxWindow
*wxFindControlFromMacControl(ControlRef inControl
)
911 MacControlMap::iterator node
= wxWinMacControlList
.find(inControl
);
913 return (node
== wxWinMacControlList
.end()) ? NULL
: node
->second
;
916 void wxAssociateControlWithMacControl(ControlRef inControl
, wxWindow
*control
)
918 // adding NULL ControlRef is (first) surely a result of an error and
919 // (secondly) breaks native event processing
920 wxCHECK_RET( inControl
!= (ControlRef
) NULL
, wxT("attempt to add a NULL WindowRef to window list") );
922 wxWinMacControlList
[inControl
] = control
;
925 void wxRemoveMacControlAssociation(wxWindow
*control
)
927 // iterate over all the elements in the class
928 // is the iterator stable ? as we might have two associations pointing to the same wxWindow
929 // we should go on...
935 MacControlMap::iterator it
;
936 for ( it
= wxWinMacControlList
.begin(); it
!= wxWinMacControlList
.end(); ++it
)
938 if ( it
->second
== control
)
940 wxWinMacControlList
.erase(it
);
948 // ----------------------------------------------------------------------------
949 // constructors and such
950 // ----------------------------------------------------------------------------
952 wxWindowMac::wxWindowMac()
957 wxWindowMac::wxWindowMac(wxWindowMac
*parent
,
962 const wxString
& name
)
965 Create(parent
, id
, pos
, size
, style
, name
);
968 void wxWindowMac::Init()
974 #if wxMAC_USE_CORE_GRAPHICS
975 m_cgContextRef
= NULL
;
978 // as all windows are created with WS_VISIBLE style...
981 m_hScrollBar
= NULL
;
982 m_vScrollBar
= NULL
;
983 m_hScrollBarAlwaysShown
= false;
984 m_vScrollBarAlwaysShown
= false;
986 m_macBackgroundBrush
= wxNullBrush
;
988 m_macIsUserPane
= true;
989 m_clipChildren
= false ;
990 m_cachedClippedRectValid
= false ;
992 // we need a valid font for the encodings
993 wxWindowBase::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
996 wxWindowMac::~wxWindowMac()
1000 m_isBeingDeleted
= true;
1002 MacInvalidateBorders() ;
1004 #ifndef __WXUNIVERSAL__
1005 // VS: make sure there's no wxFrame with last focus set to us:
1006 for ( wxWindow
*win
= GetParent(); win
; win
= win
->GetParent() )
1008 wxFrame
*frame
= wxDynamicCast(win
, wxFrame
);
1011 if ( frame
->GetLastFocus() == this )
1012 frame
->SetLastFocus((wxWindow
*)NULL
);
1018 // destroy children before destroying this window itself
1021 // wxRemoveMacControlAssociation( this ) ;
1022 // If we delete an item, we should initialize the parent panel,
1023 // because it could now be invalid.
1024 wxTopLevelWindow
*tlw
= wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow
);
1027 if ( tlw
->GetDefaultItem() == (wxButton
*) this)
1028 tlw
->SetDefaultItem(NULL
);
1031 if ( m_peer
&& m_peer
->Ok() )
1033 // in case the callback might be called during destruction
1034 wxRemoveMacControlAssociation( this) ;
1035 ::RemoveEventHandler( (EventHandlerRef
) m_macControlEventHandler
) ;
1036 // we currently are not using this hook
1037 // ::SetControlColorProc( *m_peer , NULL ) ;
1041 if ( g_MacLastWindow
== this )
1042 g_MacLastWindow
= NULL
;
1044 wxFrame
* frame
= wxDynamicCast( wxGetTopLevelParent( this ) , wxFrame
) ;
1047 if ( frame
->GetLastFocus() == this )
1048 frame
->SetLastFocus( NULL
) ;
1051 // delete our drop target if we've got one
1052 #if wxUSE_DRAG_AND_DROP
1053 if ( m_dropTarget
!= NULL
)
1055 delete m_dropTarget
;
1056 m_dropTarget
= NULL
;
1063 WXWidget
wxWindowMac::GetHandle() const
1065 return (WXWidget
) m_peer
->GetControlRef() ;
1068 void wxWindowMac::MacInstallEventHandler( WXWidget control
)
1070 wxAssociateControlWithMacControl( (ControlRef
) control
, this ) ;
1071 InstallControlEventHandler( (ControlRef
)control
, GetwxMacWindowEventHandlerUPP(),
1072 GetEventTypeCount(eventList
), eventList
, this,
1073 (EventHandlerRef
*)&m_macControlEventHandler
);
1075 #if !TARGET_API_MAC_OSX
1076 if ( (ControlRef
) control
== m_peer
->GetControlRef() )
1078 m_peer
->SetData
<ControlUserPaneDrawUPP
>(kControlEntireControl
, kControlUserPaneDrawProcTag
, GetwxMacControlUserPaneDrawProc()) ;
1079 m_peer
->SetData
<ControlUserPaneHitTestUPP
>(kControlEntireControl
, kControlUserPaneHitTestProcTag
, GetwxMacControlUserPaneHitTestProc()) ;
1080 m_peer
->SetData
<ControlUserPaneTrackingUPP
>(kControlEntireControl
, kControlUserPaneTrackingProcTag
, GetwxMacControlUserPaneTrackingProc()) ;
1081 m_peer
->SetData
<ControlUserPaneIdleUPP
>(kControlEntireControl
, kControlUserPaneIdleProcTag
, GetwxMacControlUserPaneIdleProc()) ;
1082 m_peer
->SetData
<ControlUserPaneKeyDownUPP
>(kControlEntireControl
, kControlUserPaneKeyDownProcTag
, GetwxMacControlUserPaneKeyDownProc()) ;
1083 m_peer
->SetData
<ControlUserPaneActivateUPP
>(kControlEntireControl
, kControlUserPaneActivateProcTag
, GetwxMacControlUserPaneActivateProc()) ;
1084 m_peer
->SetData
<ControlUserPaneFocusUPP
>(kControlEntireControl
, kControlUserPaneFocusProcTag
, GetwxMacControlUserPaneFocusProc()) ;
1085 m_peer
->SetData
<ControlUserPaneBackgroundUPP
>(kControlEntireControl
, kControlUserPaneBackgroundProcTag
, GetwxMacControlUserPaneBackgroundProc()) ;
1091 bool wxWindowMac::Create(wxWindowMac
*parent
,
1096 const wxString
& name
)
1098 wxCHECK_MSG( parent
, false, wxT("can't create wxWindowMac without parent") );
1100 if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) )
1103 m_windowVariant
= parent
->GetWindowVariant() ;
1105 if ( m_macIsUserPane
)
1107 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
) ;
1110 | kControlSupportsEmbedding
1111 | kControlSupportsLiveFeedback
1112 | kControlGetsFocusOnClick
1113 // | kControlHasSpecialBackground
1114 // | kControlSupportsCalcBestRect
1115 | kControlHandlesTracking
1116 | kControlSupportsFocus
1117 | kControlWantsActivate
1118 | kControlWantsIdle
;
1120 m_peer
= new wxMacControl(this) ;
1121 OSStatus err
=::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds
, features
, m_peer
->GetControlRefAddr() );
1122 verify_noerr( err
);
1124 MacPostControlCreate(pos
, size
) ;
1127 #ifndef __WXUNIVERSAL__
1128 // Don't give scrollbars to wxControls unless they ask for them
1129 if ( (! IsKindOf(CLASSINFO(wxControl
)) && ! IsKindOf(CLASSINFO(wxStatusBar
)))
1130 || (IsKindOf(CLASSINFO(wxControl
)) && ((style
& wxHSCROLL
) || (style
& wxVSCROLL
))))
1132 MacCreateScrollBars( style
) ;
1136 wxWindowCreateEvent
event(this);
1137 GetEventHandler()->AddPendingEvent(event
);
1142 void wxWindowMac::MacChildAdded()
1145 m_vScrollBar
->Raise() ;
1147 m_hScrollBar
->Raise() ;
1150 void wxWindowMac::MacPostControlCreate(const wxPoint
& pos
, const wxSize
& size
)
1152 wxASSERT_MSG( m_peer
!= NULL
&& m_peer
->Ok() , wxT("No valid mac control") ) ;
1154 m_peer
->SetReference( (URefCon
) this ) ;
1155 GetParent()->AddChild( this );
1157 MacInstallEventHandler( (WXWidget
) m_peer
->GetControlRef() );
1159 ControlRef container
= (ControlRef
) GetParent()->GetHandle() ;
1160 wxASSERT_MSG( container
!= NULL
, wxT("No valid mac container control") ) ;
1161 ::EmbedControl( m_peer
->GetControlRef() , container
) ;
1162 GetParent()->MacChildAdded() ;
1164 // adjust font, controlsize etc
1165 DoSetWindowVariant( m_windowVariant
) ;
1167 m_peer
->SetLabel( wxStripMenuCodes(m_label
, wxStrip_Mnemonics
) ) ;
1169 if (!m_macIsUserPane
)
1170 SetInitialSize(size
);
1172 SetCursor( *wxSTANDARD_CURSOR
) ;
1175 void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant
)
1177 // Don't assert, in case we set the window variant before
1178 // the window is created
1179 // wxASSERT( m_peer->Ok() ) ;
1181 m_windowVariant
= variant
;
1183 if (m_peer
== NULL
|| !m_peer
->Ok())
1187 ThemeFontID themeFont
= kThemeSystemFont
;
1189 // we will get that from the settings later
1190 // and make this NORMAL later, but first
1191 // we have a few calculations that we must fix
1195 case wxWINDOW_VARIANT_NORMAL
:
1196 size
= kControlSizeNormal
;
1197 themeFont
= kThemeSystemFont
;
1200 case wxWINDOW_VARIANT_SMALL
:
1201 size
= kControlSizeSmall
;
1202 themeFont
= kThemeSmallSystemFont
;
1205 case wxWINDOW_VARIANT_MINI
:
1206 if (UMAGetSystemVersion() >= 0x1030 )
1208 // not always defined in the headers
1214 size
= kControlSizeSmall
;
1215 themeFont
= kThemeSmallSystemFont
;
1219 case wxWINDOW_VARIANT_LARGE
:
1220 size
= kControlSizeLarge
;
1221 themeFont
= kThemeSystemFont
;
1225 wxFAIL_MSG(_T("unexpected window variant"));
1229 m_peer
->SetData
<ControlSize
>(kControlEntireControl
, kControlSizeTag
, &size
) ;
1232 font
.MacCreateThemeFont( themeFont
) ;
1236 void wxWindowMac::MacUpdateControlFont()
1238 m_peer
->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ;
1242 bool wxWindowMac::SetFont(const wxFont
& font
)
1244 bool retval
= wxWindowBase::SetFont( font
);
1246 MacUpdateControlFont() ;
1251 bool wxWindowMac::SetForegroundColour(const wxColour
& col
)
1253 bool retval
= wxWindowBase::SetForegroundColour( col
);
1256 MacUpdateControlFont();
1261 bool wxWindowMac::SetBackgroundColour(const wxColour
& col
)
1263 if ( !wxWindowBase::SetBackgroundColour(col
) && m_hasBgCol
)
1267 wxColour
newCol(GetBackgroundColour());
1269 if ( newCol
== wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW
) )
1270 brush
.MacSetTheme( kThemeBrushDocumentWindowBackground
) ;
1271 else if ( newCol
== wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE
) )
1272 brush
.MacSetTheme( kThemeBrushDialogBackgroundActive
) ;
1274 brush
.SetColour( newCol
) ;
1276 MacSetBackgroundBrush( brush
) ;
1277 MacUpdateControlFont() ;
1282 void wxWindowMac::MacSetBackgroundBrush( const wxBrush
&brush
)
1284 m_macBackgroundBrush
= brush
;
1285 m_peer
->SetBackground( brush
) ;
1288 bool wxWindowMac::MacCanFocus() const
1290 // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so
1291 // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning,
1292 // but the value range is nowhere documented
1293 Boolean keyExistsAndHasValidFormat
;
1294 CFIndex fullKeyboardAccess
= CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) ,
1295 kCFPreferencesCurrentApplication
, &keyExistsAndHasValidFormat
);
1297 if ( keyExistsAndHasValidFormat
&& fullKeyboardAccess
> 0 )
1303 UInt32 features
= 0 ;
1304 m_peer
->GetFeatures( &features
) ;
1306 return features
& ( kControlSupportsFocus
| kControlGetsFocusOnClick
) ;
1310 void wxWindowMac::SetFocus()
1312 if ( !AcceptsFocus() )
1315 wxWindow
* former
= FindFocus() ;
1316 if ( former
== this )
1319 // as we cannot rely on the control features to find out whether we are in full keyboard mode,
1320 // we can only leave in case of an error
1321 OSStatus err
= m_peer
->SetFocus( kControlFocusNextPart
) ;
1322 if ( err
== errCouldntSetFocus
)
1325 SetUserFocusWindow( (WindowRef
)MacGetTopLevelWindowRef() );
1327 #if !TARGET_API_MAC_OSX
1328 // emulate carbon events when running under CarbonLib where they are not natively available
1331 EventRef evRef
= NULL
;
1333 err
= MacCreateEvent(
1334 NULL
, kEventClassControl
, kEventControlSetFocusPart
, TicksToEventTime( TickCount() ) ,
1335 kEventAttributeUserEvent
, &evRef
);
1336 verify_noerr( err
);
1338 wxMacCarbonEvent
cEvent( evRef
) ;
1339 cEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, (ControlRef
) former
->GetHandle() ) ;
1340 cEvent
.SetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
, kControlFocusNoPart
) ;
1342 wxMacWindowEventHandler( NULL
, evRef
, former
) ;
1343 ReleaseEvent( evRef
) ;
1346 // send new focus event
1348 EventRef evRef
= NULL
;
1350 err
= MacCreateEvent(
1351 NULL
, kEventClassControl
, kEventControlSetFocusPart
, TicksToEventTime( TickCount() ) ,
1352 kEventAttributeUserEvent
, &evRef
);
1353 verify_noerr( err
);
1355 wxMacCarbonEvent
cEvent( evRef
) ;
1356 cEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, (ControlRef
) GetHandle() ) ;
1357 cEvent
.SetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
, kControlFocusNextPart
) ;
1359 wxMacWindowEventHandler( NULL
, evRef
, this ) ;
1360 ReleaseEvent( evRef
) ;
1365 void wxWindowMac::DoCaptureMouse()
1367 wxApp::s_captureWindow
= this ;
1370 wxWindow
* wxWindowBase::GetCapture()
1372 return wxApp::s_captureWindow
;
1375 void wxWindowMac::DoReleaseMouse()
1377 wxApp::s_captureWindow
= NULL
;
1380 #if wxUSE_DRAG_AND_DROP
1382 void wxWindowMac::SetDropTarget(wxDropTarget
*pDropTarget
)
1384 if ( m_dropTarget
!= NULL
)
1385 delete m_dropTarget
;
1387 m_dropTarget
= pDropTarget
;
1388 if ( m_dropTarget
!= NULL
)
1396 // Old-style File Manager Drag & Drop
1397 void wxWindowMac::DragAcceptFiles(bool accept
)
1402 // Returns the size of the native control. In the case of the toplevel window
1403 // this is the content area root control
1405 void wxWindowMac::MacGetPositionAndSizeFromControl(int& x
, int& y
,
1406 int& w
, int& h
) const
1408 wxFAIL_MSG( wxT("Not currently supported") ) ;
1411 // From a wx position / size calculate the appropriate size of the native control
1413 bool wxWindowMac::MacGetBoundsForControl(
1417 int& w
, int& h
, bool adjustOrigin
) const
1419 // the desired size, minus the border pixels gives the correct size of the control
1423 // TODO: the default calls may be used as soon as PostCreateControl Is moved here
1424 w
= wxMax(size
.x
, 0) ; // WidthDefault( size.x );
1425 h
= wxMax(size
.y
, 0) ; // HeightDefault( size.y ) ;
1427 x
+= MacGetLeftBorderSize() ;
1428 y
+= MacGetTopBorderSize() ;
1429 w
-= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1430 h
-= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1433 AdjustForParentClientOrigin( x
, y
) ;
1435 // this is in window relative coordinate, as this parent may have a border, its physical position is offset by this border
1436 if ( !GetParent()->IsTopLevel() )
1438 x
-= GetParent()->MacGetLeftBorderSize() ;
1439 y
-= GetParent()->MacGetTopBorderSize() ;
1445 // Get window size (not client size)
1446 void wxWindowMac::DoGetSize(int *x
, int *y
) const
1449 m_peer
->GetRect( &bounds
) ;
1452 *x
= bounds
.right
- bounds
.left
+ MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1454 *y
= bounds
.bottom
- bounds
.top
+ MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1457 // get the position of the bounds of this window in client coordinates of its parent
1458 void wxWindowMac::DoGetPosition(int *x
, int *y
) const
1461 m_peer
->GetRect( &bounds
) ;
1463 int x1
= bounds
.left
;
1464 int y1
= bounds
.top
;
1466 // get the wx window position from the native one
1467 x1
-= MacGetLeftBorderSize() ;
1468 y1
-= MacGetTopBorderSize() ;
1470 if ( !IsTopLevel() )
1472 wxWindow
*parent
= GetParent();
1475 // we must first adjust it to be in window coordinates of the parent,
1476 // as otherwise it gets lost by the ClientAreaOrigin fix
1477 x1
+= parent
->MacGetLeftBorderSize() ;
1478 y1
+= parent
->MacGetTopBorderSize() ;
1480 // and now to client coordinates
1481 wxPoint
pt(parent
->GetClientAreaOrigin());
1493 void wxWindowMac::DoScreenToClient(int *x
, int *y
) const
1495 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
1496 wxCHECK_RET( window
, wxT("TopLevel Window missing") ) ;
1498 Point localwhere
= { 0, 0 } ;
1505 wxMacGlobalToLocal( window
, &localwhere
) ;
1512 MacRootWindowToWindow( x
, y
) ;
1514 wxPoint origin
= GetClientAreaOrigin() ;
1521 void wxWindowMac::DoClientToScreen(int *x
, int *y
) const
1523 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
1524 wxCHECK_RET( window
, wxT("TopLevel window missing") ) ;
1526 wxPoint origin
= GetClientAreaOrigin() ;
1532 MacWindowToRootWindow( x
, y
) ;
1534 Point localwhere
= { 0, 0 };
1540 wxMacLocalToGlobal( window
, &localwhere
) ;
1548 void wxWindowMac::MacClientToRootWindow( int *x
, int *y
) const
1550 wxPoint origin
= GetClientAreaOrigin() ;
1556 MacWindowToRootWindow( x
, y
) ;
1559 void wxWindowMac::MacRootWindowToClient( int *x
, int *y
) const
1561 MacRootWindowToWindow( x
, y
) ;
1563 wxPoint origin
= GetClientAreaOrigin() ;
1570 void wxWindowMac::MacWindowToRootWindow( int *x
, int *y
) const
1579 if ( !IsTopLevel() )
1581 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
1584 pt
.x
-= MacGetLeftBorderSize() ;
1585 pt
.y
-= MacGetTopBorderSize() ;
1586 wxMacControl::Convert( &pt
, m_peer
, top
->m_peer
) ;
1596 void wxWindowMac::MacWindowToRootWindow( short *x
, short *y
) const
1605 MacWindowToRootWindow( &x1
, &y1
) ;
1613 void wxWindowMac::MacRootWindowToWindow( int *x
, int *y
) const
1622 if ( !IsTopLevel() )
1624 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
1627 wxMacControl::Convert( &pt
, top
->m_peer
, m_peer
) ;
1628 pt
.x
+= MacGetLeftBorderSize() ;
1629 pt
.y
+= MacGetTopBorderSize() ;
1639 void wxWindowMac::MacRootWindowToWindow( short *x
, short *y
) const
1648 MacRootWindowToWindow( &x1
, &y1
) ;
1656 void wxWindowMac::MacGetContentAreaInset( int &left
, int &top
, int &right
, int &bottom
)
1658 RgnHandle rgn
= NewRgn() ;
1660 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1662 Rect structure
, content
;
1664 GetRegionBounds( rgn
, &content
) ;
1665 m_peer
->GetRect( &structure
) ;
1666 OffsetRect( &structure
, -structure
.left
, -structure
.top
) ;
1668 left
= content
.left
- structure
.left
;
1669 top
= content
.top
- structure
.top
;
1670 right
= structure
.right
- content
.right
;
1671 bottom
= structure
.bottom
- content
.bottom
;
1675 left
= top
= right
= bottom
= 0 ;
1681 wxSize
wxWindowMac::DoGetSizeFromClientSize( const wxSize
& size
) const
1683 wxSize sizeTotal
= size
;
1685 RgnHandle rgn
= NewRgn() ;
1686 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1688 Rect content
, structure
;
1689 GetRegionBounds( rgn
, &content
) ;
1690 m_peer
->GetRect( &structure
) ;
1692 // structure is in parent coordinates, but we only need width and height, so it's ok
1694 sizeTotal
.x
+= (structure
.right
- structure
.left
) - (content
.right
- content
.left
) ;
1695 sizeTotal
.y
+= (structure
.bottom
- structure
.top
) - (content
.bottom
- content
.top
) ;
1700 sizeTotal
.x
+= MacGetLeftBorderSize() + MacGetRightBorderSize() ;
1701 sizeTotal
.y
+= MacGetTopBorderSize() + MacGetBottomBorderSize() ;
1706 // Get size *available for subwindows* i.e. excluding menu bar etc.
1707 void wxWindowMac::DoGetClientSize( int *x
, int *y
) const
1711 RgnHandle rgn
= NewRgn() ;
1713 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
1714 GetRegionBounds( rgn
, &content
) ;
1716 m_peer
->GetRect( &content
) ;
1719 ww
= content
.right
- content
.left
;
1720 hh
= content
.bottom
- content
.top
;
1722 if (m_hScrollBar
&& m_hScrollBar
->IsShown() )
1723 hh
-= m_hScrollBar
->GetSize().y
;
1725 if (m_vScrollBar
&& m_vScrollBar
->IsShown() )
1726 ww
-= m_vScrollBar
->GetSize().x
;
1734 bool wxWindowMac::SetCursor(const wxCursor
& cursor
)
1736 if (m_cursor
.IsSameAs(cursor
))
1741 if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR
) )
1746 if ( ! wxWindowBase::SetCursor( cursor
) )
1750 wxASSERT_MSG( m_cursor
.Ok(),
1751 wxT("cursor must be valid after call to the base version"));
1753 wxWindowMac
*mouseWin
= 0 ;
1755 wxTopLevelWindowMac
*tlw
= MacGetTopLevelWindow() ;
1756 WindowRef window
= (WindowRef
) ( tlw
? tlw
->MacGetWindowRef() : 0 ) ;
1758 ControlPartCode part
;
1759 ControlRef control
;
1761 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
1763 HIGetMousePosition(kHICoordSpaceWindow
, window
, &hiPoint
);
1768 Boolean swapped
= QDSwapPort( GetWindowPort( window
) , &savePort
) ;
1770 // TODO: If we ever get a GetCurrentEvent... replacement
1771 // for the mouse position, use it...
1776 control
= wxMacFindControlUnderMouse( tlw
, pt
, window
, &part
) ;
1778 mouseWin
= wxFindControlFromMacControl( control
) ;
1780 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
1782 QDSwapPort( savePort
, NULL
) ;
1786 if ( mouseWin
== this && !wxIsBusy() )
1787 m_cursor
.MacInstall() ;
1793 bool wxWindowMac::DoPopupMenu(wxMenu
*menu
, int x
, int y
)
1795 menu
->SetInvokingWindow(this);
1798 if ( x
== wxDefaultCoord
&& y
== wxDefaultCoord
)
1800 wxPoint mouse
= wxGetMousePosition();
1806 ClientToScreen( &x
, &y
) ;
1809 menu
->MacBeforeDisplay( true ) ;
1810 long menuResult
= ::PopUpMenuSelect((MenuHandle
) menu
->GetHMenu() , y
, x
, 0) ;
1811 if ( HiWord(menuResult
) != 0 )
1814 GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult
)) , LoWord(menuResult
) , &macid
);
1815 int id
= wxMacCommandToId( macid
);
1816 wxMenuItem
* item
= NULL
;
1818 item
= menu
->FindItem( id
, &realmenu
) ;
1821 if (item
->IsCheckable())
1822 item
->Check( !item
->IsChecked() ) ;
1824 menu
->SendEvent( id
, item
->IsCheckable() ? item
->IsChecked() : -1 ) ;
1828 menu
->MacAfterDisplay( true ) ;
1829 menu
->SetInvokingWindow( NULL
);
1835 // ----------------------------------------------------------------------------
1837 // ----------------------------------------------------------------------------
1841 void wxWindowMac::DoSetToolTip(wxToolTip
*tooltip
)
1843 wxWindowBase::DoSetToolTip(tooltip
);
1846 m_tooltip
->SetWindow(this);
1851 void wxWindowMac::MacInvalidateBorders()
1853 if ( m_peer
== NULL
)
1856 bool vis
= MacIsReallyShown() ;
1860 int outerBorder
= MacGetLeftBorderSize() ;
1861 if ( m_peer
->NeedsFocusRect() && m_peer
->HasFocus() )
1864 if ( outerBorder
== 0 )
1867 // now we know that we have something to do at all
1869 // as the borders are drawn on the parent we have to properly invalidate all these areas
1870 RgnHandle updateInner
, updateOuter
;
1873 // this rectangle is in HIViewCoordinates under OSX and in Window Coordinates under Carbon
1874 updateInner
= NewRgn() ;
1875 updateOuter
= NewRgn() ;
1877 m_peer
->GetRect( &rect
) ;
1878 RectRgn( updateInner
, &rect
) ;
1879 InsetRect( &rect
, -outerBorder
, -outerBorder
) ;
1880 RectRgn( updateOuter
, &rect
) ;
1881 DiffRgn( updateOuter
, updateInner
, updateOuter
) ;
1883 #ifdef __WXMAC_OSX__
1884 GetParent()->m_peer
->SetNeedsDisplay( updateOuter
) ;
1886 WindowRef tlw
= (WindowRef
) MacGetTopLevelWindowRef() ;
1888 InvalWindowRgn( tlw
, updateOuter
) ;
1891 DisposeRgn( updateOuter
) ;
1892 DisposeRgn( updateInner
) ;
1895 void wxWindowMac::DoMoveWindow(int x
, int y
, int width
, int height
)
1897 // this is never called for a toplevel window, so we know we have a parent
1898 int former_x
, former_y
, former_w
, former_h
;
1900 // Get true coordinates of former position
1901 DoGetPosition( &former_x
, &former_y
) ;
1902 DoGetSize( &former_w
, &former_h
) ;
1904 wxWindow
*parent
= GetParent();
1907 wxPoint
pt(parent
->GetClientAreaOrigin());
1912 int actualWidth
= width
;
1913 int actualHeight
= height
;
1917 if ((m_minWidth
!= -1) && (actualWidth
< m_minWidth
))
1918 actualWidth
= m_minWidth
;
1919 if ((m_minHeight
!= -1) && (actualHeight
< m_minHeight
))
1920 actualHeight
= m_minHeight
;
1921 if ((m_maxWidth
!= -1) && (actualWidth
> m_maxWidth
))
1922 actualWidth
= m_maxWidth
;
1923 if ((m_maxHeight
!= -1) && (actualHeight
> m_maxHeight
))
1924 actualHeight
= m_maxHeight
;
1926 bool doMove
= false, doResize
= false ;
1928 if ( actualX
!= former_x
|| actualY
!= former_y
)
1931 if ( actualWidth
!= former_w
|| actualHeight
!= former_h
)
1934 if ( doMove
|| doResize
)
1936 // as the borders are drawn outside the native control, we adjust now
1938 wxRect
bounds( wxPoint( actualX
+ MacGetLeftBorderSize() ,actualY
+ MacGetTopBorderSize() ),
1939 wxSize( actualWidth
- (MacGetLeftBorderSize() + MacGetRightBorderSize()) ,
1940 actualHeight
- (MacGetTopBorderSize() + MacGetBottomBorderSize()) ) ) ;
1943 wxMacRectToNative( &bounds
, &r
) ;
1945 if ( !GetParent()->IsTopLevel() )
1946 wxMacWindowToNative( GetParent() , &r
) ;
1948 MacInvalidateBorders() ;
1950 m_cachedClippedRectValid
= false ;
1951 m_peer
->SetRect( &r
) ;
1953 wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
1955 MacInvalidateBorders() ;
1957 MacRepositionScrollBars() ;
1960 wxPoint
point(actualX
, actualY
);
1961 wxMoveEvent
event(point
, m_windowId
);
1962 event
.SetEventObject(this);
1963 GetEventHandler()->ProcessEvent(event
) ;
1968 MacRepositionScrollBars() ;
1969 wxSize
size(actualWidth
, actualHeight
);
1970 wxSizeEvent
event(size
, m_windowId
);
1971 event
.SetEventObject(this);
1972 GetEventHandler()->ProcessEvent(event
);
1977 wxSize
wxWindowMac::DoGetBestSize() const
1979 if ( m_macIsUserPane
|| IsTopLevel() )
1980 return wxWindowBase::DoGetBestSize() ;
1982 Rect bestsize
= { 0 , 0 , 0 , 0 } ;
1983 int bestWidth
, bestHeight
;
1985 m_peer
->GetBestRect( &bestsize
) ;
1986 if ( EmptyRect( &bestsize
) )
1991 bestsize
.bottom
= 16 ;
1993 if ( IsKindOf( CLASSINFO( wxScrollBar
) ) )
1995 bestsize
.bottom
= 16 ;
1998 else if ( IsKindOf( CLASSINFO( wxSpinButton
) ) )
2000 bestsize
.bottom
= 24 ;
2005 // return wxWindowBase::DoGetBestSize() ;
2009 bestWidth
= bestsize
.right
- bestsize
.left
;
2010 bestHeight
= bestsize
.bottom
- bestsize
.top
;
2011 if ( bestHeight
< 10 )
2014 return wxSize(bestWidth
, bestHeight
);
2017 // set the size of the window: if the dimensions are positive, just use them,
2018 // but if any of them is equal to -1, it means that we must find the value for
2019 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
2020 // which case -1 is a valid value for x and y)
2022 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
2023 // the width/height to best suit our contents, otherwise we reuse the current
2025 void wxWindowMac::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
2027 // get the current size and position...
2028 int currentX
, currentY
;
2029 int currentW
, currentH
;
2031 GetPosition(¤tX
, ¤tY
);
2032 GetSize(¤tW
, ¤tH
);
2034 // ... and don't do anything (avoiding flicker) if it's already ok
2035 if ( x
== currentX
&& y
== currentY
&&
2036 width
== currentW
&& height
== currentH
&& ( height
!= -1 && width
!= -1 ) )
2039 MacRepositionScrollBars() ; // we might have a real position shift
2044 if ( !(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) )
2046 if ( x
== wxDefaultCoord
)
2048 if ( y
== wxDefaultCoord
)
2052 AdjustForParentClientOrigin( x
, y
, sizeFlags
);
2054 wxSize size
= wxDefaultSize
;
2055 if ( width
== wxDefaultCoord
)
2057 if ( sizeFlags
& wxSIZE_AUTO_WIDTH
)
2059 size
= DoGetBestSize();
2064 // just take the current one
2069 if ( height
== wxDefaultCoord
)
2071 if ( sizeFlags
& wxSIZE_AUTO_HEIGHT
)
2073 if ( size
.x
== wxDefaultCoord
)
2074 size
= DoGetBestSize();
2075 // else: already called DoGetBestSize() above
2081 // just take the current one
2086 DoMoveWindow( x
, y
, width
, height
);
2089 wxPoint
wxWindowMac::GetClientAreaOrigin() const
2091 RgnHandle rgn
= NewRgn() ;
2093 if ( m_peer
->GetRegion( kControlContentMetaPart
, rgn
) == noErr
)
2095 GetRegionBounds( rgn
, &content
) ;
2105 return wxPoint( content
.left
+ MacGetLeftBorderSize() , content
.top
+ MacGetTopBorderSize() );
2108 void wxWindowMac::DoSetClientSize(int clientwidth
, int clientheight
)
2110 if ( clientwidth
!= wxDefaultCoord
|| clientheight
!= wxDefaultCoord
)
2112 int currentclientwidth
, currentclientheight
;
2113 int currentwidth
, currentheight
;
2115 GetClientSize( ¤tclientwidth
, ¤tclientheight
) ;
2116 GetSize( ¤twidth
, ¤theight
) ;
2118 DoSetSize( wxDefaultCoord
, wxDefaultCoord
, currentwidth
+ clientwidth
- currentclientwidth
,
2119 currentheight
+ clientheight
- currentclientheight
, wxSIZE_USE_EXISTING
) ;
2123 void wxWindowMac::SetLabel(const wxString
& title
)
2125 m_label
= wxStripMenuCodes(title
, wxStrip_Mnemonics
) ;
2127 if ( m_peer
&& m_peer
->Ok() )
2128 m_peer
->SetLabel( m_label
) ;
2133 wxString
wxWindowMac::GetLabel() const
2138 bool wxWindowMac::Show(bool show
)
2140 bool former
= MacIsReallyShown() ;
2141 if ( !wxWindowBase::Show(show
) )
2144 // TODO: use visibilityChanged Carbon Event for OSX
2146 m_peer
->SetVisibility( show
, true ) ;
2148 if ( former
!= MacIsReallyShown() )
2149 MacPropagateVisibilityChanged() ;
2154 void wxWindowMac::DoEnable(bool enable
)
2156 m_peer
->Enable( enable
) ;
2160 // status change propagations (will be not necessary for OSX later )
2163 void wxWindowMac::MacPropagateVisibilityChanged()
2165 #if !TARGET_API_MAC_OSX
2166 MacVisibilityChanged() ;
2169 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
2172 child
= node
->GetData();
2173 if ( child
->IsShown() )
2174 child
->MacPropagateVisibilityChanged() ;
2176 node
= node
->GetNext();
2181 void wxWindowMac::OnEnabled(bool enabled
)
2183 #if !TARGET_API_MAC_OSX
2184 MacEnabledStateChanged() ;
2188 void wxWindowMac::MacPropagateHiliteChanged()
2190 #if !TARGET_API_MAC_OSX
2191 MacHiliteChanged() ;
2194 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
2197 child
= node
->GetData();
2198 if (child
/* && child->IsEnabled() */)
2199 child
->MacPropagateHiliteChanged() ;
2201 node
= node
->GetNext();
2207 // status change notifications
2210 void wxWindowMac::MacVisibilityChanged()
2214 void wxWindowMac::MacHiliteChanged()
2218 void wxWindowMac::MacEnabledStateChanged()
2223 // status queries on the inherited window's state
2226 bool wxWindowMac::MacIsReallyShown()
2228 // only under OSX the visibility of the TLW is taken into account
2229 if ( m_isBeingDeleted
)
2232 #if TARGET_API_MAC_OSX
2233 if ( m_peer
&& m_peer
->Ok() )
2234 return m_peer
->IsVisible();
2237 wxWindow
* win
= this ;
2238 while ( win
->IsShown() )
2240 if ( win
->IsTopLevel() )
2243 win
= win
->GetParent() ;
2251 bool wxWindowMac::MacIsReallyEnabled()
2253 return m_peer
->IsEnabled() ;
2256 bool wxWindowMac::MacIsReallyHilited()
2258 return m_peer
->IsActive();
2261 void wxWindowMac::MacFlashInvalidAreas()
2263 #if TARGET_API_MAC_OSX
2264 HIViewFlashDirtyArea( (WindowRef
) MacGetTopLevelWindowRef() ) ;
2268 int wxWindowMac::GetCharHeight() const
2270 wxClientDC
dc( (wxWindowMac
*)this ) ;
2272 return dc
.GetCharHeight() ;
2275 int wxWindowMac::GetCharWidth() const
2277 wxClientDC
dc( (wxWindowMac
*)this ) ;
2279 return dc
.GetCharWidth() ;
2282 void wxWindowMac::GetTextExtent(const wxString
& string
, int *x
, int *y
,
2283 int *descent
, int *externalLeading
, const wxFont
*theFont
) const
2285 const wxFont
*fontToUse
= theFont
;
2287 fontToUse
= &m_font
;
2289 wxClientDC
dc( (wxWindowMac
*) this ) ;
2290 wxCoord lx
,ly
,ld
,le
;
2291 dc
.GetTextExtent( string
, &lx
, &ly
, &ld
, &le
, (wxFont
*)fontToUse
) ;
2292 if ( externalLeading
)
2293 *externalLeading
= le
;
2303 * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect
2304 * we always intersect with the entire window, not only with the client area
2307 void wxWindowMac::Refresh(bool eraseBack
, const wxRect
*rect
)
2309 if ( m_peer
== NULL
)
2312 if ( !MacIsReallyShown() )
2319 wxMacRectToNative( rect
, &r
) ;
2320 m_peer
->SetNeedsDisplay( &r
) ;
2324 m_peer
->SetNeedsDisplay() ;
2328 void wxWindowMac::Freeze()
2330 #if TARGET_API_MAC_OSX
2331 if ( !m_frozenness
++ )
2333 if ( m_peer
&& m_peer
->Ok() )
2334 m_peer
->SetDrawingEnabled( false ) ;
2339 void wxWindowMac::Thaw()
2341 #if TARGET_API_MAC_OSX
2342 wxASSERT_MSG( m_frozenness
> 0, wxT("Thaw() without matching Freeze()") );
2344 if ( !--m_frozenness
)
2346 if ( m_peer
&& m_peer
->Ok() )
2348 m_peer
->SetDrawingEnabled( true ) ;
2349 m_peer
->InvalidateWithChildren() ;
2355 bool wxWindowMac::IsFrozen() const
2357 return m_frozenness
!= 0;
2360 wxWindowMac
*wxGetActiveWindow()
2362 // actually this is a windows-only concept
2366 // Coordinates relative to the window
2367 void wxWindowMac::WarpPointer(int x_pos
, int y_pos
)
2369 // We really don't move the mouse programmatically under Mac.
2372 void wxWindowMac::OnEraseBackground(wxEraseEvent
& event
)
2374 if ( MacGetTopLevelWindow() == NULL
)
2377 #if TARGET_API_MAC_OSX
2378 if ( !m_macBackgroundBrush
.Ok() || m_macBackgroundBrush
.GetStyle() == wxTRANSPARENT
2379 || GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT
)
2386 event
.GetDC()->Clear() ;
2390 void wxWindowMac::OnNcPaint( wxNcPaintEvent
& event
)
2395 int wxWindowMac::GetScrollPos(int orient
) const
2397 if ( orient
== wxHORIZONTAL
)
2400 return m_hScrollBar
->GetThumbPosition() ;
2405 return m_vScrollBar
->GetThumbPosition() ;
2411 // This now returns the whole range, not just the number
2412 // of positions that we can scroll.
2413 int wxWindowMac::GetScrollRange(int orient
) const
2415 if ( orient
== wxHORIZONTAL
)
2418 return m_hScrollBar
->GetRange() ;
2423 return m_vScrollBar
->GetRange() ;
2429 int wxWindowMac::GetScrollThumb(int orient
) const
2431 if ( orient
== wxHORIZONTAL
)
2434 return m_hScrollBar
->GetThumbSize() ;
2439 return m_vScrollBar
->GetThumbSize() ;
2445 void wxWindowMac::SetScrollPos(int orient
, int pos
, bool refresh
)
2447 if ( orient
== wxHORIZONTAL
)
2450 m_hScrollBar
->SetThumbPosition( pos
) ;
2455 m_vScrollBar
->SetThumbPosition( pos
) ;
2460 wxWindowMac::AlwaysShowScrollbars(bool hflag
, bool vflag
)
2462 bool needVisibilityUpdate
= false;
2464 if ( m_hScrollBarAlwaysShown
!= hflag
)
2466 m_hScrollBarAlwaysShown
= hflag
;
2467 needVisibilityUpdate
= true;
2470 if ( m_vScrollBarAlwaysShown
!= vflag
)
2472 m_vScrollBarAlwaysShown
= vflag
;
2473 needVisibilityUpdate
= true;
2476 if ( needVisibilityUpdate
)
2477 DoUpdateScrollbarVisibility();
2480 // we draw borders and grow boxes, are already set up and clipped in the current port / cgContextRef
2481 // our own window origin is at leftOrigin/rightOrigin
2484 void wxWindowMac::MacPaintBorders( int leftOrigin
, int rightOrigin
)
2490 bool hasFocus
= m_peer
->NeedsFocusRect() && m_peer
->HasFocus() ;
2491 bool hasBothScrollbars
= (m_hScrollBar
&& m_hScrollBar
->IsShown()) && (m_vScrollBar
&& m_vScrollBar
->IsShown()) ;
2493 // back to the surrounding frame rectangle
2494 m_peer
->GetRect( &rect
) ;
2495 InsetRect( &rect
, -1 , -1 ) ;
2497 #if wxMAC_USE_CORE_GRAPHICS
2499 CGRect cgrect
= CGRectMake( rect
.left
, rect
.top
, rect
.right
- rect
.left
,
2500 rect
.bottom
- rect
.top
) ;
2502 HIThemeFrameDrawInfo info
;
2503 memset( &info
, 0 , sizeof(info
) ) ;
2507 info
.state
= IsEnabled() ? kThemeStateActive
: kThemeStateInactive
;
2508 info
.isFocused
= hasFocus
;
2510 CGContextRef cgContext
= (CGContextRef
) GetParent()->MacGetCGContextRef() ;
2511 wxASSERT( cgContext
) ;
2513 if ( HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
) )
2515 info
.kind
= kHIThemeFrameTextFieldSquare
;
2516 HIThemeDrawFrame( &cgrect
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2518 else if ( HasFlag(wxSIMPLE_BORDER
) )
2520 info
.kind
= kHIThemeFrameListBox
;
2521 HIThemeDrawFrame( &cgrect
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2523 else if ( hasFocus
)
2525 HIThemeDrawFocusRect( &cgrect
, true , cgContext
, kHIThemeOrientationNormal
) ;
2528 m_peer
->GetRect( &rect
) ;
2529 if ( hasBothScrollbars
)
2531 int size
= m_hScrollBar
->GetWindowVariant() == wxWINDOW_VARIANT_NORMAL
? 16 : 12 ;
2532 CGRect cgrect
= CGRectMake( rect
.right
- size
, rect
.bottom
- size
, size
, size
) ;
2533 CGPoint cgpoint
= CGPointMake( rect
.right
- size
, rect
.bottom
- size
) ;
2534 HIThemeGrowBoxDrawInfo info
;
2535 memset( &info
, 0, sizeof(info
) ) ;
2537 info
.state
= IsEnabled() ? kThemeStateActive
: kThemeStateInactive
;
2538 info
.kind
= kHIThemeGrowBoxKindNone
;
2539 info
.size
= kHIThemeGrowBoxSizeNormal
;
2540 info
.direction
= kThemeGrowRight
| kThemeGrowDown
;
2541 HIThemeDrawGrowBox( &cgpoint
, &info
, cgContext
, kHIThemeOrientationNormal
) ;
2546 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2550 wxMacControl::Convert( &pt
, GetParent()->m_peer
, top
->m_peer
) ;
2551 OffsetRect( &rect
, pt
.x
, pt
.y
) ;
2554 if ( HasFlag(wxRAISED_BORDER
) || HasFlag( wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
) )
2555 DrawThemeEditTextFrame( &rect
, IsEnabled() ? kThemeStateActive
: kThemeStateInactive
) ;
2556 else if ( HasFlag(wxSIMPLE_BORDER
) )
2557 DrawThemeListBoxFrame( &rect
, IsEnabled() ? kThemeStateActive
: kThemeStateInactive
) ;
2560 DrawThemeFocusRect( &rect
, true ) ;
2562 if ( hasBothScrollbars
)
2564 // GetThemeStandaloneGrowBoxBounds
2565 // DrawThemeStandaloneNoGrowBox
2571 void wxWindowMac::RemoveChild( wxWindowBase
*child
)
2573 if ( child
== m_hScrollBar
)
2574 m_hScrollBar
= NULL
;
2575 if ( child
== m_vScrollBar
)
2576 m_vScrollBar
= NULL
;
2578 wxWindowBase::RemoveChild( child
) ;
2581 void wxWindowMac::DoUpdateScrollbarVisibility()
2583 bool triggerSizeEvent
= false;
2587 bool showHScrollBar
= m_hScrollBarAlwaysShown
|| m_hScrollBar
->IsNeeded();
2589 if ( m_hScrollBar
->IsShown() != showHScrollBar
)
2591 m_hScrollBar
->Show( showHScrollBar
);
2592 triggerSizeEvent
= true;
2598 bool showVScrollBar
= m_vScrollBarAlwaysShown
|| m_vScrollBar
->IsNeeded();
2600 if ( m_vScrollBar
->IsShown() != showVScrollBar
)
2602 m_vScrollBar
->Show( showVScrollBar
) ;
2603 triggerSizeEvent
= true;
2607 MacRepositionScrollBars() ;
2608 if ( triggerSizeEvent
)
2610 wxSizeEvent
event(GetSize(), m_windowId
);
2611 event
.SetEventObject(this);
2612 GetEventHandler()->ProcessEvent(event
);
2616 // New function that will replace some of the above.
2617 void wxWindowMac::SetScrollbar(int orient
, int pos
, int thumb
,
2618 int range
, bool refresh
)
2620 if ( orient
== wxHORIZONTAL
&& m_hScrollBar
)
2621 m_hScrollBar
->SetScrollbar(pos
, thumb
, range
, thumb
, refresh
);
2622 else if ( orient
== wxVERTICAL
&& m_vScrollBar
)
2623 m_vScrollBar
->SetScrollbar(pos
, thumb
, range
, thumb
, refresh
);
2625 DoUpdateScrollbarVisibility();
2628 // Does a physical scroll
2629 void wxWindowMac::ScrollWindow(int dx
, int dy
, const wxRect
*rect
)
2631 if ( dx
== 0 && dy
== 0 )
2634 int width
, height
;
2635 GetClientSize( &width
, &height
) ;
2638 // note there currently is a bug in OSX which makes inefficient refreshes in case an entire control
2639 // area is scrolled, this does not occur if width and height are 2 pixels less,
2640 // TODO: write optimal workaround
2641 wxRect
scrollrect( MacGetLeftBorderSize() , MacGetTopBorderSize() , width
, height
) ;
2643 scrollrect
.Intersect( *rect
) ;
2645 if ( m_peer
->GetNeedsDisplay() )
2647 // because HIViewScrollRect does not scroll the already invalidated area we have two options:
2648 // in case there is already a pending redraw on that area
2649 // either immediate redraw or full invalidate
2651 // is the better overall solution, as it does not slow down scrolling
2652 m_peer
->SetNeedsDisplay() ;
2654 // this would be the preferred version for fast drawing controls
2656 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
2657 if ( UMAGetSystemVersion() >= 0x1030 )
2658 HIViewRender(m_peer
->GetControlRef()) ;
2665 // as the native control might be not a 0/0 wx window coordinates, we have to offset
2666 scrollrect
.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ;
2667 m_peer
->ScrollRect( &scrollrect
, dx
, dy
) ;
2670 // this would be the preferred version for fast drawing controls
2671 HIViewRender(m_peer
->GetControlRef()) ;
2677 for (wxWindowList::compatibility_iterator node
= GetChildren().GetFirst(); node
; node
= node
->GetNext())
2679 child
= node
->GetData();
2682 if (child
== m_vScrollBar
)
2684 if (child
== m_hScrollBar
)
2686 if (child
->IsTopLevel())
2689 child
->GetPosition( &x
, &y
);
2690 child
->GetSize( &w
, &h
);
2693 wxRect
rc( x
, y
, w
, h
);
2694 if (rect
->Intersects( rc
))
2695 child
->SetSize( x
+ dx
, y
+ dy
, w
, h
, wxSIZE_AUTO
|wxSIZE_ALLOW_MINUS_ONE
);
2699 child
->SetSize( x
+ dx
, y
+ dy
, w
, h
, wxSIZE_AUTO
|wxSIZE_ALLOW_MINUS_ONE
);
2704 void wxWindowMac::MacOnScroll( wxScrollEvent
&event
)
2706 if ( event
.GetEventObject() == m_vScrollBar
|| event
.GetEventObject() == m_hScrollBar
)
2708 wxScrollWinEvent wevent
;
2709 wevent
.SetPosition(event
.GetPosition());
2710 wevent
.SetOrientation(event
.GetOrientation());
2711 wevent
.SetEventObject(this);
2713 if (event
.GetEventType() == wxEVT_SCROLL_TOP
)
2714 wevent
.SetEventType( wxEVT_SCROLLWIN_TOP
);
2715 else if (event
.GetEventType() == wxEVT_SCROLL_BOTTOM
)
2716 wevent
.SetEventType( wxEVT_SCROLLWIN_BOTTOM
);
2717 else if (event
.GetEventType() == wxEVT_SCROLL_LINEUP
)
2718 wevent
.SetEventType( wxEVT_SCROLLWIN_LINEUP
);
2719 else if (event
.GetEventType() == wxEVT_SCROLL_LINEDOWN
)
2720 wevent
.SetEventType( wxEVT_SCROLLWIN_LINEDOWN
);
2721 else if (event
.GetEventType() == wxEVT_SCROLL_PAGEUP
)
2722 wevent
.SetEventType( wxEVT_SCROLLWIN_PAGEUP
);
2723 else if (event
.GetEventType() == wxEVT_SCROLL_PAGEDOWN
)
2724 wevent
.SetEventType( wxEVT_SCROLLWIN_PAGEDOWN
);
2725 else if (event
.GetEventType() == wxEVT_SCROLL_THUMBTRACK
)
2726 wevent
.SetEventType( wxEVT_SCROLLWIN_THUMBTRACK
);
2727 else if (event
.GetEventType() == wxEVT_SCROLL_THUMBRELEASE
)
2728 wevent
.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE
);
2730 GetEventHandler()->ProcessEvent(wevent
);
2734 // Get the window with the focus
2735 wxWindowMac
*wxWindowBase::DoFindFocus()
2737 ControlRef control
;
2738 GetKeyboardFocus( GetUserFocusWindow() , &control
) ;
2739 return wxFindControlFromMacControl( control
) ;
2742 void wxWindowMac::OnSetFocus( wxFocusEvent
& event
)
2744 // panel wants to track the window which was the last to have focus in it,
2745 // so we want to set ourselves as the window which last had focus
2747 // notice that it's also important to do it upwards the tree because
2748 // otherwise when the top level panel gets focus, it won't set it back to
2749 // us, but to some other sibling
2751 // CS: don't know if this is still needed:
2752 //wxChildFocusEvent eventFocus(this);
2753 //(void)GetEventHandler()->ProcessEvent(eventFocus);
2755 if ( MacGetTopLevelWindow() && m_peer
->NeedsFocusRect() )
2757 #if wxMAC_USE_CORE_GRAPHICS
2758 GetParent()->Refresh() ;
2760 wxMacWindowStateSaver
sv( this ) ;
2763 m_peer
->GetRect( &rect
) ;
2764 // auf den umgebenden Rahmen zur\81Â\9fck
2765 InsetRect( &rect
, -1 , -1 ) ;
2767 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2771 wxMacControl::Convert( &pt
, GetParent()->m_peer
, top
->m_peer
) ;
2773 rect
.right
+= pt
.x
;
2775 rect
.bottom
+= pt
.y
;
2778 bool bIsFocusEvent
= (event
.GetEventType() == wxEVT_SET_FOCUS
);
2779 DrawThemeFocusRect( &rect
, bIsFocusEvent
) ;
2780 if ( !bIsFocusEvent
)
2782 // as this erases part of the frame we have to redraw borders
2783 // and because our z-ordering is not always correct (staticboxes)
2784 // we have to invalidate things, we cannot simple redraw
2785 MacInvalidateBorders() ;
2793 void wxWindowMac::OnInternalIdle()
2795 // This calls the UI-update mechanism (querying windows for
2796 // menu/toolbar/control state information)
2797 if (wxUpdateUIEvent::CanUpdate(this))
2798 UpdateWindowUI(wxUPDATE_UI_FROMIDLE
);
2801 // Raise the window to the top of the Z order
2802 void wxWindowMac::Raise()
2804 m_peer
->SetZOrder( true , NULL
) ;
2807 // Lower the window to the bottom of the Z order
2808 void wxWindowMac::Lower()
2810 m_peer
->SetZOrder( false , NULL
) ;
2813 // static wxWindow *gs_lastWhich = NULL;
2815 bool wxWindowMac::MacSetupCursor( const wxPoint
& pt
)
2817 // first trigger a set cursor event
2819 wxPoint clientorigin
= GetClientAreaOrigin() ;
2820 wxSize clientsize
= GetClientSize() ;
2822 if ( wxRect2DInt( clientorigin
.x
, clientorigin
.y
, clientsize
.x
, clientsize
.y
).Contains( wxPoint2DInt( pt
) ) )
2824 wxSetCursorEvent
event( pt
.x
, pt
.y
);
2826 bool processedEvtSetCursor
= GetEventHandler()->ProcessEvent(event
);
2827 if ( processedEvtSetCursor
&& event
.HasCursor() )
2829 cursor
= event
.GetCursor() ;
2833 // the test for processedEvtSetCursor is here to prevent using m_cursor
2834 // if the user code caught EVT_SET_CURSOR() and returned nothing from
2835 // it - this is a way to say that our cursor shouldn't be used for this
2837 if ( !processedEvtSetCursor
&& m_cursor
.Ok() )
2840 if ( !wxIsBusy() && !GetParent() )
2841 cursor
= *wxSTANDARD_CURSOR
;
2845 cursor
.MacInstall() ;
2848 return cursor
.Ok() ;
2851 wxString
wxWindowMac::MacGetToolTipString( wxPoint
&pt
)
2855 return m_tooltip
->GetTip() ;
2858 return wxEmptyString
;
2861 void wxWindowMac::ClearBackground()
2867 void wxWindowMac::Update()
2869 #if TARGET_API_MAC_OSX
2870 wxTopLevelWindowMac
* top
= MacGetTopLevelWindow();
2872 top
->MacPerformUpdates() ;
2874 ::Draw1Control( m_peer
->GetControlRef() ) ;
2878 wxTopLevelWindowMac
* wxWindowMac::MacGetTopLevelWindow() const
2880 wxTopLevelWindowMac
* win
= NULL
;
2881 WindowRef window
= (WindowRef
) MacGetTopLevelWindowRef() ;
2883 win
= wxFindWinFromMacWindow( window
) ;
2888 const wxRect
& wxWindowMac::MacGetClippedClientRect() const
2890 MacUpdateClippedRects() ;
2892 return m_cachedClippedClientRect
;
2895 const wxRect
& wxWindowMac::MacGetClippedRect() const
2897 MacUpdateClippedRects() ;
2899 return m_cachedClippedRect
;
2902 const wxRect
&wxWindowMac:: MacGetClippedRectWithOuterStructure() const
2904 MacUpdateClippedRects() ;
2906 return m_cachedClippedRectWithOuterStructure
;
2909 const wxRegion
& wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures
)
2911 static wxRegion emptyrgn
;
2913 if ( !m_isBeingDeleted
&& MacIsReallyShown() /*m_peer->IsVisible() */ )
2915 MacUpdateClippedRects() ;
2916 if ( includeOuterStructures
)
2917 return m_cachedClippedRegionWithOuterStructure
;
2919 return m_cachedClippedRegion
;
2927 void wxWindowMac::MacUpdateClippedRects() const
2929 if ( m_cachedClippedRectValid
)
2932 // includeOuterStructures is true if we try to draw somthing like a focus ring etc.
2933 // also a window dc uses this, in this case we only clip in the hierarchy for hard
2934 // borders like a scrollwindow, splitter etc otherwise we end up in a paranoia having
2935 // to add focus borders everywhere
2937 Rect r
, rIncludingOuterStructures
;
2939 m_peer
->GetRect( &r
) ;
2940 r
.left
-= MacGetLeftBorderSize() ;
2941 r
.top
-= MacGetTopBorderSize() ;
2942 r
.bottom
+= MacGetBottomBorderSize() ;
2943 r
.right
+= MacGetRightBorderSize() ;
2950 rIncludingOuterStructures
= r
;
2951 InsetRect( &rIncludingOuterStructures
, -4 , -4 ) ;
2953 wxRect cl
= GetClientRect() ;
2954 Rect rClient
= { cl
.y
, cl
.x
, cl
.y
+ cl
.height
, cl
.x
+ cl
.width
} ;
2958 const wxWindow
* child
= this ;
2959 const wxWindow
* parent
= NULL
;
2961 while ( !child
->IsTopLevel() && ( parent
= child
->GetParent() ) != NULL
)
2963 if ( parent
->MacIsChildOfClientArea(child
) )
2965 size
= parent
->GetClientSize() ;
2966 wxPoint origin
= parent
->GetClientAreaOrigin() ;
2972 // this will be true for scrollbars, toolbars etc.
2973 size
= parent
->GetSize() ;
2974 y
= parent
->MacGetTopBorderSize() ;
2975 x
= parent
->MacGetLeftBorderSize() ;
2976 size
.x
-= parent
->MacGetLeftBorderSize() + parent
->MacGetRightBorderSize() ;
2977 size
.y
-= parent
->MacGetTopBorderSize() + parent
->MacGetBottomBorderSize() ;
2980 parent
->MacWindowToRootWindow( &x
, &y
) ;
2981 MacRootWindowToWindow( &x
, &y
) ;
2983 Rect rparent
= { y
, x
, y
+ size
.y
, x
+ size
.x
} ;
2985 // the wxwindow and client rects will always be clipped
2986 SectRect( &r
, &rparent
, &r
) ;
2987 SectRect( &rClient
, &rparent
, &rClient
) ;
2989 // the structure only at 'hard' borders
2990 if ( parent
->MacClipChildren() ||
2991 ( parent
->GetParent() && parent
->GetParent()->MacClipGrandChildren() ) )
2993 SectRect( &rIncludingOuterStructures
, &rparent
, &rIncludingOuterStructures
) ;
2999 m_cachedClippedRect
= wxRect( r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
- r
.top
) ;
3000 m_cachedClippedClientRect
= wxRect( rClient
.left
, rClient
.top
,
3001 rClient
.right
- rClient
.left
, rClient
.bottom
- rClient
.top
) ;
3002 m_cachedClippedRectWithOuterStructure
= wxRect(
3003 rIncludingOuterStructures
.left
, rIncludingOuterStructures
.top
,
3004 rIncludingOuterStructures
.right
- rIncludingOuterStructures
.left
,
3005 rIncludingOuterStructures
.bottom
- rIncludingOuterStructures
.top
) ;
3007 m_cachedClippedRegionWithOuterStructure
= wxRegion( m_cachedClippedRectWithOuterStructure
) ;
3008 m_cachedClippedRegion
= wxRegion( m_cachedClippedRect
) ;
3009 m_cachedClippedClientRegion
= wxRegion( m_cachedClippedClientRect
) ;
3011 m_cachedClippedRectValid
= true ;
3015 This function must not change the updatergn !
3017 bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr
, long time
)
3019 bool handled
= false ;
3021 RgnHandle updatergn
= (RgnHandle
) updatergnr
;
3022 GetRegionBounds( updatergn
, &updatebounds
) ;
3024 // wxLogDebug(wxT("update for %s bounds %d, %d, %d, %d"), wxString(GetClassInfo()->GetClassName()).c_str(), updatebounds.left, updatebounds.top , updatebounds.right , updatebounds.bottom ) ;
3026 if ( !EmptyRgn(updatergn
) )
3028 RgnHandle newupdate
= NewRgn() ;
3029 wxSize point
= GetClientSize() ;
3030 wxPoint origin
= GetClientAreaOrigin() ;
3031 SetRectRgn( newupdate
, origin
.x
, origin
.y
, origin
.x
+ point
.x
, origin
.y
+ point
.y
) ;
3032 SectRgn( newupdate
, updatergn
, newupdate
) ;
3034 // first send an erase event to the entire update area
3036 // for the toplevel window this really is the entire area
3037 // for all the others only their client area, otherwise they
3038 // might be drawing with full alpha and eg put blue into
3039 // the grow-box area of a scrolled window (scroll sample)
3040 wxDC
* dc
= new wxWindowDC(this);
3042 dc
->SetClippingRegion(wxRegion(updatergn
));
3044 dc
->SetClippingRegion(wxRegion(newupdate
));
3046 wxEraseEvent
eevent( GetId(), dc
);
3047 eevent
.SetEventObject( this );
3048 GetEventHandler()->ProcessEvent( eevent
);
3052 // calculate a client-origin version of the update rgn and set m_updateRegion to that
3053 OffsetRgn( newupdate
, -origin
.x
, -origin
.y
) ;
3054 m_updateRegion
= newupdate
;
3055 DisposeRgn( newupdate
) ;
3057 if ( !m_updateRegion
.Empty() )
3059 // paint the window itself
3062 event
.SetTimestamp(time
);
3063 event
.SetEventObject(this);
3064 GetEventHandler()->ProcessEvent(event
);
3068 // now we cannot rely on having its borders drawn by a window itself, as it does not
3069 // get the updateRgn wide enough to always do so, so we do it from the parent
3070 // this would also be the place to draw any custom backgrounds for native controls
3071 // in Composited windowing
3072 wxPoint clientOrigin
= GetClientAreaOrigin() ;
3076 for (wxWindowList::compatibility_iterator node
= GetChildren().GetFirst(); node
; node
= node
->GetNext())
3078 child
= node
->GetData();
3081 if (child
== m_vScrollBar
)
3083 if (child
== m_hScrollBar
)
3085 if (child
->IsTopLevel())
3087 if (!child
->IsShown())
3090 // only draw those in the update region (add a safety margin of 10 pixels for shadow effects
3092 child
->GetPosition( &x
, &y
);
3093 child
->GetSize( &w
, &h
);
3094 Rect childRect
= { y
, x
, y
+ h
, x
+ w
} ;
3095 OffsetRect( &childRect
, clientOrigin
.x
, clientOrigin
.y
) ;
3096 InsetRect( &childRect
, -10 , -10) ;
3098 if ( RectInRgn( &childRect
, updatergn
) )
3100 // paint custom borders
3101 wxNcPaintEvent
eventNc( child
->GetId() );
3102 eventNc
.SetEventObject( child
);
3103 if ( !child
->GetEventHandler()->ProcessEvent( eventNc
) )
3105 #if wxMAC_USE_CORE_GRAPHICS
3106 child
->MacPaintBorders(0, 0) ;
3109 wxWindowDC
dc(this) ;
3110 dc
.SetClippingRegion(wxRegion(updatergn
));
3111 wxMacPortSetter
helper(&dc
) ;
3112 child
->MacPaintBorders(0, 0) ;
3124 WXWindow
wxWindowMac::MacGetTopLevelWindowRef() const
3126 wxWindowMac
*iter
= (wxWindowMac
*)this ;
3130 if ( iter
->IsTopLevel() )
3131 return ((wxTopLevelWindow
*)iter
)->MacGetWindowRef() ;
3133 iter
= iter
->GetParent() ;
3139 void wxWindowMac::MacCreateScrollBars( long style
)
3141 wxASSERT_MSG( m_vScrollBar
== NULL
&& m_hScrollBar
== NULL
, wxT("attempt to create window twice") ) ;
3143 if ( style
& ( wxVSCROLL
| wxHSCROLL
) )
3145 bool hasBoth
= ( style
& wxVSCROLL
) && ( style
& wxHSCROLL
) ;
3146 int scrlsize
= MAC_SCROLLBAR_SIZE
;
3147 if ( GetWindowVariant() == wxWINDOW_VARIANT_SMALL
|| GetWindowVariant() == wxWINDOW_VARIANT_MINI
)
3149 scrlsize
= MAC_SMALL_SCROLLBAR_SIZE
;
3152 int adjust
= hasBoth
? scrlsize
- 1: 0 ;
3154 GetClientSize( &width
, &height
) ;
3156 wxPoint
vPoint(width
- scrlsize
, 0) ;
3157 wxSize
vSize(scrlsize
, height
- adjust
) ;
3158 wxPoint
hPoint(0, height
- scrlsize
) ;
3159 wxSize
hSize(width
- adjust
, scrlsize
) ;
3161 if ( style
& wxVSCROLL
)
3162 m_vScrollBar
= new wxScrollBar(this, wxID_ANY
, vPoint
, vSize
, wxVERTICAL
);
3164 if ( style
& wxHSCROLL
)
3165 m_hScrollBar
= new wxScrollBar(this, wxID_ANY
, hPoint
, hSize
, wxHORIZONTAL
);
3168 // because the create does not take into account the client area origin
3169 // we might have a real position shift
3170 MacRepositionScrollBars() ;
3173 bool wxWindowMac::MacIsChildOfClientArea( const wxWindow
* child
) const
3175 bool result
= ((child
== NULL
) || ((child
!= m_hScrollBar
) && (child
!= m_vScrollBar
)));
3180 void wxWindowMac::MacRepositionScrollBars()
3182 if ( !m_hScrollBar
&& !m_vScrollBar
)
3185 bool hasBoth
= (m_hScrollBar
&& m_hScrollBar
->IsShown()) && ( m_vScrollBar
&& m_vScrollBar
->IsShown()) ;
3186 int scrlsize
= m_hScrollBar
? m_hScrollBar
->GetSize().y
: ( m_vScrollBar
? m_vScrollBar
->GetSize().x
: MAC_SCROLLBAR_SIZE
) ;
3187 int adjust
= hasBoth
? scrlsize
- 1 : 0 ;
3189 // get real client area
3191 GetSize( &width
, &height
);
3193 width
-= MacGetLeftBorderSize() + MacGetRightBorderSize();
3194 height
-= MacGetTopBorderSize() + MacGetBottomBorderSize();
3196 wxPoint
vPoint( width
- scrlsize
, 0 ) ;
3197 wxSize
vSize( scrlsize
, height
- adjust
) ;
3198 wxPoint
hPoint( 0 , height
- scrlsize
) ;
3199 wxSize
hSize( width
- adjust
, scrlsize
) ;
3202 int x
= 0, y
= 0, w
, h
;
3203 GetSize( &w
, &h
) ;
3205 MacClientToRootWindow( &x
, &y
) ;
3206 MacClientToRootWindow( &w
, &h
) ;
3208 wxWindowMac
*iter
= (wxWindowMac
*)this ;
3210 int totW
= 10000 , totH
= 10000;
3213 if ( iter
->IsTopLevel() )
3215 iter
->GetSize( &totW
, &totH
) ;
3219 iter
= iter
->GetParent() ;
3233 if ( w
- x
>= totW
)
3238 if ( h
- y
>= totH
)
3246 m_vScrollBar
->SetSize( vPoint
.x
, vPoint
.y
, vSize
.x
, vSize
.y
, wxSIZE_ALLOW_MINUS_ONE
);
3248 m_hScrollBar
->SetSize( hPoint
.x
, hPoint
.y
, hSize
.x
, hSize
.y
, wxSIZE_ALLOW_MINUS_ONE
);
3251 bool wxWindowMac::AcceptsFocus() const
3253 return MacCanFocus() && wxWindowBase::AcceptsFocus();
3256 void wxWindowMac::MacSuperChangedPosition()
3258 // only window-absolute structures have to be moved i.e. controls
3260 m_cachedClippedRectValid
= false ;
3263 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
3266 child
= node
->GetData();
3267 child
->MacSuperChangedPosition() ;
3269 node
= node
->GetNext();
3273 void wxWindowMac::MacTopLevelWindowChangedPosition()
3275 // only screen-absolute structures have to be moved i.e. glcanvas
3278 wxWindowList::compatibility_iterator node
= GetChildren().GetFirst();
3281 child
= node
->GetData();
3282 child
->MacTopLevelWindowChangedPosition() ;
3284 node
= node
->GetNext();
3288 long wxWindowMac::MacGetLeftBorderSize() const
3295 if (HasFlag(wxRAISED_BORDER
) || HasFlag( wxSUNKEN_BORDER
) || HasFlag(wxDOUBLE_BORDER
))
3297 // this metric is only the 'outset' outside the simple frame rect
3298 GetThemeMetric( kThemeMetricEditTextFrameOutset
, &border
) ;
3301 else if (HasFlag(wxSIMPLE_BORDER
))
3303 // this metric is only the 'outset' outside the simple frame rect
3304 GetThemeMetric( kThemeMetricListBoxFrameOutset
, &border
) ;
3311 long wxWindowMac::MacGetRightBorderSize() const
3313 // they are all symmetric in mac themes
3314 return MacGetLeftBorderSize() ;
3317 long wxWindowMac::MacGetTopBorderSize() const
3319 // they are all symmetric in mac themes
3320 return MacGetLeftBorderSize() ;
3323 long wxWindowMac::MacGetBottomBorderSize() const
3325 // they are all symmetric in mac themes
3326 return MacGetLeftBorderSize() ;
3329 long wxWindowMac::MacRemoveBordersFromStyle( long style
)
3331 return style
& ~wxBORDER_MASK
;
3334 // Find the wxWindowMac at the current mouse position, returning the mouse
3336 wxWindowMac
* wxFindWindowAtPointer( wxPoint
& pt
)
3338 pt
= wxGetMousePosition();
3339 wxWindowMac
* found
= wxFindWindowAtPoint(pt
);
3344 // Get the current mouse position.
3345 wxPoint
wxGetMousePosition()
3349 wxGetMousePosition( &x
, &y
);
3351 return wxPoint(x
, y
);
3354 void wxWindowMac::OnMouseEvent( wxMouseEvent
&event
)
3356 if ( event
.GetEventType() == wxEVT_RIGHT_DOWN
)
3358 // copied from wxGTK : CS
3359 // VZ: shouldn't we move this to base class then?
3361 // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN
3364 // (a) it's a command event and so is propagated to the parent
3365 // (b) under MSW it can be generated from kbd too
3366 // (c) it uses screen coords (because of (a))
3367 wxContextMenuEvent
evtCtx(wxEVT_CONTEXT_MENU
,
3369 this->ClientToScreen(event
.GetPosition()));
3370 if ( ! GetEventHandler()->ProcessEvent(evtCtx
) )
3379 void wxWindowMac::OnPaint( wxPaintEvent
& event
)
3381 if ( wxTheApp
->MacGetCurrentEvent() != NULL
&& wxTheApp
->MacGetCurrentEventHandlerCallRef() != NULL
3382 && GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT
)
3383 CallNextEventHandler(
3384 (EventHandlerCallRef
)wxTheApp
->MacGetCurrentEventHandlerCallRef() ,
3385 (EventRef
) wxTheApp
->MacGetCurrentEvent() ) ;
3388 void wxWindowMac::MacHandleControlClick( WXWidget control
, wxInt16 controlpart
, bool WXUNUSED( mouseStillDown
) )
3392 Rect
wxMacGetBoundsForControl( wxWindow
* window
, const wxPoint
& pos
, const wxSize
&size
, bool adjustForOrigin
)
3396 window
->MacGetBoundsForControl( pos
, size
, x
, y
, w
, h
, adjustForOrigin
) ;
3397 Rect bounds
= { y
, x
, y
+ h
, x
+ w
};
3402 wxInt32
wxWindowMac::MacControlHit(WXEVENTHANDLERREF
WXUNUSED(handler
) , WXEVENTREF
WXUNUSED(event
) )
3404 return eventNotHandledErr
;
3407 bool wxWindowMac::Reparent(wxWindowBase
*newParentBase
)
3409 wxWindowMac
*newParent
= (wxWindowMac
*)newParentBase
;
3410 if ( !wxWindowBase::Reparent(newParent
) )
3413 // copied from MacPostControlCreate
3414 ControlRef container
= (ControlRef
) GetParent()->GetHandle() ;
3416 wxASSERT_MSG( container
!= NULL
, wxT("No valid mac container control") ) ;
3418 ::EmbedControl( m_peer
->GetControlRef() , container
) ;
3423 bool wxWindowMac::SetTransparent(wxByte alpha
)
3425 #if wxMAC_USE_CORE_GRAPHICS
3426 SetBackgroundStyle(wxBG_STYLE_TRANSPARENT
);
3428 if ( alpha
!= m_macAlpha
)
3430 m_macAlpha
= alpha
;
3440 bool wxWindowMac::CanSetTransparent()
3442 #if wxMAC_USE_CORE_GRAPHICS
3449 wxByte
wxWindowMac::GetTransparent() const