Added support for variable-width fonts
to wxTextCtrl. This excludes syntax highlighting, which is probably OK. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14970 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -227,6 +227,9 @@ public:
|
||||
|
||||
// implementation from now on...
|
||||
|
||||
int PosToPixel( int line, int pos );
|
||||
int PixelToPos( int line, int pixel );
|
||||
|
||||
void SearchForBrackets();
|
||||
|
||||
void DoChar( char c );
|
||||
|
@@ -153,19 +153,12 @@ void wxTextCtrl::Init()
|
||||
m_editable = TRUE;
|
||||
m_modified = FALSE;
|
||||
|
||||
m_sourceFont = wxFont( 12, wxMODERN, wxNORMAL, wxNORMAL );
|
||||
|
||||
m_undos.DeleteContents( TRUE );
|
||||
|
||||
m_lang = wxSOURCE_LANG_NONE;
|
||||
|
||||
m_capturing = FALSE;
|
||||
|
||||
wxClientDC dc(this);
|
||||
dc.SetFont( m_sourceFont );
|
||||
m_lineHeight = dc.GetCharHeight();
|
||||
m_charWidth = dc.GetCharWidth();
|
||||
|
||||
m_cursorX = 0;
|
||||
m_cursorY = 0;
|
||||
|
||||
@@ -227,6 +220,16 @@ bool wxTextCtrl::Create( wxWindow *parent,
|
||||
|
||||
SetCursor( wxCursor( wxCURSOR_IBEAM ) );
|
||||
|
||||
if (HasFlag(wxTE_PASSWORD))
|
||||
m_sourceFont = wxFont( 12, wxMODERN, wxNORMAL, wxNORMAL );
|
||||
else
|
||||
m_sourceFont = GetFont();
|
||||
|
||||
wxClientDC dc(this);
|
||||
dc.SetFont( m_sourceFont );
|
||||
m_lineHeight = dc.GetCharHeight();
|
||||
m_charWidth = dc.GetCharWidth();
|
||||
|
||||
SetValue( value );
|
||||
|
||||
wxSize size_best( DoGetBestSize() );
|
||||
@@ -283,19 +286,31 @@ void wxTextCtrl::SetValue(const wxString& value)
|
||||
pos = value.find( wxT('\n'), begin );
|
||||
if (pos < 0)
|
||||
{
|
||||
if (value.Len()-begin > m_longestLine)
|
||||
m_longestLine = value.Len()-begin;
|
||||
wxSourceLine *sl = new wxSourceLine( value.Mid( begin, value.Len()-begin ) );
|
||||
m_lines.Add( sl );
|
||||
|
||||
m_lines.Add( new wxSourceLine( value.Mid( begin, value.Len()-begin ) ) );
|
||||
// if (sl->m_text.Len() > m_longestLine)
|
||||
// m_longestLine = sl->m_text.Len();
|
||||
int ww = 0;
|
||||
GetTextExtent( sl->m_text, &ww, NULL, NULL, NULL );
|
||||
ww /= m_charWidth;
|
||||
if (ww > m_longestLine)
|
||||
m_longestLine = ww;
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pos-begin > m_longestLine)
|
||||
m_longestLine = pos-begin;
|
||||
wxSourceLine *sl = new wxSourceLine( value.Mid( begin, pos-begin ) );
|
||||
m_lines.Add( sl );
|
||||
|
||||
m_lines.Add( new wxSourceLine( value.Mid( begin, pos-begin ) ) );
|
||||
// if (sl->m_text.Len() > m_longestLine)
|
||||
// m_longestLine = sl->m_text.Len();
|
||||
int ww = 0;
|
||||
GetTextExtent( sl->m_text, &ww, NULL, NULL, NULL );
|
||||
ww /= m_charWidth;
|
||||
if (ww > m_longestLine)
|
||||
m_longestLine = ww;
|
||||
|
||||
begin = pos+1;
|
||||
}
|
||||
@@ -376,6 +391,50 @@ void wxTextCtrl::SetMaxLength(unsigned long len)
|
||||
{
|
||||
}
|
||||
|
||||
int wxTextCtrl::PosToPixel( int line, int pos )
|
||||
{
|
||||
// TODO add support for Tabs
|
||||
|
||||
if (line >= m_lines.GetCount()) return 0;
|
||||
|
||||
wxString text = m_lines[line].m_text;
|
||||
|
||||
if (text.IsEmpty()) return 0;
|
||||
|
||||
if (pos < text.Len())
|
||||
text.Remove( pos, text.Len()-pos );
|
||||
|
||||
int w = 0;
|
||||
|
||||
GetTextExtent( text, &w, NULL, NULL, NULL );
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
int wxTextCtrl::PixelToPos( int line, int pixel )
|
||||
{
|
||||
if (pixel < 2) return 0;
|
||||
|
||||
if (line >= m_lines.GetCount()) return 0;
|
||||
|
||||
wxString text = m_lines[line].m_text;
|
||||
|
||||
int w = 0;
|
||||
int res = text.Len();
|
||||
while (res > 0)
|
||||
{
|
||||
GetTextExtent( text, &w, NULL, NULL, NULL );
|
||||
|
||||
if (w < pixel)
|
||||
return res;
|
||||
|
||||
res--;
|
||||
text.Remove( res,1 );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void wxTextCtrl::WriteText(const wxString& text2)
|
||||
{
|
||||
if (text2.IsEmpty()) return;
|
||||
@@ -1030,16 +1089,26 @@ void wxTextCtrl::DoChar( char c )
|
||||
|
||||
m_lines[m_cursorY].m_text = tmp;
|
||||
|
||||
if (tmp.Len() > m_longestLine)
|
||||
// if (tmp.Len() > m_longestLine)
|
||||
// {
|
||||
// m_longestLine = tmp.Len();
|
||||
// MyAdjustScrollbars();
|
||||
// }
|
||||
|
||||
int ww = 0;
|
||||
GetTextExtent( tmp, &ww, NULL, NULL, NULL );
|
||||
ww /= m_charWidth;
|
||||
if (ww > m_longestLine)
|
||||
{
|
||||
m_longestLine = tmp.Len();
|
||||
m_longestLine = ww;
|
||||
MyAdjustScrollbars();
|
||||
}
|
||||
|
||||
m_cursorX++;
|
||||
|
||||
int y = m_cursorY*m_lineHeight;
|
||||
int x = (m_cursorX-1)*m_charWidth;
|
||||
// int x = (m_cursorX-1)*m_charWidth;
|
||||
int x = PosToPixel( m_cursorY, m_cursorX-1 );
|
||||
CalcScrolledPosition( x, y, &x, &y );
|
||||
wxRect rect( x+2, y+2, 10000, m_lineHeight );
|
||||
Refresh( TRUE, &rect );
|
||||
@@ -1053,10 +1122,13 @@ void wxTextCtrl::DoChar( char c )
|
||||
int view_y = 0;
|
||||
GetViewStart( &view_x, &view_y );
|
||||
|
||||
if (m_cursorX < view_x)
|
||||
Scroll( m_cursorX, -1 );
|
||||
else if (m_cursorX > view_x+size_x-1)
|
||||
Scroll( m_cursorX-size_x+1, -1 );
|
||||
//int xx = m_cursorX;
|
||||
int xx = PosToPixel( m_cursorY, m_cursorX ) / m_charWidth;
|
||||
|
||||
if (xx < view_x)
|
||||
Scroll( xx, -1 );
|
||||
else if (xx > view_x+size_x-1)
|
||||
Scroll( xx-size_x+1, -1 );
|
||||
}
|
||||
|
||||
void wxTextCtrl::DoBack()
|
||||
@@ -1091,7 +1163,8 @@ void wxTextCtrl::DoBack()
|
||||
m_cursorX--;
|
||||
|
||||
int y = m_cursorY*m_lineHeight;
|
||||
int x = m_cursorX*m_charWidth;
|
||||
// int x = m_cursorX*m_charWidth;
|
||||
int x = PosToPixel( m_cursorY, m_cursorX );
|
||||
CalcScrolledPosition( x, y, &x, &y );
|
||||
wxRect rect( x+2, y+2, 10000, m_lineHeight );
|
||||
Refresh( TRUE, &rect );
|
||||
@@ -1130,7 +1203,8 @@ void wxTextCtrl::DoDelete()
|
||||
m_lines[m_cursorY].m_text = tmp;
|
||||
|
||||
int y = m_cursorY*m_lineHeight;
|
||||
int x = m_cursorX*m_charWidth;
|
||||
// int x = m_cursorX*m_charWidth;
|
||||
int x = PosToPixel( m_cursorY, m_cursorX );
|
||||
CalcScrolledPosition( x, y, &x, &y );
|
||||
wxRect rect( x+2, y+2, 10000, m_lineHeight );
|
||||
Refresh( TRUE, &rect );
|
||||
@@ -1344,6 +1418,8 @@ void wxTextCtrl::DrawLine( wxDC &dc, int x, int y, const wxString &line2, int li
|
||||
wxString comment( ' ', line.Len() );
|
||||
wxString my_string( ' ', line.Len() );
|
||||
|
||||
if (m_lang != wxSOURCE_LANG_NONE)
|
||||
{
|
||||
if (lineNum == m_bracketY)
|
||||
{
|
||||
wxString red( ' ', line.Len() );
|
||||
@@ -1421,10 +1497,13 @@ void wxTextCtrl::DrawLine( wxDC &dc, int x, int y, const wxString &line2, int li
|
||||
pos += token.Len();
|
||||
token = GetNextToken( line, pos);
|
||||
}
|
||||
}
|
||||
|
||||
if ((lineNum < selStartY) || (lineNum > selEndY))
|
||||
{
|
||||
dc.DrawText( line, x, y );
|
||||
if (m_lang != wxSOURCE_LANG_NONE)
|
||||
{
|
||||
dc.SetTextForeground( m_keywordColour );
|
||||
dc.DrawText( keyword, x, y );
|
||||
dc.SetTextForeground( m_defineColour );
|
||||
@@ -1436,16 +1515,24 @@ void wxTextCtrl::DrawLine( wxDC &dc, int x, int y, const wxString &line2, int li
|
||||
dc.SetTextForeground( m_stringColour );
|
||||
dc.DrawText( my_string, x, y );
|
||||
dc.SetTextForeground( *wxBLACK );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (selStartY == selEndY)
|
||||
{
|
||||
// int xx = selStartX*m_charWidth;
|
||||
int xx = PosToPixel( lineNum, selStartX );
|
||||
// int ww = (selEndX-selStartX)*m_charWidth;
|
||||
int ww = PosToPixel( lineNum, selEndX ) - xx;
|
||||
dc.DrawRectangle( xx+2, lineNum*m_lineHeight+2, ww, m_lineHeight );
|
||||
|
||||
if (m_lang != wxSOURCE_LANG_NONE)
|
||||
{
|
||||
int i;
|
||||
wxString tmp1( line );
|
||||
wxString tmp2( line );
|
||||
dc.DrawRectangle( selStartX*m_charWidth+2, lineNum*m_lineHeight+2,
|
||||
(selEndX-selStartX)*m_charWidth, m_lineHeight );
|
||||
|
||||
for (i = selStartX; i < selEndX; i++)
|
||||
if ((int)tmp1.Len() > i)
|
||||
tmp1.SetChar( i, ' ' );
|
||||
@@ -1459,21 +1546,29 @@ void wxTextCtrl::DrawLine( wxDC &dc, int x, int y, const wxString &line2, int li
|
||||
dc.SetTextForeground( *wxWHITE );
|
||||
dc.DrawText( tmp2, x, y );
|
||||
dc.SetTextForeground( *wxBLACK );
|
||||
}
|
||||
} else
|
||||
if ((lineNum > selStartY) && (lineNum < selEndY))
|
||||
{
|
||||
dc.DrawRectangle( 0+2, lineNum*m_lineHeight+2, 10000, m_lineHeight );
|
||||
if (m_lang != wxSOURCE_LANG_NONE)
|
||||
{
|
||||
dc.SetTextForeground( *wxWHITE );
|
||||
dc.DrawText( line, x, y );
|
||||
dc.SetTextForeground( *wxBLACK );
|
||||
}
|
||||
} else
|
||||
if (lineNum == selStartY)
|
||||
{
|
||||
// int xx = selStartX*m_charWidth;
|
||||
int xx = PosToPixel( lineNum, selStartX );
|
||||
dc.DrawRectangle( xx+2, lineNum*m_lineHeight+2, 10000, m_lineHeight );
|
||||
|
||||
if (m_lang != wxSOURCE_LANG_NONE)
|
||||
{
|
||||
int i;
|
||||
wxString tmp1( line );
|
||||
wxString tmp2( line );
|
||||
dc.DrawRectangle( selStartX*m_charWidth+2, lineNum*m_lineHeight+2,
|
||||
10000, m_lineHeight );
|
||||
for (i = selStartX; i < (int)tmp1.Len(); i++)
|
||||
tmp1.SetChar( i, ' ' );
|
||||
dc.DrawText( tmp1, x, y );
|
||||
@@ -1483,14 +1578,19 @@ void wxTextCtrl::DrawLine( wxDC &dc, int x, int y, const wxString &line2, int li
|
||||
dc.SetTextForeground( *wxWHITE );
|
||||
dc.DrawText( tmp2, x, y );
|
||||
dc.SetTextForeground( *wxBLACK );
|
||||
}
|
||||
} else
|
||||
if (lineNum == selEndY)
|
||||
{
|
||||
// int ww = selEndX*m_charWidth;
|
||||
int ww = PosToPixel( lineNum, selEndX );
|
||||
dc.DrawRectangle( 0+2, lineNum*m_lineHeight+2, ww, m_lineHeight );
|
||||
|
||||
if (m_lang != wxSOURCE_LANG_NONE)
|
||||
{
|
||||
int i;
|
||||
wxString tmp1( line );
|
||||
wxString tmp2( line );
|
||||
dc.DrawRectangle( 0+2, lineNum*m_lineHeight+2,
|
||||
selEndX*m_charWidth, m_lineHeight );
|
||||
for (i = 0; i < selEndX; i++)
|
||||
if ((int)tmp1.Len() > i)
|
||||
tmp1.SetChar( i, ' ' );
|
||||
@@ -1501,7 +1601,14 @@ void wxTextCtrl::DrawLine( wxDC &dc, int x, int y, const wxString &line2, int li
|
||||
dc.DrawText( tmp2, x, y );
|
||||
dc.SetTextForeground( *wxBLACK );
|
||||
}
|
||||
}
|
||||
|
||||
if (m_lang == wxSOURCE_LANG_NONE)
|
||||
{
|
||||
dc.DrawText( line, x, y );
|
||||
}
|
||||
else
|
||||
{
|
||||
dc.SetTextForeground( m_keywordColour );
|
||||
dc.DrawText( keyword, x, y );
|
||||
dc.SetTextForeground( m_defineColour );
|
||||
@@ -1514,6 +1621,7 @@ void wxTextCtrl::DrawLine( wxDC &dc, int x, int y, const wxString &line2, int li
|
||||
dc.DrawText( my_string, x, y );
|
||||
dc.SetTextForeground( *wxBLACK );
|
||||
}
|
||||
}
|
||||
|
||||
void wxTextCtrl::OnPaint( wxPaintEvent &event )
|
||||
{
|
||||
@@ -1547,7 +1655,9 @@ void wxTextCtrl::OnPaint( wxPaintEvent &event )
|
||||
}
|
||||
|
||||
dc.SetBrush( *wxRED_BRUSH );
|
||||
dc.DrawRectangle( m_cursorX*m_charWidth+2, m_cursorY*m_lineHeight+2, 2, m_lineHeight );
|
||||
// int xx = m_cursorX*m_charWidth;
|
||||
int xx = PosToPixel( m_cursorY, m_cursorX );
|
||||
dc.DrawRectangle( xx+2, m_cursorY*m_lineHeight+2, 2, m_lineHeight );
|
||||
}
|
||||
|
||||
void wxTextCtrl::OnMouse( wxMouseEvent &event )
|
||||
@@ -1587,8 +1697,9 @@ void wxTextCtrl::OnMouse( wxMouseEvent &event )
|
||||
int x = event.GetX();
|
||||
int y = event.GetY();
|
||||
CalcUnscrolledPosition( x, y, &x, &y );
|
||||
x /= m_charWidth;
|
||||
y /= m_lineHeight;
|
||||
// x /= m_charWidth;
|
||||
x = PixelToPos( y, x );
|
||||
MoveCursor(
|
||||
wxMin( 1000, wxMax( 0, x ) ),
|
||||
wxMin( (int)m_lines.GetCount()-1, wxMax( 0, y ) ),
|
||||
@@ -1776,6 +1887,7 @@ void wxTextCtrl::OnIdle( wxIdleEvent &event )
|
||||
{
|
||||
m_ignoreInput = FALSE;
|
||||
|
||||
if (m_lang != wxSOURCE_LANG_NONE)
|
||||
SearchForBrackets();
|
||||
|
||||
event.Skip( TRUE );
|
||||
@@ -1932,13 +2044,17 @@ void wxTextCtrl::MoveCursor( int new_x, int new_y, bool shift, bool centre )
|
||||
h = m_lineHeight;
|
||||
if (m_selEndX > new_x)
|
||||
{
|
||||
x = new_x*m_charWidth;
|
||||
w = (m_selEndX-new_x)*m_charWidth;
|
||||
// x = new_x*m_charWidth;
|
||||
x = PosToPixel( new_y, new_x );
|
||||
// w = (m_selEndX-new_x)*m_charWidth;
|
||||
w = PosToPixel( new_y, m_selEndX ) - x;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = m_selEndX*m_charWidth;
|
||||
w = (-m_selEndX+new_x)*m_charWidth;
|
||||
// x = m_selEndX*m_charWidth;
|
||||
x = PosToPixel( new_y, m_selEndX );
|
||||
// w = (-m_selEndX+new_x)*m_charWidth;
|
||||
w = PosToPixel( new_y, new_x ) - x;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1989,7 +2105,7 @@ void wxTextCtrl::MoveCursor( int new_x, int new_y, bool shift, bool centre )
|
||||
int x = 0;
|
||||
int y = ry1*m_lineHeight;
|
||||
CalcScrolledPosition( x, y, &x, &y );
|
||||
wxRect rect( 0+2, y+2, 10000, (ry2-ry1+1)*m_lineHeight );
|
||||
wxRect rect( 0, y+2, 10000, (ry2-ry1+1)*m_lineHeight );
|
||||
|
||||
Refresh( TRUE, &rect );
|
||||
}
|
||||
@@ -2004,7 +2120,8 @@ void wxTextCtrl::MoveCursor( int new_x, int new_y, bool shift, bool centre )
|
||||
|
||||
if (!no_cursor_refresh)
|
||||
{
|
||||
int x = m_cursorX*m_charWidth;
|
||||
// int x = m_cursorX*m_charWidth;
|
||||
int x = PosToPixel( m_cursorY, m_cursorX );
|
||||
int y = m_cursorY*m_lineHeight;
|
||||
CalcScrolledPosition( x, y, &x, &y );
|
||||
wxRect rect( x+2, y+2, 4, m_lineHeight+2 );
|
||||
@@ -2018,7 +2135,9 @@ void wxTextCtrl::MoveCursor( int new_x, int new_y, bool shift, bool centre )
|
||||
PrepareDC( dc );
|
||||
dc.SetPen( *wxTRANSPARENT_PEN );
|
||||
dc.SetBrush( *wxRED_BRUSH );
|
||||
dc.DrawRectangle( m_cursorX*m_charWidth+2, m_cursorY*m_lineHeight+2, 2, m_lineHeight );
|
||||
// int xx = m_cursorX*m_charWidth;
|
||||
int xx = PosToPixel( m_cursorY, m_cursorX );
|
||||
dc.DrawRectangle( xx+2, m_cursorY*m_lineHeight+2, 2, m_lineHeight );
|
||||
}
|
||||
|
||||
int size_x = 0;
|
||||
@@ -2045,10 +2164,13 @@ void wxTextCtrl::MoveCursor( int new_x, int new_y, bool shift, bool centre )
|
||||
Scroll( -1, m_cursorY-size_y+1 );
|
||||
}
|
||||
|
||||
if (m_cursorX < view_x)
|
||||
Scroll( m_cursorX, -1 );
|
||||
else if (m_cursorX > view_x+size_x-1)
|
||||
Scroll( m_cursorX-size_x+1, -1 );
|
||||
//int xx = m_cursorX;
|
||||
int xx = PosToPixel( m_cursorY, m_cursorX ) / m_charWidth;
|
||||
|
||||
if (xx < view_x)
|
||||
Scroll( xx, -1 );
|
||||
else if (xx > view_x+size_x-1)
|
||||
Scroll( xx-size_x+1, -1 );
|
||||
}
|
||||
|
||||
void wxTextCtrl::MyAdjustScrollbars()
|
||||
|
Reference in New Issue
Block a user