+ if( dx == 0 && dy ==0 )
+ return ;
+
+
+ {
+ wxClientDC dc(this) ;
+ wxMacPortSetter helper(&dc) ;
+
+ int width , height ;
+ GetClientSize( &width , &height ) ;
+
+
+ wxPoint pos;
+ pos.x = pos.y = 0;
+
+ Rect scrollrect;
+ // TODO take out the boundaries
+ GetControlBounds( (ControlRef) m_macControl, &scrollrect);
+
+ RgnHandle updateRgn = NewRgn() ;
+ if ( rect )
+ {
+ Rect r = { dc.YLOG2DEVMAC(rect->y) , dc.XLOG2DEVMAC(rect->x) , dc.YLOG2DEVMAC(rect->y + rect->height) ,
+ dc.XLOG2DEVMAC(rect->x + rect->width) } ;
+ SectRect( &scrollrect , &r , &scrollrect ) ;
+ }
+ ScrollRect( &scrollrect , dx , dy , updateRgn ) ;
+#if TARGET_CARBON
+ //KO: The docs say ScrollRect creates an update region, which thus calls an update event
+ // but it seems the update only refreshes the background of the control, rather than calling
+ // kEventControlDraw, so we need to force a proper update here. There has to be a better
+ // way of doing this... (Note that code below under !TARGET_CARBON does not work either...)
+ Update();
+#endif
+ // we also have to scroll the update rgn in this rectangle
+ // in order not to loose updates
+#if !TARGET_CARBON
+ WindowRef rootWindow = (WindowRef) MacGetTopLevelWindowRef() ;
+ RgnHandle formerUpdateRgn = NewRgn() ;
+ RgnHandle scrollRgn = NewRgn() ;
+ RectRgn( scrollRgn , &scrollrect ) ;
+ GetWindowUpdateRgn( rootWindow , formerUpdateRgn ) ;
+ Point pt = {0,0} ;
+ LocalToGlobal( &pt ) ;
+ OffsetRgn( formerUpdateRgn , -pt.h , -pt.v ) ;
+ SectRgn( formerUpdateRgn , scrollRgn , formerUpdateRgn ) ;
+ if ( !EmptyRgn( formerUpdateRgn ) )
+ {
+ MacOffsetRgn( formerUpdateRgn , dx , dy ) ;
+ SectRgn( formerUpdateRgn , scrollRgn , formerUpdateRgn ) ;
+ InvalWindowRgn(rootWindow , formerUpdateRgn ) ;
+ }
+ InvalWindowRgn(rootWindow , updateRgn ) ;
+ DisposeRgn( updateRgn ) ;
+ DisposeRgn( formerUpdateRgn ) ;
+ DisposeRgn( scrollRgn ) ;
+#endif
+ }
+
+ for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext())
+ {
+ wxWindowMac *child = node->GetData();
+ if (child == m_vScrollBar) continue;
+ if (child == m_hScrollBar) continue;
+ if (child->IsTopLevel()) continue;
+
+ int x,y;
+ child->GetPosition( &x, &y );
+ int w,h;
+ child->GetSize( &w, &h );
+ if (rect)
+ {
+ wxRect rc(x,y,w,h);
+ if (rect->Intersects(rc))
+ child->SetSize( x+dx, y+dy, w, h );
+ }
+ else
+ {
+ child->SetSize( x+dx, y+dy, w, h );
+ }
+ }
+
+// TODO remove, was moved higher up Update() ;
+
+}
+
+void wxWindowMac::MacOnScroll(wxScrollEvent &event )
+{
+ if ( event.m_eventObject == m_vScrollBar || event.m_eventObject == m_hScrollBar )
+ {
+ wxScrollWinEvent wevent;
+ wevent.SetPosition(event.GetPosition());
+ wevent.SetOrientation(event.GetOrientation());
+ wevent.m_eventObject = this;
+
+ if (event.m_eventType == wxEVT_SCROLL_TOP)
+ wevent.m_eventType = wxEVT_SCROLLWIN_TOP;
+ else if (event.m_eventType == wxEVT_SCROLL_BOTTOM)
+ wevent.m_eventType = wxEVT_SCROLLWIN_BOTTOM;
+ else if (event.m_eventType == wxEVT_SCROLL_LINEUP)
+ wevent.m_eventType = wxEVT_SCROLLWIN_LINEUP;
+ else if (event.m_eventType == wxEVT_SCROLL_LINEDOWN)
+ wevent.m_eventType = wxEVT_SCROLLWIN_LINEDOWN;
+ else if (event.m_eventType == wxEVT_SCROLL_PAGEUP)
+ wevent.m_eventType = wxEVT_SCROLLWIN_PAGEUP;
+ else if (event.m_eventType == wxEVT_SCROLL_PAGEDOWN)
+ wevent.m_eventType = wxEVT_SCROLLWIN_PAGEDOWN;
+ else if (event.m_eventType == wxEVT_SCROLL_THUMBTRACK)
+ wevent.m_eventType = wxEVT_SCROLLWIN_THUMBTRACK;
+ else if (event.m_eventType == wxEVT_SCROLL_THUMBRELEASE)
+ wevent.m_eventType = wxEVT_SCROLLWIN_THUMBRELEASE;
+
+ GetEventHandler()->ProcessEvent(wevent);
+ }
+}
+
+// Get the window with the focus
+wxWindowMac *wxWindowBase::FindFocus()
+{
+ return gFocusWindow ;
+}
+
+void wxWindowMac::OnSetFocus(wxFocusEvent& event)
+{
+ // panel wants to track the window which was the last to have focus in it,
+ // so we want to set ourselves as the window which last had focus
+ //
+ // notice that it's also important to do it upwards the tree becaus
+ // otherwise when the top level panel gets focus, it won't set it back to
+ // us, but to some other sibling
+
+ // CS:don't know if this is still needed:
+ //wxChildFocusEvent eventFocus(this);
+ //(void)GetEventHandler()->ProcessEvent(eventFocus);
+
+ event.Skip();
+}
+
+void wxWindowMac::OnInternalIdle()
+{
+ // This calls the UI-update mechanism (querying windows for
+ // menu/toolbar/control state information)
+ if (wxUpdateUIEvent::CanUpdate(this))
+ UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
+}
+
+// Raise the window to the top of the Z order
+void wxWindowMac::Raise()
+{
+}
+
+// Lower the window to the bottom of the Z order
+void wxWindowMac::Lower()
+{
+}
+
+
+// static wxWindow *gs_lastWhich = NULL;
+
+bool wxWindowMac::MacSetupCursor( const wxPoint& pt)
+{
+ // first trigger a set cursor event
+
+ wxPoint clientorigin = GetClientAreaOrigin() ;
+ wxSize clientsize = GetClientSize() ;
+ wxCursor cursor ;
+ if ( wxRect2DInt( clientorigin.x , clientorigin.y , clientsize.x , clientsize.y ).Contains( wxPoint2DInt( pt ) ) )
+ {
+ wxSetCursorEvent event( pt.x , pt.y );
+
+ bool processedEvtSetCursor = GetEventHandler()->ProcessEvent(event);
+ if ( processedEvtSetCursor && event.HasCursor() )
+ {
+ cursor = event.GetCursor() ;
+ }
+ else
+ {
+
+ // the test for processedEvtSetCursor is here to prevent using m_cursor
+ // if the user code caught EVT_SET_CURSOR() and returned nothing from
+ // it - this is a way to say that our cursor shouldn't be used for this
+ // point
+ if ( !processedEvtSetCursor && m_cursor.Ok() )
+ {
+ cursor = m_cursor ;
+ }
+ if ( wxIsBusy() )
+ {
+ }
+ else
+ {
+ if ( !GetParent() )
+ cursor = *wxSTANDARD_CURSOR ;
+ }
+ }
+ if ( cursor.Ok() )
+ cursor.MacInstall() ;
+ }
+ return cursor.Ok() ;
+}
+
+wxString wxWindowMac::MacGetToolTipString( wxPoint &pt )
+{
+ if ( m_tooltip )
+ {
+ return m_tooltip->GetTip() ;
+ }
+ return wxEmptyString ;
+}
+
+void wxWindowMac::Update()
+{
+#if TARGET_API_MAC_OSX
+ HIViewSetNeedsDisplay( (ControlRef) m_macControl , true ) ;
+#else
+ ::Draw1Control( (ControlRef) m_macControl ) ;
+#endif
+}
+
+wxTopLevelWindowMac* wxWindowMac::MacGetTopLevelWindow() const
+{
+ wxTopLevelWindowMac* win = NULL ;
+ WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
+ if ( window )
+ {
+ win = wxFindWinFromMacWindow( window ) ;
+ }
+ return win ;
+}
+wxRegion wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures )
+{
+
+ Rect r ;
+ RgnHandle visRgn = NewRgn() ;
+ RgnHandle tempRgn = NewRgn() ;
+ if ( IsControlVisible( (ControlRef) m_macControl ) )
+ {
+ GetControlBounds( (ControlRef) m_macControl , &r ) ;
+ if (! MacGetTopLevelWindow()->MacUsesCompositing() )
+ {
+ MacRootWindowToWindow( &r.left , & r.top ) ;
+ MacRootWindowToWindow( &r.right , & r.bottom ) ;
+ }
+ else
+ {
+ r.right -= r.left ;
+ r.bottom -= r.top ;
+ r.left = 0 ;
+ r.top = 0 ;
+ }
+ if ( includeOuterStructures )
+ InsetRect( &r , -3 , -3 ) ;
+ RectRgn( visRgn , &r ) ;
+ if ( !IsTopLevel() )
+ {
+ wxWindow* child = this ;
+ wxWindow* parent = child->GetParent() ;
+ while( parent )
+ {
+ int x , y ;
+ wxSize size ;
+ // we have to find a better clipping algorithm here, in order not to clip things
+ // positioned like status and toolbar
+ if ( 1 /* parent->IsTopLevel() && child->IsKindOf( CLASSINFO( wxToolBar ) ) */ )
+ {
+ size = parent->GetSize() ;
+ x = y = 0 ;
+ }
+ else
+ {
+ size = parent->GetClientSize() ;
+ wxPoint origin = parent->GetClientAreaOrigin() ;
+ x = origin.x ;
+ y = origin.y ;
+ }
+ parent->MacWindowToRootWindow( &x, &y ) ;
+ MacRootWindowToWindow( &x , &y ) ;
+
+ SetRectRgn( tempRgn ,
+ x + parent->MacGetLeftBorderSize() , y + parent->MacGetTopBorderSize() ,
+ x + size.x - parent->MacGetRightBorderSize(),
+ y + size.y - parent->MacGetBottomBorderSize()) ;
+
+ SectRgn( visRgn , tempRgn , visRgn ) ;
+ if ( parent->IsTopLevel() )
+ break ;
+ child = parent ;
+ parent = child->GetParent() ;
+ }
+ }
+ }
+
+ wxRegion vis = visRgn ;
+ DisposeRgn( visRgn ) ;
+ DisposeRgn( tempRgn ) ;
+ return vis ;
+}
+
+/*
+ This function must not change the updatergn !
+ */
+bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time )
+{
+ RgnHandle updatergn = (RgnHandle) updatergnr ;
+ bool handled = false ;
+
+ // calculate a client-origin version of the update rgn and set m_updateRegion to that
+ {
+ RgnHandle newupdate = NewRgn() ;
+ wxSize point = GetClientSize() ;
+ wxPoint origin = GetClientAreaOrigin() ;
+ SetRectRgn( newupdate , origin.x , origin.y , origin.x + point.x , origin.y+point.y ) ;
+ SectRgn( newupdate , updatergn , newupdate ) ;
+ OffsetRgn( newupdate , -origin.x , -origin.y ) ;
+ m_updateRegion = newupdate ;
+ DisposeRgn( newupdate ) ;
+ }
+
+ if ( !EmptyRgn(updatergn) )
+ {
+ wxWindowDC dc(this);
+ if (!EmptyRgn(updatergn))
+ dc.SetClippingRegion(wxRegion(updatergn));
+
+ wxEraseEvent eevent( GetId(), &dc );
+ eevent.SetEventObject( this );
+ GetEventHandler()->ProcessEvent( eevent );
+
+ if ( !m_updateRegion.Empty() )
+ {
+ // paint the window itself
+ wxPaintEvent event;
+ event.m_timeStamp = time ;
+ event.SetEventObject(this);
+ handled = GetEventHandler()->ProcessEvent(event);
+
+ // paint custom borders
+ wxNcPaintEvent eventNc( GetId() );
+ eventNc.SetEventObject( this );
+ GetEventHandler()->ProcessEvent( eventNc );
+ }
+ }
+ return handled ;
+}
+
+void wxWindowMac::MacRedraw( WXHRGN updatergnr , long time, bool erase)
+{
+ RgnHandle updatergn = (RgnHandle) updatergnr ;
+ // updatergn is always already clipped to our boundaries
+ // if we are in compositing mode then it is in relative to the upper left of the control
+ // if we are in non-compositing, then it is relatvie to the uppder left of the content area
+ // of the toplevel window
+ // it is in window coordinates, not in client coordinates
+
+ // ownUpdateRgn is the area that this window has to repaint, it is in window coordinates
+ RgnHandle ownUpdateRgn = NewRgn() ;
+ CopyRgn( updatergn , ownUpdateRgn ) ;
+
+ if ( MacGetTopLevelWindow()->MacUsesCompositing() == false )
+ {
+ Rect bounds;
+ UMAGetControlBoundsInWindowCoords( (ControlRef)m_macControl, &bounds );
+ RgnHandle controlRgn = NewRgn();
+ RectRgn( controlRgn, &bounds );
+ //KO: This sets the ownUpdateRgn to the area of this control that is inside
+ // the window update region
+ SectRgn( ownUpdateRgn, controlRgn, ownUpdateRgn );
+ DisposeRgn( controlRgn );
+
+ //KO: convert ownUpdateRgn to local coordinates
+ OffsetRgn( ownUpdateRgn, -bounds.left, -bounds.top );
+ }
+
+ MacDoRedraw( ownUpdateRgn , time ) ;
+ DisposeRgn( ownUpdateRgn ) ;
+
+}
+
+WXWindow wxWindowMac::MacGetTopLevelWindowRef() const
+{
+ wxWindowMac *iter = (wxWindowMac*)this ;
+
+ while( iter )
+ {
+ if ( iter->IsTopLevel() )
+ return ((wxTopLevelWindow*)iter)->MacGetWindowRef() ;
+
+ iter = iter->GetParent() ;
+ }
+ wxASSERT_MSG( 1 , wxT("No valid mac root window") ) ;
+ return NULL ;
+}
+
+void wxWindowMac::MacCreateScrollBars( long style )
+{
+ wxASSERT_MSG( m_vScrollBar == NULL && m_hScrollBar == NULL , wxT("attempt to create window twice") ) ;
+
+ bool hasBoth = ( style & wxVSCROLL ) && ( style & wxHSCROLL ) ;
+ int adjust = hasBoth ? MAC_SCROLLBAR_SIZE - 1: 0 ;
+ int width, height ;
+ GetClientSize( &width , &height ) ;
+
+ wxPoint vPoint(width-MAC_SCROLLBAR_SIZE, 0) ;
+ wxSize vSize(MAC_SCROLLBAR_SIZE, height - adjust) ;
+ wxPoint hPoint(0 , height-MAC_SCROLLBAR_SIZE ) ;
+ wxSize hSize( width - adjust, MAC_SCROLLBAR_SIZE) ;
+
+ m_vScrollBar = new wxScrollBar(this, wxWINDOW_VSCROLL, vPoint,
+ vSize , wxVERTICAL);
+
+ if ( style & wxVSCROLL )
+ {
+
+ }
+ else
+ {
+ m_vScrollBar->Show(false) ;
+ }
+ m_hScrollBar = new wxScrollBar(this, wxWINDOW_HSCROLL, hPoint,
+ hSize , wxHORIZONTAL);
+ if ( style & wxHSCROLL )
+ {
+ }
+ else
+ {
+ m_hScrollBar->Show(false) ;
+ }
+
+ // because the create does not take into account the client area origin
+ MacRepositionScrollBars() ; // we might have a real position shift
+}
+
+void wxWindowMac::MacRepositionScrollBars()
+{
+ bool hasBoth = ( m_hScrollBar && m_hScrollBar->IsShown()) && ( m_vScrollBar && m_vScrollBar->IsShown()) ;
+ int adjust = hasBoth ? MAC_SCROLLBAR_SIZE - 1 : 0 ;
+
+ // get real client area
+
+ int width ;
+ int height ;
+ GetSize( &width , &height ) ;
+
+ width -= MacGetLeftBorderSize() + MacGetRightBorderSize();
+ height -= MacGetTopBorderSize() + MacGetBottomBorderSize();
+
+ wxPoint vPoint(width-MAC_SCROLLBAR_SIZE, 0) ;
+ wxSize vSize(MAC_SCROLLBAR_SIZE, height - adjust) ;
+ wxPoint hPoint(0 , height-MAC_SCROLLBAR_SIZE ) ;
+ wxSize hSize( width - adjust, MAC_SCROLLBAR_SIZE) ;
+
+ int x = 0 ;
+ int y = 0 ;
+ int w ;
+ int h ;
+ GetSize( &w , &h ) ;
+
+ MacClientToRootWindow( &x , &y ) ;
+ MacClientToRootWindow( &w , &h ) ;
+
+ wxWindowMac *iter = (wxWindowMac*)this ;
+
+ int totW = 10000 , totH = 10000;
+ while( iter )
+ {
+ if ( iter->IsTopLevel() )
+ {
+ iter->GetSize( &totW , &totH ) ;
+ break ;
+ }
+
+ iter = iter->GetParent() ;
+ }
+
+ if ( x == 0 )
+ {
+ hPoint.x = -1 ;
+ hSize.x += 1 ;
+ }
+ if ( y == 0 )
+ {
+ vPoint.y = -1 ;
+ vSize.y += 1 ;
+ }
+
+ if ( w-x >= totW )
+ {
+ hSize.x += 1 ;
+ vPoint.x += 1 ;
+ }
+
+ if ( h-y >= totH )
+ {
+ vSize.y += 1 ;
+ hPoint.y += 1 ;
+ }
+
+ if ( m_vScrollBar )
+ {
+ m_vScrollBar->SetSize( vPoint.x , vPoint.y, vSize.x, vSize.y , wxSIZE_ALLOW_MINUS_ONE);
+ }
+ if ( m_hScrollBar )
+ {
+ m_hScrollBar->SetSize( hPoint.x , hPoint.y, hSize.x, hSize.y, wxSIZE_ALLOW_MINUS_ONE);
+ }
+}
+
+bool wxWindowMac::AcceptsFocus() const
+{
+ return MacCanFocus() && wxWindowBase::AcceptsFocus();
+}
+
+void wxWindowMac::MacSuperChangedPosition()
+{
+ // only window-absolute structures have to be moved i.e. controls
+
+ wxWindowListNode *node = GetChildren().GetFirst();
+ while ( node )
+ {
+ wxWindowMac *child = node->GetData();
+ child->MacSuperChangedPosition() ;
+ node = node->GetNext();
+ }
+}
+
+void wxWindowMac::MacTopLevelWindowChangedPosition()
+{
+ // only screen-absolute structures have to be moved i.e. glcanvas
+
+ wxWindowListNode *node = GetChildren().GetFirst();
+ while ( node )
+ {
+ wxWindowMac *child = node->GetData();
+ child->MacTopLevelWindowChangedPosition() ;
+ node = node->GetNext();
+ }
+}
+
+long wxWindowMac::MacGetLeftBorderSize( ) const
+{
+ if( IsTopLevel() )
+ return 0 ;
+
+ if (m_windowStyle & wxRAISED_BORDER || m_windowStyle & wxSUNKEN_BORDER )
+ {
+ SInt32 border = 3 ;
+#if wxMAC_USE_THEME_BORDER
+ GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
+#endif
+ return border ;
+ }
+ else if ( m_windowStyle &wxDOUBLE_BORDER)
+ {
+ SInt32 border = 3 ;
+#if wxMAC_USE_THEME_BORDER
+ GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
+#endif
+ return border ;
+ }
+ else if (m_windowStyle &wxSIMPLE_BORDER)
+ {
+ return 1 ;
+ }
+ return 0 ;
+}
+
+long wxWindowMac::MacGetRightBorderSize( ) const
+{
+ // they are all symmetric in mac themes
+ return MacGetLeftBorderSize() ;
+}
+
+long wxWindowMac::MacGetTopBorderSize( ) const
+{
+ // they are all symmetric in mac themes
+ return MacGetLeftBorderSize() ;
+}
+
+long wxWindowMac::MacGetBottomBorderSize( ) const
+{
+ // they are all symmetric in mac themes
+ return MacGetLeftBorderSize() ;
+}
+
+long wxWindowMac::MacRemoveBordersFromStyle( long style )
+{
+ return style & ~( wxDOUBLE_BORDER | wxSUNKEN_BORDER | wxRAISED_BORDER | wxBORDER | wxSTATIC_BORDER ) ;
+}
+
+// Find the wxWindowMac at the current mouse position, returning the mouse
+// position.
+wxWindowMac* wxFindWindowAtPointer(wxPoint& pt)
+{
+ pt = wxGetMousePosition();
+ wxWindowMac* found = wxFindWindowAtPoint(pt);
+ return found;
+}
+
+// Get the current mouse position.
+wxPoint wxGetMousePosition()
+{
+ int x, y;
+ wxGetMousePosition(& x, & y);
+ return wxPoint(x, y);
+}
+
+void wxWindowMac::OnMouseEvent( wxMouseEvent &event )
+{
+ if ( event.GetEventType() == wxEVT_RIGHT_DOWN )