1. (hopefully) fixed horz scrolling
2. only refresh part of line in Replace() 3. changed wxWindow::Refresh() to take client coordinates 4. only refresh the text which must be refreshed when selection changes git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8449 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
3
TODO
3
TODO
@@ -4,7 +4,7 @@ TODO
|
|||||||
|
|
||||||
wxTextCtrl
|
wxTextCtrl
|
||||||
|
|
||||||
o DoDraw should iterat over update region instead of using bounding box
|
* display corrupted when typing text in quickly
|
||||||
|
|
||||||
All
|
All
|
||||||
|
|
||||||
@@ -31,6 +31,7 @@ DONE
|
|||||||
All
|
All
|
||||||
|
|
||||||
+ text ctrl horz scrolling
|
+ text ctrl horz scrolling
|
||||||
|
+ DoDraw should iterat over update region instead of using bounding box
|
||||||
|
|
||||||
MSW
|
MSW
|
||||||
|
|
||||||
|
@@ -302,6 +302,7 @@ public:
|
|||||||
void SetTop(int top) { y = top; }
|
void SetTop(int top) { y = top; }
|
||||||
void SetBottom(int bottom) { height = bottom - y + 1; }
|
void SetBottom(int bottom) { height = bottom - y + 1; }
|
||||||
|
|
||||||
|
// operations with rect
|
||||||
void Inflate(wxCoord dx, wxCoord dy)
|
void Inflate(wxCoord dx, wxCoord dy)
|
||||||
{
|
{
|
||||||
x -= dx;
|
x -= dx;
|
||||||
@@ -312,12 +313,17 @@ public:
|
|||||||
|
|
||||||
void Inflate(wxCoord d) { Inflate(d, d); }
|
void Inflate(wxCoord d) { Inflate(d, d); }
|
||||||
|
|
||||||
|
void Offset(wxCoord dx, wxCoord dy) { x += dx; y += dy; }
|
||||||
|
void Offset(const wxPoint& pt) { Offset(pt.x, pt.y); }
|
||||||
|
|
||||||
|
wxRect operator+(const wxRect& rect) const;
|
||||||
|
wxRect& operator+=(const wxRect& rect);
|
||||||
|
|
||||||
|
// tests
|
||||||
bool operator==(const wxRect& rect) const;
|
bool operator==(const wxRect& rect) const;
|
||||||
bool operator!=(const wxRect& rect) const { return !(*this == rect); }
|
bool operator!=(const wxRect& rect) const { return !(*this == rect); }
|
||||||
|
|
||||||
bool Inside(int cx, int cy) const;
|
bool Inside(int cx, int cy) const;
|
||||||
wxRect operator+(const wxRect& rect) const;
|
|
||||||
wxRect& operator+=(const wxRect& rect);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int x, y, width, height;
|
int x, y, width, height;
|
||||||
|
@@ -169,6 +169,7 @@ public:
|
|||||||
// caret stuff
|
// caret stuff
|
||||||
virtual void ShowCaret(bool show = TRUE);
|
virtual void ShowCaret(bool show = TRUE);
|
||||||
void HideCaret() { ShowCaret(FALSE); }
|
void HideCaret() { ShowCaret(FALSE); }
|
||||||
|
void CreateCaret(); // for the current font size
|
||||||
wxCoord GetCaretPosition() const; // in pixels
|
wxCoord GetCaretPosition() const; // in pixels
|
||||||
|
|
||||||
// helpers for cursor movement
|
// helpers for cursor movement
|
||||||
@@ -176,7 +177,8 @@ public:
|
|||||||
long GetWordEnd() const;
|
long GetWordEnd() const;
|
||||||
|
|
||||||
// selection helpers
|
// selection helpers
|
||||||
bool HasSelection() const { return m_selStart != -1; }
|
bool HasSelection() const
|
||||||
|
{ return m_selStart != -1 && m_selEnd > m_selStart; }
|
||||||
void ClearSelection();
|
void ClearSelection();
|
||||||
void RemoveSelection();
|
void RemoveSelection();
|
||||||
wxString GetSelectionText() const;
|
wxString GetSelectionText() const;
|
||||||
@@ -225,6 +227,9 @@ public:
|
|||||||
long numArg = -1,
|
long numArg = -1,
|
||||||
const wxString& strArg = wxEmptyString);
|
const wxString& strArg = wxEmptyString);
|
||||||
|
|
||||||
|
// override this to recreate the caret here
|
||||||
|
virtual bool SetFont(const wxFont &font);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// draw the text
|
// draw the text
|
||||||
void DrawTextLine(wxDC& dc, const wxRect& rect,
|
void DrawTextLine(wxDC& dc, const wxRect& rect,
|
||||||
@@ -251,8 +256,16 @@ protected:
|
|||||||
// get the extent (width) of the text
|
// get the extent (width) of the text
|
||||||
wxCoord GetTextWidth(const wxString& text) const;
|
wxCoord GetTextWidth(const wxString& text) const;
|
||||||
|
|
||||||
// refresh the text in the given range (in text coords) of this line
|
// refresh the text in the given range (in logical coords) of this line, if
|
||||||
void RefreshLine(long line, long from, long to);
|
// width is 0, refresh to the end of line
|
||||||
|
void RefreshPixelRange(long line, wxCoord start, wxCoord width);
|
||||||
|
|
||||||
|
// refresh the text in the given range (in text coords) in this line
|
||||||
|
void RefreshLineRange(long line, long start, long count);
|
||||||
|
|
||||||
|
// refresh the text in the given range which can span multiple lines
|
||||||
|
// (this method accepts arguments in any order)
|
||||||
|
void RefreshTextRange(long start, long end);
|
||||||
|
|
||||||
// get the text to show: either the text itself or the text replaced with
|
// get the text to show: either the text itself or the text replaced with
|
||||||
// starts for wxTE_PASSWORD control
|
// starts for wxTE_PASSWORD control
|
||||||
@@ -277,6 +290,9 @@ private:
|
|||||||
// the value (may be only part of it for the multiline controls)
|
// the value (may be only part of it for the multiline controls)
|
||||||
wxString m_value;
|
wxString m_value;
|
||||||
|
|
||||||
|
// the initially specified control size
|
||||||
|
wxSize m_sizeInitial;
|
||||||
|
|
||||||
// current position
|
// current position
|
||||||
long m_curPos,
|
long m_curPos,
|
||||||
m_curLine,
|
m_curLine,
|
||||||
|
@@ -150,9 +150,19 @@ public:
|
|||||||
// querying the current theme
|
// querying the current theme
|
||||||
wxRenderer *GetRenderer() const { return m_renderer; }
|
wxRenderer *GetRenderer() const { return m_renderer; }
|
||||||
|
|
||||||
|
// scrolling helper: like ScrollWindow() except that it doesn't refresh the
|
||||||
|
// uncovered window areas but returns the rectangle to update (don't call
|
||||||
|
// this with both dx and dy non zero)
|
||||||
|
wxRect ScrollNoRefresh(int dx, int dy, const wxRect *rect = NULL);
|
||||||
|
|
||||||
// overridden base class methods
|
// overridden base class methods
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
|
|
||||||
|
// the rect coordinates are, for us, in client coords, but if no rect is
|
||||||
|
// specified, the entire window is refreshed
|
||||||
|
virtual void Refresh(bool eraseBackground = TRUE,
|
||||||
|
const wxRect *rect = (const wxRect *) NULL);
|
||||||
|
|
||||||
// remember that the font/colour was changed
|
// remember that the font/colour was changed
|
||||||
virtual bool SetBackgroundColour(const wxColour& colour);
|
virtual bool SetBackgroundColour(const wxColour& colour);
|
||||||
virtual bool SetForegroundColour(const wxColour& colour);
|
virtual bool SetForegroundColour(const wxColour& colour);
|
||||||
|
@@ -233,7 +233,7 @@ MyUnivFrame::MyUnivFrame(const wxString& title)
|
|||||||
#ifndef TEST_TEXT_ONLY
|
#ifndef TEST_TEXT_ONLY
|
||||||
wxSize(700, 700)
|
wxSize(700, 700)
|
||||||
#else
|
#else
|
||||||
wxSize(240, 150)
|
wxSize(240, 200)
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -383,8 +383,13 @@ MyUnivFrame::MyUnivFrame(const wxString& title)
|
|||||||
new wxTextCtrl(this, -1, _T("Hello, Universe!"),
|
new wxTextCtrl(this, -1, _T("Hello, Universe!"),
|
||||||
wxPoint(550, 150), wxDefaultSize);
|
wxPoint(550, 150), wxDefaultSize);
|
||||||
#else // TEST_TEXT_ONLY
|
#else // TEST_TEXT_ONLY
|
||||||
new wxTextCtrl(this, -1, _T("Hello, Universe!"),
|
wxTextCtrl *text = new wxTextCtrl(this, -1, _T("Hello, Universe!"),
|
||||||
wxPoint(10, 40), wxSize(200, -1));
|
wxPoint(10, 40));
|
||||||
|
text->SetFont(wxFont(24, wxFONTFAMILY_DEFAULT,
|
||||||
|
wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
|
||||||
|
wxSize sizeText = text->GetBestSize();
|
||||||
|
sizeText.x = 200;
|
||||||
|
text->SetSize(sizeText);
|
||||||
#endif // !TEST_TEXT_ONLY/TEST_TEXT_ONLY
|
#endif // !TEST_TEXT_ONLY/TEST_TEXT_ONLY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -492,7 +492,10 @@ void wxListBox::OnIdle(wxIdleEvent& event)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wxRect rect = GetClientRect();
|
wxSize size = GetClientSize();
|
||||||
|
wxRect rect;
|
||||||
|
rect.width = size.x;
|
||||||
|
rect.height = size.y;
|
||||||
rect.y += m_updateFrom*GetLineHeight();
|
rect.y += m_updateFrom*GetLineHeight();
|
||||||
rect.height = m_updateCount*GetLineHeight();
|
rect.height = m_updateCount*GetLineHeight();
|
||||||
CalcScrolledPosition(rect.x, rect.y, &rect.x, &rect.y);
|
CalcScrolledPosition(rect.x, rect.y, &rect.x, &rect.y);
|
||||||
|
@@ -261,6 +261,7 @@ void wxScrollBar::OnIdle(wxIdleEvent& event)
|
|||||||
#endif // 0/1
|
#endif // 0/1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: rect is client or win (must be client)?
|
||||||
Refresh(TRUE, &rect);
|
Refresh(TRUE, &rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -53,6 +53,20 @@
|
|||||||
// turn extra wxTextCtrl-specific debugging on/off
|
// turn extra wxTextCtrl-specific debugging on/off
|
||||||
#define WXDEBUG_TEXT
|
#define WXDEBUG_TEXT
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// private functions
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static inline void OrderPositions(long& from, long& to)
|
||||||
|
{
|
||||||
|
if ( from > to )
|
||||||
|
{
|
||||||
|
long tmp = from;
|
||||||
|
from = to;
|
||||||
|
to = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// implementation
|
// implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -103,19 +117,27 @@ bool wxTextCtrl::Create(wxWindow *parent,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME use renderer
|
|
||||||
wxCaret *caret = new wxCaret(this, 1, GetCharHeight());
|
|
||||||
#ifndef __WXMSW__
|
|
||||||
caret->SetBlinkTime(0);
|
|
||||||
#endif // __WXMSW__
|
|
||||||
SetCaret(caret);
|
|
||||||
|
|
||||||
SetCursor(wxCURSOR_IBEAM);
|
SetCursor(wxCURSOR_IBEAM);
|
||||||
|
|
||||||
SetValue(value);
|
SetValue(value);
|
||||||
SetBestSize(size);
|
SetBestSize(m_sizeInitial);
|
||||||
|
CreateCaret();
|
||||||
|
|
||||||
caret->Show();
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxTextCtrl::SetFont(const wxFont& font)
|
||||||
|
{
|
||||||
|
if ( !wxControl::SetFont(font) )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
// recreate it, in fact
|
||||||
|
CreateCaret();
|
||||||
|
|
||||||
|
// and refresh everything, of course
|
||||||
|
SetInsertionPoint(0);
|
||||||
|
ClearSelection();
|
||||||
|
Refresh();
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -149,11 +171,30 @@ void wxTextCtrl::Replace(long from, long to, const wxString& text)
|
|||||||
|
|
||||||
// replace the part of the text with the new value
|
// replace the part of the text with the new value
|
||||||
wxString valueNew(m_value, (size_t)from);
|
wxString valueNew(m_value, (size_t)from);
|
||||||
|
|
||||||
|
// remember it for later use
|
||||||
|
wxCoord startNewText = GetTextWidth(valueNew);
|
||||||
|
|
||||||
|
// if we really replace something, refresh till the end of line as all
|
||||||
|
// remaining text in it is affected, but if we just added some text to the
|
||||||
|
// end of line, we only need to refresh the area occupied by this text
|
||||||
|
// refresh to the end of the line
|
||||||
|
wxCoord widthNewText;
|
||||||
|
|
||||||
valueNew += text;
|
valueNew += text;
|
||||||
if ( (unsigned long)to < m_value.length() )
|
if ( (size_t)to < m_value.length() )
|
||||||
{
|
{
|
||||||
valueNew += m_value.c_str() + (size_t)to;
|
valueNew += m_value.c_str() + (size_t)to;
|
||||||
|
|
||||||
|
// refresh till the end of line
|
||||||
|
widthNewText = 0;
|
||||||
}
|
}
|
||||||
|
else // text appended, not replaced
|
||||||
|
{
|
||||||
|
// refresh only the new text
|
||||||
|
widthNewText = GetTextWidth(text);
|
||||||
|
}
|
||||||
|
|
||||||
m_value = valueNew;
|
m_value = valueNew;
|
||||||
|
|
||||||
// force m_colLastVisible update
|
// force m_colLastVisible update
|
||||||
@@ -166,22 +207,17 @@ void wxTextCtrl::Replace(long from, long to, const wxString& text)
|
|||||||
// for selection anchor)
|
// for selection anchor)
|
||||||
ClearSelection();
|
ClearSelection();
|
||||||
|
|
||||||
// refresh to the end of the line
|
// repaint
|
||||||
RefreshLine(0, from, -1);
|
RefreshPixelRange(0, startNewText, widthNewText);
|
||||||
|
|
||||||
// and the affected parts of the next line (TODO)
|
// TODO: and the affected parts of the next line(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxTextCtrl::Remove(long from, long to)
|
void wxTextCtrl::Remove(long from, long to)
|
||||||
{
|
{
|
||||||
if ( from > to )
|
// Replace() only works with correctly ordered arguments, so exchange them
|
||||||
{
|
// if necessary
|
||||||
// Replace() only works with correctly ordered arguments, so exchange
|
OrderPositions(from, to);
|
||||||
// them
|
|
||||||
long tmp = from;
|
|
||||||
from = to;
|
|
||||||
to = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
Replace(from, to, _T(""));
|
Replace(from, to, _T(""));
|
||||||
}
|
}
|
||||||
@@ -291,7 +327,7 @@ wxString wxTextCtrl::GetSelectionText() const
|
|||||||
|
|
||||||
void wxTextCtrl::SetSelection(long from, long to)
|
void wxTextCtrl::SetSelection(long from, long to)
|
||||||
{
|
{
|
||||||
if ( from == -1 || to == -1 )
|
if ( from == -1 || to == from )
|
||||||
{
|
{
|
||||||
ClearSelection();
|
ClearSelection();
|
||||||
}
|
}
|
||||||
@@ -309,14 +345,36 @@ void wxTextCtrl::SetSelection(long from, long to)
|
|||||||
|
|
||||||
if ( from != m_selStart || to != m_selEnd )
|
if ( from != m_selStart || to != m_selEnd )
|
||||||
{
|
{
|
||||||
|
// we need to use temp vars as RefreshTextRange() may call DoDraw()
|
||||||
|
// directly and so m_selStart/End must be reset by then
|
||||||
|
long selStartOld = m_selStart,
|
||||||
|
selEndOld = m_selEnd;
|
||||||
|
|
||||||
m_selStart = from;
|
m_selStart = from;
|
||||||
m_selEnd = to;
|
m_selEnd = to;
|
||||||
|
|
||||||
wxLogTrace(_T("text"), _T("Selection range is %ld-%ld"),
|
wxLogTrace(_T("text"), _T("Selection range is %ld-%ld"),
|
||||||
m_selStart, m_selEnd);
|
m_selStart, m_selEnd);
|
||||||
|
|
||||||
// FIXME: shouldn't refresh everything
|
// refresh only the part of text which became (un)selected if
|
||||||
Refresh();
|
// possible
|
||||||
|
if ( selStartOld == m_selStart )
|
||||||
|
{
|
||||||
|
RefreshTextRange(selEndOld, m_selEnd);
|
||||||
|
}
|
||||||
|
else if ( selEndOld == m_selEnd )
|
||||||
|
{
|
||||||
|
RefreshTextRange(m_selStart, selStartOld);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// OPT: could check for other cases too but it is probably not
|
||||||
|
// worth it as the two above are the most common ones
|
||||||
|
if ( selStartOld != -1 )
|
||||||
|
RefreshTextRange(selStartOld, selEndOld);
|
||||||
|
if ( m_selStart != -1 )
|
||||||
|
RefreshTextRange(m_selStart, m_selEnd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//else: nothing to do
|
//else: nothing to do
|
||||||
}
|
}
|
||||||
@@ -326,11 +384,17 @@ void wxTextCtrl::ClearSelection()
|
|||||||
{
|
{
|
||||||
if ( HasSelection() )
|
if ( HasSelection() )
|
||||||
{
|
{
|
||||||
|
// we need to use temp vars as RefreshTextRange() may call DoDraw()
|
||||||
|
// directly (see above as well)
|
||||||
|
long selStart = m_selStart,
|
||||||
|
selEnd = m_selEnd;
|
||||||
|
|
||||||
|
// no selection any more
|
||||||
m_selStart =
|
m_selStart =
|
||||||
m_selEnd = -1;
|
m_selEnd = -1;
|
||||||
|
|
||||||
// FIXME: shouldn't refresh everything
|
// refresh the old selection
|
||||||
Refresh();
|
RefreshTextRange(selStart, selEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
// the anchor should be moved even if there was no selection previously
|
// the anchor should be moved even if there was no selection previously
|
||||||
@@ -714,7 +778,7 @@ void wxTextCtrl::UpdateLastVisible()
|
|||||||
w =
|
w =
|
||||||
wOld = 0;
|
wOld = 0;
|
||||||
|
|
||||||
m_colLastVisible = m_colStart;
|
m_colLastVisible = m_colStart - 1;
|
||||||
|
|
||||||
const wxChar *pc = m_value.c_str() + (size_t)m_colStart;
|
const wxChar *pc = m_value.c_str() + (size_t)m_colStart;
|
||||||
for ( ; *pc; pc++ )
|
for ( ; *pc; pc++ )
|
||||||
@@ -808,13 +872,13 @@ wxTextCtrlHitTestResult wxTextCtrl::HitTestLine(const wxString& line,
|
|||||||
|
|
||||||
wxString strBefore(line, (size_t)col);
|
wxString strBefore(line, (size_t)col);
|
||||||
dc.GetTextExtent(strBefore, &width, NULL);
|
dc.GetTextExtent(strBefore, &width, NULL);
|
||||||
if ( width >= x )
|
if ( width > x )
|
||||||
{
|
{
|
||||||
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 on the previous one
|
// the original position - stop on the previous one
|
||||||
//col--;
|
col--;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -829,9 +893,10 @@ wxTextCtrlHitTestResult wxTextCtrl::HitTestLine(const wxString& line,
|
|||||||
}
|
}
|
||||||
else // width < x
|
else // width < x
|
||||||
{
|
{
|
||||||
// same logic as above
|
// invert the logic above
|
||||||
if ( matchDir == -1 )
|
if ( matchDir == -1 )
|
||||||
{
|
{
|
||||||
|
// with the exception that we don't need to backtrack here
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -866,12 +931,12 @@ wxTextCtrlHitTestResult wxTextCtrl::HitTestLine(const wxString& line,
|
|||||||
text += line[col];
|
text += line[col];
|
||||||
dc.GetTextExtent(text, &width2, NULL);
|
dc.GetTextExtent(text, &width2, NULL);
|
||||||
|
|
||||||
wxASSERT_MSG( (width1 <= x) && (x <= width2),
|
wxASSERT_MSG( (width1 <= x) && (x < width2),
|
||||||
_T("incorrect HitTestLine() result") );
|
_T("incorrect HitTestLine() result") );
|
||||||
}
|
}
|
||||||
else // we return last char
|
else // we return last char
|
||||||
{
|
{
|
||||||
wxASSERT_MSG( x > width1, _T("incorrect HitTestLine() result") );
|
wxASSERT_MSG( x >= width1, _T("incorrect HitTestLine() result") );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // WXDEBUG_TEXT
|
#endif // WXDEBUG_TEXT
|
||||||
@@ -979,7 +1044,7 @@ void wxTextCtrl::ShowHorzPosition(wxCoord pos)
|
|||||||
// scroll forward
|
// scroll forward
|
||||||
long col;
|
long col;
|
||||||
HitTestLine(GetValue(), pos - width, &col);
|
HitTestLine(GetValue(), pos - width, &col);
|
||||||
ScrollText(col);
|
ScrollText(col + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1011,7 +1076,7 @@ void wxTextCtrl::ScrollText(long col)
|
|||||||
// order of operands
|
// order of operands
|
||||||
int dx = m_ofsHorz - ofsHorz;
|
int dx = m_ofsHorz - ofsHorz;
|
||||||
|
|
||||||
// NB2: ScrollWindow() calls Refresh() which results in a call to
|
// NB2: we call Refresh() below which results in a call to
|
||||||
// DoDraw(), so we must update m_ofsHorz before calling it
|
// DoDraw(), so we must update m_ofsHorz before calling it
|
||||||
m_ofsHorz = ofsHorz;
|
m_ofsHorz = ofsHorz;
|
||||||
m_colStart = col;
|
m_colStart = col;
|
||||||
@@ -1020,23 +1085,65 @@ void wxTextCtrl::ScrollText(long col)
|
|||||||
if ( dx > 0 )
|
if ( dx > 0 )
|
||||||
{
|
{
|
||||||
// scrolling to the right: we need to recalc the last visible
|
// scrolling to the right: we need to recalc the last visible
|
||||||
// position beore scrolling
|
// position beore scrolling in order to make it appear exactly at
|
||||||
|
// the right edge of the text area after scrolling
|
||||||
UpdateLastVisible();
|
UpdateLastVisible();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// when scrolling to the left, we don't need to worry about the
|
// when scrolling to the left, we need to scroll the old rectangle
|
||||||
// last visible position, it will be updated later when we draw
|
// occupied by the text - then the area where there was no text
|
||||||
// the text - but do force update
|
// before will be refreshed and redrawn
|
||||||
m_colLastVisible = -1;
|
|
||||||
|
|
||||||
m_posLastVisible++;
|
// but we still need to force updating after scrolling
|
||||||
|
m_colLastVisible = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxRect rectText = m_rectText;
|
wxRect rect = m_rectText;
|
||||||
rectText.width = m_posLastVisible;
|
rect.width = m_posLastVisible;
|
||||||
|
|
||||||
ScrollWindow(dx, 0, &rectText);
|
rect = ScrollNoRefresh(dx, 0, &rect);
|
||||||
|
|
||||||
|
/*
|
||||||
|
we need to manually refresh the part which ScrollWindow() doesn't
|
||||||
|
refresh: indeed, if we had this:
|
||||||
|
|
||||||
|
********o
|
||||||
|
|
||||||
|
where '*' is text and 'o' is blank area at the end (too small to
|
||||||
|
hold the next char) then after scrolling by 2 positions to the left
|
||||||
|
we're going to have
|
||||||
|
|
||||||
|
******RRo
|
||||||
|
|
||||||
|
where 'R' is the area refreshed by ScrollWindow() - but we still
|
||||||
|
need to refresh the 'o' at the end as it may be now big enough to
|
||||||
|
hold the new character shifted into view.
|
||||||
|
|
||||||
|
when we are scrolling to the right, we need to update this rect as
|
||||||
|
well because it might have contained something before but doesn't
|
||||||
|
contain anything any more
|
||||||
|
*/
|
||||||
|
|
||||||
|
// we can combine both rectangles into one when scrolling to the left,
|
||||||
|
// but we need two separate Refreshes() otherwise
|
||||||
|
if ( dx > 0 )
|
||||||
|
{
|
||||||
|
// refresh the uncovered part on the left
|
||||||
|
Refresh(TRUE, &rect);
|
||||||
|
|
||||||
|
// and now the area on the right
|
||||||
|
rect.x = m_rectText.x + m_posLastVisible;
|
||||||
|
rect.width = m_rectText.width - m_posLastVisible;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// just extend the rect covering the uncovered area to the edge of
|
||||||
|
// the text rect
|
||||||
|
rect.width += m_rectText.width - m_posLastVisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
Refresh(TRUE, &rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1059,16 +1166,70 @@ void wxTextCtrl::DoPrepareDC(wxDC& dc)
|
|||||||
// refresh
|
// refresh
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
void wxTextCtrl::RefreshLine(long line, long from, long to)
|
void wxTextCtrl::RefreshTextRange(long start, long end)
|
||||||
|
{
|
||||||
|
wxCHECK_RET( start != -1 && end != -1,
|
||||||
|
_T("invalid RefreshTextRange() arguments") );
|
||||||
|
|
||||||
|
// accept arguments in any order as it is more conenient for the caller
|
||||||
|
OrderPositions(start, end);
|
||||||
|
|
||||||
|
long colStart, lineStart;
|
||||||
|
if ( !PositionToXY(start, &colStart, &lineStart) )
|
||||||
|
{
|
||||||
|
// the range is entirely beyond the end of the text, nothing to do
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
long colEnd, lineEnd;
|
||||||
|
if ( !PositionToXY(end, &colEnd, &lineEnd) )
|
||||||
|
{
|
||||||
|
// the range spans beyond the end of text, refresh to the end
|
||||||
|
colEnd = wxSTRING_MAXLEN;
|
||||||
|
lineEnd = GetNumberOfLines() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// refresh all lines one by one
|
||||||
|
for ( long line = lineStart; line <= lineEnd; line++ )
|
||||||
|
{
|
||||||
|
// refresh the first line from the start of the range to the end, the
|
||||||
|
// intermediate ones entirely and the last one from the beginning to
|
||||||
|
// the end of the range
|
||||||
|
long posStart = line == lineStart ? colStart : 0;
|
||||||
|
long posCount;
|
||||||
|
if ( (line != lineEnd) || (colEnd == wxSTRING_MAXLEN) )
|
||||||
|
{
|
||||||
|
// intermediate line or the last one but we need to refresh it
|
||||||
|
// until the end anyhow - do it
|
||||||
|
posCount = wxSTRING_MAXLEN;
|
||||||
|
}
|
||||||
|
else // last line
|
||||||
|
{
|
||||||
|
// refresh just the positions in between the start and the end one
|
||||||
|
posCount = colEnd - posStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshLineRange(line, posStart, posCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxTextCtrl::RefreshLineRange(long line, long start, long count)
|
||||||
{
|
{
|
||||||
wxString text = GetLineText(line);
|
wxString text = GetLineText(line);
|
||||||
|
|
||||||
|
RefreshPixelRange(line,
|
||||||
|
GetTextWidth(text.Left((size_t)start)),
|
||||||
|
GetTextWidth(text.Mid((size_t)start, (size_t)count)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxTextCtrl::RefreshPixelRange(long line, wxCoord start, wxCoord width)
|
||||||
|
{
|
||||||
wxCoord h = GetCharHeight();
|
wxCoord h = GetCharHeight();
|
||||||
wxRect rect;
|
wxRect rect;
|
||||||
rect.x = GetTextWidth(text.Left((size_t)from)) - m_ofsHorz;
|
rect.x = start - m_ofsHorz;
|
||||||
rect.y = line*h;
|
rect.y = line*h;
|
||||||
|
|
||||||
if ( to == -1 )
|
if ( width == 0 )
|
||||||
{
|
{
|
||||||
// till the end of line
|
// till the end of line
|
||||||
rect.width = m_rectText.width - rect.x;
|
rect.width = m_rectText.width - rect.x;
|
||||||
@@ -1076,15 +1237,13 @@ void wxTextCtrl::RefreshLine(long line, long from, long to)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// only part of line
|
// only part of line
|
||||||
rect.width = GetTextWidth(text.Mid((size_t)from, (size_t)(to - from + 1)));
|
rect.width = width;
|
||||||
}
|
}
|
||||||
|
|
||||||
rect.height = h;
|
rect.height = h;
|
||||||
|
|
||||||
// account for the origin offset
|
// account for the text area offset
|
||||||
wxPoint pt = GetClientAreaOrigin() + m_rectText.GetPosition();
|
rect.Offset(m_rectText.GetPosition());
|
||||||
rect.x += pt.x;
|
|
||||||
rect.y += pt.y;
|
|
||||||
|
|
||||||
wxLogTrace(_T("text"), _T("Refreshing (%d, %d)-(%d, %d)"),
|
wxLogTrace(_T("text"), _T("Refreshing (%d, %d)-(%d, %d)"),
|
||||||
rect.x, rect.y, rect.x + rect.width, rect.y + rect.height);
|
rect.x, rect.y, rect.x + rect.width, rect.y + rect.height);
|
||||||
@@ -1100,7 +1259,7 @@ void wxTextCtrl::RefreshLine(long line, long from, long to)
|
|||||||
Several remarks about wxTextCtrl redraw logic:
|
Several remarks about wxTextCtrl redraw logic:
|
||||||
|
|
||||||
1. only the regions which must be updated are redrawn, this means that we
|
1. only the regions which must be updated are redrawn, this means that we
|
||||||
never Refresh() the entire window but use RefreshLine() and
|
never Refresh() the entire window but use RefreshPixelRange() and
|
||||||
ScrollWindow() which only refresh small parts of it and iterate over the
|
ScrollWindow() which only refresh small parts of it and iterate over the
|
||||||
update region in our DoDraw()
|
update region in our DoDraw()
|
||||||
|
|
||||||
@@ -1172,7 +1331,7 @@ void wxTextCtrl::DrawTextLine(wxDC& dc, const wxRect& rect,
|
|||||||
void wxTextCtrl::DoDrawTextInRect(wxDC& dc, const wxRect& rectUpdate)
|
void wxTextCtrl::DoDrawTextInRect(wxDC& dc, const wxRect& rectUpdate)
|
||||||
{
|
{
|
||||||
// debugging trick to see the update rect visually
|
// debugging trick to see the update rect visually
|
||||||
#if 1
|
#ifdef WXDEBUG_TEXT
|
||||||
if ( 0 )
|
if ( 0 )
|
||||||
{
|
{
|
||||||
wxWindowDC dc(this);
|
wxWindowDC dc(this);
|
||||||
@@ -1181,7 +1340,7 @@ void wxTextCtrl::DoDrawTextInRect(wxDC& dc, const wxRect& rectUpdate)
|
|||||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||||
dc.DrawRectangle(rectUpdate);
|
dc.DrawRectangle(rectUpdate);
|
||||||
}
|
}
|
||||||
#endif
|
#endif // WXDEBUG_TEXT
|
||||||
|
|
||||||
// calculate the range of lines to refresh
|
// calculate the range of lines to refresh
|
||||||
wxPoint pt1 = rectUpdate.GetPosition();
|
wxPoint pt1 = rectUpdate.GetPosition();
|
||||||
@@ -1204,7 +1363,12 @@ void wxTextCtrl::DoDrawTextInRect(wxDC& dc, const wxRect& rectUpdate)
|
|||||||
rectText.y = m_rectText.y + lineStart*rectText.height;
|
rectText.y = m_rectText.y + lineStart*rectText.height;
|
||||||
|
|
||||||
// do draw the invalidated parts of each line
|
// do draw the invalidated parts of each line
|
||||||
for ( long line = lineStart; line <= lineEnd; line++ )
|
for ( long line = lineStart;
|
||||||
|
line <= lineEnd;
|
||||||
|
line++,
|
||||||
|
rectText.y += rectText.height,
|
||||||
|
pt1.y += rectText.height,
|
||||||
|
pt2.y += rectText.height )
|
||||||
{
|
{
|
||||||
// calculate the update rect in text positions for this line
|
// calculate the update rect in text positions for this line
|
||||||
if ( HitTest(pt1, &colStart, NULL) == wxTE_HT_AFTER )
|
if ( HitTest(pt1, &colStart, NULL) == wxTE_HT_AFTER )
|
||||||
@@ -1232,8 +1396,12 @@ void wxTextCtrl::DoDrawTextInRect(wxDC& dc, const wxRect& rectUpdate)
|
|||||||
UpdateLastVisible();
|
UpdateLastVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
wxASSERT_MSG( colStart <= m_colLastVisible,
|
if ( colStart > m_colLastVisible )
|
||||||
_T("incorrect m_colLastVisible value") );
|
{
|
||||||
|
// don't bother redrawing something that is beyond the last
|
||||||
|
// visible position
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ( colEnd > m_colLastVisible )
|
if ( colEnd > m_colLastVisible )
|
||||||
colEnd = m_colLastVisible;
|
colEnd = m_colLastVisible;
|
||||||
@@ -1251,8 +1419,14 @@ void wxTextCtrl::DoDrawTextInRect(wxDC& dc, const wxRect& rectUpdate)
|
|||||||
// these values are relative to the start of the line while the
|
// these values are relative to the start of the line while the
|
||||||
// string passed to DrawTextLine() is only part of it, so adjust
|
// string passed to DrawTextLine() is only part of it, so adjust
|
||||||
// the selection range accordingly
|
// the selection range accordingly
|
||||||
selStart += colStart;
|
selStart -= colStart;
|
||||||
selEnd += colStart;
|
selEnd -= colStart;
|
||||||
|
|
||||||
|
if ( selStart < 0 )
|
||||||
|
selStart = 0;
|
||||||
|
|
||||||
|
if ( (size_t)selEnd >= text.length() )
|
||||||
|
selEnd = text.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate the logical text coords
|
// calculate the logical text coords
|
||||||
@@ -1263,11 +1437,6 @@ void wxTextCtrl::DoDrawTextInRect(wxDC& dc, const wxRect& rectUpdate)
|
|||||||
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."),
|
||||||
line, colStart, colEnd);
|
line, colStart, colEnd);
|
||||||
|
|
||||||
// adjust for the next line
|
|
||||||
rectText.y += rectText.height;
|
|
||||||
pt1.y += rectText.height;
|
|
||||||
pt2.y += rectText.height;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1319,6 +1488,24 @@ void wxTextCtrl::DoDraw(wxControlRenderer *renderer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// caret
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void wxTextCtrl::CreateCaret()
|
||||||
|
{
|
||||||
|
// FIXME use renderer
|
||||||
|
wxCaret *caret = new wxCaret(this, 1, GetCharHeight());
|
||||||
|
#ifndef __WXMSW__
|
||||||
|
caret->SetBlinkTime(0);
|
||||||
|
#endif // __WXMSW__
|
||||||
|
|
||||||
|
// SetCaret() will delete the old caret if any
|
||||||
|
SetCaret(caret);
|
||||||
|
|
||||||
|
caret->Show();
|
||||||
|
}
|
||||||
|
|
||||||
wxCoord wxTextCtrl::GetCaretPosition() const
|
wxCoord wxTextCtrl::GetCaretPosition() const
|
||||||
{
|
{
|
||||||
wxString textBeforeCaret(GetLineText(m_curLine), (size_t)m_curRow);
|
wxString textBeforeCaret(GetLineText(m_curLine), (size_t)m_curRow);
|
||||||
@@ -1371,7 +1558,12 @@ bool wxTextCtrl::PerformAction(const wxControlAction& actionOrig,
|
|||||||
action = actionOrig;
|
action = actionOrig;
|
||||||
}
|
}
|
||||||
|
|
||||||
long newPos = -1;
|
// set newPos to -2 as it can't become equal to it in the assignments below
|
||||||
|
// (but it can become -1)
|
||||||
|
static const long INVALID_POS_VALUE = -2;
|
||||||
|
|
||||||
|
long newPos = INVALID_POS_VALUE;
|
||||||
|
|
||||||
if ( action == wxACTION_TEXT_HOME )
|
if ( action == wxACTION_TEXT_HOME )
|
||||||
{
|
{
|
||||||
newPos = m_curPos - m_curRow;
|
newPos = m_curPos - m_curRow;
|
||||||
@@ -1434,7 +1626,7 @@ bool wxTextCtrl::PerformAction(const wxControlAction& actionOrig,
|
|||||||
return wxControl::PerformAction(action, numArg, strArg);
|
return wxControl::PerformAction(action, numArg, strArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( newPos != -1 )
|
if ( newPos != INVALID_POS_VALUE )
|
||||||
{
|
{
|
||||||
// bring the new position into the range
|
// bring the new position into the range
|
||||||
if ( newPos < 0 )
|
if ( newPos < 0 )
|
||||||
|
@@ -272,6 +272,32 @@ void wxWindow::DoDraw(wxControlRenderer *renderer)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxWindow::Refresh(bool eraseBackground, const wxRect *rectClient)
|
||||||
|
{
|
||||||
|
if ( rectClient )
|
||||||
|
{
|
||||||
|
wxRect rectWin = *rectClient;
|
||||||
|
rectWin.Offset(GetClientAreaOrigin());
|
||||||
|
|
||||||
|
wxWindowNative::Refresh(eraseBackground, &rectWin);
|
||||||
|
|
||||||
|
// debugging helper
|
||||||
|
#if 0
|
||||||
|
wxWindowDC dc(this);
|
||||||
|
dc.SetBrush(*wxBLUE_BRUSH);
|
||||||
|
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||||
|
dc.DrawRectangle(rectWin);
|
||||||
|
|
||||||
|
::GdiFlush();
|
||||||
|
::Sleep(1000);
|
||||||
|
#endif // 0
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxWindowNative::Refresh(eraseBackground);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// state flags
|
// state flags
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -576,25 +602,47 @@ int wxWindow::GetScrollRange(int orient) const
|
|||||||
|
|
||||||
void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect)
|
void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect)
|
||||||
{
|
{
|
||||||
|
wxRect r;
|
||||||
|
|
||||||
|
if ( dx )
|
||||||
|
{
|
||||||
|
r = ScrollNoRefresh(dx, 0, rect);
|
||||||
|
Refresh(TRUE /* erase bkgnd */, &r);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( dy )
|
||||||
|
{
|
||||||
|
r = ScrollNoRefresh(0, dy, rect);
|
||||||
|
Refresh(TRUE /* erase bkgnd */, &r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wxRect wxWindow::ScrollNoRefresh(int dx, int dy, const wxRect *rectTotal)
|
||||||
|
{
|
||||||
|
wxASSERT_MSG( !dx || !dy, _T("can't be used for diag scrolling") );
|
||||||
|
|
||||||
|
// the rect to refresh (which we will calculate)
|
||||||
|
wxRect rect;
|
||||||
|
|
||||||
if ( !dx && !dy )
|
if ( !dx && !dy )
|
||||||
{
|
{
|
||||||
// nothing to do
|
// nothing to do
|
||||||
return;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate the part of the window which we can just redraw in the new
|
// calculate the part of the window which we can just redraw in the new
|
||||||
// location
|
// location
|
||||||
wxSize sizeTotal = rect ? rect->GetSize() : GetClientSize();
|
wxSize sizeTotal = rectTotal ? rectTotal->GetSize() : GetClientSize();
|
||||||
|
|
||||||
wxLogTrace(_T("scroll"), _T("rect is %dx%d, scroll by %d, %d"),
|
wxLogTrace(_T("scroll"), _T("rect is %dx%d, scroll by %d, %d"),
|
||||||
sizeTotal.x, sizeTotal.y, dx, dy);
|
sizeTotal.x, sizeTotal.y, dx, dy);
|
||||||
|
|
||||||
// the initial and end point of the region we move in client coords
|
// the initial and end point of the region we move in client coords
|
||||||
wxPoint ptSource, ptDest;
|
wxPoint ptSource, ptDest;
|
||||||
if ( rect )
|
if ( rectTotal )
|
||||||
{
|
{
|
||||||
ptSource = rect->GetPosition();
|
ptSource = rectTotal->GetPosition();
|
||||||
ptDest = rect->GetPosition();
|
ptDest = rectTotal->GetPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
// the size of this region
|
// the size of this region
|
||||||
@@ -606,12 +654,10 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect)
|
|||||||
// just redraw everything as nothing of the displayed image will stay
|
// just redraw everything as nothing of the displayed image will stay
|
||||||
wxLogTrace(_T("scroll"), _T("refreshing everything"));
|
wxLogTrace(_T("scroll"), _T("refreshing everything"));
|
||||||
|
|
||||||
Refresh(TRUE, rect);
|
rect = rectTotal ? *rectTotal : GetClientRect();
|
||||||
}
|
}
|
||||||
else // move the part which doesn't change to the new location
|
else // move the part which doesn't change to the new location
|
||||||
{
|
{
|
||||||
wxPoint ptOrigin = GetClientAreaOrigin();
|
|
||||||
|
|
||||||
// note that when we scroll the canvas in some direction we move the
|
// note that when we scroll the canvas in some direction we move the
|
||||||
// block which doesn't need to be refreshed in the opposite direction
|
// block which doesn't need to be refreshed in the opposite direction
|
||||||
|
|
||||||
@@ -645,7 +691,7 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect)
|
|||||||
|
|
||||||
dcMem.Blit(wxPoint(0, 0), size, &dc, ptSource
|
dcMem.Blit(wxPoint(0, 0), size, &dc, ptSource
|
||||||
#if defined(__WXGTK__) && !defined(__WX_DC_BLIT_FIXED__)
|
#if defined(__WXGTK__) && !defined(__WX_DC_BLIT_FIXED__)
|
||||||
+ ptOrigin
|
+ GetClientAreaOrigin()
|
||||||
#endif // broken wxGTK wxDC::Blit
|
#endif // broken wxGTK wxDC::Blit
|
||||||
);
|
);
|
||||||
dc.Blit(ptDest, size, &dcMem, wxPoint(0, 0));
|
dc.Blit(ptDest, size, &dcMem, wxPoint(0, 0));
|
||||||
@@ -663,9 +709,8 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect)
|
|||||||
// diagonally anyhow and so adding extra logic to compute
|
// diagonally anyhow and so adding extra logic to compute
|
||||||
// rectangle intersection is probably not worth the effort
|
// rectangle intersection is probably not worth the effort
|
||||||
|
|
||||||
wxRect rect;
|
rect.x = ptSource.x;
|
||||||
rect.x = ptOrigin.x + ptSource.x;
|
rect.y = ptSource.y;
|
||||||
rect.y = ptOrigin.y + ptSource.y;
|
|
||||||
|
|
||||||
if ( dx )
|
if ( dx )
|
||||||
{
|
{
|
||||||
@@ -686,8 +731,6 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect)
|
|||||||
wxLogTrace(_T("scroll"), _T("refreshing (%d, %d)-(%d, %d)"),
|
wxLogTrace(_T("scroll"), _T("refreshing (%d, %d)-(%d, %d)"),
|
||||||
rect.x, rect.y,
|
rect.x, rect.y,
|
||||||
rect.GetRight() + 1, rect.GetBottom() + 1);
|
rect.GetRight() + 1, rect.GetBottom() + 1);
|
||||||
|
|
||||||
Refresh(TRUE /* erase bkgnd */, &rect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( dy )
|
if ( dy )
|
||||||
@@ -709,10 +752,10 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect)
|
|||||||
wxLogTrace(_T("scroll"), _T("refreshing (%d, %d)-(%d, %d)"),
|
wxLogTrace(_T("scroll"), _T("refreshing (%d, %d)-(%d, %d)"),
|
||||||
rect.x, rect.y,
|
rect.x, rect.y,
|
||||||
rect.GetRight() + 1, rect.GetBottom() + 1);
|
rect.GetRight() + 1, rect.GetBottom() + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Refresh(TRUE /* erase bkgnd */, &rect);
|
return rect;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
Reference in New Issue
Block a user