text is shown correctly in controls without wxHSCROLL (line wrap) style

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8718 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2000-11-11 04:31:42 +00:00
parent 8637e11695
commit 45911360b2
5 changed files with 278 additions and 278 deletions

2
TODO
View File

@@ -16,7 +16,6 @@ wxTextCtrl
*! display corrupted when typing text in quickly (caret problem?)
* caret leaves traces under wxGTK
* scrollbars don't disappear after deleting long line
? text ctrl display pb when text is truncated
* too much is refreshed when double clicking (word select)
@@ -52,6 +51,7 @@ All
+ DoDraw should iterate over update region instead of using bounding box
+ listbox: horz scrollbar doesn't appear
+ wxTextCtrl update rect overlaps with horz scrollbar
+ scrollbars don't disappear after deleting long line
MSW

View File

@@ -300,6 +300,9 @@ protected:
// starts for wxTE_PASSWORD control
wxString GetTextToShow(const wxString& text) const;
// find the number of characters of a line before it wraps at given width
size_t GetPartOfWrappedLine(const wxChar* text, wxCoord width) const;
// get the start and end of the selection for this line: if the line is
// outside the selection, both will be -1 and FALSE will be returned
bool GetSelectedPartOfLine(long line, int *start, int *end) const;
@@ -331,6 +334,15 @@ protected:
// update the max width after the given line was modified
void UpdateMaxWidth(long line);
// HitTest2() is more efficient than 2 consecutive HitTest()s with the same
// line (i.e. y) and it also returns the offset of the starting position in
// pixels
wxTextCtrlHitTestResult HitTest2(wxCoord y,
wxCoord x1, wxCoord x2,
long *row,
long *colStart, long *colEnd,
wxCoord *ofsStart) const;
// event handlers
void OnIdle(wxIdleEvent& event);
void OnChar(wxKeyEvent& event);

View File

