X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/55866801f0927556c6a63ca91560a69fda21b965..30962327c9d5a850d9dc00864b1ffb448a832e6f:/src/mac/carbon/textctrl.cpp?ds=sidebyside diff --git a/src/mac/carbon/textctrl.cpp b/src/mac/carbon/textctrl.cpp index a35a213678..58e7befd83 100644 --- a/src/mac/carbon/textctrl.cpp +++ b/src/mac/carbon/textctrl.cpp @@ -40,11 +40,12 @@ #include "wx/button.h" #include "wx/toplevel.h" #include "wx/textctrl.h" -#include "wx/notebook.h" -#include "wx/tabctrl.h" #include "wx/settings.h" #include "wx/filefn.h" #include "wx/utils.h" +#include "wx/sysopt.h" +#include "wx/menu.h" +#include "wx/intl.h" #if defined(__BORLANDC__) && !defined(__WIN32__) #include @@ -59,20 +60,22 @@ // if this is set to 1 then under OSX 10.2 the 'classic' MLTE implementation will be used // if set to 0 then the unicode textctrl will be used #ifndef wxMAC_AWAYS_USE_MLTE -#define wxMAC_AWAYS_USE_MLTE 0 +#define wxMAC_AWAYS_USE_MLTE 1 #endif #ifndef __WXMAC_OSX__ -enum +enum { kTXNVisibilityTag = 'visb' /*set the visibility state of the object */ }; #endif +#ifndef __DARWIN__ #include #include #include #include +#endif #include "wx/mac/uma.h" class wxMacFunctor @@ -196,6 +199,7 @@ public : virtual void ShowPosition( long WXUNUSED(pos) ) ; virtual int GetLineLength(long lineNo) const ; virtual wxString GetLineText(long lineNo) const ; + virtual bool SetupCursor( const wxPoint& pt ) { return false ; } #ifndef __WXMAC_OSX__ virtual void MacControlUserPaneDrawProc(wxInt16 part) = 0 ; @@ -214,7 +218,7 @@ public : class wxMacMLTEControl : public wxMacTextControl { public : - wxMacMLTEControl( wxTextCtrl *peer ) : wxMacTextControl( peer ) {} + wxMacMLTEControl( wxTextCtrl *peer ) ; virtual wxString GetStringValue() const ; virtual void SetStringValue( const wxString &str) ; @@ -271,7 +275,6 @@ public : const wxSize& size, long style ) ; virtual OSStatus SetFocus( ControlFocusPart focusPart ) ; virtual bool HasFocus() const ; - virtual bool NeedsFocusRect() const; protected : HIViewRef m_scrollView ; HIViewRef m_textView ; @@ -317,7 +320,7 @@ public : const wxSize& size, long style ) ; ~wxMacMLTEClassicControl() ; virtual void VisibilityChanged(bool shown) ; - virtual bool NeedsFocusRect() const; + virtual void SuperChangedPosition() ; virtual void MacControlUserPaneDrawProc(wxInt16 part) ; virtual wxInt16 MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y) ; @@ -328,11 +331,13 @@ public : virtual wxInt16 MacControlUserPaneFocusProc(wxInt16 action) ; virtual void MacControlUserPaneBackgroundProc(void* info) ; + virtual bool SetupCursor( const wxPoint& WXUNUSED(pt) ) { MacControlUserPaneIdleProc() ; return true ;} + virtual void SetRect( Rect *r ) ; protected : OSStatus DoCreate(); - + void MacUpdatePosition() ; void MacActivatePaneText(Boolean setActive) ; void MacFocusPaneText(Boolean setFocus) ; @@ -341,18 +346,23 @@ protected : private : TXNFrameID m_txnFrameID ; GrafPtr m_txnPort ; + WindowRef m_txnWindow ; // bounds of the control as we last did set the txn frames Rect m_txnControlBounds ; - - bool m_txnIsFocused ; - bool m_txnIsActive ; - bool m_txnIsVisible ; - bool m_controlIsActive ; + Rect m_txnVisBounds ; +#ifdef __WXMAC_OSX__ + static pascal void TXNScrollInfoProc (SInt32 iValue, SInt32 iMaximumValue, + TXNScrollBarOrientation iScrollBarOrientation, SInt32 iRefCon) ; + static pascal void TXNScrollActionProc( ControlRef controlRef , ControlPartCode partCode ) ; + ControlRef m_sbHorizontal ; + SInt32 m_lastHorizontalValue ; + ControlRef m_sbVertical ; + SInt32 m_lastVerticalValue ; +#endif } ; #define TE_UNLIMITED_LENGTH 0xFFFFFFFFUL -#if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl) BEGIN_EVENT_TABLE(wxTextCtrl, wxControl) @@ -364,26 +374,34 @@ BEGIN_EVENT_TABLE(wxTextCtrl, wxControl) EVT_MENU(wxID_PASTE, wxTextCtrl::OnPaste) EVT_MENU(wxID_UNDO, wxTextCtrl::OnUndo) EVT_MENU(wxID_REDO, wxTextCtrl::OnRedo) + EVT_MENU(wxID_CLEAR, wxTextCtrl::OnDelete) + EVT_MENU(wxID_SELECTALL, wxTextCtrl::OnSelectAll) + + EVT_CONTEXT_MENU(wxTextCtrl::OnContextMenu) EVT_UPDATE_UI(wxID_CUT, wxTextCtrl::OnUpdateCut) EVT_UPDATE_UI(wxID_COPY, wxTextCtrl::OnUpdateCopy) EVT_UPDATE_UI(wxID_PASTE, wxTextCtrl::OnUpdatePaste) EVT_UPDATE_UI(wxID_UNDO, wxTextCtrl::OnUpdateUndo) EVT_UPDATE_UI(wxID_REDO, wxTextCtrl::OnUpdateRedo) + EVT_UPDATE_UI(wxID_CLEAR, wxTextCtrl::OnUpdateDelete) + EVT_UPDATE_UI(wxID_SELECTALL, wxTextCtrl::OnUpdateSelectAll) END_EVENT_TABLE() -#endif // Text item void wxTextCtrl::Init() { - m_editable = true ; - m_dirty = false; + m_editable = true ; + m_dirty = false; + + m_privateContextMenu = NULL; - m_maxLength = TE_UNLIMITED_LENGTH ; + m_maxLength = TE_UNLIMITED_LENGTH ; } wxTextCtrl::~wxTextCtrl() { + delete m_privateContextMenu; } @@ -403,8 +421,6 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id, if ( !wxTextCtrlBase::Create(parent, id, pos, size, style & ~(wxHSCROLL|wxVSCROLL), validator, name) ) return false; - Rect bounds = wxMacGetBoundsForControl( this , pos , size ) ; - if ( m_windowStyle & wxTE_MULTILINE ) { wxASSERT_MSG( !(m_windowStyle & wxTE_PROCESS_ENTER), @@ -414,19 +430,27 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id, style |= wxTE_PROCESS_ENTER ; } + bool forceMLTE = false ; +#if wxUSE_SYSTEM_OPTIONS + if ( (wxSystemOptions::HasOption(wxMAC_TEXTCONTROL_USE_MLTE) ) && ( wxSystemOptions::GetOptionInt( wxMAC_TEXTCONTROL_USE_MLTE ) == 1) ) + { + forceMLTE = true ; + } +#endif + #ifdef __WXMAC_OSX__ #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 - if ( UMAGetSystemVersion() >= 0x1050 ) + if ( UMAGetSystemVersion() >= 0x1030 && forceMLTE == false ) { - m_peer = new wxMacMLTEHIViewControl( this , str , pos , size , style ) ; + if ( m_windowStyle & wxTE_MULTILINE ) + m_peer = new wxMacMLTEHIViewControl( this , str , pos , size , style ) ; } #endif -#if !wxMAC_AWAYS_USE_MLTE if ( !m_peer ) { - m_peer = new wxMacUnicodeTextControl( this , str , pos , size , style ) ; + if ( !(m_windowStyle & wxTE_MULTILINE) && forceMLTE == false ) + m_peer = new wxMacUnicodeTextControl( this , str , pos , size , style ) ; } -#endif #endif if ( !m_peer ) { @@ -435,14 +459,26 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id, MacPostControlCreate(pos,size) ; + // only now the embedding is correct and we can do a positioning update + + MacSuperChangedPosition() ; + if ( m_windowStyle & wxTE_READONLY) { SetEditable( false ) ; } + SetCursor( wxCursor( wxCURSOR_IBEAM ) ) ; + return true; } +void wxTextCtrl::MacSuperChangedPosition() +{ + wxWindow::MacSuperChangedPosition() ; + GetPeer()->SuperChangedPosition() ; +} + void wxTextCtrl::MacVisibilityChanged() { GetPeer()->VisibilityChanged( MacIsReallyShown() ) ; @@ -628,7 +664,7 @@ void wxTextCtrl::WriteText(const wxString& str) if ( !wxIsMainThread() ) { // unfortunately CW 8 is not able to correctly deduce the template types, so we have - // to instantiate explicitely + // to instantiate explicitly wxMacMPRemoteGUICall( this , &wxTextCtrl::WriteText , str ) ; return ; } @@ -882,7 +918,7 @@ void wxTextCtrl::OnChar(wxKeyEvent& event) event.SetEventObject(def); def->Command(event); return ; - } + } } // this will make wxWidgets eat the ENTER key so that @@ -974,6 +1010,19 @@ void wxTextCtrl::OnRedo(wxCommandEvent& WXUNUSED(event)) Redo(); } +void wxTextCtrl::OnDelete(wxCommandEvent& WXUNUSED(event)) +{ + long from, to; + GetSelection(& from, & to); + if (from != -1 && to != -1) + Remove(from, to); +} + +void wxTextCtrl::OnSelectAll(wxCommandEvent& WXUNUSED(event)) +{ + SetSelection(-1, -1); +} + void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent& event) { event.Enable( CanCut() ); @@ -999,9 +1048,46 @@ void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event) event.Enable( CanRedo() ); } +void wxTextCtrl::OnUpdateDelete(wxUpdateUIEvent& event) +{ + long from, to; + GetSelection(& from, & to); + event.Enable(from != -1 && to != -1 && from != to && IsEditable()) ; +} + +void wxTextCtrl::OnUpdateSelectAll(wxUpdateUIEvent& event) +{ + event.Enable(GetLastPosition() > 0); +} + +// CS: Context Menus only work with mlte implementations or non-multiline HIViews at the moment + +void wxTextCtrl::OnContextMenu(wxContextMenuEvent& event) +{ + if (m_privateContextMenu == NULL) + { + m_privateContextMenu = new wxMenu; + m_privateContextMenu->Append(wxID_UNDO, _("&Undo")); + m_privateContextMenu->Append(wxID_REDO, _("&Redo")); + m_privateContextMenu->AppendSeparator(); + m_privateContextMenu->Append(wxID_CUT, _("Cu&t")); + m_privateContextMenu->Append(wxID_COPY, _("&Copy")); + m_privateContextMenu->Append(wxID_PASTE, _("&Paste")); + m_privateContextMenu->Append(wxID_CLEAR, _("&Delete")); + m_privateContextMenu->AppendSeparator(); + m_privateContextMenu->Append(wxID_SELECTALL, _("Select &All")); + } + + if (m_privateContextMenu != NULL) + PopupMenu(m_privateContextMenu); +} + bool wxTextCtrl::MacSetupCursor( const wxPoint& pt ) { - return true ; + if ( !GetPeer()->SetupCursor(pt) ) + return wxWindow::MacSetupCursor( pt ) ; + else + return true ; } #if !TARGET_API_MAC_OSX @@ -1303,6 +1389,11 @@ void wxMacUnicodeTextControl::GetSelection( long* from, long* to) const void wxMacUnicodeTextControl::SetSelection( long from , long to ) { ControlEditTextSelectionRec sel ; + if ((from == -1) && (to == -1)) + { + from = 0 ; + to = 32767 ; // sel has 16 bit signed values, max is 32767 + } sel.selStart = from ; sel.selEnd = to ; SetData( 0 , kControlEditTextSelectionTag, &sel ) ; @@ -1337,10 +1428,10 @@ void wxMacUnicodeTextControl::WriteText(const wxString& str) // procedural API, in order to allow changes via API all the same we must undo // the readonly status while we are executing, this class helps to do so -class EditHelper +class wxMacEditHelper { public : - EditHelper( TXNObject txn ) + wxMacEditHelper( TXNObject txn ) { TXNControlTag tag[] = { kTXNIOPrivilegesTag } ; m_txn = txn ; @@ -1351,7 +1442,7 @@ public : TXNSetTXNObjectControls( m_txn , false , 1 , tag , data ) ; } } - ~EditHelper() + ~wxMacEditHelper() { TXNControlTag tag[] = { kTXNIOPrivilegesTag } ; if ( m_data[0].uValue == kTXNReadOnly ) @@ -1364,6 +1455,11 @@ public : TXNControlData m_data[1] ; } ; +wxMacMLTEControl::wxMacMLTEControl( wxTextCtrl *peer ) : wxMacTextControl( peer ) +{ + SetNeedsFocusRect( true ) ; +} + wxString wxMacMLTEControl::GetStringValue() const { wxString result ; @@ -1391,7 +1487,7 @@ wxString wxMacMLTEControl::GetStringValue() const SetHandleSize( theText , ( actualSize + 1 ) * sizeof( UniChar ) ) ; HLock( theText ) ; (((UniChar*)*theText)[actualSize]) = 0 ; - wxMBConvUTF16BE converter ; + wxMBConvUTF16 converter ; size_t noChars = converter.MB2WC( NULL , (const char*)*theText , 0 ) ; ptr = new wxChar[noChars + 1] ; @@ -1439,22 +1535,26 @@ void wxMacMLTEControl::SetStringValue( const wxString &str) wxString st = str ; wxMacConvertNewlines10To13( &st ) ; - EditHelper help(m_txn) ; - -#if !TARGET_API_MAC_OSX - // otherwise scrolling might have problems ? -// MacUpdatePosition( m_controlRef ) ; -#endif - wxMacWindowClipper c( m_peer ) ; - SetTXNData( st , kTXNStartOffset, kTXNEndOffset ) ; - TXNSetSelection( m_txn, 0, 0); - TXNShowSelection( m_txn, kTXNShowStart); + { + wxMacWindowClipper c( m_peer ) ; + { + wxMacEditHelper help(m_txn) ; + SetTXNData( st , kTXNStartOffset, kTXNEndOffset ) ; + } + TXNSetSelection( m_txn, 0, 0); + TXNShowSelection( m_txn, kTXNShowStart); + } } TXNFrameOptions wxMacMLTEControl::FrameOptionsFromWXStyle( long wxStyle ) { TXNFrameOptions frameOptions = - kTXNDontDrawCaretWhenInactiveMask ; + kTXNDontDrawCaretWhenInactiveMask +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 + | kTXNDoFontSubstitutionMask +#endif + ; + if ( ! ( wxStyle & wxTE_NOHIDESEL ) ) frameOptions |= kTXNDontDrawSelectionWhenInactiveMask ; @@ -1469,7 +1569,11 @@ TXNFrameOptions wxMacMLTEControl::FrameOptionsFromWXStyle( long wxStyle ) } if ( !(wxStyle & wxTE_NO_VSCROLL ) ) + { frameOptions |= kTXNWantVScrollBarMask ; + if ( frameOptions & kTXNWantHScrollBarMask ) + frameOptions |= kTXNDrawGrowIconMask ; + } } else frameOptions |= kTXNSingleLineOnlyMask ; @@ -1482,14 +1586,18 @@ TXNFrameOptions wxMacMLTEControl::FrameOptionsFromWXStyle( long wxStyle ) void wxMacMLTEControl::AdjustCreationAttributes( const wxColour &background, bool visible ) { - TXNControlTag iControlTags[3] = { kTXNDoFontSubstitution, kTXNWordWrapStateTag }; - TXNControlData iControlData[3] = { {false}, {kTXNNoAutoWrap} }; - int toptag = 2 ; -#if TARGET_API_MAC_OSX - iControlTags[2] = kTXNVisibilityTag ; - iControlData[2].uValue = visible ; - toptag++ ; -#endif + TXNControlTag iControlTags[] = + { + kTXNDoFontSubstitution, + kTXNWordWrapStateTag , + }; + TXNControlData iControlData[] = + { + {true}, + {kTXNNoAutoWrap}, + }; + + int toptag = WXSIZEOF( iControlTags ) ; if ( m_windowStyle & wxTE_MULTILINE ) { @@ -1498,27 +1606,31 @@ void wxMacMLTEControl::AdjustCreationAttributes( const wxColour &background, boo else iControlData[1].uValue = kTXNAutoWrap ; } - verify_noerr( TXNSetTXNObjectControls( m_txn, true, toptag, + verify_noerr( TXNSetTXNObjectControls( m_txn, false, toptag, iControlTags, iControlData )) ; // setting the default font + // under 10.2 this causes a visible caret, therefore we avoid it - Str255 fontName ; - SInt16 fontSize ; - Style fontStyle ; + if ( UMAGetSystemVersion() >= 0x1030 ) + { + Str255 fontName ; + SInt16 fontSize ; + Style fontStyle ; - GetThemeFont(kThemeSystemFont , GetApplicationScript() , fontName , &fontSize , &fontStyle ) ; + GetThemeFont(kThemeSystemFont , GetApplicationScript() , fontName , &fontSize , &fontStyle ) ; - TXNTypeAttributes typeAttr[] = - { - { kTXNQDFontNameAttribute , kTXNQDFontNameAttributeSize , { (void*) fontName } } , - { kTXNQDFontSizeAttribute , kTXNFontSizeAttributeSize , { (void*) (fontSize << 16) } } , - { kTXNQDFontStyleAttribute , kTXNQDFontStyleAttributeSize , { (void*) normal } } , - } ; + TXNTypeAttributes typeAttr[] = + { + { kTXNQDFontNameAttribute , kTXNQDFontNameAttributeSize , { (void*) fontName } } , + { kTXNQDFontSizeAttribute , kTXNFontSizeAttributeSize , { (void*) (fontSize << 16) } } , + { kTXNQDFontStyleAttribute , kTXNQDFontStyleAttributeSize , { (void*) normal } } , + } ; - verify_noerr( TXNSetTypeAttributes (m_txn, sizeof( typeAttr ) / sizeof(TXNTypeAttributes) , typeAttr, - kTXNStartOffset, - kTXNEndOffset) ); + verify_noerr( TXNSetTypeAttributes (m_txn, sizeof( typeAttr ) / sizeof(TXNTypeAttributes) , typeAttr, + kTXNStartOffset, + kTXNEndOffset) ); + } if ( m_windowStyle & wxTE_PASSWORD ) { @@ -1588,12 +1700,12 @@ void wxMacMLTEControl::TXNSetAttribute( const wxTextAttr& style , long from , lo void wxMacMLTEControl::SetFont( const wxFont & font , const wxColour& foreground , long windowStyle ) { - EditHelper help(m_txn) ; + wxMacEditHelper help(m_txn) ; TXNSetAttribute( wxTextAttr(foreground,wxNullColour,font) , kTXNStartOffset,kTXNEndOffset ) ; } void wxMacMLTEControl::SetStyle(long start, long end, const wxTextAttr& style) { - EditHelper help(m_txn) ; + wxMacEditHelper help(m_txn) ; TXNSetAttribute( style , start,end ) ; } @@ -1626,7 +1738,7 @@ void wxMacMLTEControl::SetEditable(bool editable) { TXNControlTag tag[] = { kTXNIOPrivilegesTag } ; TXNControlData data[] = { { editable ? kTXNReadWrite : kTXNReadOnly } } ; - TXNSetTXNObjectControls( m_txn , false , sizeof(tag) / sizeof (TXNControlTag) , tag , data ) ; + TXNSetTXNObjectControls( m_txn , false , WXSIZEOF(tag) , tag , data ) ; } wxTextPos wxMacMLTEControl::GetLastPosition() const @@ -1654,7 +1766,7 @@ void wxMacMLTEControl::Replace( long from , long to , const wxString str ) wxString value = str ; wxMacConvertNewlines10To13( &value ) ; - EditHelper help( m_txn ) ; + wxMacEditHelper help( m_txn ) ; wxMacWindowClipper c( m_peer ) ; TXNSetSelection(m_txn , from , to ) ; @@ -1665,7 +1777,7 @@ void wxMacMLTEControl::Replace( long from , long to , const wxString str ) void wxMacMLTEControl::Remove( long from , long to ) { wxMacWindowClipper c( m_peer ) ; - EditHelper help( m_txn ) ; + wxMacEditHelper help( m_txn ) ; TXNSetSelection(m_txn , from , to ) ; TXNClear( m_txn ) ; } @@ -1688,22 +1800,24 @@ void wxMacMLTEControl::SetSelection( long from , long to ) void wxMacMLTEControl::WriteText(const wxString& str) { - EditHelper helper( m_txn ) ; wxString st = str ; wxMacConvertNewlines10To13( &st ) ; - wxMacWindowClipper c( m_peer ) ; long start , end , dummy ; GetSelection( &start , &dummy ) ; - SetTXNData( st , kTXNUseCurrentSelection, kTXNUseCurrentSelection ) ; + wxMacWindowClipper c( m_peer ) ; + { + wxMacEditHelper helper( m_txn ) ; + SetTXNData( st , kTXNUseCurrentSelection, kTXNUseCurrentSelection ) ; + } GetSelection( &dummy , &end ) ; // TODO SetStyle( start , end , GetDefaultStyle() ) ; } void wxMacMLTEControl::Clear() { - EditHelper st(m_txn) ; wxMacWindowClipper c( m_peer ) ; + wxMacEditHelper st(m_txn) ; TXNSetSelection( m_txn , kTXNStartOffset , kTXNEndOffset ) ; TXNClear(m_txn); } @@ -1829,7 +1943,9 @@ void wxMacMLTEControl::ShowPosition( long pos ) SInt32 dh = desired.h - current.h ; TXNShowSelection( m_txn , true ) ; theErr = TXNScroll( m_txn, kTXNScrollUnitsInPixels , kTXNScrollUnitsInPixels , &dv , &dh ); - wxASSERT_MSG( theErr == noErr, _T("TXNScroll returned an error!") ); + // there will be an error returned for classic mlte implementation when the control is + // invisible, but HITextView works correctly, so we don't assert that one + // wxASSERT_MSG( theErr == noErr, _T("TXNScroll returned an error!") ); } } #endif @@ -1843,7 +1959,7 @@ void wxMacMLTEControl::SetTXNData( const wxString& st , TXNOffset start , TXNOff TXNSetData( m_txn , kTXNUnicodeTextData, (void*)st.wc_str(), len * 2, start, end); #else - wxMBConvUTF16BE converter ; + wxMBConvUTF16 converter ; ByteCount byteBufferLen = converter.WC2MB( NULL , st.wc_str() , 0 ) ; UniChar *unibuf = (UniChar*) malloc(byteBufferLen) ; converter.WC2MB( (char*) unibuf , st.wc_str() , byteBufferLen ) ; @@ -1942,137 +2058,161 @@ int wxMacMLTEControl::GetLineLength(long lineNo) const // MLTE control implementation (classic part) // ---------------------------------------------------------------------------- -// CS:TODO we still have a problem getting properly at the text events of a control because under Carbon -// the MLTE engine registers itself for the key events thus the normal flow never occurs, the only measure for the -// moment is to avoid setting the true focus on the control, the proper solution at the end would be to have -// an alternate path for carbon key events that routes automatically into the same wx flow of events +// OS X Notes : We still don't have a full replacement for MLTE, so this implementation +// has to live on. We have different problems coming from outdated implementations on the +// various OS X versions. Most deal with the scrollbars: they are not correctly embedded +// while this can be solved on 10.3 by reassigning them the correct place, on 10.2 there is +// no way out, therefore we are using our own implementation and our own scrollbars .... -/* part codes */ +#ifdef __WXMAC_OSX__ -/* kmUPTextPart is the part code we return to indicate the user has clicked -in the text area of our control */ -#define kmUPTextPart 1 +TXNScrollInfoUPP gTXNScrollInfoProc = NULL ; +ControlActionUPP gTXNScrollActionProc = NULL ; +pascal void wxMacMLTEClassicControl::TXNScrollInfoProc (SInt32 iValue, SInt32 iMaximumValue, TXNScrollBarOrientation + iScrollBarOrientation, SInt32 iRefCon) +{ + wxMacMLTEClassicControl* mlte = (wxMacMLTEClassicControl*) iRefCon ; + SInt32 value = wxMax( iValue , 0 ) ; + SInt32 maximum = wxMax( iMaximumValue , 0 ) ; -/* routines for using existing user pane controls. -These routines are useful for cases where you would like to use an -existing user pane control in, say, a dialog window as a scrolling -text edit field.*/ + if ( iScrollBarOrientation == kTXNHorizontal ) + { + if ( mlte->m_sbHorizontal ) + { + SetControl32BitValue( mlte->m_sbHorizontal , value ) ; + SetControl32BitMaximum( mlte->m_sbHorizontal , maximum ) ; + mlte->m_lastHorizontalValue = value ; + } + } + else if ( iScrollBarOrientation == kTXNVertical ) + { + if ( mlte->m_sbVertical ) + { + SetControl32BitValue( mlte->m_sbVertical , value ) ; + SetControl32BitMaximum( mlte->m_sbVertical , maximum ) ; + mlte->m_lastVerticalValue = value ; + } + } +} -/* Utility Routines */ +pascal void wxMacMLTEClassicControl::TXNScrollActionProc( ControlRef controlRef , ControlPartCode partCode ) +{ + OSStatus err ; + wxMacMLTEClassicControl* mlte = (wxMacMLTEClassicControl*) GetControlReference( controlRef ) ; + if ( mlte == NULL ) + return ; -/* kUserClickedToFocusPart is a part code we pass to the SetKeyboardFocus -routine. In our focus switching routine this part code is understood -as meaning 'the user has clicked in the control and we need to switch -the current focus to ourselves before we can continue'. */ -#define kUserClickedToFocusPart 100 + if ( controlRef != mlte->m_sbVertical && controlRef != mlte->m_sbHorizontal ) + return ; -/* STPTextPaneVars is a structure used for storing the the mUP Control's -internal variables and state information. A handle to this record is -stored in the pane control's reference value field using the -SetControlReference routine. */ + bool isHorizontal = ( controlRef == mlte->m_sbHorizontal ) ; -/* Univerals Procedure Pointer variables used by the -mUP Control. These variables are set up -the first time that mUPOpenControl is called. */ -ControlUserPaneDrawUPP gTPDrawProc = NULL; -ControlUserPaneHitTestUPP gTPHitProc = NULL; -ControlUserPaneTrackingUPP gTPTrackProc = NULL; -ControlUserPaneIdleUPP gTPIdleProc = NULL; -ControlUserPaneKeyDownUPP gTPKeyProc = NULL; -ControlUserPaneActivateUPP gTPActivateProc = NULL; -ControlUserPaneFocusUPP gTPFocusProc = NULL; + SInt32 minimum = 0 ; + SInt32 maximum = GetControl32BitMaximum( controlRef ) ; + SInt32 value = GetControl32BitValue( controlRef ) ; + SInt32 delta = 0; + switch ( partCode ) + { + case kControlDownButtonPart : + delta = 10 ; + break ; + case kControlUpButtonPart : + delta = -10 ; + break ; + case kControlPageDownPart : + delta = GetControlViewSize( controlRef ) ; + break ; + case kControlPageUpPart : + delta = -GetControlViewSize( controlRef ) ; + break ; + case kControlIndicatorPart : + delta = value - + ( isHorizontal ? mlte->m_lastHorizontalValue : mlte->m_lastVerticalValue ) ; + break ; + default : + break ; + } + if ( delta != 0 ) + { + SInt32 newValue = value ; + if ( partCode != kControlIndicatorPart ) + { + if( value + delta < minimum ) + delta = minimum - value ; + if ( value + delta > maximum ) + delta = maximum - value ; -class wxMacMLTENoDraw -{ -public : - wxMacMLTENoDraw( TXNObject txn ) ; - ~wxMacMLTENoDraw() ; - -private : - bool m_formerDraw ; - TXNObject m_txn ; -} ; + SetControl32BitValue( controlRef , value + delta ) ; + newValue = value + delta ; + } -wxMacMLTENoDraw::wxMacMLTENoDraw( TXNObject txn ) -{ - m_txn = txn ; -#ifdef __WXMAC_OSX__ - TXNControlTag iControlTags[1] = { kTXNVisibilityTag }; - TXNControlData iControlData[1] ; - - TXNGetTXNObjectControls( m_txn , 1 , iControlTags , iControlData ) ; - m_formerDraw = iControlData[0].uValue ; - if ( m_formerDraw ) - { - iControlData[0].uValue = 0 ; - TXNSetTXNObjectControls( m_txn , 1 , true , iControlTags , iControlData ) ; - } -#endif -} + SInt32 verticalDelta = isHorizontal ? 0 : delta ; + SInt32 horizontalDelta = isHorizontal ? delta : 0 ; -wxMacMLTENoDraw::~wxMacMLTENoDraw() -{ -#ifdef __WXMAC_OSX__ - if ( m_formerDraw ) - { - TXNControlTag iControlTags[1] = { kTXNVisibilityTag }; - TXNControlData iControlData[1] ; - - iControlData[0].uValue = m_formerDraw ; - TXNSetTXNObjectControls( m_txn , 1 , true , iControlTags , iControlData ) ; + err = TXNScroll( mlte->m_txn , kTXNScrollUnitsInPixels, kTXNScrollUnitsInPixels, + &verticalDelta , &horizontalDelta ); + + if ( isHorizontal ) + mlte->m_lastHorizontalValue = newValue ; + else + mlte->m_lastVerticalValue = newValue ; } -#endif } - +#endif // make correct activations -void wxMacMLTEClassicControl::MacActivatePaneText(Boolean setActive) +void wxMacMLTEClassicControl::MacActivatePaneText(Boolean setActive) { wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(m_controlRef); - if (m_txnIsActive != setActive && textctrl->MacIsReallyShown() ) - { - m_txnIsActive = setActive; - // TXNSetScrollBarState - - TXNActivate(m_txn, m_txnFrameID, m_txnIsActive); - if (m_txnIsFocused) - TXNFocus( m_txn, m_txnIsActive); - } -} -// update TXN focus state -void wxMacMLTEClassicControl::MacFocusPaneText(Boolean setFocus) { -/* wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(m_controlRef); */ + wxMacWindowClipper clipper( textctrl ) ; + TXNActivate(m_txn, m_txnFrameID, setActive); - if (m_txnIsFocused != setFocus /*&& textctrl->MacIsReallyShown() */ ) { - m_txnIsFocused = setFocus; - TXNFocus( m_txn, m_txnIsFocused); - } + ControlRef controlFocus = 0 ; + GetKeyboardFocus( m_txnWindow , &controlFocus ) ; + if ( controlFocus == m_controlRef ) + TXNFocus( m_txn, setActive); } -// makes sure that the TXNObject is either offscreen or on screen +void wxMacMLTEClassicControl::MacFocusPaneText(Boolean setFocus) +{ + TXNFocus( m_txn, setFocus); +} + +// guards against inappropriate redraw (hidden objects drawing onto window) void wxMacMLTEClassicControl::MacSetObjectVisibility(Boolean vis) { -#ifdef __WXMAC_OSX__ - OSStatus err = noErr ; - - wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(m_controlRef); - if ( textctrl ) + ControlRef controlFocus = 0 ; + GetKeyboardFocus( m_txnWindow , &controlFocus ) ; + + if ( controlFocus == m_controlRef && vis == false ) { - UMAGetControlBoundsInWindowCoords( m_controlRef, &m_txnControlBounds); - TXNControlTag iControlTags[1] = { kTXNVisibilityTag }; - TXNControlData iControlData[1] = { { vis } }; - - TXNSetTXNObjectControls( m_txn , 1 , true , iControlTags , iControlData ) ; + SetKeyboardFocus( m_txnWindow , m_controlRef , kControlFocusNoPart ) ; } -#endif + + 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 )) ; + } + // we right now are always clipping 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() + +void wxMacMLTEClassicControl::MacUpdatePosition() { wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(m_controlRef); if ( textctrl == NULL ) @@ -2080,29 +2220,108 @@ void wxMacMLTEClassicControl::MacUpdatePosition() Rect bounds ; UMAGetControlBoundsInWindowCoords(m_controlRef, &bounds); - - if ( !EqualRect( &bounds , &m_txnControlBounds ) ) + + 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) ) { - // old position - Rect oldBounds = m_txnControlBounds ; 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 ) ; +/* + 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); +*/ +#else + TXNSetFrameBounds( m_txn, m_txnControlBounds.top, m_txnControlBounds.left, - m_txnControlBounds.bottom, m_txnControlBounds.right, m_txnFrameID); + wxMax( m_txnControlBounds.bottom , m_txnControlBounds.top ) , + wxMax( m_txnControlBounds.right , m_txnControlBounds.left ) , m_txnFrameID); +#endif + // the SetFrameBounds method unter classic sometimes does not correctly scroll a selection into sight after a + // movement, therefore we have to force it + + // according to David Surovell this problem also sometimes occurs under OSX, so we use this as well + + TXNLongRect textRect ; + TXNGetRectBounds( m_txn , NULL , NULL , &textRect ) ; + if ( textRect.left < m_txnControlBounds.left ) + { + TXNShowSelection( m_txn , false ) ; + } } } -void wxMacMLTEClassicControl::SetRect( Rect *r ) +void wxMacMLTEClassicControl::SetRect( Rect *r ) { wxMacControl::SetRect( r ) ; MacUpdatePosition() ; } -// draw the control -void wxMacMLTEClassicControl::MacControlUserPaneDrawProc(wxInt16 thePart) +void wxMacMLTEClassicControl::MacControlUserPaneDrawProc(wxInt16 thePart) { - /* set up our globals */ - wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(m_controlRef); if ( textctrl == NULL ) return ; @@ -2114,25 +2333,20 @@ void wxMacMLTEClassicControl::MacControlUserPaneDrawProc(wxInt16 thePart) } } - -/* TPPaneHitTestProc is called when the control manager would -like to determine what part of the control the mouse resides over. -We also call this routine from our tracking proc to determine how -to handle mouse clicks. */ -wxInt16 wxMacMLTEClassicControl::MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y) +wxInt16 wxMacMLTEClassicControl::MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y) { Point where = { y , x } ; ControlPartCode result; - /* set up our locals and lock down our globals*/ + result = 0; wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(m_controlRef); if ( textctrl == NULL ) return 0 ; - + if (textctrl->MacIsReallyShown() ) { if (PtInRect(where, &m_txnControlBounds)) - result = kmUPTextPart; + result = kControlEditTextPart ; else { // sometimes we get the coords also in control local coordinates, therefore test again @@ -2144,7 +2358,7 @@ wxInt16 wxMacMLTEClassicControl::MacControlUserPaneHitTestProc(wxInt16 x, wxInt1 where.v += y ; } if (PtInRect(where, &m_txnControlBounds)) - result = kmUPTextPart; + result = kControlEditTextPart ; else result = 0; } @@ -2152,30 +2366,17 @@ wxInt16 wxMacMLTEClassicControl::MacControlUserPaneHitTestProc(wxInt16 x, wxInt1 return result; } -/* TPPaneTrackingProc is called when the mouse is being held down -over our control. This routine handles clicks in the text area -and in the scroll bar. */ - -wxInt16 wxMacMLTEClassicControl::MacControlUserPaneTrackingProc( wxInt16 x, wxInt16 y, void* actionProc ) +wxInt16 wxMacMLTEClassicControl::MacControlUserPaneTrackingProc( wxInt16 x, wxInt16 y, void* actionProc ) { - Point startPt = { y ,x } ; - ControlPartCode partCodeResult; - /* make sure we have some variables... */ - partCodeResult = 0; wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(m_controlRef); if ( textctrl == NULL ) return 0; + ControlPartCode partCodeResult = 0; + if (textctrl->MacIsReallyShown() ) { - /* we don't do any of these functions unless we're in focus */ - if ( ! m_txnIsFocused) { - WindowPtr owner; - owner = GetControlOwner(m_controlRef); - ClearKeyboardFocus(owner); - SetKeyboardFocus(owner, m_controlRef, kUserClickedToFocusPart); - } - /* find the location for the click */ + Point startPt = { y ,x } ; // for compositing, we must convert these into toplevel window coordinates, because hittesting expects them if ( textctrl->MacGetTopLevelWindow()->MacUsesCompositing() ) { @@ -2187,8 +2388,7 @@ wxInt16 wxMacMLTEClassicControl::MacControlUserPaneTrackingProc( wxInt16 x, wxIn switch (MacControlUserPaneHitTestProc( startPt.h , startPt.v )) { - /* handle clicks in the text part */ - case kmUPTextPart: + case kControlEditTextPart : { wxMacWindowClipper clipper( textctrl ) ; @@ -2197,123 +2397,65 @@ wxInt16 wxMacMLTEClassicControl::MacControlUserPaneTrackingProc( wxInt16 x, wxIn TXNClick( m_txn, &rec ); } - break; - + break; } } return partCodeResult; } - -/* TPPaneIdleProc is our user pane idle routine. When our text field -is active and in focus, we use this routine to set the cursor. */ -void wxMacMLTEClassicControl::MacControlUserPaneIdleProc() +void wxMacMLTEClassicControl::MacControlUserPaneIdleProc() { - /* set up locals */ wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(m_controlRef); if ( textctrl == NULL ) return ; - if (textctrl->MacIsReallyShown()) + if (textctrl->MacIsReallyShown()) { - /* if we're not active, then we have nothing to say about the cursor */ - if (m_controlIsActive) + if (IsControlActive(m_controlRef)) { - Rect bounds; Point mousep; wxMacWindowClipper clipper( textctrl ) ; GetMouse(&mousep); - /* there's a 'focus thing' and an 'unfocused thing' */ - if (m_txnIsFocused) - { - /* flash the cursor */ - SetPort(m_txnPort); - TXNIdle(m_txn); - /* set the cursor */ - if (PtInRect(mousep, &m_txnControlBounds)) - { - RgnHandle theRgn; - RectRgn((theRgn = NewRgn()), &m_txnControlBounds); - TXNAdjustCursor(m_txn, theRgn); - DisposeRgn(theRgn); - } - else - { - // SetThemeCursor(kThemeArrowCursor); - } - } - else + + TXNIdle(m_txn); + + if (PtInRect(mousep, &m_txnControlBounds)) { - /* if it's in our bounds, set the cursor */ - UMAGetControlBoundsInWindowCoords(m_controlRef, &bounds); - if (PtInRect(mousep, &bounds)) - { - // SetThemeCursor(kThemeArrowCursor); - } + RgnHandle theRgn; + RectRgn((theRgn = NewRgn()), &m_txnControlBounds); + TXNAdjustCursor(m_txn, theRgn); + DisposeRgn(theRgn); } } } } - -/* TPPaneKeyDownProc is called whenever a keydown event is directed -at our control. Here, we direct the keydown event to the text -edit record and redraw the scroll bar and text field as appropriate. */ -wxInt16 wxMacMLTEClassicControl::MacControlUserPaneKeyDownProc (wxInt16 keyCode, wxInt16 charCode, wxInt16 modifiers) +wxInt16 wxMacMLTEClassicControl::MacControlUserPaneKeyDownProc (wxInt16 keyCode, wxInt16 charCode, wxInt16 modifiers) { wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(m_controlRef); if ( textctrl == NULL ) return 0; - // MacUpdatePosition() ; - if (m_txnIsFocused) - { - /* turn autoscrolling on and send the key event to text edit */ - 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; -} + 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); -/* TPPaneActivateProc is called when the window containing -the user pane control receives activate events. Here, we redraw -the control and it's text as necessary for the activation state. */ + return kControlEntireControl; +} -void wxMacMLTEClassicControl::MacControlUserPaneActivateProc( bool activating) +void wxMacMLTEClassicControl::MacControlUserPaneActivateProc( bool activating) { - /* set up locals */ - wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(m_controlRef); - - if ( textctrl == NULL ) - return ; - - if ( m_controlIsActive != activating ) - { - wxLogDebug(wxString::Format( wxT("id %xd activating with %d") , (long) this , activating ) ) ; - // MacUpdatePosition() ; - m_controlIsActive = activating; - wxMacWindowClipper clipper( textctrl ) ; - MacActivatePaneText( activating ); - } - - + MacActivatePaneText( activating ); } - -/* TPPaneFocusProc is called when every the focus changes to or -from our control. Herein, switch the focus appropriately -according to the parameters and redraw the control as -necessary. */ -wxInt16 wxMacMLTEClassicControl::MacControlUserPaneFocusProc(wxInt16 action) +wxInt16 wxMacMLTEClassicControl::MacControlUserPaneFocusProc(wxInt16 action) { - wxLogDebug(wxString::Format( wxT("id %xd Focus Proc with action %d") , (long) this , action ) ) ; ControlPartCode focusResult; focusResult = kControlFocusNoPart; @@ -2322,43 +2464,24 @@ wxInt16 wxMacMLTEClassicControl::MacControlUserPaneFocusProc(wxInt16 action) return 0; wxMacWindowClipper clipper( textctrl ) ; - - // MacUpdatePosition() ; - - /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is - tabbing forwards (or shift tabbing backwards) through the items in the dialog, - and kControlFocusNextPart will be received. When the user clicks in our field - and it is not the current focus, then the constant kUserClickedToFocusPart will - be received. The constant kControlFocusNoPart will be received when our control - is the current focus and the user clicks in another control. In your focus routine, - you should respond to these codes as follows: - - kControlFocusNoPart - turn off focus and return kControlFocusNoPart. redraw - the control and the focus rectangle as necessary. - - kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off - depending on its current state. redraw the control and the focus rectangle - as appropriate for the new focus state. If the focus state is 'off', return the constant - kControlFocusNoPart, otherwise return a non-zero part code. - kUserClickedToFocusPart - is a constant defined for this example. You should - define your own value for handling click-to-focus type events. */ - /* calculate the next highlight state */ - switch (action) + + ControlRef controlFocus = 0 ; + GetKeyboardFocus( m_txnWindow , &controlFocus ) ; + bool wasFocused = ( controlFocus == m_controlRef ) ; + + switch (action) { - default: + case kControlFocusPrevPart: + case kControlFocusNextPart: + MacFocusPaneText( ( !wasFocused)); + focusResult = (!wasFocused) ? (ControlPartCode) kControlEditTextPart : (ControlPartCode) kControlFocusNoPart; + break; + case kControlFocusNoPart: + default: MacFocusPaneText( false); focusResult = kControlFocusNoPart; break; - case kUserClickedToFocusPart: - MacFocusPaneText(true); - focusResult = 1; - break; - case kControlFocusPrevPart: - case kControlFocusNextPart: - MacFocusPaneText( ( ! m_txnIsFocused)); - focusResult = m_txnIsFocused ? 1 : kControlFocusNoPart; - break; } return focusResult; @@ -2376,55 +2499,62 @@ wxMacMLTEClassicControl::wxMacMLTEClassicControl( wxTextCtrl *wxPeer, m_font = wxPeer->GetFont() ; m_windowStyle = style ; Rect bounds = wxMacGetBoundsForControl( wxPeer , pos , size ) ; - wxString st = str ; - wxMacConvertNewlines10To13( &st ) ; short featurSet; featurSet = kControlSupportsEmbedding | kControlSupportsFocus | kControlWantsIdle - | kControlWantsActivate | kControlHandlesTracking | kControlHasSpecialBackground + | kControlWantsActivate | kControlHandlesTracking // | kControlHasSpecialBackground | kControlGetsFocusOnClick | kControlSupportsLiveFeedback; - /* create the control */ verify_noerr( ::CreateUserPaneControl( MAC_WXHWND(wxPeer->GetParent()->MacGetTopLevelWindowRef()), &bounds, featurSet, &m_controlRef ) ); DoCreate(); - if ( wxPeer->MacIsReallyShown() ) - MacSetObjectVisibility( true ) ; + AdjustCreationAttributes( *wxWHITE , true) ; - AdjustCreationAttributes( *wxWHITE , true ) ; + MacSetObjectVisibility( wxPeer->MacIsReallyShown() ) ; { + wxString st = str ; + wxMacConvertNewlines10To13( &st ) ; wxMacWindowClipper clipper( m_peer ) ; SetTXNData( st , kTXNStartOffset, kTXNEndOffset ) ; TXNSetSelection( m_txn, 0, 0); - TXNShowSelection( m_txn, kTXNShowStart); } } wxMacMLTEClassicControl::~wxMacMLTEClassicControl() { -// SetControlReference(m_controlRef , 0) ; TXNDeleteObject(m_txn); + m_txn = NULL ; } void wxMacMLTEClassicControl::VisibilityChanged(bool shown) { MacSetObjectVisibility( shown ) ; + wxMacControl::VisibilityChanged( shown ) ; } -bool wxMacMLTEClassicControl::NeedsFocusRect() const +void wxMacMLTEClassicControl::SuperChangedPosition() { - return true; + 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 ? dynamic_cast(textCtrl->GetPeer()) : NULL ; + wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ; if ( win ) win->MacControlUserPaneDrawProc(part) ; } @@ -2432,7 +2562,7 @@ static pascal void wxMacControlUserPaneDrawProc(ControlRef control, SInt16 part) static pascal ControlPartCode wxMacControlUserPaneHitTestProc(ControlRef control, Point where) { wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ; - wxMacMLTEClassicControl * win = textCtrl ? dynamic_cast(textCtrl->GetPeer()) : NULL ; + wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ; if ( win ) return win->MacControlUserPaneHitTestProc(where.h , where.v) ; else @@ -2442,7 +2572,7 @@ static pascal ControlPartCode wxMacControlUserPaneHitTestProc(ControlRef control static pascal ControlPartCode wxMacControlUserPaneTrackingProc(ControlRef control, Point startPt, ControlActionUPP actionProc) { wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ; - wxMacMLTEClassicControl * win = textCtrl ? dynamic_cast(textCtrl->GetPeer()) : NULL ; + wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ; if ( win ) return win->MacControlUserPaneTrackingProc( startPt.h , startPt.v , (void*) actionProc) ; else @@ -2452,7 +2582,7 @@ static pascal ControlPartCode wxMacControlUserPaneTrackingProc(ControlRef contro static pascal void wxMacControlUserPaneIdleProc(ControlRef control) { wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ; - wxMacMLTEClassicControl * win = textCtrl ? dynamic_cast(textCtrl->GetPeer()) : NULL ; + wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ; if ( win ) win->MacControlUserPaneIdleProc() ; } @@ -2460,7 +2590,7 @@ static pascal void wxMacControlUserPaneIdleProc(ControlRef control) static pascal ControlPartCode wxMacControlUserPaneKeyDownProc(ControlRef control, SInt16 keyCode, SInt16 charCode, SInt16 modifiers) { wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ; - wxMacMLTEClassicControl * win = textCtrl ? dynamic_cast(textCtrl->GetPeer()) : NULL ; + wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ; if ( win ) return win->MacControlUserPaneKeyDownProc(keyCode,charCode,modifiers) ; else @@ -2470,7 +2600,7 @@ static pascal ControlPartCode wxMacControlUserPaneKeyDownProc(ControlRef control static pascal void wxMacControlUserPaneActivateProc(ControlRef control, Boolean activating) { wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ; - wxMacMLTEClassicControl * win = textCtrl ? dynamic_cast(textCtrl->GetPeer()) : NULL ; + wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ; if ( win ) win->MacControlUserPaneActivateProc(activating) ; } @@ -2478,22 +2608,26 @@ static pascal void wxMacControlUserPaneActivateProc(ControlRef control, Boolean static pascal ControlPartCode wxMacControlUserPaneFocusProc(ControlRef control, ControlFocusPart action) { wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ; - wxMacMLTEClassicControl * win = textCtrl ? dynamic_cast(textCtrl->GetPeer()) : NULL ; + wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ; if ( win ) return win->MacControlUserPaneFocusProc(action) ; else return kControlNoPart ; } +/* static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control, ControlBackgroundPtr info) { wxTextCtrl *textCtrl = wxDynamicCast( wxFindControlFromMacControl(control) , wxTextCtrl ) ; - wxMacMLTEClassicControl * win = textCtrl ? dynamic_cast(textCtrl->GetPeer()) : NULL ; + wxMacMLTEClassicControl * win = textCtrl ? (wxMacMLTEClassicControl*)(textCtrl->GetPeer()) : NULL ; if ( win ) win->MacControlUserPaneBackgroundProc(info) ; } +*/ #endif +// TXNRegisterScrollInfoProc + OSStatus wxMacMLTEClassicControl::DoCreate() { Rect bounds; @@ -2509,17 +2643,15 @@ OSStatus wxMacMLTEClassicControl::DoCreate() if (gTPKeyProc == NULL) gTPKeyProc = NewControlUserPaneKeyDownUPP(wxMacControlUserPaneKeyDownProc); if (gTPActivateProc == NULL) gTPActivateProc = NewControlUserPaneActivateUPP(wxMacControlUserPaneActivateProc); if (gTPFocusProc == NULL) gTPFocusProc = NewControlUserPaneFocusUPP(wxMacControlUserPaneFocusProc); + + if (gTXNScrollInfoProc == NULL ) gTXNScrollInfoProc = NewTXNScrollInfoUPP(TXNScrollInfoProc) ; + if (gTXNScrollActionProc == NULL ) gTXNScrollActionProc = NewControlActionUPP(TXNScrollActionProc) ; #endif /* set the initial settings for our private data */ - m_txnIsFocused = false; - m_controlIsActive = true; - m_txnIsActive = false; - m_txnIsVisible = true ; - - WindowRef owningWindow = GetControlOwner(m_controlRef); - m_txnPort = (GrafPtr) GetWindowPort(owningWindow); + m_txnWindow =GetControlOwner(m_controlRef); + m_txnPort = (GrafPtr) GetWindowPort(m_txnWindow); #ifdef __WXMAC_OSX__ /* set up the user pane procedures */ @@ -2533,9 +2665,10 @@ OSStatus wxMacMLTEClassicControl::DoCreate() #endif /* calculate the rectangles used by the control */ UMAGetControlBoundsInWindowCoords(m_controlRef, &bounds); - + m_txnControlBounds = bounds ; - + m_txnVisBounds = bounds ; + CGrafPtr origPort = NULL ; GDHandle origDev = NULL ; GetGWorld( &origPort , &origDev ) ; @@ -2545,17 +2678,72 @@ OSStatus wxMacMLTEClassicControl::DoCreate() TXNFrameOptions frameOptions = FrameOptionsFromWXStyle( m_windowStyle ) ; - verify_noerr(TXNNewObject(NULL, owningWindow , &bounds, +#ifdef __WXMAC_OSX__ + + // the scrollbars are not correctly embedded but are inserted at the root + // this gives us problems as we have erratic redraws even over the structure + // area + + m_sbHorizontal = 0 ; + m_sbVertical = 0 ; + m_lastHorizontalValue = 0 ; + m_lastVerticalValue = 0 ; + + Rect sb = { 0 , 0 , 0 , 0 } ; + if ( frameOptions & kTXNWantVScrollBarMask ) + { + CreateScrollBarControl( m_txnWindow , &sb , 0 , 0 , 100 , 1 , true , gTXNScrollActionProc , &m_sbVertical ) ; + SetControlReference( m_sbVertical , (SInt32) this ) ; + SetControlAction( m_sbVertical, gTXNScrollActionProc ); + ShowControl( m_sbVertical ) ; + EmbedControl( m_sbVertical , m_controlRef ) ; + frameOptions &= ~kTXNWantVScrollBarMask ; + } + if ( frameOptions & kTXNWantHScrollBarMask ) + { + CreateScrollBarControl( m_txnWindow , &sb , 0 , 0 , 100 , 1 , true , gTXNScrollActionProc , &m_sbHorizontal ) ; + SetControlReference( m_sbHorizontal , (SInt32) this ) ; + SetControlAction( m_sbHorizontal, gTXNScrollActionProc ); + ShowControl( m_sbHorizontal ) ; + EmbedControl( m_sbHorizontal , m_controlRef ) ; + frameOptions &= ~(kTXNWantHScrollBarMask | kTXNDrawGrowIconMask); + } + +#endif + + verify_noerr(TXNNewObject(NULL, m_txnWindow , &bounds, frameOptions , kTXNTextEditStyleFrameType, kTXNTextensionFile, kTXNSystemDefaultEncoding, &m_txn, &m_txnFrameID, NULL ) ); +/* + TXNCarbonEventInfo cInfo ; + + cInfo.useCarbonEvents = false ; + cInfo.filler = 0 ; + cInfo.flags = 0 ; + cInfo.fDictionary = NULL ; + + TXNControlTag iControlTags[] = + { + kTXNUseCarbonEvents , + }; + TXNControlData iControlData[] = + { + {(UInt32) &cInfo }, + }; + + int toptag = WXSIZEOF( iControlTags ) ; + + verify_noerr( TXNSetTXNObjectControls( m_txn, false , toptag, + iControlTags, iControlData )) ; + +*/ +#ifdef __WXMAC_OSX__ + TXNRegisterScrollInfoProc( m_txn, gTXNScrollInfoProc, (SInt32) this); +#endif - /* perform final activations and setup for our text field. Here, - we assume that the window is going to be the 'active' window. */ - // MacActivatePaneText(m_controlIsActive && m_txnIsFocused); - /* all done */ SetGWorld( origPort , origDev ) ; return err; } @@ -2579,7 +2767,8 @@ wxMacMLTEHIViewControl::wxMacMLTEHIViewControl( wxTextCtrl *wxPeer, wxString st = str ; wxMacConvertNewlines10To13( &st ) ; - HIRect hr = { bounds.left , bounds.top , bounds.right - bounds.left , bounds.bottom- bounds.top } ; + HIRect hr = { { bounds.left , bounds.top} , + { bounds.right - bounds.left , bounds.bottom - bounds.top} } ; m_scrollView = NULL ; TXNFrameOptions frameOptions = FrameOptionsFromWXStyle( style ) ; @@ -2631,11 +2820,6 @@ bool wxMacMLTEHIViewControl::HasFocus() const return control == m_textView ; } -bool wxMacMLTEHIViewControl::NeedsFocusRect() const -{ - return m_windowStyle & wxNO_BORDER ? false : true; -} - #endif // MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2