+ ControlRef controlFocus = 0 ;
+ GetKeyboardFocus( m_txnWindow , &controlFocus ) ;
+
+ if ( !vis && (controlFocus == m_controlRef ) )
+ SetKeyboardFocus( m_txnWindow , m_controlRef , kControlFocusNoPart ) ;
+
+ TXNControlTag iControlTags[1] = { kTXNVisibilityTag };
+ TXNControlData iControlData[1] = { { (UInt32)false } };
+
+ verify_noerr( TXNGetTXNObjectControls( m_txn , 1, iControlTags, iControlData ) ) ;
+
+ if ( iControlData[0].uValue != vis )
+ {
+ iControlData[0].uValue = vis ;
+ verify_noerr( TXNSetTXNObjectControls( m_txn, false , 1, iControlTags, iControlData ) ) ;
+ }
+
+ // currently, we always clip as partial visibility (overlapped) visibility is also a problem,
+ // if we run into further problems we might set the FrameBounds to an empty rect here
+}
+
+// make sure that the TXNObject is at the right position
+
+void wxMacMLTEClassicControl::MacUpdatePosition()
+{
+ wxTextCtrl* textctrl = (wxTextCtrl*)GetControlReference( m_controlRef );
+ if ( textctrl == NULL )
+ return ;
+
+ Rect bounds ;
+ UMAGetControlBoundsInWindowCoords( m_controlRef, &bounds );
+
+ wxRect visRect = textctrl->MacGetClippedClientRect() ;
+ Rect visBounds = { visRect.y , visRect.x , visRect.y + visRect.height , visRect.x + visRect.width } ;
+ int x , y ;
+ x = y = 0 ;
+ textctrl->MacWindowToRootWindow( &x , &y ) ;
+ OffsetRect( &visBounds , x , y ) ;
+
+ if ( !EqualRect( &bounds, &m_txnControlBounds ) || !EqualRect( &visBounds, &m_txnVisBounds ) )
+ {
+ m_txnControlBounds = bounds ;
+ m_txnVisBounds = visBounds ;
+ wxMacWindowClipper cl( textctrl ) ;
+
+#ifdef __WXMAC_OSX__
+ bool isCompositing = textctrl->MacGetTopLevelWindow()->MacUsesCompositing() ;
+ if ( m_sbHorizontal || m_sbVertical )
+ {
+ int w = bounds.right - bounds.left ;
+ int h = bounds.bottom - bounds.top ;
+
+ if ( m_sbHorizontal )
+ {
+ Rect sbBounds ;
+
+ sbBounds.left = -1 ;
+ sbBounds.top = h - 14 ;
+ sbBounds.right = w + 1 ;
+ sbBounds.bottom = h + 1 ;
+
+ if ( !isCompositing )
+ OffsetRect( &sbBounds , m_txnControlBounds.left , m_txnControlBounds.top ) ;
+
+ SetControlBounds( m_sbHorizontal , &sbBounds ) ;
+ SetControlViewSize( m_sbHorizontal , w ) ;
+ }
+
+ if ( m_sbVertical )
+ {
+ Rect sbBounds ;
+
+ sbBounds.left = w - 14 ;
+ sbBounds.top = -1 ;
+ sbBounds.right = w + 1 ;
+ sbBounds.bottom = m_sbHorizontal ? h - 14 : h + 1 ;
+
+ if ( !isCompositing )
+ OffsetRect( &sbBounds , m_txnControlBounds.left , m_txnControlBounds.top ) ;
+
+ SetControlBounds( m_sbVertical , &sbBounds ) ;
+ SetControlViewSize( m_sbVertical , h ) ;
+ }
+ }
+
+ Rect oldviewRect ;
+ TXNLongRect olddestRect ;
+ TXNGetRectBounds( m_txn , &oldviewRect , &olddestRect , NULL ) ;
+
+ Rect viewRect = { m_txnControlBounds.top, m_txnControlBounds.left,
+ m_txnControlBounds.bottom - ( m_sbHorizontal ? 14 : 0 ) ,
+ m_txnControlBounds.right - ( m_sbVertical ? 14 : 0 ) } ;
+ TXNLongRect destRect = { m_txnControlBounds.top, m_txnControlBounds.left,
+ m_txnControlBounds.bottom - ( m_sbHorizontal ? 14 : 0 ) ,
+ m_txnControlBounds.right - ( m_sbVertical ? 14 : 0 ) } ;
+
+ if ( olddestRect.right >= 10000 )
+ destRect.right = destRect.left + 32000 ;
+
+ if ( olddestRect.bottom >= 0x20000000 )
+ destRect.bottom = destRect.top + 0x40000000 ;
+
+ SectRect( &viewRect , &visBounds , &viewRect ) ;
+ TXNSetRectBounds( m_txn , &viewRect , &destRect , true ) ;
+
+#if 0
+ TXNSetFrameBounds(
+ m_txn,
+ m_txnControlBounds.top,
+ m_txnControlBounds.left,
+ m_txnControlBounds.bottom - (m_sbHorizontal ? 14 : 0),
+ m_txnControlBounds.right - (m_sbVertical ? 14 : 0),
+ m_txnFrameID );
+#endif
+#else
+
+ TXNSetFrameBounds(
+ m_txn, m_txnControlBounds.top, m_txnControlBounds.left,
+ wxMax( m_txnControlBounds.bottom, m_txnControlBounds.top ),
+ wxMax( m_txnControlBounds.right, m_txnControlBounds.left ), m_txnFrameID );
+#endif
+
+ // the SetFrameBounds method under Classic sometimes does not correctly scroll a selection into sight after a
+ // movement, therefore we have to force it
+
+ // this problem has been reported in OSX as well, so we use this here once again
+
+ TXNLongRect textRect ;
+ TXNGetRectBounds( m_txn , NULL , NULL , &textRect ) ;
+ if ( textRect.left < m_txnControlBounds.left )
+ TXNShowSelection( m_txn , kTXNShowStart ) ;
+ }
+}
+
+void wxMacMLTEClassicControl::SetRect( Rect *r )
+{
+ wxMacControl::SetRect( r ) ;
+ MacUpdatePosition() ;
+}
+
+void wxMacMLTEClassicControl::MacControlUserPaneDrawProc(wxInt16 thePart)
+{
+ wxTextCtrl* textctrl = (wxTextCtrl*)GetControlReference( m_controlRef );
+ if ( textctrl == NULL )
+ return ;
+
+ if ( textctrl->MacIsReallyShown() )
+ {
+ wxMacWindowClipper clipper( textctrl ) ;
+ TXNDraw( m_txn , NULL ) ;
+ }
+}
+
+wxInt16 wxMacMLTEClassicControl::MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y)
+{
+ Point where = { y , x } ;
+ ControlPartCode result = kControlNoPart;
+
+ wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference( m_controlRef );
+ if ( (textctrl != NULL) && textctrl->MacIsReallyShown() )
+ {
+ if (PtInRect( where, &m_txnControlBounds ))
+ {
+ result = kControlEditTextPart ;
+ }
+ else
+ {
+ // sometimes we get the coords also in control local coordinates, therefore test again
+ if ( textctrl->MacGetTopLevelWindow()->MacUsesCompositing() )
+ {
+ int x = 0 , y = 0 ;
+ textctrl->MacClientToRootWindow( &x , &y ) ;
+ where.h += x ;
+ where.v += y ;
+ }
+
+ if (PtInRect( where, &m_txnControlBounds ))
+ result = kControlEditTextPart ;
+ }
+ }
+
+ return result;
+}
+
+wxInt16 wxMacMLTEClassicControl::MacControlUserPaneTrackingProc( wxInt16 x, wxInt16 y, void* actionProc )
+{
+ ControlPartCode result = kControlNoPart;
+
+ wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference( m_controlRef );
+ if ( (textctrl != NULL) && textctrl->MacIsReallyShown() )
+ {
+ Point startPt = { y , x } ;
+ // for compositing, we must convert these into toplevel window coordinates, because hittesting expects them
+ if ( textctrl->MacGetTopLevelWindow()->MacUsesCompositing() )
+ {
+ int x = 0 , y = 0 ;
+ textctrl->MacClientToRootWindow( &x , &y ) ;
+ startPt.h += x ;
+ startPt.v += y ;
+ }
+
+ switch (MacControlUserPaneHitTestProc( startPt.h , startPt.v ))
+ {
+ case kControlEditTextPart :
+ {
+ wxMacWindowClipper clipper( textctrl ) ;
+ EventRecord rec ;
+
+ ConvertEventRefToEventRecord( (EventRef) wxTheApp->MacGetCurrentEvent() , &rec ) ;
+ TXNClick( m_txn, &rec );
+ }
+ break;
+
+ default :
+ break;
+ }
+ }
+
+ return result;
+}
+
+void wxMacMLTEClassicControl::MacControlUserPaneIdleProc()
+{
+ wxTextCtrl* textctrl = (wxTextCtrl*)GetControlReference( m_controlRef );
+ if ( textctrl == NULL )
+ return ;
+
+ if (textctrl->MacIsReallyShown())
+ {
+ if (IsControlActive(m_controlRef))
+ {
+ Point mousep;
+
+ wxMacWindowClipper clipper( textctrl ) ;
+ GetMouse(&mousep);
+
+ TXNIdle(m_txn);
+
+ if (PtInRect(mousep, &m_txnControlBounds))
+ {
+ RgnHandle theRgn = NewRgn();
+ RectRgn(theRgn, &m_txnControlBounds);
+ TXNAdjustCursor(m_txn, theRgn);
+ DisposeRgn(theRgn);
+ }
+ }
+ }
+}
+
+wxInt16 wxMacMLTEClassicControl::MacControlUserPaneKeyDownProc (wxInt16 keyCode, wxInt16 charCode, wxInt16 modifiers)
+{
+ wxTextCtrl* textctrl = (wxTextCtrl*)GetControlReference( m_controlRef );
+ if ( textctrl == NULL )
+ return kControlNoPart;
+
+ wxMacWindowClipper clipper( textctrl ) ;
+
+ EventRecord ev ;
+ memset( &ev , 0 , sizeof( ev ) ) ;
+ ev.what = keyDown ;
+ ev.modifiers = modifiers ;
+ ev.message = ((keyCode << 8) & keyCodeMask) | (charCode & charCodeMask);
+ TXNKeyDown( m_txn , &ev );
+
+ return kControlEntireControl;
+}
+
+void wxMacMLTEClassicControl::MacControlUserPaneActivateProc(bool activating)
+{
+ MacActivatePaneText( activating );
+}
+
+wxInt16 wxMacMLTEClassicControl::MacControlUserPaneFocusProc(wxInt16 action)
+{
+ ControlPartCode focusResult = kControlFocusNoPart;
+
+ wxTextCtrl* textctrl = (wxTextCtrl*)GetControlReference( m_controlRef );
+ if ( textctrl == NULL )
+ return focusResult;
+
+ wxMacWindowClipper clipper( textctrl ) ;
+
+ ControlRef controlFocus = NULL ;
+ GetKeyboardFocus( m_txnWindow , &controlFocus ) ;
+ bool wasFocused = ( controlFocus == m_controlRef ) ;
+
+ switch (action)
+ {
+ case kControlFocusPrevPart:
+ case kControlFocusNextPart:
+ MacFocusPaneText( !wasFocused );
+ focusResult = (!wasFocused ? (ControlPartCode) kControlEditTextPart : (ControlPartCode) kControlFocusNoPart);
+ break;
+
+ case kControlFocusNoPart:
+ default:
+ MacFocusPaneText( false );
+ focusResult = kControlFocusNoPart;
+ break;
+ }
+
+ return focusResult;
+}
+
+void wxMacMLTEClassicControl::MacControlUserPaneBackgroundProc( void *info )
+{
+}
+
+wxMacMLTEClassicControl::wxMacMLTEClassicControl( wxTextCtrl *wxPeer,
+ const wxString& str,
+ const wxPoint& pos,
+ const wxSize& size, long style ) : wxMacMLTEControl( wxPeer )
+{
+ m_font = wxPeer->GetFont() ;
+ m_windowStyle = style ;
+ Rect bounds = wxMacGetBoundsForControl( wxPeer , pos , size ) ;
+
+ short featureSet =
+ kControlSupportsEmbedding | kControlSupportsFocus | kControlWantsIdle
+ | kControlWantsActivate | kControlHandlesTracking
+// | kControlHasSpecialBackground
+ | kControlGetsFocusOnClick | kControlSupportsLiveFeedback;
+
+ verify_noerr(
+ ::CreateUserPaneControl(
+ MAC_WXHWND(wxPeer->GetParent()->MacGetTopLevelWindowRef()),
+ &bounds, featureSet, &m_controlRef ) );
+
+ DoCreate();
+
+ AdjustCreationAttributes( *wxWHITE , true ) ;
+
+ MacSetObjectVisibility( wxPeer->MacIsReallyShown() ) ;
+
+ {
+ wxString st = str ;
+ wxMacConvertNewlines10To13( &st ) ;
+ wxMacWindowClipper clipper( m_peer ) ;
+ SetTXNData( st , kTXNStartOffset, kTXNEndOffset ) ;
+ TXNSetSelection( m_txn, 0, 0 ) ;
+ }
+}
+
+wxMacMLTEClassicControl::~wxMacMLTEClassicControl()
+{
+ TXNDeleteObject( m_txn );
+ m_txn = NULL ;
+}
+
+void wxMacMLTEClassicControl::VisibilityChanged(bool shown)
+{
+ MacSetObjectVisibility( shown ) ;
+ wxMacControl::VisibilityChanged( shown ) ;
+}
+
+void wxMacMLTEClassicControl::SuperChangedPosition()
+{
+ MacUpdatePosition() ;
+ wxMacControl::SuperChangedPosition() ;
+}
+
+#ifdef __WXMAC_OSX__
+
+ControlUserPaneDrawUPP gTPDrawProc = NULL;
+ControlUserPaneHitTestUPP gTPHitProc = NULL;
+ControlUserPaneTrackingUPP gTPTrackProc = NULL;
+ControlUserPaneIdleUPP gTPIdleProc = NULL;
+ControlUserPaneKeyDownUPP gTPKeyProc = NULL;
+ControlUserPaneActivateUPP gTPActivateProc = NULL;
+ControlUserPaneFocusUPP gTPFocusProc = NULL;
+
+static pascal void wxMacControlUserPaneDrawProc(ControlRef control, SInt16 part)
+{
+ wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ;
+ wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ;
+ if ( win )
+ win->MacControlUserPaneDrawProc(part) ;
+}
+
+static pascal ControlPartCode wxMacControlUserPaneHitTestProc(ControlRef control, Point where)
+{
+ wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ;
+ wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ;
+ if ( win )
+ return win->MacControlUserPaneHitTestProc(where.h , where.v) ;
+ else
+ return kControlNoPart ;
+}
+
+static pascal ControlPartCode wxMacControlUserPaneTrackingProc(ControlRef control, Point startPt, ControlActionUPP actionProc)
+{
+ wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ;
+ wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ;
+ if ( win )
+ return win->MacControlUserPaneTrackingProc( startPt.h , startPt.v , (void*) actionProc) ;
+ else
+ return kControlNoPart ;
+}
+
+static pascal void wxMacControlUserPaneIdleProc(ControlRef control)
+{
+ wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ;
+ wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ;
+ if ( win )
+ win->MacControlUserPaneIdleProc() ;
+}
+
+static pascal ControlPartCode wxMacControlUserPaneKeyDownProc(ControlRef control, SInt16 keyCode, SInt16 charCode, SInt16 modifiers)
+{
+ wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ;
+ wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ;
+ if ( win )
+ return win->MacControlUserPaneKeyDownProc(keyCode,charCode,modifiers) ;
+ else
+ return kControlNoPart ;