diff --git a/docs/changes.txt b/docs/changes.txt index 6729649081..1f4de6a7e4 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -220,6 +220,7 @@ wxOSX: - wxiOS now needs a minimum of iOS 9 for deployment - Fix handling CTM in wxGraphicsContext::SeTransform and GetTransform(). - Allow turning on/off opacity selector in wxColourDialog. +- Implement wxTextCtrl::PositionToXY() and XYToPosition(). Unix: diff --git a/include/wx/osx/cocoa/private/textimpl.h b/include/wx/osx/cocoa/private/textimpl.h index b1c0d3d0a2..7d21290800 100644 --- a/include/wx/osx/cocoa/private/textimpl.h +++ b/include/wx/osx/cocoa/private/textimpl.h @@ -62,6 +62,8 @@ public : virtual void SetEditable(bool editable) ; virtual void GetSelection( long* from, long* to) const ; virtual void SetSelection( long from , long to ); + virtual bool PositionToXY(long pos, long *x, long *y) const wxOVERRIDE; + virtual long XYToPosition(long x, long y) const wxOVERRIDE; virtual void WriteText(const wxString& str) ; virtual bool HasOwnContextMenu() const { return true; } virtual bool SetHint(const wxString& hint); @@ -102,6 +104,8 @@ public: virtual void SetEditable(bool editable) ; virtual void GetSelection( long* from, long* to) const ; virtual void SetSelection( long from , long to ); + virtual bool PositionToXY(long pos, long *x, long *y) const wxOVERRIDE; + virtual long XYToPosition(long x, long y) const wxOVERRIDE; virtual void WriteText(const wxString& str) ; virtual void SetFont( const wxFont & font , const wxColour& foreground , long windowStyle, bool ignoreBlack = true ); diff --git a/src/osx/cocoa/textctrl.mm b/src/osx/cocoa/textctrl.mm index f9610c7ff2..a655cb06eb 100644 --- a/src/osx/cocoa/textctrl.mm +++ b/src/osx/cocoa/textctrl.mm @@ -873,6 +873,66 @@ void wxNSTextViewControl::SetSelection( long from , long to ) [m_textView scrollRangeToVisible:selrange]; } +bool wxNSTextViewControl::PositionToXY(long pos, long *x, long *y) const +{ + wxCHECK( m_textView, false ); + wxCHECK_MSG( pos >= 0, false, wxS("Invalid character position") ); + + NSString* txt = [m_textView string]; + if ( pos > [txt length] ) + return false; + + // Last valid position is past the last character + // of the text control, so add one virtual character + // at the end to make calculations easier. + txt = [txt stringByAppendingString:@"x"]; + + long nline = 0; + NSRange lineRng; + for ( long i = 0; i <= pos; nline++ ) + { + lineRng = [txt lineRangeForRange:NSMakeRange(i, 0)]; + i = NSMaxRange(lineRng); + } + + if ( y ) + *y = nline-1; + + if ( x ) + *x = pos - lineRng.location; + + return true; +} + +long wxNSTextViewControl::XYToPosition(long x, long y) const +{ + wxCHECK( m_textView, -1 ); + wxCHECK_MSG( x >= 0 && y >= 0, -1, wxS("Invalid line/column number") ); + + NSString* txt = [m_textView string]; + const long txtLen = [txt length]; + long nline = 0; + NSRange lineRng; + for ( long i = 0; i < txtLen && nline <= y; nline++ ) + { + lineRng = [txt lineRangeForRange:NSMakeRange(i, 0)]; + i = NSMaxRange(lineRng); + } + nline--; + + // Return error if contol contains + // less lines than given y position. + if ( nline != y ) + return -1; + + // Return error if given x position + // is past the line. + if ( x >= lineRng.length ) + return -1; + + return lineRng.location + x; +} + void wxNSTextViewControl::WriteText(const wxString& str) { wxString st = str; @@ -1160,6 +1220,32 @@ void wxNSTextFieldControl::SetSelection( long from , long to ) m_selEnd = to; } +bool wxNSTextFieldControl::PositionToXY(long pos, long *x, long *y) const +{ + wxCHECK_MSG( pos >= 0, false, wxS("Invalid character position") ); + + if ( pos > [[m_textField stringValue] length] ) + return false; + + if ( y ) + *y = 0; + + if ( x ) + *x = pos; + + return true; +} + +long wxNSTextFieldControl::XYToPosition(long x, long y) const +{ + wxCHECK_MSG( x >= 0 && y >= 0, -1, wxS("Invalid line/column number") ); + + if ( y != 0 || x >= [[m_textField stringValue] length] ) + return -1; + + return x; +} + void wxNSTextFieldControl::WriteText(const wxString& str) { NSEvent* formerEvent = m_lastKeyDownEvent;