@@ -68,30 +68,29 @@ enum
TextTest_Insert,
TextTest_Clear,
#if 0
TextTest_AddText,
TextTest_AddSeveral,
TextTest_AddMany,
TextTest_Change,
TextTest_ChangeText,
TextTest_Delete,
TextTest_DeleteText,
TextTest_DeleteSel,
#endif // 0
TextTest_Password,
TextTest_HScroll,
TextTest_WrapLines,
TextTest_Textctrl,
TextTest_Quit
};
// textctrl line number radiobox values
enum
enum TextLines
{
TextLines_Single,
TextLines_Multi
};
// default values for the controls
static const struct ControlValues
{
TextLines textLines;
bool password;
bool wraplines;
bool readonly;
} DEFAULTS =
{ TextLines_Multi, FALSE, TRUE, FALSE };
// ----------------------------------------------------------------------------
// our classes
// ----------------------------------------------------------------------------
@@ -135,14 +134,6 @@ protected:
void OnButtonAdd(wxCommandEvent& event);
void OnButtonClear(wxCommandEvent& event);
#if 0
void OnButtonChange(wxCommandEvent& event);
void OnButtonDelete(wxCommandEvent& event);
void OnButtonDeleteSel(wxCommandEvent& event);
void OnButtonAddSeveral(wxCommandEvent& event);
void OnButtonAddMany(wxCommandEvent& event);
#endif // 0
void OnButtonQuit(wxCommandEvent& event);
void OnText(wxCommandEvent& event);
@@ -152,14 +143,8 @@ protected:
void OnUpdateUIClearButton(wxUpdateUIEvent& event);
#if 0
void OnUpdateUIAddSeveral(wxUpdateUIEvent& event);
void OnUpdateUIDeleteButton(wxUpdateUIEvent& event);
void OnUpdateUIDeleteSelButton(wxUpdateUIEvent& event);
#endif
void OnUpdateUIPasswordCheckbox(wxUpdateUIEvent& event);
void OnUpdateUIHScrollCheckbox(wxUpdateUIEvent& event);
void OnUpdateUIWrapLinesCheckbox(wxUpdateUIEvent& event);
void OnUpdateUIResetButton(wxUpdateUIEvent& event);
@@ -188,7 +173,7 @@ protected:
// the checkboxes controlling text ctrl styles
wxCheckBox *m_chkPassword,
*m_chkHScroll,
*m_chkWrapLines,
*m_chkReadonly;
// the textctrl itself and the sizer it is in
@@ -200,6 +185,8 @@ protected:
// the information text zones
wxTextCtrl *m_textPosCur,
*m_textRowCur,
*m_textColCur,
*m_textPosLast,
*m_textSelFrom,
*m_textSelTo;
@@ -244,30 +231,10 @@ BEGIN_EVENT_TABLE(TextTestFrame, wxFrame)
EVT_BUTTON(TextTest_Add, TextTestFrame::OnButtonAdd)
EVT_BUTTON(TextTest_Insert, TextTestFrame::OnButtonInsert)
#if 0
EVT_BUTTON(TextTest_Change, TextTestFrame::OnButtonChange)
EVT_BUTTON(TextTest_Delete, TextTestFrame::OnButtonDelete)
EVT_BUTTON(TextTest_DeleteSel, TextTestFrame::OnButtonDeleteSel)
EVT_BUTTON(TextTest_AddSeveral, TextTestFrame::OnButtonAddSeveral)
EVT_BUTTON(TextTest_AddMany, TextTestFrame::OnButtonAddMany)
EVT_TEXT_ENTER(TextTest_AddText, TextTestFrame::OnButtonAdd)
EVT_TEXT_ENTER(TextTest_DeleteText, TextTestFrame::OnButtonDelete)
#endif // 0
EVT_UPDATE_UI(TextTest_Clear, TextTestFrame::OnUpdateUIClearButton)
#if 0
EVT_UPDATE_UI(TextTest_AddSeveral, TextTestFrame::OnUpdateUIAddSeveral)
EVT_UPDATE_UI(TextTest_DeleteText, TextTestFrame::OnUpdateUIClearButton)
EVT_UPDATE_UI(TextTest_Delete, TextTestFrame::OnUpdateUIDeleteButton)
EVT_UPDATE_UI(TextTest_Change, TextTestFrame::OnUpdateUIDeleteSelButton)
EVT_UPDATE_UI(TextTest_ChangeText, TextTestFrame::OnUpdateUIDeleteSelButton)
EVT_UPDATE_UI(TextTest_DeleteSel, TextTestFrame::OnUpdateUIDeleteSelButton)
#endif // 0
EVT_UPDATE_UI(TextTest_Password, TextTestFrame::OnUpdateUIPasswordCheckbox)
EVT_UPDATE_UI(TextTest_HScroll, TextTestFrame::OnUpdateUIHScrollCheckbox)
EVT_UPDATE_UI(TextTest_WrapLines, TextTestFrame::OnUpdateUIWrapLinesCheckbox)
EVT_UPDATE_UI(TextTest_Reset, TextTestFrame::OnUpdateUIResetButton)
@@ -308,12 +275,14 @@ TextTestFrame::TextTestFrame(const wxString& title)
m_radioTextLines = (wxRadioBox *)NULL;
m_chkPassword =
m_chkHScroll =
m_chkWrapLines =
m_chkReadonly = (wxCheckBox *)NULL;
m_text =
m_textLog =
m_textPosCur =
m_textRowCur =
m_textColCur =
m_textPosLast =
m_textSelFrom =
m_textSelTo = (wxTextCtrl *)NULL;
@@ -352,7 +321,7 @@ TextTestFrame::TextTestFrame(const wxString& title)
1, wxRA_SPECIFY_COLS);
m_chkPassword = new wxCheckBox(m_panel, TextTest_Password, _T("&Password control"));
m_chkHScroll = new wxCheckBox(m_panel, TextTest_HScroll, _T("&Horz scrollbar"));
m_chkWrapLines = new wxCheckBox(m_panel, TextTest_WrapLines, _T("&Horz scrollbar"));
m_chkReadonly = new wxCheckBox(m_panel, -1, _T("&Read-only mode"));
sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL);
@@ -360,7 +329,7 @@ TextTestFrame::TextTestFrame(const wxString& title)
sizerLeft->Add(m_radioTextLines, 0, wxGROW | wxALL, 5);
sizerLeft->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer
sizerLeft->Add(m_chkPassword, 0, wxLEFT | wxRIGHT, 5);
sizerLeft->Add(m_chkHScroll, 0, wxLEFT | wxRIGHT, 5);
sizerLeft->Add(m_chkWrapLines, 0, wxLEFT | wxRIGHT, 5);
sizerLeft->Add(m_chkReadonly, 0, wxLEFT | wxRIGHT, 5);
wxButton *btn = new wxButton(m_panel, TextTest_Reset, _T("&Reset"));
@@ -379,44 +348,32 @@ TextTestFrame::TextTestFrame(const wxString& title)
btn = new wxButton(m_panel, TextTest_Clear, _T("&Clear"));
sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 5);
#if 0
btn = new wxButton(m_panel, TextTest_AddSeveral, _T("&Insert a few strings"));
sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
btn = new wxButton(m_panel, TextTest_AddMany, _T("Add &many strings"));
sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
sizerRow = new wxBoxSizer(wxHORIZONTAL);
btn = new wxButton(m_panel, TextTest_Change, _T("C&hange current"));
m_textChange = new wxTextCtrl(m_panel, TextTest_ChangeText, _T(""));
sizerRow->Add(btn, 0, wxRIGHT, 5);
sizerRow->Add(m_textChange, 1, wxLEFT, 5);
sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
sizerRow = new wxBoxSizer(wxHORIZONTAL);
btn = new wxButton(m_panel, TextTest_Delete, _T("&Delete this item"));
m_textDelete = new wxTextCtrl(m_panel, TextTest_DeleteText, _T(""));
sizerRow->Add(btn, 0, wxRIGHT, 5);
sizerRow->Add(m_textDelete, 1, wxLEFT, 5);
sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
btn = new wxButton(m_panel, TextTest_DeleteSel, _T("Delete &selection"));
sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
#endif // 0
wxStaticBox *box4 = new wxStaticBox(m_panel, -1, _T("&Info:"));
wxSizer *sizerMiddleDown = new wxStaticBoxSizer(box4, wxVERTICAL);
m_textPosCur = CreateInfoText();
sizerMiddleDown->Add
m_textRowCur = CreateInfoText();
m_textColCur = CreateInfoText();
wxSizer *sizerRow = new wxBoxSizer(wxHORIZONTAL);
sizerRow->Add(CreateTextWithLabelSizer
(
CreateTextWithLabelSizer
(
_T("Current position:"),
_T("Current pos:"),
m_textPosCur
),
0, wxALL | wxGROW, 5
);
0, wxRIGHT | wxGROW, 5);
sizerRow->Add(CreateTextWithLabelSizer
(
_T("Col:"),
m_textColCur
),
0, wxRIGHT | wxLEFT | wxGROW, 5);
sizerRow->Add(CreateTextWithLabelSizer
(
_T("Row:"),
m_textRowCur
),
0, wxLEFT | wxGROW, 5);
sizerMiddleDown->Add(sizerRow, 0, wxALL | wxGROW, 5);
m_textPosLast = CreateInfoText();
sizerMiddleDown->Add
@@ -449,9 +406,15 @@ TextTestFrame::TextTestFrame(const wxString& title)
// right pane
wxStaticBox *box3 = new wxStaticBox(m_panel, -1, _T("&Text:"));
m_sizerText = new wxStaticBoxSizer(box3, wxHORIZONTAL);
m_text = new wxTextCtrl(m_panel, TextTest_Textctrl, _T("Hello, world!"));
m_sizerText->Add(m_text, 1, wxALL | wxALIGN_CENTRE_VERTICAL, 5);
m_sizerText->SetMinSize(250, 300);
Reset();
CreateText();
m_sizerText->SetMinSize(250,
#ifdef __WXGTK__
300
#else
0
#endif
);
// the 3 panes panes compose the upper part of the window
sizerUp->Add(sizerLeft, 0, wxGROW | (wxALL & ~wxLEFT), 10);
@@ -487,9 +450,6 @@ TextTestFrame::TextTestFrame(const wxString& title)
sizerTop->Add(0, 5, 0, wxGROW); // spacer in between
sizerTop->Add(sizerDown, 0, wxGROW | (wxALL & ~wxTOP), 10);
// final initialization
Reset();
m_panel->SetAutoLayout(TRUE);
m_panel->SetSizer(sizerTop);
@@ -551,10 +511,10 @@ wxSizer *TextTestFrame::CreateTextWithLabelSizer(const wxString& label,
void TextTestFrame::Reset()
{
m_radioTextLines->SetSelection(TextLines_Single);
m_chkPassword->SetValue(FALSE);
m_chkHScroll->SetValue(TRUE);
m_chkReadonly->SetValue(FALSE);
m_radioTextLines->SetSelection(DEFAULTS.textLines);
m_chkPassword->SetValue(DEFAULTS.password);
m_chkWrapLines->SetValue(DEFAULTS.wraplines);
m_chkReadonly->SetValue(DEFAULTS.readonly);
}
void TextTestFrame::CreateText()
@@ -578,7 +538,7 @@ void TextTestFrame::CreateText()
flags |= wxTE_PASSWORD;
if ( m_chkReadonly->GetValue() )
flags |= wxTE_READONLY;
if ( m_chkHScroll->GetValue() )
if ( !m_chkWrapLines->GetValue() )
flags |= wxHSCROLL;
wxString valueOld;
@@ -589,6 +549,10 @@ void TextTestFrame::CreateText()
m_sizerText->Remove(m_text);
delete m_text;
}
else
{
valueOld = _T("Hello, Universe!");
}
m_text = new wxTextCtrl(m_panel, TextTest_Textctrl,
valueOld,
@@ -614,7 +578,15 @@ void TextTestFrame::OnIdle(wxIdleEvent& WXUNUSED(event))
if ( posCur != m_posCur )
{
m_textPosCur->Clear();
m_textRowCur->Clear();
m_textColCur->Clear();
long col, row;
m_text->PositionToXY(posCur, &col, &row);
*m_textPosCur << posCur;
*m_textRowCur << row;
*m_textColCur << col;
m_posCur = posCur;
}
@@ -689,98 +661,12 @@ void TextTestFrame::OnButtonClear(wxCommandEvent& WXUNUSED(event))
m_text->SetFocus();
}
#if 0
void TextTestFrame::OnButtonChange(wxCommandEvent& WXUNUSED(event))
{
wxArrayInt selections;
int count = m_text->GetSelections(selections);
wxString s = m_textChange->GetValue();
for ( int n = 0; n < count; n++ )
{
m_text->SetString(selections[n], s);
}
}
void TextTestFrame::OnButtonDelete(wxCommandEvent& WXUNUSED(event))
{
unsigned long n;
if ( !m_textDelete->GetValue().ToULong(&n) ||
(n >= (unsigned)m_text->GetCount()) )
{
return;
}
m_text->Delete(n);
}
void TextTestFrame::OnButtonDeleteSel(wxCommandEvent& WXUNUSED(event))
{
wxArrayInt selections;
int n = m_text->GetSelections(selections);
while ( n > 0 )
{
m_text->Delete(selections[--n]);
}
}
void TextTestFrame::OnButtonAdd(wxCommandEvent& event)
{
static size_t s_item = 0;
wxString s = m_textAdd->GetValue();
if ( !m_textAdd->IsModified() )
{
// update the default string
m_textAdd->SetValue(wxString::Format(_T("test item %u"), ++s_item));
}
m_text->Append(s);
}
void TextTestFrame::OnButtonAddMany(wxCommandEvent& WXUNUSED(event))
{
// "many" means 1000 here
for ( size_t n = 0; n < 1000; n++ )
{
m_text->Append(wxString::Format(_T("item #%u"), n));
}
}
void TextTestFrame::OnButtonAddSeveral(wxCommandEvent& event)
{
wxArrayString items;
items.Add(_T("First"));
items.Add(_T("another one"));
items.Add(_T("and the last (very very very very very very very very very very long) one"));
m_text->InsertItems(items, 0);
}
void TextTestFrame::OnUpdateUIDeleteButton(wxUpdateUIEvent& event)
{
unsigned long n;
event.Enable(m_textDelete->GetValue().ToULong(&n) &&
(n < (unsigned)m_text->GetCount()));
}
void TextTestFrame::OnUpdateUIDeleteSelButton(wxUpdateUIEvent& event)
{
wxArrayInt selections;
event.Enable(m_text->GetSelections(selections) != 0);
}
void TextTestFrame::OnUpdateUIAddSeveral(wxUpdateUIEvent& event)
{
event.Enable(!(m_text->GetWindowStyle() & wxLB_SORT));
}
#endif // 0
void TextTestFrame::OnUpdateUIClearButton(wxUpdateUIEvent& event)
{
event.Enable(!m_text->GetValue().empty());
}
void TextTestFrame::OnUpdateUIHScrollCheckbox(wxUpdateUIEvent& event)
void TextTestFrame::OnUpdateUIWrapLinesCheckbox(wxUpdateUIEvent& event)
{
event.Enable( !IsSingleLine() );
}
@@ -793,14 +679,24 @@ void TextTestFrame::OnUpdateUIPasswordCheckbox(wxUpdateUIEvent& event)
void TextTestFrame::OnUpdateUIResetButton(wxUpdateUIEvent& event)
{
event.Enable( (m_radioTextLines->GetSelection() != TextLines_Single) ||
m_chkReadonly->GetValue() ||
m_chkPassword->GetValue() ||
!m_chkHScroll->GetValue() );
event.Enable( (m_radioTextLines->GetSelection() != DEFAULTS.textLines) ||
(m_chkReadonly->GetValue() != DEFAULTS.readonly) ||
(m_chkPassword->GetValue() != DEFAULTS.password) ||
(m_chkWrapLines->GetValue() != DEFAULTS.wraplines) );
}
void TextTestFrame::OnText(wxCommandEvent& event)
{
// small hack to suppress the very first message: by then the logging is
// not yet redirected and so initial setting of the text value results in
// an annoying message box
static bool s_firstTime = TRUE;
if ( s_firstTime )
{
s_firstTime = FALSE;
return;
}
wxLogMessage(_T("Text ctrl value changed"));
}

