1. more work on line wrap - mostly works now
2. small fixes to wxStaticText (best size calc) and to check box git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8755 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
10
TODO
10
TODO
@@ -14,10 +14,11 @@ samples:
|
|||||||
|
|
||||||
wxTextCtrl
|
wxTextCtrl
|
||||||
|
|
||||||
* adjust refresh/scroll for WrapLines() case
|
*! call to RefreshLineRange() from Replace() is broken
|
||||||
*! display corrupted when typing text in quickly (caret problem?)
|
*! display corrupted when typing text in quickly (caret problem?)
|
||||||
* caret leaves traces under wxGTK
|
* caret leaves traces under wxGTK
|
||||||
? text ctrl display pb when text is truncated
|
? text ctrl display pb when text is truncated
|
||||||
|
* remember selection when losing/gaining activation
|
||||||
* too much is refreshed when double clicking (word select)
|
* too much is refreshed when double clicking (word select)
|
||||||
|
|
||||||
All
|
All
|
||||||
@@ -27,15 +28,13 @@ All
|
|||||||
|
|
||||||
* wxCheckListBox: redraw only the bitmap when toggled
|
* wxCheckListBox: redraw only the bitmap when toggled
|
||||||
|
|
||||||
* problem with lbox horz scrolling: the focus rect isn't drawn entirely...
|
? problem with lbox horz scrolling: the focus rect isn't drawn entirely...
|
||||||
* write sample testing all listbox styles/events
|
|
||||||
* text ctrl wxTE_XXX styles support
|
|
||||||
* listbox inc kbd search
|
|
||||||
|
|
||||||
* popup menu for text ctrls
|
* popup menu for text ctrls
|
||||||
|
|
||||||
MSW
|
MSW
|
||||||
|
|
||||||
|
* checkboxes don't look correctly in checked+disabled state (radio too?)
|
||||||
* text control scrollbar has text cursor
|
* text control scrollbar has text cursor
|
||||||
scrollbar behaves strangely in log lbox with many strings
|
scrollbar behaves strangely in log lbox with many strings
|
||||||
|
|
||||||
@@ -49,6 +48,7 @@ DONE
|
|||||||
|
|
||||||
All
|
All
|
||||||
|
|
||||||
|
+ adjust refresh/scroll for WrapLines() case
|
||||||
+ text ctrl horz scrolling
|
+ text ctrl horz scrolling
|
||||||
+ DoDraw should iterate over update region instead of using bounding box
|
+ DoDraw should iterate over update region instead of using bounding box
|
||||||
+ listbox: horz scrollbar doesn't appear
|
+ listbox: horz scrollbar doesn't appear
|
||||||
|
@@ -304,6 +304,7 @@ public:
|
|||||||
const wxMouseEvent& event);
|
const wxMouseEvent& event);
|
||||||
virtual bool HandleMouseMove(wxControl *control,
|
virtual bool HandleMouseMove(wxControl *control,
|
||||||
const wxMouseEvent& event);
|
const wxMouseEvent& event);
|
||||||
|
virtual bool HandleFocus(wxControl *control, const wxFocusEvent& event);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// get the position of the mouse click
|
// get the position of the mouse click
|
||||||
|
@@ -79,12 +79,15 @@ typedef long wxTextCoord;
|
|||||||
// wxTextCtrl::HitTest return values
|
// wxTextCtrl::HitTest return values
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// the point asked is ...
|
||||||
enum wxTextCtrlHitTestResult
|
enum wxTextCtrlHitTestResult
|
||||||
{
|
{
|
||||||
wxTE_HT_BEFORE = -1,
|
wxTE_HT_BEFORE = -1, // either to the left or upper
|
||||||
wxTE_HT_ON_TEXT,
|
wxTE_HT_ON_TEXT, // directly on
|
||||||
wxTE_HT_AFTER
|
wxTE_HT_BELOW, // below [the last line]
|
||||||
|
wxTE_HT_BEYOND // after [the end of line]
|
||||||
};
|
};
|
||||||
|
// ... the character returned
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxTextCtrl
|
// wxTextCtrl
|
||||||
@@ -163,8 +166,10 @@ public:
|
|||||||
wxTextCoord *x, wxTextCoord *y) const;
|
wxTextCoord *x, wxTextCoord *y) const;
|
||||||
|
|
||||||
// wxUniv-specific: find a screen position (in client coordinates) of the
|
// wxUniv-specific: find a screen position (in client coordinates) of the
|
||||||
// given text position
|
// given text position or of the caret
|
||||||
bool PositionToPixelXY(wxTextPos pos, wxCoord *x, wxCoord *y) const;
|
bool PositionToLogicalXY(wxTextPos pos, wxCoord *x, wxCoord *y) const;
|
||||||
|
bool PositionToDeviceXY(wxTextPos pos, wxCoord *x, wxCoord *y) const;
|
||||||
|
wxPoint GetCaretPosition() const;
|
||||||
|
|
||||||
virtual void ShowPosition(wxTextPos pos);
|
virtual void ShowPosition(wxTextPos pos);
|
||||||
|
|
||||||
@@ -301,7 +306,7 @@ protected:
|
|||||||
wxRect GetRealTextArea() const;
|
wxRect GetRealTextArea() const;
|
||||||
|
|
||||||
// refresh the text in the given (in logical coords) rect
|
// refresh the text in the given (in logical coords) rect
|
||||||
void RefreshTextRect(wxRect& rect);
|
void RefreshTextRect(const wxRect& rect);
|
||||||
|
|
||||||
// refresh the text in the given range (in logical coords) of this line, if
|
// refresh the text in the given range (in logical coords) of this line, if
|
||||||
// width is 0, refresh to the end of line
|
// width is 0, refresh to the end of line
|
||||||
@@ -321,8 +326,10 @@ protected:
|
|||||||
// starts for wxTE_PASSWORD control
|
// starts for wxTE_PASSWORD control
|
||||||
wxString GetTextToShow(const wxString& text) const;
|
wxString GetTextToShow(const wxString& text) const;
|
||||||
|
|
||||||
// find the number of characters of a line before it wraps at given width
|
// find the number of characters of a line before it wraps
|
||||||
size_t GetPartOfWrappedLine(const wxChar* text, wxCoord width) const;
|
// (and optionally also the real width of the line)
|
||||||
|
size_t GetPartOfWrappedLine(const wxChar* text,
|
||||||
|
wxCoord *widthReal = NULL) const;
|
||||||
|
|
||||||
// get the start and end of the selection for this line: if the line is
|
// 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
|
// outside the selection, both will be -1 and FALSE will be returned
|
||||||
@@ -359,19 +366,23 @@ protected:
|
|||||||
// HitTest2() is more efficient than 2 consecutive HitTest()s with the same
|
// 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
|
// line (i.e. y) and it also returns the offset of the starting position in
|
||||||
// pixels
|
// pixels
|
||||||
|
//
|
||||||
|
// as the last hack, this function accepts either logical or device (by
|
||||||
|
// default) coords depending on devCoords flag
|
||||||
wxTextCtrlHitTestResult HitTest2(wxCoord y,
|
wxTextCtrlHitTestResult HitTest2(wxCoord y,
|
||||||
wxCoord x1,
|
wxCoord x1,
|
||||||
wxCoord x2,
|
wxCoord x2,
|
||||||
wxTextCoord *row,
|
wxTextCoord *row,
|
||||||
wxTextCoord *colStart,
|
wxTextCoord *colStart,
|
||||||
wxTextCoord *colEnd,
|
wxTextCoord *colEnd,
|
||||||
wxTextCoord *colRowStart) const;
|
wxTextCoord *colRowStart,
|
||||||
|
bool devCoords = TRUE) const;
|
||||||
|
|
||||||
// HitTest() version for use in wxTextCtrl: it takes the text coordinates
|
// HitTest() version which takes the logical text coordinates and not the
|
||||||
// (i.e. coords relative to the text rect)
|
// device ones
|
||||||
wxTextCtrlHitTestResult HitTestClient(wxCoord x, wxCoord y,
|
wxTextCtrlHitTestResult HitTestLogical(const wxPoint& pos,
|
||||||
wxTextCoord *col,
|
wxTextCoord *col,
|
||||||
wxTextCoord *row) const;
|
wxTextCoord *row) const;
|
||||||
|
|
||||||
// event handlers
|
// event handlers
|
||||||
void OnIdle(wxIdleEvent& event);
|
void OnIdle(wxIdleEvent& event);
|
||||||
|
@@ -363,19 +363,19 @@ TextTestFrame::TextTestFrame(const wxString& title)
|
|||||||
_T("Current pos:"),
|
_T("Current pos:"),
|
||||||
m_textPosCur
|
m_textPosCur
|
||||||
),
|
),
|
||||||
0, wxRIGHT | wxGROW, 5);
|
0, wxGROW | wxRIGHT, 5);
|
||||||
sizerRow->Add(CreateTextWithLabelSizer
|
sizerRow->Add(CreateTextWithLabelSizer
|
||||||
(
|
(
|
||||||
_T("Col:"),
|
_T("Col:"),
|
||||||
m_textColCur
|
m_textColCur
|
||||||
),
|
),
|
||||||
0, wxRIGHT | wxLEFT | wxGROW, 5);
|
0, wxGROW | wxLEFT | wxRIGHT, 5);
|
||||||
sizerRow->Add(CreateTextWithLabelSizer
|
sizerRow->Add(CreateTextWithLabelSizer
|
||||||
(
|
(
|
||||||
_T("Row:"),
|
_T("Row:"),
|
||||||
m_textRowCur
|
m_textRowCur
|
||||||
),
|
),
|
||||||
0, wxLEFT | wxGROW, 5);
|
0, wxGROW | wxLEFT, 5);
|
||||||
sizerMiddleDown->Add(sizerRow, 0, wxALL | wxGROW, 5);
|
sizerMiddleDown->Add(sizerRow, 0, wxALL | wxGROW, 5);
|
||||||
|
|
||||||
m_textLineLast = CreateInfoText();
|
m_textLineLast = CreateInfoText();
|
||||||
@@ -566,7 +566,7 @@ void TextTestFrame::CreateText()
|
|||||||
flags);
|
flags);
|
||||||
m_sizerText->Add(m_text, 1, wxALL |
|
m_sizerText->Add(m_text, 1, wxALL |
|
||||||
(flags & wxTE_MULTILINE ? wxGROW
|
(flags & wxTE_MULTILINE ? wxGROW
|
||||||
: wxALIGN_CENTRE_VERTICAL), 5);
|
: wxALIGN_TOP), 5);
|
||||||
m_sizerText->Layout();
|
m_sizerText->Layout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -74,7 +74,9 @@ void wxStaticText::SetLabel(const wxString& label)
|
|||||||
|
|
||||||
wxSize wxStaticText::DoGetBestClientSize() const
|
wxSize wxStaticText::DoGetBestClientSize() const
|
||||||
{
|
{
|
||||||
wxClientDC dc(wxConstCast(this, wxStaticText));
|
wxStaticText *self = wxConstCast(this, wxStaticText);
|
||||||
|
wxClientDC dc(self);
|
||||||
|
dc.SetFont(GetFont());
|
||||||
wxCoord width, height;
|
wxCoord width, height;
|
||||||
dc.GetMultiLineTextExtent(GetLabel(), &width, &height);
|
dc.GetMultiLineTextExtent(GetLabel(), &width, &height);
|
||||||
|
|
||||||
|
@@ -12,10 +12,13 @@
|
|||||||
/*
|
/*
|
||||||
TODO
|
TODO
|
||||||
|
|
||||||
! 1. update vert scrollbar when any line length changes for WrapLines()
|
+ 1. update vert scrollbar when any line length changes for WrapLines()
|
||||||
2. cursor movement ("Hello,^" -> "^verse!" on Arrow Down)?
|
+ 2. cursor movement ("Hello,^" -> "^verse!" on Arrow Down)?
|
||||||
|
-> maybe save the x position and use it instead of current in handling
|
||||||
|
DOWN/UP actions (this would make up/down always return the cursor to
|
||||||
|
the same location)?
|
||||||
3. split file into chunks
|
3. split file into chunks
|
||||||
! 4. rewrite Replace() refresh logic to deal with wrapping lines
|
+? 4. rewrite Replace() refresh logic to deal with wrapping lines
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -359,6 +362,11 @@ bool wxTextCtrl::Create(wxWindow *parent,
|
|||||||
|
|
||||||
// TODO: support wxTE_NO_VSCROLL (?)
|
// TODO: support wxTE_NO_VSCROLL (?)
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// this doesn't make sense for single line controls
|
||||||
|
style &= ~wxHSCROLL;
|
||||||
|
}
|
||||||
|
|
||||||
if ( !wxControl::Create(parent, id, pos, size, style,
|
if ( !wxControl::Create(parent, id, pos, size, style,
|
||||||
validator, name) )
|
validator, name) )
|
||||||
@@ -513,6 +521,9 @@ void wxTextCtrl::Replace(wxTextPos from, wxTextPos to, const wxString& text)
|
|||||||
replace a part of it with the new text and break it into lines again.
|
replace a part of it with the new text and break it into lines again.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// (0) remember the number of rows before we started
|
||||||
|
wxTextCoord rowsOld = GetNumberOfRowsBefore(GetNumberOfLines());
|
||||||
|
|
||||||
// (1) join lines
|
// (1) join lines
|
||||||
wxString textOrig;
|
wxString textOrig;
|
||||||
wxTextCoord line;
|
wxTextCoord line;
|
||||||
@@ -631,20 +642,46 @@ void wxTextCtrl::Replace(wxTextPos from, wxTextPos to, const wxString& text)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// (5) now refresh the changed area
|
// (5) now refresh the changed area
|
||||||
RefreshPixelRange(lineStart, startNewText, widthNewText);
|
|
||||||
if ( m_lines.GetCount() == countOld )
|
// we may optimize refresh if the number of rows didn't change - but if
|
||||||
|
// it did we have to refresh everything below the part we chanegd as
|
||||||
|
// well as it might have moved
|
||||||
|
wxTextCoord rowsNew = GetNumberOfRowsBefore(GetNumberOfLines());
|
||||||
|
if ( rowsNew == rowsOld )
|
||||||
{
|
{
|
||||||
// number of lines didn't change, refresh the updated lines and the
|
// refresh the line we changed
|
||||||
|
RefreshPixelRange(lineStart, startNewText, widthNewText);
|
||||||
|
|
||||||
|
// number of rows didn't change, refresh the updated rows and the
|
||||||
// last one
|
// last one
|
||||||
if ( lineStart < lineEnd )
|
if ( lineStart < lineEnd )
|
||||||
RefreshLineRange(lineStart + 1, lineEnd);
|
RefreshLineRange(lineStart + 1, lineEnd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// number of lines did change, we need to refresh everything below
|
if ( !WrapLines() )
|
||||||
// the start line
|
{
|
||||||
RefreshLineRange(lineStart + 1,
|
// refresh only part of the first line
|
||||||
wxMax(m_lines.GetCount(), countOld) - 1);
|
RefreshPixelRange(lineStart, startNewText, widthNewText);
|
||||||
|
|
||||||
|
// and refresh the rest below
|
||||||
|
lineStart++;
|
||||||
|
}
|
||||||
|
//else: refresh all lines we changed (OPT?)
|
||||||
|
|
||||||
|
RefreshLineRange(lineStart, m_lines.GetCount() - 1);
|
||||||
|
|
||||||
|
// refresh text rect left below
|
||||||
|
if ( rowsNew < rowsOld )
|
||||||
|
{
|
||||||
|
wxCoord h = GetCharHeight();
|
||||||
|
wxRect rect;
|
||||||
|
rect.x = 0;
|
||||||
|
rect.width = m_rectText.width;
|
||||||
|
rect.y = rowsNew*h;
|
||||||
|
rect.height = (rowsOld - rowsNew)*h;
|
||||||
|
RefreshTextRect(rect);
|
||||||
|
}
|
||||||
|
|
||||||
// the vert scrollbar might [dis]appear
|
// the vert scrollbar might [dis]appear
|
||||||
m_updateScrollbarY = TRUE;
|
m_updateScrollbarY = TRUE;
|
||||||
@@ -664,8 +701,24 @@ void wxTextCtrl::Replace(wxTextPos from, wxTextPos to, const wxString& text)
|
|||||||
// end of the replacement text
|
// end of the replacement text
|
||||||
DoSetInsertionPoint(from + text.length());
|
DoSetInsertionPoint(from + text.length());
|
||||||
|
|
||||||
// and the selection (do it after setting the cursor to have correct value
|
// and the selection: this is complicated by the fact that selection coords
|
||||||
// for selection anchor)
|
// must be first updated to reflect change in text coords, i.e. if we had
|
||||||
|
// selection from 17 to 19 and we just removed this range, we don't have to
|
||||||
|
// refresh anything, so we can't just use ClearSelection() here
|
||||||
|
if ( HasSelection() )
|
||||||
|
{
|
||||||
|
// refresh the parst of the selection outside the changed text (which
|
||||||
|
// we already refreshed)
|
||||||
|
if ( m_selStart < from )
|
||||||
|
RefreshTextRange(m_selStart, from);
|
||||||
|
if ( to < m_selEnd )
|
||||||
|
RefreshTextRange(to, m_selEnd);
|
||||||
|
|
||||||
|
m_selStart =
|
||||||
|
m_selEnd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now call it to do the rest (not related to refreshing)
|
||||||
ClearSelection();
|
ClearSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1145,11 +1198,26 @@ bool wxTextCtrl::PositionToXY(wxTextPos pos,
|
|||||||
|
|
||||||
wxTextCoord wxTextCtrl::GetRowsPerLine(wxTextCoord line) const
|
wxTextCoord wxTextCtrl::GetRowsPerLine(wxTextCoord line) const
|
||||||
{
|
{
|
||||||
wxCoord wLine = m_rectText.width,
|
// we can't just divide the line length by the width of the window as there
|
||||||
wLineTotal = GetTextWidth(GetLineText(line));
|
// are "unuse" parts of rows at the end, so we really need to use
|
||||||
|
// GetPartOfWrappedLine() here
|
||||||
|
wxString lineText = GetLineText(line);
|
||||||
|
|
||||||
// an empty line still has 1 row in it
|
wxTextCoord rows = 0;
|
||||||
return wLineTotal == 0 ? 1 : (wLineTotal + wLine - 1) / wLine;
|
size_t rowLen,
|
||||||
|
colRowStart = 0;
|
||||||
|
for ( ;; )
|
||||||
|
{
|
||||||
|
rowLen = GetPartOfWrappedLine(lineText.c_str() + colRowStart);
|
||||||
|
if ( !rowLen )
|
||||||
|
break;
|
||||||
|
|
||||||
|
colRowStart += rowLen;
|
||||||
|
rows++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// empty line still takes one row
|
||||||
|
return rows == 0 ? 1 : rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxTextCoord wxTextCtrl::GetNumberOfRowsBefore(wxTextCoord lineMax) const
|
wxTextCoord wxTextCtrl::GetNumberOfRowsBefore(wxTextCoord lineMax) const
|
||||||
@@ -1166,8 +1234,9 @@ wxTextCoord wxTextCtrl::GetNumberOfRowsBefore(wxTextCoord lineMax) const
|
|||||||
return nRows;
|
return nRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxTextCtrl::PositionToPixelXY(wxTextPos pos,
|
bool wxTextCtrl::PositionToLogicalXY(wxTextPos pos,
|
||||||
wxCoord *xOut, wxCoord *yOut) const
|
wxCoord *xOut,
|
||||||
|
wxCoord *yOut) const
|
||||||
{
|
{
|
||||||
wxTextCoord col, line;
|
wxTextCoord col, line;
|
||||||
|
|
||||||
@@ -1205,8 +1274,7 @@ bool wxTextCtrl::PositionToPixelXY(wxTextPos pos,
|
|||||||
wxTextCoord colRowStart = 0;
|
wxTextCoord colRowStart = 0;
|
||||||
for ( ;; )
|
for ( ;; )
|
||||||
{
|
{
|
||||||
int rowLen = GetPartOfWrappedLine(textLine.c_str() + colRowStart,
|
int rowLen = GetPartOfWrappedLine(textLine.c_str() + colRowStart);
|
||||||
m_rectText.width);
|
|
||||||
|
|
||||||
// the test is quite interesting because the last position in any
|
// the test is quite interesting because the last position in any
|
||||||
// but the last row of the line is invalid: you can't put the
|
// but the last row of the line is invalid: you can't put the
|
||||||
@@ -1237,6 +1305,22 @@ bool wxTextCtrl::PositionToPixelXY(wxTextPos pos,
|
|||||||
x = GetTextWidth(textLine.Mid(colRowStart, col - colRowStart));
|
x = GetTextWidth(textLine.Mid(colRowStart, col - colRowStart));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( xOut )
|
||||||
|
*xOut = x;
|
||||||
|
if ( yOut )
|
||||||
|
*yOut = y;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxTextCtrl::PositionToDeviceXY(wxTextPos pos,
|
||||||
|
wxCoord *xOut,
|
||||||
|
wxCoord *yOut) const
|
||||||
|
{
|
||||||
|
wxCoord x, y;
|
||||||
|
if ( !PositionToLogicalXY(pos, &x, &y) )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
// finally translate the logical text rect coords into physical client
|
// finally translate the logical text rect coords into physical client
|
||||||
// coords
|
// coords
|
||||||
CalcScrolledPosition(m_rectText.x + x - m_ofsHorz,
|
CalcScrolledPosition(m_rectText.x + x - m_ofsHorz,
|
||||||
@@ -1247,6 +1331,17 @@ bool wxTextCtrl::PositionToPixelXY(wxTextPos pos,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxPoint wxTextCtrl::GetCaretPosition() const
|
||||||
|
{
|
||||||
|
wxCoord xCaret, yCaret;
|
||||||
|
if ( !PositionToDeviceXY(m_curPos, &xCaret, &yCaret) )
|
||||||
|
{
|
||||||
|
wxFAIL_MSG( _T("Caret can't be beyond the text!") );
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxPoint(xCaret, yCaret);
|
||||||
|
}
|
||||||
|
|
||||||
// pos may be -1 to show the current position
|
// pos may be -1 to show the current position
|
||||||
void wxTextCtrl::ShowPosition(wxTextPos pos)
|
void wxTextCtrl::ShowPosition(wxTextPos pos)
|
||||||
{
|
{
|
||||||
@@ -1261,19 +1356,11 @@ void wxTextCtrl::ShowPosition(wxTextPos pos)
|
|||||||
int xStart, yStart;
|
int xStart, yStart;
|
||||||
GetViewStart(&xStart, &yStart);
|
GetViewStart(&xStart, &yStart);
|
||||||
|
|
||||||
wxTextCoord row, col;
|
if ( pos == -1 )
|
||||||
if ( (pos == -1) || (pos == m_curPos) )
|
pos = m_curPos;
|
||||||
{
|
|
||||||
row = m_curRow;
|
|
||||||
col = m_curCol;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
wxFAIL_MSG(_T("not implemented for multiline"));
|
|
||||||
|
|
||||||
return;
|
wxCoord x, y;
|
||||||
}
|
PositionToLogicalXY(pos, &x, &y);
|
||||||
|
|
||||||
wxRect rectText = GetRealTextArea();
|
wxRect rectText = GetRealTextArea();
|
||||||
|
|
||||||
@@ -1281,9 +1368,11 @@ void wxTextCtrl::ShowPosition(wxTextPos pos)
|
|||||||
// it, make it the first one, otherwise the last one
|
// it, make it the first one, otherwise the last one
|
||||||
if ( m_scrollRangeY )
|
if ( m_scrollRangeY )
|
||||||
{
|
{
|
||||||
if ( row < yStart )
|
y /= GetCharHeight();
|
||||||
|
|
||||||
|
if ( y < yStart )
|
||||||
{
|
{
|
||||||
Scroll(0, row);
|
Scroll(0, y);
|
||||||
}
|
}
|
||||||
else // we are currently in or below the view area
|
else // we are currently in or below the view area
|
||||||
{
|
{
|
||||||
@@ -1293,8 +1382,27 @@ void wxTextCtrl::ShowPosition(wxTextPos pos)
|
|||||||
if ( WrapLines() )
|
if ( WrapLines() )
|
||||||
{
|
{
|
||||||
// to find the last row we need to use the generic HitTest
|
// to find the last row we need to use the generic HitTest
|
||||||
HitTestClient(0, rectText.height, NULL, &yEnd);
|
wxTextCoord col;
|
||||||
yEnd--;
|
|
||||||
|
// OPT this is a bit silly: we undo this in HitTest(), so
|
||||||
|
// it would be better to factor out the common
|
||||||
|
// functionality into a separate function (OTOH it
|
||||||
|
// won't probably save us that much)
|
||||||
|
wxPoint pt(0, rectText.height - 1);
|
||||||
|
pt += GetClientAreaOrigin();
|
||||||
|
pt += m_rectText.GetPosition();
|
||||||
|
HitTest(pt, &col, &yEnd);
|
||||||
|
|
||||||
|
// find the row inside the line
|
||||||
|
wxString text = GetLineText(yEnd);
|
||||||
|
yEnd = GetNumberOfRowsBefore(yEnd);
|
||||||
|
wxTextCoord colRowStart = GetPartOfWrappedLine(text);
|
||||||
|
while ( colRowStart < col )
|
||||||
|
{
|
||||||
|
yEnd++;
|
||||||
|
colRowStart += GetPartOfWrappedLine(text.c_str() +
|
||||||
|
colRowStart);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1303,11 +1411,11 @@ void wxTextCtrl::ShowPosition(wxTextPos pos)
|
|||||||
yEnd = yStart + rectText.height / GetCharHeight() - 1;
|
yEnd = yStart + rectText.height / GetCharHeight() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( yEnd < row )
|
if ( yEnd < y )
|
||||||
{
|
{
|
||||||
// scroll down: the current item should appear at the
|
// scroll down: the current item should appear at the
|
||||||
// bottom of the view
|
// bottom of the view
|
||||||
Scroll(0, row - (yEnd - yStart));
|
Scroll(0, y - (yEnd - yStart));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1319,25 +1427,28 @@ void wxTextCtrl::ShowPosition(wxTextPos pos)
|
|||||||
// column as they all have different widths, so we need to
|
// column as they all have different widths, so we need to
|
||||||
// translate everything to pixels
|
// translate everything to pixels
|
||||||
|
|
||||||
// we want the text between posLeft and posRight be entirely inside
|
// we want the text between x and x2 be entirely inside the view
|
||||||
// the view (i.e. the current character)
|
// (i.e. the current character)
|
||||||
wxString line = GetLineText(row);
|
|
||||||
wxCoord posLeft = GetTextWidth(line.Left(col));
|
|
||||||
|
|
||||||
// make xStart the first visible pixel (and not position)
|
// make xStart the first visible pixel (and not position)
|
||||||
int wChar = GetCharWidth();
|
int wChar = GetCharWidth();
|
||||||
xStart *= GetCharWidth();
|
xStart *= GetCharWidth();
|
||||||
|
|
||||||
if ( posLeft < xStart )
|
if ( x < xStart )
|
||||||
{
|
{
|
||||||
Scroll(posLeft / wChar, row);
|
Scroll(x / wChar, y);
|
||||||
}
|
}
|
||||||
else // maybe we're beyond the right border of the view?
|
else // maybe we're beyond the right border of the view?
|
||||||
{
|
{
|
||||||
wxCoord posRight = posLeft + GetTextWidth(line[(size_t)col]);
|
wxTextCoord col, row;
|
||||||
if ( posRight > xStart + rectText.width )
|
if ( PositionToXY(pos, &col, &row) )
|
||||||
{
|
{
|
||||||
Scroll(posRight / wChar, row);
|
wxString lineText = GetLineText(row);
|
||||||
|
wxCoord x2 = x + GetTextWidth(lineText[(size_t)col]);
|
||||||
|
if ( x2 > xStart + rectText.width )
|
||||||
|
{
|
||||||
|
Scroll(x2 / wChar, row);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1771,22 +1882,26 @@ wxRect wxTextCtrl::GetRealTextArea() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t wxTextCtrl::GetPartOfWrappedLine(const wxChar* text,
|
size_t wxTextCtrl::GetPartOfWrappedLine(const wxChar* text,
|
||||||
wxCoord width) const
|
wxCoord *widthReal) const
|
||||||
{
|
{
|
||||||
wxTextCtrl *self = wxConstCast(this, wxTextCtrl);
|
wxTextCtrl *self = wxConstCast(this, wxTextCtrl);
|
||||||
wxClientDC dc(self);
|
wxClientDC dc(self);
|
||||||
dc.SetFont(GetFont());
|
dc.SetFont(GetFont());
|
||||||
self->DoPrepareDC(dc);
|
self->DoPrepareDC(dc);
|
||||||
|
|
||||||
|
wxCoord widthMax = m_rectText.width;
|
||||||
|
|
||||||
// the text which we can keep in this ROW
|
// the text which we can keep in this ROW
|
||||||
wxString str;
|
wxString str;
|
||||||
for ( wxCoord w = 0; *text && (w <= width); )
|
wxCoord w, wOld;
|
||||||
|
for ( wOld = w = 0; *text && (w <= widthMax); )
|
||||||
{
|
{
|
||||||
|
wOld = w;
|
||||||
str += *text++;
|
str += *text++;
|
||||||
dc.GetTextExtent(str, &w, NULL);
|
dc.GetTextExtent(str, &w, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( *text )
|
if ( w > widthMax )
|
||||||
{
|
{
|
||||||
// if we wrapped, the last letter was one too much
|
// if we wrapped, the last letter was one too much
|
||||||
if ( str.length() > 1 )
|
if ( str.length() > 1 )
|
||||||
@@ -1794,7 +1909,21 @@ size_t wxTextCtrl::GetPartOfWrappedLine(const wxChar* text,
|
|||||||
// remove it
|
// remove it
|
||||||
str.erase(str.length() - 1, 1);
|
str.erase(str.length() - 1, 1);
|
||||||
}
|
}
|
||||||
//else: but always keep at least one letter in each row
|
else // but always keep at least one letter in each row
|
||||||
|
{
|
||||||
|
// the real width then is the last value of w and not teh one
|
||||||
|
// before last
|
||||||
|
wOld = w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // we didn't wrap
|
||||||
|
{
|
||||||
|
wOld = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( widthReal )
|
||||||
|
{
|
||||||
|
*widthReal = wOld;
|
||||||
}
|
}
|
||||||
|
|
||||||
return str.length();
|
return str.length();
|
||||||
@@ -1820,7 +1949,7 @@ wxTextCtrlHitTestResult wxTextCtrl::HitTestLine(const wxString& line,
|
|||||||
// the end of it
|
// the end of it
|
||||||
col = line.length() - 1;
|
col = line.length() - 1;
|
||||||
|
|
||||||
res = wxTE_HT_AFTER;
|
res = wxTE_HT_BEYOND;
|
||||||
}
|
}
|
||||||
else if ( x < 0 )
|
else if ( x < 0 )
|
||||||
{
|
{
|
||||||
@@ -1952,17 +2081,11 @@ wxTextCtrlHitTestResult wxTextCtrl::HitTest(const wxPoint& pos,
|
|||||||
return HitTest2(pos.y, pos.x, 0, rowOut, colOut, NULL, NULL);
|
return HitTest2(pos.y, pos.x, 0, rowOut, colOut, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxTextCtrlHitTestResult wxTextCtrl::HitTestClient(wxCoord x, wxCoord y,
|
wxTextCtrlHitTestResult wxTextCtrl::HitTestLogical(const wxPoint& pos,
|
||||||
wxTextCoord *col,
|
wxTextCoord *colOut,
|
||||||
wxTextCoord *row) const
|
wxTextCoord *rowOut) const
|
||||||
{
|
{
|
||||||
// OPT this is a bit silly: we undo this in HitTest(), so it would be
|
return HitTest2(pos.y, pos.x, 0, rowOut, colOut, NULL, NULL, FALSE);
|
||||||
// better to factor out the common functionality into a separate
|
|
||||||
// function (OTOH it won't probably save us that much)
|
|
||||||
wxPoint pt(x, y);
|
|
||||||
pt += GetClientAreaOrigin();
|
|
||||||
pt += m_rectText.GetPosition();
|
|
||||||
return HitTest(pt, col, row);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxTextCtrlHitTestResult wxTextCtrl::HitTest2(wxCoord y0,
|
wxTextCtrlHitTestResult wxTextCtrl::HitTest2(wxCoord y0,
|
||||||
@@ -1971,16 +2094,26 @@ wxTextCtrlHitTestResult wxTextCtrl::HitTest2(wxCoord y0,
|
|||||||
wxTextCoord *rowOut,
|
wxTextCoord *rowOut,
|
||||||
wxTextCoord *colStart,
|
wxTextCoord *colStart,
|
||||||
wxTextCoord *colEnd,
|
wxTextCoord *colEnd,
|
||||||
wxTextCoord *colRowStartOut) const
|
wxTextCoord *colRowStartOut,
|
||||||
|
bool deviceCoords) const
|
||||||
{
|
{
|
||||||
// is the point in the text area or to the right or below it?
|
// is the point in the text area or to the right or below it?
|
||||||
wxTextCtrlHitTestResult res = wxTE_HT_ON_TEXT;
|
wxTextCtrlHitTestResult res = wxTE_HT_ON_TEXT;
|
||||||
|
|
||||||
// translate the window coords x0 and y0 into the client coords in the text
|
// translate the window coords x0 and y0 into the client coords in the text
|
||||||
// area by adjusting for both the client and text area offsets
|
// area by adjusting for both the client and text area offsets (unless this
|
||||||
wxPoint pt = GetClientAreaOrigin() + m_rectText.GetPosition();
|
// was already done)
|
||||||
int x1, y;
|
int x1, y;
|
||||||
CalcUnscrolledPosition(x10 - pt.x, y0 - pt.y, &x1, &y);
|
if ( deviceCoords )
|
||||||
|
{
|
||||||
|
wxPoint pt = GetClientAreaOrigin() + m_rectText.GetPosition();
|
||||||
|
CalcUnscrolledPosition(x10 - pt.x, y0 - pt.y, &x1, &y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
y = y0;
|
||||||
|
x1 = x10;
|
||||||
|
}
|
||||||
|
|
||||||
// calculate the row (it is really a LINE, not a ROW)
|
// calculate the row (it is really a LINE, not a ROW)
|
||||||
wxTextCoord row;
|
wxTextCoord row;
|
||||||
@@ -2005,7 +2138,7 @@ wxTextCtrlHitTestResult wxTextCtrl::HitTest2(wxCoord y0,
|
|||||||
// line
|
// line
|
||||||
row = rowLast;
|
row = rowLast;
|
||||||
|
|
||||||
res = wxTE_HT_AFTER;
|
res = wxTE_HT_BELOW;
|
||||||
}
|
}
|
||||||
else if ( row < 0 )
|
else if ( row < 0 )
|
||||||
{
|
{
|
||||||
@@ -2036,26 +2169,28 @@ wxTextCtrlHitTestResult wxTextCtrl::HitTest2(wxCoord y0,
|
|||||||
textLine = GetLineText(row);
|
textLine = GetLineText(row);
|
||||||
size_t nRowInLine,
|
size_t nRowInLine,
|
||||||
nRowsPerLine = GetRowsPerLine(row);
|
nRowsPerLine = GetRowsPerLine(row);
|
||||||
for ( nRowInLine = 0; nRowInLine < nRowsPerLine; nRowInLine++ )
|
for ( nRowInLine = 0;
|
||||||
|
!found && (nRowInLine < nRowsPerLine);
|
||||||
|
nRowInLine++ )
|
||||||
{
|
{
|
||||||
int yCurNew = yCur + hLine;
|
rowLen = GetPartOfWrappedLine(textLine.c_str() + colRowStart);
|
||||||
if ( yCurNew > y )
|
|
||||||
|
yCur += hLine;
|
||||||
|
if ( yCur > y )
|
||||||
{
|
{
|
||||||
// point is in this row
|
// point is in this row, so don't change colRowStart
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
yCur = yCurNew;
|
{
|
||||||
|
// the start of the next row
|
||||||
rowLen = GetPartOfWrappedLine(textLine.c_str() + colRowStart,
|
colRowStart += rowLen;
|
||||||
m_rectText.width);
|
}
|
||||||
colRowStart += rowLen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// we shouldn't increase LINE in the outer for loop if we found
|
// we shouldn't increase LINE in the outer for loop if we found
|
||||||
// match inside this one
|
// match inside this one, this is why we break here instead of just
|
||||||
|
// putting "& !found" in for condition
|
||||||
if ( found )
|
if ( found )
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
@@ -2070,12 +2205,14 @@ wxTextCtrlHitTestResult wxTextCtrl::HitTest2(wxCoord y0,
|
|||||||
if ( row > rowLast )
|
if ( row > rowLast )
|
||||||
{
|
{
|
||||||
// we are beyond the last line
|
// we are beyond the last line
|
||||||
res = wxTE_HT_AFTER;
|
res = wxTE_HT_BELOW;
|
||||||
|
|
||||||
|
row = rowLast;
|
||||||
}
|
}
|
||||||
else if ( !rowLen )
|
else if ( !rowLen )
|
||||||
{
|
{
|
||||||
// find the length of the first row of the line we just found
|
// we must get the length of the first row of the next line
|
||||||
rowLen = GetPartOfWrappedLine(GetLineText(row), m_rectText.width);
|
rowLen = GetPartOfWrappedLine(GetLineText(row));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2132,7 +2269,7 @@ wxTextCtrlHitTestResult wxTextCtrl::HitTest2(wxCoord y0,
|
|||||||
// corresponding line
|
// corresponding line
|
||||||
if ( res == wxTE_HT_BEFORE )
|
if ( res == wxTE_HT_BEFORE )
|
||||||
*colStart = 0;
|
*colStart = 0;
|
||||||
else // res == wxTE_HT_AFTER
|
else // res == wxTE_HT_BELOW
|
||||||
*colStart = GetLineText(GetNumberOfLines() - 1).length();
|
*colStart = GetLineText(GetNumberOfLines() - 1).length();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2465,13 +2602,7 @@ void wxTextCtrl::RefreshLineRange(wxTextCoord lineFirst, wxTextCoord lineLast)
|
|||||||
wxCoord h = GetCharHeight();
|
wxCoord h = GetCharHeight();
|
||||||
rect.y = GetNumberOfRowsBefore(lineFirst)*h;
|
rect.y = GetNumberOfRowsBefore(lineFirst)*h;
|
||||||
|
|
||||||
// don't refresh beyond the window boundary
|
|
||||||
if ( lineLast > GetNumberOfLines() - 1 )
|
|
||||||
lineLast = GetNumberOfLines() - 1;
|
|
||||||
wxCoord bottom = GetNumberOfRowsBefore(lineLast + 1)*h;
|
wxCoord bottom = GetNumberOfRowsBefore(lineLast + 1)*h;
|
||||||
if ( bottom > m_rectText.height )
|
|
||||||
bottom = m_rectText.height;
|
|
||||||
|
|
||||||
rect.SetBottom(bottom);
|
rect.SetBottom(bottom);
|
||||||
|
|
||||||
RefreshTextRect(rect);
|
RefreshTextRect(rect);
|
||||||
@@ -2485,6 +2616,10 @@ void wxTextCtrl::RefreshTextRange(wxTextPos start, wxTextPos end)
|
|||||||
// accept arguments in any order as it is more conenient for the caller
|
// accept arguments in any order as it is more conenient for the caller
|
||||||
OrderPositions(start, end);
|
OrderPositions(start, end);
|
||||||
|
|
||||||
|
// this is acceptable but we don't do anything in this case
|
||||||
|
if ( start == end )
|
||||||
|
return;
|
||||||
|
|
||||||
wxTextPos colStart, lineStart;
|
wxTextPos colStart, lineStart;
|
||||||
if ( !PositionToXY(start, &colStart, &lineStart) )
|
if ( !PositionToXY(start, &colStart, &lineStart) )
|
||||||
{
|
{
|
||||||
@@ -2520,7 +2655,8 @@ void wxTextCtrl::RefreshTextRange(wxTextPos start, wxTextPos end)
|
|||||||
posCount = colEnd - posStart;
|
posCount = colEnd - posStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefreshColRange(line, posStart, posCount);
|
if ( posCount )
|
||||||
|
RefreshColRange(line, posStart, posCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2530,6 +2666,9 @@ void wxTextCtrl::RefreshColRange(wxTextCoord line,
|
|||||||
{
|
{
|
||||||
wxString text = GetLineText(line);
|
wxString text = GetLineText(line);
|
||||||
|
|
||||||
|
wxASSERT_MSG( (size_t)start <= text.length() && count,
|
||||||
|
_T("invalid RefreshColRange() parameter") );
|
||||||
|
|
||||||
RefreshPixelRange(line,
|
RefreshPixelRange(line,
|
||||||
GetTextWidth(text.Left((size_t)start)),
|
GetTextWidth(text.Left((size_t)start)),
|
||||||
GetTextWidth(text.Mid((size_t)start, (size_t)count)));
|
GetTextWidth(text.Mid((size_t)start, (size_t)count)));
|
||||||
@@ -2542,23 +2681,31 @@ void wxTextCtrl::RefreshPixelRange(wxTextCoord line,
|
|||||||
wxCoord start,
|
wxCoord start,
|
||||||
wxCoord width)
|
wxCoord width)
|
||||||
{
|
{
|
||||||
|
// we will use line text only in line wrap case
|
||||||
|
wxString text;
|
||||||
|
if ( WrapLines() )
|
||||||
|
{
|
||||||
|
text = GetLineText(line);
|
||||||
|
}
|
||||||
|
|
||||||
// special case: width == 0 means to refresh till the end of line
|
// special case: width == 0 means to refresh till the end of line
|
||||||
if ( width == 0 )
|
if ( width == 0 )
|
||||||
{
|
{
|
||||||
|
// FIXME we refresh till the end of the current line here, but we can't
|
||||||
|
// tell if the line didn't have fewer or more rows before - it is
|
||||||
|
// the callers responsability to not call us in this way if it is
|
||||||
|
// the case
|
||||||
if ( WrapLines() )
|
if ( WrapLines() )
|
||||||
{
|
{
|
||||||
// if we need to refresh until the end of line, refresh all text
|
width = wxMax(GetTextWidth(text), GetTotalWidth());
|
||||||
// below because the next lines might have changed - we have no way
|
|
||||||
// to know if they did or not
|
|
||||||
RefreshLineRange(line, GetNumberOfLines());
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// refresh till the end of line
|
// refresh till the end of visible line
|
||||||
width = GetTotalWidth() - start;
|
width = GetTotalWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
width -= start;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxCoord h = GetCharHeight();
|
wxCoord h = GetCharHeight();
|
||||||
@@ -2569,26 +2716,32 @@ void wxTextCtrl::RefreshPixelRange(wxTextCoord line,
|
|||||||
|
|
||||||
if ( WrapLines() )
|
if ( WrapLines() )
|
||||||
{
|
{
|
||||||
wxCoord wLine = m_rectText.width;
|
// (1) skip all rows which we don't touch at all
|
||||||
|
wxCoord wLine;
|
||||||
// find the row where we start to refresh
|
size_t ofs = GetPartOfWrappedLine(text.c_str(), &wLine);
|
||||||
while ( rect.x > wLine )
|
while ( wLine && (rect.x >= wLine) )
|
||||||
{
|
{
|
||||||
rect.x -= wLine;
|
rect.x -= wLine;
|
||||||
rect.y += h;
|
rect.y += h;
|
||||||
|
|
||||||
|
ofs += GetPartOfWrappedLine(text.c_str() + ofs, &wLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
// now refresh all lines except the last one
|
// (2) now refresh all lines except the last one: note that the first
|
||||||
while ( width > wLine )
|
// line is refreshed from the given start to the end, all the next
|
||||||
|
// ones - entirely
|
||||||
|
while ( wLine && (rect.x + width > wLine) )
|
||||||
{
|
{
|
||||||
rect.width = GetTotalWidth() - rect.x;
|
rect.width = GetTotalWidth() - rect.x;
|
||||||
RefreshTextRect(rect);
|
RefreshTextRect(rect);
|
||||||
|
width -= wLine - rect.x;
|
||||||
rect.x = 0;
|
rect.x = 0;
|
||||||
width -= wLine;
|
|
||||||
rect.y += h;
|
rect.y += h;
|
||||||
|
|
||||||
|
ofs += GetPartOfWrappedLine(text.c_str() + ofs, &wLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
// the code below will refresh the line too
|
// (3) the code below will refresh the last line
|
||||||
}
|
}
|
||||||
|
|
||||||
rect.width = width;
|
rect.width = width;
|
||||||
@@ -2596,8 +2749,9 @@ void wxTextCtrl::RefreshPixelRange(wxTextCoord line,
|
|||||||
RefreshTextRect(rect);
|
RefreshTextRect(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxTextCtrl::RefreshTextRect(wxRect& rect)
|
void wxTextCtrl::RefreshTextRect(const wxRect& rectClient)
|
||||||
{
|
{
|
||||||
|
wxRect rect = rectClient;
|
||||||
if ( IsSingleLine() )
|
if ( IsSingleLine() )
|
||||||
{
|
{
|
||||||
// account for horz scrolling
|
// account for horz scrolling
|
||||||
@@ -2709,36 +2863,51 @@ void wxTextCtrl::DoDrawTextInRect(wxDC& dc, const wxRect& rectUpdate)
|
|||||||
#endif // WXDEBUG_TEXT
|
#endif // WXDEBUG_TEXT
|
||||||
|
|
||||||
// calculate the range lineStart..lineEnd of lines to redraw
|
// calculate the range lineStart..lineEnd of lines to redraw
|
||||||
wxPoint pt = rectUpdate.GetPosition();
|
wxTextCoord lineStart, lineEnd;
|
||||||
wxTextCoord lineStart;
|
if ( IsSingleLine() )
|
||||||
(void)HitTest(pt, NULL, &lineStart);
|
{
|
||||||
|
lineStart =
|
||||||
|
lineEnd = 0;
|
||||||
|
}
|
||||||
|
else // multiline
|
||||||
|
{
|
||||||
|
wxPoint pt = rectUpdate.GetPosition();
|
||||||
|
(void)HitTest(pt, NULL, &lineStart);
|
||||||
|
|
||||||
pt.y += rectUpdate.height;
|
pt.y += rectUpdate.height;
|
||||||
wxTextCoord lineEnd;
|
(void)HitTest(pt, NULL, &lineEnd);
|
||||||
(void)HitTest(pt, NULL, &lineEnd);
|
}
|
||||||
|
|
||||||
// prepare for drawing
|
// prepare for drawing
|
||||||
wxCoord hLine = GetCharHeight();
|
wxCoord hLine = GetCharHeight();
|
||||||
wxRect rectText;
|
|
||||||
rectText.height = hLine;
|
|
||||||
rectText.y = m_rectText.y + lineStart*rectText.height;
|
|
||||||
|
|
||||||
// these vars will be used for hit testing of the current row
|
// these vars will be used for hit testing of the current row
|
||||||
wxCoord y = rectUpdate.y;
|
wxCoord y = rectUpdate.y;
|
||||||
const wxCoord x1 = rectUpdate.x;
|
const wxCoord x1 = rectUpdate.x;
|
||||||
const wxCoord x2 = rectUpdate.x + rectUpdate.width;
|
const wxCoord x2 = rectUpdate.x + rectUpdate.width;
|
||||||
|
|
||||||
|
wxRect rectText;
|
||||||
|
rectText.height = hLine;
|
||||||
|
if ( !IsSingleLine() )
|
||||||
|
{
|
||||||
|
CalcUnscrolledPosition(0, y - GetClientAreaOrigin().y,
|
||||||
|
NULL, &rectText.y);
|
||||||
|
}
|
||||||
|
|
||||||
// do draw the invalidated parts of each line: note that we iterate here
|
// do draw the invalidated parts of each line: note that we iterate here
|
||||||
// over ROWs, not over LINEs
|
// over ROWs, not over LINEs
|
||||||
for ( wxTextCoord line = lineStart;
|
for ( wxTextCoord line = lineStart;
|
||||||
y < rectUpdate.y + rectUpdate.height;
|
y < rectUpdate.y + rectUpdate.height;
|
||||||
rectText.y += hLine,
|
y += hLine,
|
||||||
y += hLine )
|
rectText.y += hLine )
|
||||||
{
|
{
|
||||||
// calculate the update rect in text positions for this line
|
// calculate the update rect in text positions for this line
|
||||||
wxTextCoord colStart, colEnd, colRowStart;
|
wxTextCoord colStart, colEnd, colRowStart;
|
||||||
if ( HitTest2(y, x1, x2,
|
wxTextCtrlHitTestResult ht = HitTest2(y, x1, x2,
|
||||||
&line, &colStart, &colEnd, &colRowStart) == wxTE_HT_AFTER )
|
&line, &colStart, &colEnd,
|
||||||
|
&colRowStart);
|
||||||
|
|
||||||
|
if ( (ht == wxTE_HT_BEYOND) || (ht == wxTE_HT_BELOW) )
|
||||||
{
|
{
|
||||||
wxASSERT_MSG( line <= lineEnd, _T("how did we get that far?") );
|
wxASSERT_MSG( line <= lineEnd, _T("how did we get that far?") );
|
||||||
|
|
||||||
@@ -2781,13 +2950,15 @@ void wxTextCtrl::DoDrawTextInRect(wxDC& dc, const wxRect& rectUpdate)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( colEnd > m_colLastVisible )
|
if ( colEnd > m_colLastVisible )
|
||||||
|
{
|
||||||
colEnd = m_colLastVisible;
|
colEnd = m_colLastVisible;
|
||||||
|
|
||||||
// we don't draw the last character because it may be shown only
|
// we don't draw the last character because it may be shown
|
||||||
// partially in single line mode (in multi line we can't avoid
|
// only partially in single line mode (in multi line we can't
|
||||||
// showing parts of characters anyhow)
|
// avoid showing parts of characters anyhow)
|
||||||
if ( colEnd > colStart )
|
if ( colEnd > colStart )
|
||||||
colEnd--;
|
colEnd--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// extract the part of line we need to redraw
|
// extract the part of line we need to redraw
|
||||||
@@ -2814,7 +2985,7 @@ void wxTextCtrl::DoDrawTextInRect(wxDC& dc, const wxRect& rectUpdate)
|
|||||||
selEnd = text.length();
|
selEnd = text.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate the physical text coords
|
// calculate the text coords on screen
|
||||||
wxCoord ofsStart = GetTextWidth(
|
wxCoord ofsStart = GetTextWidth(
|
||||||
textLine.Mid(colRowStart,
|
textLine.Mid(colRowStart,
|
||||||
colStart - colRowStart));
|
colStart - colRowStart));
|
||||||
@@ -2952,13 +3123,7 @@ void wxTextCtrl::ShowCaret(bool show)
|
|||||||
if ( caret )
|
if ( caret )
|
||||||
{
|
{
|
||||||
// (re)position caret correctly
|
// (re)position caret correctly
|
||||||
wxCoord xCaret, yCaret;
|
caret->Move(GetCaretPosition());
|
||||||
if ( !PositionToPixelXY(m_curPos, &xCaret, &yCaret) )
|
|
||||||
{
|
|
||||||
wxFAIL_MSG( _T("Caret can't be beyond the text!") );
|
|
||||||
}
|
|
||||||
|
|
||||||
caret->Move(xCaret, yCaret);
|
|
||||||
|
|
||||||
// and show it there
|
// and show it there
|
||||||
caret->Show(show);
|
caret->Show(show);
|
||||||
@@ -3030,13 +3195,34 @@ bool wxTextCtrl::PerformAction(const wxControlAction& actionOrig,
|
|||||||
}
|
}
|
||||||
else if ( action == wxACTION_TEXT_UP )
|
else if ( action == wxACTION_TEXT_UP )
|
||||||
{
|
{
|
||||||
if ( m_curRow > 0 )
|
// move the cursor up by one ROW not by one LINE: this means that we
|
||||||
newPos = XYToPosition(m_curCol, m_curRow - 1);
|
// should really use HitTest() and not just go to the same position in
|
||||||
|
// the previous line
|
||||||
|
wxPoint pt = GetCaretPosition() - m_rectText.GetPosition();
|
||||||
|
CalcUnscrolledPosition(pt.x, pt.y, &pt.x, &pt.y);
|
||||||
|
pt.y -= GetCharHeight();
|
||||||
|
|
||||||
|
wxTextCoord col, row;
|
||||||
|
if ( HitTestLogical(pt, &col, &row) != wxTE_HT_BEFORE )
|
||||||
|
{
|
||||||
|
newPos = XYToPosition(col, row);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ( action == wxACTION_TEXT_DOWN )
|
else if ( action == wxACTION_TEXT_DOWN )
|
||||||
{
|
{
|
||||||
if ( (size_t)m_curRow < m_lines.GetCount() )
|
// see comments for wxACTION_TEXT_UP
|
||||||
newPos = XYToPosition(m_curCol, m_curRow + 1);
|
wxPoint pt = GetCaretPosition() - m_rectText.GetPosition();
|
||||||
|
CalcUnscrolledPosition(pt.x, pt.y, &pt.x, &pt.y);
|
||||||
|
pt.y += GetCharHeight();
|
||||||
|
|
||||||
|
wxTextCoord col, row;
|
||||||
|
if ( HitTestLogical(pt, &col, &row) != wxTE_HT_BELOW )
|
||||||
|
{
|
||||||
|
// note that wxTE_HT_BEYOND is ok: it happens when we go down from
|
||||||
|
// a longer line to a shorter one, for example (OTOH wxTE_HT_BEFORE
|
||||||
|
// can never happen)
|
||||||
|
newPos = XYToPosition(col, row);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ( action == wxACTION_TEXT_LEFT )
|
else if ( action == wxACTION_TEXT_LEFT )
|
||||||
{
|
{
|
||||||
@@ -3249,7 +3435,7 @@ wxTextPos wxStdTextCtrlInputHandler::HitTest(const wxTextCtrl *text,
|
|||||||
|
|
||||||
// if the point is after the last column we must adjust the position to be
|
// if the point is after the last column we must adjust the position to be
|
||||||
// the last position in the line (unless it is already the last)
|
// the last position in the line (unless it is already the last)
|
||||||
if ( (ht == wxTE_HT_AFTER) && (pos < text->GetLastPosition()) )
|
if ( (ht == wxTE_HT_BEYOND) && (pos < text->GetLastPosition()) )
|
||||||
{
|
{
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
@@ -3426,4 +3612,18 @@ bool wxStdTextCtrlInputHandler::HandleMouseMove(wxControl *control,
|
|||||||
return wxStdInputHandler::HandleMouseMove(control, event);
|
return wxStdInputHandler::HandleMouseMove(control, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxStdTextCtrlInputHandler::HandleFocus(wxControl *control,
|
||||||
|
const wxFocusEvent& event)
|
||||||
|
{
|
||||||
|
if ( event.GetEventType() == wxEVT_KILL_FOCUS )
|
||||||
|
{
|
||||||
|
wxStaticCast(control, wxTextCtrl)->ClearSelection();
|
||||||
|
|
||||||
|
// don't refresh
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxStdInputHandler::HandleFocus(control, event);
|
||||||
|
}
|
||||||
|
|
||||||
#endif // wxUSE_TEXTCTRL
|
#endif // wxUSE_TEXTCTRL
|
||||||
|
@@ -1484,6 +1484,12 @@ void wxWin32Renderer::DrawCheckItem(wxDC& dc,
|
|||||||
|
|
||||||
wxBitmap wxWin32Renderer::GetCheckBitmap(int flags)
|
wxBitmap wxWin32Renderer::GetCheckBitmap(int flags)
|
||||||
{
|
{
|
||||||
|
if ( flags & wxCONTROL_DISABLED )
|
||||||
|
{
|
||||||
|
// the disabled indicators look the same as pressed ones in Windows
|
||||||
|
flags |= wxCONTROL_PRESSED;
|
||||||
|
}
|
||||||
|
|
||||||
char **xpm;
|
char **xpm;
|
||||||
if ( flags & wxCONTROL_CHECKED )
|
if ( flags & wxCONTROL_CHECKED )
|
||||||
{
|
{
|
||||||
@@ -1501,6 +1507,12 @@ wxBitmap wxWin32Renderer::GetCheckBitmap(int flags)
|
|||||||
|
|
||||||
wxBitmap wxWin32Renderer::GetRadioBitmap(int flags)
|
wxBitmap wxWin32Renderer::GetRadioBitmap(int flags)
|
||||||
{
|
{
|
||||||
|
if ( flags & wxCONTROL_DISABLED )
|
||||||
|
{
|
||||||
|
// the disabled indicators look the same as pressed ones in Windows
|
||||||
|
flags |= wxCONTROL_PRESSED;
|
||||||
|
}
|
||||||
|
|
||||||
char **xpm;
|
char **xpm;
|
||||||
if ( flags & wxCONTROL_CHECKED )
|
if ( flags & wxCONTROL_CHECKED )
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user