added debugging code to HitTest(), added m_posLastVisible and m_colLastVisible
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8447 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -266,6 +266,9 @@ protected:
|
|||||||
// client coords) which contains the text
|
// client coords) which contains the text
|
||||||
void UpdateTextRect();
|
void UpdateTextRect();
|
||||||
|
|
||||||
|
// calculate the last visible position
|
||||||
|
void UpdateLastVisible();
|
||||||
|
|
||||||
// event handlers
|
// event handlers
|
||||||
void OnChar(wxKeyEvent& event);
|
void OnChar(wxKeyEvent& event);
|
||||||
void OnSize(wxSizeEvent& event);
|
void OnSize(wxSizeEvent& event);
|
||||||
@@ -291,12 +294,17 @@ private:
|
|||||||
// the rectangle (in client coordinates) to draw text inside
|
// the rectangle (in client coordinates) to draw text inside
|
||||||
wxRect m_rectText;
|
wxRect m_rectText;
|
||||||
|
|
||||||
// for the controls without horz scrollbar only: the position of the first
|
// this section is for the controls without horz scrollbar only
|
||||||
// and last visible pixels and the first visible column
|
|
||||||
wxCoord m_ofsHorz,
|
// the position of the first visible pixel and the first visible column
|
||||||
m_posLastVisible;
|
wxCoord m_ofsHorz;
|
||||||
long m_colStart;
|
long m_colStart;
|
||||||
|
|
||||||
|
// and the last ones (m_posLastVisible is the width but m_colLastVisible
|
||||||
|
// is an absolute value)
|
||||||
|
wxCoord m_posLastVisible;
|
||||||
|
long m_colLastVisible;
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
DECLARE_DYNAMIC_CLASS(wxTextCtrl)
|
DECLARE_DYNAMIC_CLASS(wxTextCtrl)
|
||||||
};
|
};
|
||||||
|
@@ -9,6 +9,10 @@
|
|||||||
// Licence: wxWindows license
|
// Licence: wxWindows license
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
Search for "OPT" for possible optimizations
|
||||||
|
*/
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// declarations
|
// declarations
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -46,6 +50,9 @@
|
|||||||
#include "wx/univ/colschem.h"
|
#include "wx/univ/colschem.h"
|
||||||
#include "wx/univ/theme.h"
|
#include "wx/univ/theme.h"
|
||||||
|
|
||||||
|
// turn extra wxTextCtrl-specific debugging on/off
|
||||||
|
#define WXDEBUG_TEXT
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// implementation
|
// implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -72,7 +79,9 @@ void wxTextCtrl::Init()
|
|||||||
|
|
||||||
m_colStart = 0;
|
m_colStart = 0;
|
||||||
m_ofsHorz = 0;
|
m_ofsHorz = 0;
|
||||||
m_posLastVisible = 0;
|
|
||||||
|
m_colLastVisible = -1;
|
||||||
|
m_posLastVisible = -1;
|
||||||
|
|
||||||
m_curPos =
|
m_curPos =
|
||||||
m_curRow =
|
m_curRow =
|
||||||
@@ -147,6 +156,9 @@ void wxTextCtrl::Replace(long from, long to, const wxString& text)
|
|||||||
}
|
}
|
||||||
m_value = valueNew;
|
m_value = valueNew;
|
||||||
|
|
||||||
|
// force m_colLastVisible update
|
||||||
|
m_colLastVisible = -1;
|
||||||
|
|
||||||
// update the current position
|
// update the current position
|
||||||
SetInsertionPoint(from + text.length());
|
SetInsertionPoint(from + text.length());
|
||||||
|
|
||||||
@@ -689,9 +701,40 @@ void wxTextCtrl::UpdateTextRect()
|
|||||||
GetTextClientArea(this,
|
GetTextClientArea(this,
|
||||||
wxRect(wxPoint(0, 0), GetClientSize()));
|
wxRect(wxPoint(0, 0), GetClientSize()));
|
||||||
|
|
||||||
// it will be updated the next time we're redrawn, don't redo the (rather
|
UpdateLastVisible();
|
||||||
// complex and time consuming) calculation of it here
|
}
|
||||||
m_posLastVisible = m_rectText.width;
|
|
||||||
|
void wxTextCtrl::UpdateLastVisible()
|
||||||
|
{
|
||||||
|
// OPT: estimate the correct value first, just adjust it later
|
||||||
|
|
||||||
|
wxString text;
|
||||||
|
wxCoord w, wOld;
|
||||||
|
|
||||||
|
w =
|
||||||
|
wOld = 0;
|
||||||
|
|
||||||
|
m_colLastVisible = m_colStart;
|
||||||
|
|
||||||
|
const wxChar *pc = m_value.c_str() + (size_t)m_colStart;
|
||||||
|
for ( ; *pc; pc++ )
|
||||||
|
{
|
||||||
|
text += *pc;
|
||||||
|
wOld = w;
|
||||||
|
w = GetTextWidth(text);
|
||||||
|
if ( w > m_rectText.width )
|
||||||
|
{
|
||||||
|
// this char is too much
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_colLastVisible++;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_posLastVisible = wOld;
|
||||||
|
|
||||||
|
wxLogTrace(_T("text"), _T("Last visible column/position is %d/%ld"),
|
||||||
|
m_colLastVisible, m_posLastVisible);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxTextCtrl::OnSize(wxSizeEvent& event)
|
void wxTextCtrl::OnSize(wxSizeEvent& event)
|
||||||
@@ -770,7 +813,9 @@ wxTextCtrlHitTestResult wxTextCtrl::HitTestLine(const wxString& line,
|
|||||||
if ( matchDir == 1 )
|
if ( matchDir == 1 )
|
||||||
{
|
{
|
||||||
// we were going to the right and, finally, moved beyond
|
// we were going to the right and, finally, moved beyond
|
||||||
// the original position - stop here
|
// the original position - stop on the previous one
|
||||||
|
//col--;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -807,6 +852,30 @@ wxTextCtrlHitTestResult wxTextCtrl::HitTestLine(const wxString& line,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check that we calculated it correctly
|
||||||
|
#ifdef WXDEBUG_TEXT
|
||||||
|
if ( res == wxTE_HT_ON_TEXT )
|
||||||
|
{
|
||||||
|
wxCoord width1;
|
||||||
|
wxString text = line.Left(col);
|
||||||
|
dc.GetTextExtent(text, &width1, NULL);
|
||||||
|
if ( (size_t)col < line.length() )
|
||||||
|
{
|
||||||
|
wxCoord width2;
|
||||||
|
|
||||||
|
text += line[col];
|
||||||
|
dc.GetTextExtent(text, &width2, NULL);
|
||||||
|
|
||||||
|
wxASSERT_MSG( (width1 <= x) && (x <= width2),
|
||||||
|
_T("incorrect HitTestLine() result") );
|
||||||
|
}
|
||||||
|
else // we return last char
|
||||||
|
{
|
||||||
|
wxASSERT_MSG( x > width1, _T("incorrect HitTestLine() result") );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // WXDEBUG_TEXT
|
||||||
|
|
||||||
if ( colOut )
|
if ( colOut )
|
||||||
*colOut = col;
|
*colOut = col;
|
||||||
|
|
||||||
@@ -926,10 +995,18 @@ void wxTextCtrl::ScrollText(long col)
|
|||||||
if ( col < 0 )
|
if ( col < 0 )
|
||||||
col = 0;
|
col = 0;
|
||||||
|
|
||||||
|
// OPT: could only get the extent of the part of the string between col
|
||||||
|
// and m_colStart
|
||||||
wxCoord ofsHorz = GetTextWidth(GetLineText(0).Left(col));
|
wxCoord ofsHorz = GetTextWidth(GetLineText(0).Left(col));
|
||||||
|
|
||||||
if ( ofsHorz != m_ofsHorz )
|
if ( ofsHorz != m_ofsHorz )
|
||||||
{
|
{
|
||||||
|
// what is currently shown?
|
||||||
|
if ( m_colLastVisible == -1 )
|
||||||
|
{
|
||||||
|
UpdateLastVisible();
|
||||||
|
}
|
||||||
|
|
||||||
// NB1: to scroll to the right, offset must be negative, hence the
|
// NB1: to scroll to the right, offset must be negative, hence the
|
||||||
// order of operands
|
// order of operands
|
||||||
int dx = m_ofsHorz - ofsHorz;
|
int dx = m_ofsHorz - ofsHorz;
|
||||||
@@ -939,10 +1016,26 @@ void wxTextCtrl::ScrollText(long col)
|
|||||||
m_ofsHorz = ofsHorz;
|
m_ofsHorz = ofsHorz;
|
||||||
m_colStart = col;
|
m_colStart = col;
|
||||||
|
|
||||||
// NB3: scroll only the text shown, not the entire text area (there may
|
// scroll only the rectangle inside which there is the text
|
||||||
// be blank area at the end)
|
if ( dx > 0 )
|
||||||
|
{
|
||||||
|
// scrolling to the right: we need to recalc the last visible
|
||||||
|
// position beore scrolling
|
||||||
|
UpdateLastVisible();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// when scrolling to the left, we don't need to worry about the
|
||||||
|
// last visible position, it will be updated later when we draw
|
||||||
|
// the text - but do force update
|
||||||
|
m_colLastVisible = -1;
|
||||||
|
|
||||||
|
m_posLastVisible++;
|
||||||
|
}
|
||||||
|
|
||||||
wxRect rectText = m_rectText;
|
wxRect rectText = m_rectText;
|
||||||
rectText.width = m_posLastVisible;
|
rectText.width = m_posLastVisible;
|
||||||
|
|
||||||
ScrollWindow(dx, 0, &rectText);
|
ScrollWindow(dx, 0, &rectText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1122,11 +1215,29 @@ void wxTextCtrl::DoDrawTextInRect(wxDC& dc, const wxRect& rectUpdate)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// don't show the columns which are scrolled out to the left
|
// don't show the columns which are scrolled out to the left
|
||||||
if ( colStart > m_colStart )
|
if ( colStart < m_colStart )
|
||||||
colStart = m_colStart;
|
colStart = m_colStart;
|
||||||
|
|
||||||
(void)HitTest(pt2, &colEnd, NULL);
|
(void)HitTest(pt2, &colEnd, NULL);
|
||||||
|
|
||||||
|
// colEnd may be less than colStart if colStart was changed by the
|
||||||
|
// assignment above
|
||||||
|
if ( colEnd < colStart )
|
||||||
|
colEnd = colStart;
|
||||||
|
|
||||||
|
// don't draw the chars beyond the rightmost one
|
||||||
|
if ( m_colLastVisible == -1 )
|
||||||
|
{
|
||||||
|
// recalculate this rightmost column
|
||||||
|
UpdateLastVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
wxASSERT_MSG( colStart <= m_colLastVisible,
|
||||||
|
_T("incorrect m_colLastVisible value") );
|
||||||
|
|
||||||
|
if ( colEnd > m_colLastVisible )
|
||||||
|
colEnd = m_colLastVisible;
|
||||||
|
|
||||||
// extract the part of line we need to redraw
|
// extract the part of line we need to redraw
|
||||||
wxString textLine = GetLineText(line);
|
wxString textLine = GetLineText(line);
|
||||||
wxString text = textLine.Mid(colStart, colEnd - colStart + 1);
|
wxString text = textLine.Mid(colStart, colEnd - colStart + 1);
|
||||||
@@ -1148,23 +1259,6 @@ void wxTextCtrl::DoDrawTextInRect(wxDC& dc, const wxRect& rectUpdate)
|
|||||||
rectText.x = m_rectText.x + GetTextWidth(textLine.Left(colStart));
|
rectText.x = m_rectText.x + GetTextWidth(textLine.Left(colStart));
|
||||||
rectText.width = GetTextWidth(text);
|
rectText.width = GetTextWidth(text);
|
||||||
|
|
||||||
// check that the string that we draw fits entirely into the text area,
|
|
||||||
// we don't want to draw just a part of characters
|
|
||||||
while ( rectText.GetRight() > m_ofsHorz + m_rectText.GetRight() )
|
|
||||||
{
|
|
||||||
rectText.width -= GetTextWidth(text.Last());
|
|
||||||
text.RemoveLast();
|
|
||||||
|
|
||||||
// remember the position of the last pixel shown
|
|
||||||
m_posLastVisible = rectText.GetRight() - m_rectText.GetLeft();
|
|
||||||
|
|
||||||
if ( !text )
|
|
||||||
{
|
|
||||||
// string became empty, nothing to draw finally
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// do draw the text
|
// do draw the text
|
||||||
DrawTextLine(dc, rectText, text, selStart, selEnd);
|
DrawTextLine(dc, rectText, text, selStart, selEnd);
|
||||||
wxLogTrace(_T("text"), _T("Line %ld: positions %ld-%ld redrawn."),
|
wxLogTrace(_T("text"), _T("Line %ld: positions %ld-%ld redrawn."),
|
||||||
@@ -1214,7 +1308,14 @@ void wxTextCtrl::DoDraw(wxControlRenderer *renderer)
|
|||||||
wxRegionIterator iter(rgnUpdate);
|
wxRegionIterator iter(rgnUpdate);
|
||||||
for ( ; iter.HaveRects(); iter++ )
|
for ( ; iter.HaveRects(); iter++ )
|
||||||
{
|
{
|
||||||
DoDrawTextInRect(dc, iter.GetRect());
|
wxRect r = iter.GetRect();
|
||||||
|
if ( !r.width || !r.height )
|
||||||
|
{
|
||||||
|
// this happens under wxGTK
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
DoDrawTextInRect(dc, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user