View File

@@ -60,20 +60,23 @@
The same example for a control with line wrap assuming "Universe" is too
long to fit on the same line with "Hello,":
pos: 0 1 2 3 4 5 6
pos: 0 1 2 3 4 5
H e l l o , line 0 (row 0)
col: 0 1 2 3 4 5
1 1 1 1 1 1 1
pos: 7 8 9 0 1 2 3 4 5 6
pos: 6 7 8 9 0 1 2 3 4 5 6
U n i v e r s e ! line 0 (row 1)
col: 6 7 8 9 1 1 1 1 1
0 1 2 3 4
col: 6 7 8 9 1 1 1 1 1 1
0 1 2 3 4 5
(line 1 == row 2 same as above)
Note that now columns are offset relative to positions as the positions 6
and 7 correspond to the same character.
Note that there is still the same number of columns and positions and that
there is no (logical) position at the end of the first ROW. This position
is identified with the preceding one (which is not how Windows does it: it
identifies it with the next one, i.e. the first position of the next line,
but much more logical IMHO).
*/
// ============================================================================
@@ -1862,6 +1865,25 @@ wxRect wxTextCtrl::GetRealTextArea() const
return rectText;
}
size_t wxTextCtrl::GetPartOfWrappedLine(const wxChar* text,
wxCoord width) const
{
wxTextCtrl *self = wxConstCast(this, wxTextCtrl);
wxClientDC dc(self);
dc.SetFont(GetFont());
self->DoPrepareDC(dc);
// the text which we can keep in this ROW
wxString str;
for ( wxCoord w = 0; w < width; )
{
str += *text++;
dc.GetTextExtent(str, &w, NULL);
}
return str.length();
}
wxTextCtrlHitTestResult wxTextCtrl::HitTestLine(const wxString& line,
wxCoord x,
long *colOut) const
@@ -2018,46 +2040,13 @@ wxTextCtrlHitTestResult wxTextCtrl::HitTest(const wxPoint& pos,
// calculate the row
int row;
if ( IsSingleLine() )
{
// there is only one row anyhow
row = 0;
}
else // multi line
{
int rowMax = GetNumberOfLines() - 1;
size_t ofsLineStart = 0; // used only for WrapLines() case
int hLine = GetCharHeight();
if ( WrapLines() )
int rowMax = GetNumberOfLines() - 1;
if ( IsSingleLine() || !WrapLines() )
{
// one line can take several rows in this case, so we need to
// rescan the text
// OPT: as for horz hit testing we might approximate the result
// with y / hLine first and then scan from there, this is
// probably much more efficient when there is a lot of text
int yCur = 0;
wxCoord wLine = m_rectText.w;
for ( row = 0; (yCur < y) && (row <= rowMax); row++ )
{
wxCoord widthLineTotal = GetTextWidth(GetLineText(row));
int nRowsPerLine = widthLineTotal == 0
? 1
: (widthLineTotal + wLine - 1) / wLine;
yCur += nRowsPerLine*hLine;
}
if ( row > rowMax )
{
row = rowMax;
res = wxTE_HT_AFTER;
}
}
else // no line wrap
{
// in this case row calculation is simple as we all lines have the
// in this case row calculation is simple as all lines have the
// same height
row = y / hLine;
if ( row > rowMax )
@@ -2077,15 +2066,72 @@ wxTextCtrlHitTestResult wxTextCtrl::HitTest(const wxPoint& pos,
res = wxTE_HT_BEFORE;
}
}
else // multline control with line wrap
{
// one line can take several rows in this case, so we need to
// rescan the text
// OPT: as for horz hit testing we might approximate the result
// with y / hLine first and then scan from there, this is
// probably much more efficient when there is a lot of text
wxString textLine;
row = 0;
int nRowInLine = 0,
nRowsPerLine = 0;
wxCoord wLine = m_rectText.width;
for ( int yCur = 0; yCur < y; yCur += hLine )
{
if ( nRowInLine == nRowsPerLine )
{
// pass to the next line
row++;
if ( row > rowMax )
{
// no next line
row = rowMax;
res = wxTE_HT_AFTER;
break;
}
textLine = GetLineText(row);
wxCoord widthLineTotal = GetTextWidth(textLine);
nRowsPerLine = widthLineTotal == 0
? 1
: (widthLineTotal + wLine - 1) / wLine;
// the offset of the start of the ROW in which y is from the
// start of this LINE
ofsLineStart = 0;
}
else
{
// pass to the next row in this line
ofsLineStart += GetPartOfWrappedLine
(
textLine.c_str() + ofsLineStart,
wLine
);
nRowInLine++;
}
}
}
if ( res == wxTE_HT_ON_TEXT )
{
// now find the position in the line
wxString line = GetLineText(row);
wxString line;
if ( ofsLineStart )
{
//
// look in this row only, not in whole line (well, we leave the
// tail unchanged, but it shouldn't hurt)
line = GetLineText(row).c_str() + ofsLineStart;
}
else
{
// just take the whole string
line = GetLineText(row);
}
res = HitTestLine(GetTextToShow(line), x, colOut);
@@ -2116,6 +2162,44 @@ wxTextCtrlHitTestResult wxTextCtrl::HitTest(const wxPoint& pos,
return res;
}
// TODO: implement HitTest() via HitTest2(), not the other way round!
wxTextCtrlHitTestResult wxTextCtrl::HitTest2(wxCoord y,
wxCoord x1,
wxCoord x2,
long *row,
long *colStart,
long *colEnd,
wxCoord *ofsStart) const
{
wxTextCtrlHitTestResult htr = HitTest(wxPoint(x1, y), colStart, row);
if ( htr == wxTE_HT_AFTER )
{
// if the start is after the text, the end is too
return wxTE_HT_AFTER;
}
if ( colEnd )
{
(void)HitTest(wxPoint(x2, y), colEnd, NULL);
}
if ( ofsStart )
{
long colStartRow;
(void)HitTest(wxPoint(GetRealTextArea().x + GetClientAreaOrigin().x, y),
&colStartRow, NULL);
wxASSERT_MSG( colStartRow <= *colStart, _T("are they on same line?") );
wxString s = GetLineText(*row);
*ofsStart = GetTextWidth(s.Mid((size_t)colStartRow,
(size_t)(*colStart - colStartRow)));
}
return htr;
}
// ----------------------------------------------------------------------------
// scrolling
// ----------------------------------------------------------------------------
@@ -2371,7 +2455,7 @@ void wxTextCtrl::UpdateScrollbars()
// is our width enough to show the longest line?
wxCoord charWidth, maxWidth;
bool showScrollbarX;
if ( GetWindowStyle() && wxHSCROLL )
if ( !WrapLines() )
{
charWidth = GetCharWidth();
maxWidth = GetMaxWidth();
@@ -2636,39 +2720,49 @@ void wxTextCtrl::DoDrawTextInRect(wxDC& dc, const wxRect& rectUpdate)
}
#endif // WXDEBUG_TEXT
// calculate the range of lines to refresh
wxPoint pt1 = rectUpdate.GetPosition();
long colStart, lineStart;
(void)HitTest(pt1, &colStart, &lineStart);
// calculate the range lineStart..lineEnd of lines to redraw
wxPoint pt = rectUpdate.GetPosition();
long lineStart;
(void)HitTest(pt, NULL, &lineStart);
wxPoint pt2 = pt1;
pt2.x += rectUpdate.width;
pt2.y += rectUpdate.height;
long colEnd, lineEnd;
(void)HitTest(pt2, &colEnd, &lineEnd);
// pt1 and pt2 will run along the left and right update rect borders
// respectively from top to bottom (NB: they're in device coords)
pt2.y = pt1.y;
pt.y += rectUpdate.height;
long lineEnd;
(void)HitTest(pt, NULL, &lineEnd);
// prepare for drawing
wxCoord hLine = GetCharHeight();
wxRect rectText;
rectText.height = GetCharHeight();
rectText.height = hLine;
rectText.y = m_rectText.y + lineStart*rectText.height;
// do draw the invalidated parts of each line
// these vars will be used for hit testing of the current row
wxCoord y = rectUpdate.y;
const wxCoord x1 = rectUpdate.x;
const wxCoord x2 = rectUpdate.x + rectUpdate.width;
// do draw the invalidated parts of each line: note that we iterate here
// over ROWs, not over LINEs
for ( long line = lineStart;
line <= lineEnd;
line++,
rectText.y += rectText.height,
pt1.y += rectText.height,
pt2.y += rectText.height )
rectText.y += hLine,
y += hLine )
{
// calculate the update rect in text positions for this line
if ( HitTest(pt1, &colStart, NULL) == wxTE_HT_AFTER )
long colStart, colEnd;
wxCoord ofsStart;
if ( HitTest2(y, x1, x2,
&line, &colStart, &colEnd, &ofsStart) == wxTE_HT_AFTER )
{
wxASSERT_MSG( line <= lineEnd, _T("how did we get that far?") );
if ( line == lineEnd )
{
// we redrew everything
break;
}
// the update rect is beyond the end of line, no need to redraw
// anything
// anything on this line - but continue with the remaining ones
continue;
}
@@ -2676,8 +2770,6 @@ void wxTextCtrl::DoDrawTextInRect(wxDC& dc, const wxRect& rectUpdate)
if ( colStart < m_colStart )
colStart = m_colStart;
(void)HitTest(pt2, &colEnd, NULL);
// colEnd may be less than colStart if colStart was changed by the
// assignment above
if ( colEnd < colStart )
@@ -2735,7 +2827,7 @@ void wxTextCtrl::DoDrawTextInRect(wxDC& dc, const wxRect& rectUpdate)
}
// calculate the logical text coords
rectText.x = m_rectText.x + GetTextWidth(textLine.Left(colStart));
rectText.x = m_rectText.x + ofsStart;
rectText.width = GetTextWidth(text);
// do draw the text

View File

@@ -701,7 +701,7 @@ wxColour wxWin32ColourScheme::GetBackground(wxWindow *win) const
wxTextCtrl *text = wxDynamicCast(win, wxTextCtrl);
if ( text )
{
if ( !text->IsEditable() )
if ( !text->IsEnabled() ) // not IsEditable()
col = Get(CONTROL);
//else: execute code below
}
@@ -1736,7 +1736,7 @@ wxRect wxWin32Renderer::GetTextTotalArea(const wxTextCtrl *text,
{
// this is what Windows does
wxRect rectTotal = rect;
rectTotal.Inflate(10);
rectTotal.Inflate(1);
rectTotal.height++;
return rectTotal;
@@ -1748,7 +1748,7 @@ wxRect wxWin32Renderer::GetTextClientArea(const wxTextCtrl *text,
// undo GetTextTotalArea()
wxRect rectText = rect;
rectText.height--;
rectText.Inflate(-10);
rectText.Inflate(-1);
return rectText;
}