1. more work on multiline text ctrl (scrolling...)
2. minor bugs in listbox/scrollbar fixed git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8565 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -296,7 +296,14 @@ protected:
|
|||||||
// set the caret to its initial (default) position
|
// set the caret to its initial (default) position
|
||||||
void InitInsertionPoint();
|
void InitInsertionPoint();
|
||||||
|
|
||||||
|
// get the width of the longest line in pixels
|
||||||
|
wxCoord GetMaxWidth() const;
|
||||||
|
|
||||||
|
// update the max width if the width of this line is greater than it
|
||||||
|
void UpdateMaxWidth(long line);
|
||||||
|
|
||||||
// event handlers
|
// event handlers
|
||||||
|
void OnIdle(wxIdleEvent& event);
|
||||||
void OnChar(wxKeyEvent& event);
|
void OnChar(wxKeyEvent& event);
|
||||||
void OnSize(wxSizeEvent& event);
|
void OnSize(wxSizeEvent& event);
|
||||||
|
|
||||||
@@ -315,6 +322,9 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// update the scrollbars (only called from OnIdle)
|
||||||
|
void UpdateScrollbars();
|
||||||
|
|
||||||
// the initially specified control size
|
// the initially specified control size
|
||||||
wxSize m_sizeInitial;
|
wxSize m_sizeInitial;
|
||||||
|
|
||||||
@@ -329,6 +339,9 @@ private:
|
|||||||
m_curCol,
|
m_curCol,
|
||||||
m_curRow;
|
m_curRow;
|
||||||
|
|
||||||
|
// last position (only used by GetLastPosition())
|
||||||
|
long m_posLast;
|
||||||
|
|
||||||
// selection
|
// selection
|
||||||
long m_selAnchor,
|
long m_selAnchor,
|
||||||
m_selStart,
|
m_selStart,
|
||||||
@@ -353,6 +366,19 @@ private:
|
|||||||
wxCoord m_posLastVisible;
|
wxCoord m_posLastVisible;
|
||||||
long m_colLastVisible;
|
long m_colLastVisible;
|
||||||
|
|
||||||
|
// this section is for the controls with scrollbar(s)
|
||||||
|
|
||||||
|
// the current ranges of the scrollbars
|
||||||
|
int m_scrollRangeX,
|
||||||
|
m_scrollRangeY;
|
||||||
|
|
||||||
|
// should we adjust the horz/vert scrollbar?
|
||||||
|
bool m_updateScrollbarX,
|
||||||
|
m_updateScrollbarY;
|
||||||
|
|
||||||
|
// the max line length in pixels
|
||||||
|
wxCoord m_widthMax;
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
DECLARE_DYNAMIC_CLASS(wxTextCtrl)
|
DECLARE_DYNAMIC_CLASS(wxTextCtrl)
|
||||||
};
|
};
|
||||||
|
@@ -397,6 +397,7 @@ MyUnivFrame::MyUnivFrame(const wxString& title)
|
|||||||
text = new wxTextCtrl(this, -1, _T("Hello,\nMultiverse!"),
|
text = new wxTextCtrl(this, -1, _T("Hello,\nMultiverse!"),
|
||||||
wxPoint(10, 10), wxDefaultSize,
|
wxPoint(10, 10), wxDefaultSize,
|
||||||
wxTE_MULTILINE);
|
wxTE_MULTILINE);
|
||||||
|
text->SetFocus();
|
||||||
#endif // !TEST_TEXT_ONLY/TEST_TEXT_ONLY
|
#endif // !TEST_TEXT_ONLY/TEST_TEXT_ONLY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -540,7 +540,7 @@ void wxListBox::OnIdle(wxIdleEvent& event)
|
|||||||
{
|
{
|
||||||
UpdateScrollbars();
|
UpdateScrollbars();
|
||||||
|
|
||||||
m_updateScrollbarX = FALSE;
|
m_updateScrollbarX =
|
||||||
m_updateScrollbarY = FALSE;
|
m_updateScrollbarY = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -678,6 +678,10 @@ void wxListBox::OnSize(wxSizeEvent& event)
|
|||||||
// recalculate the number of items per page
|
// recalculate the number of items per page
|
||||||
CalcItemsPerPage();
|
CalcItemsPerPage();
|
||||||
|
|
||||||
|
// the scrollbars might [dis]appear
|
||||||
|
m_updateScrollbarX =
|
||||||
|
m_updateScrollbarY = TRUE;
|
||||||
|
|
||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -116,6 +116,9 @@ bool wxScrollBar::Create(wxWindow *parent,
|
|||||||
|
|
||||||
SetBestSize(size);
|
SetBestSize(size);
|
||||||
|
|
||||||
|
// override the cursor of the target window (if any)
|
||||||
|
SetCursor(wxCURSOR_ARROW);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -84,7 +84,10 @@ static inline void OrderPositions(long& from, long& to)
|
|||||||
|
|
||||||
BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
|
BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
|
||||||
EVT_CHAR(OnChar)
|
EVT_CHAR(OnChar)
|
||||||
|
|
||||||
EVT_SIZE(OnSize)
|
EVT_SIZE(OnSize)
|
||||||
|
|
||||||
|
EVT_IDLE(OnIdle)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
|
IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
|
||||||
@@ -112,6 +115,17 @@ void wxTextCtrl::Init()
|
|||||||
m_curPos =
|
m_curPos =
|
||||||
m_curCol =
|
m_curCol =
|
||||||
m_curRow = 0;
|
m_curRow = 0;
|
||||||
|
|
||||||
|
m_scrollRangeX =
|
||||||
|
m_scrollRangeY = 0;
|
||||||
|
|
||||||
|
m_updateScrollbarX =
|
||||||
|
m_updateScrollbarY = FALSE;
|
||||||
|
|
||||||
|
m_widthMax = -1;
|
||||||
|
|
||||||
|
// init wxScrollHelper
|
||||||
|
SetWindow(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxTextCtrl::Create(wxWindow *parent,
|
bool wxTextCtrl::Create(wxWindow *parent,
|
||||||
@@ -131,10 +145,25 @@ bool wxTextCtrl::Create(wxWindow *parent,
|
|||||||
|
|
||||||
SetCursor(wxCURSOR_IBEAM);
|
SetCursor(wxCURSOR_IBEAM);
|
||||||
|
|
||||||
// we should always have at least one line in a multiline control
|
|
||||||
if ( style & wxTE_MULTILINE )
|
if ( style & wxTE_MULTILINE )
|
||||||
{
|
{
|
||||||
|
// we should always have at least one line in a multiline control
|
||||||
m_lines.Add(wxEmptyString);
|
m_lines.Add(wxEmptyString);
|
||||||
|
|
||||||
|
// we might support it but it's quite useless and other ports don't
|
||||||
|
// support it anyhow
|
||||||
|
wxASSERT_MSG( !(style & wxTE_PASSWORD),
|
||||||
|
_T("wxTE_PASSWORD can't be used with multiline ctrls") );
|
||||||
|
|
||||||
|
// create vertical scrollbar if necessary (on by default)
|
||||||
|
if ( !(style & wxTE_NO_VSCROLL) )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// and the horizontal one
|
||||||
|
if ( style & wxHSCROLL )
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetValue(value);
|
SetValue(value);
|
||||||
@@ -161,6 +190,9 @@ bool wxTextCtrl::SetFont(const wxFont& font)
|
|||||||
// and refresh everything, of course
|
// and refresh everything, of course
|
||||||
InitInsertionPoint();
|
InitInsertionPoint();
|
||||||
ClearSelection();
|
ClearSelection();
|
||||||
|
|
||||||
|
m_widthMax = -1;
|
||||||
|
|
||||||
Refresh();
|
Refresh();
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -523,6 +555,8 @@ void wxTextCtrl::Replace(long from, long to, const wxString& text)
|
|||||||
{
|
{
|
||||||
// we have the replacement line for this one
|
// we have the replacement line for this one
|
||||||
m_lines[line] = lines[nReplaceLine];
|
m_lines[line] = lines[nReplaceLine];
|
||||||
|
|
||||||
|
UpdateMaxWidth(line);
|
||||||
}
|
}
|
||||||
else // no more replacement lines
|
else // no more replacement lines
|
||||||
{
|
{
|
||||||
@@ -538,6 +572,8 @@ void wxTextCtrl::Replace(long from, long to, const wxString& text)
|
|||||||
while ( nReplaceLine < nReplaceCount )
|
while ( nReplaceLine < nReplaceCount )
|
||||||
{
|
{
|
||||||
m_lines.Insert(lines[nReplaceLine++], ++lineEnd);
|
m_lines.Insert(lines[nReplaceLine++], ++lineEnd);
|
||||||
|
|
||||||
|
UpdateMaxWidth(lineEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
// (5) now refresh the changed area
|
// (5) now refresh the changed area
|
||||||
@@ -554,6 +590,9 @@ void wxTextCtrl::Replace(long from, long to, const wxString& text)
|
|||||||
// number of lines did change, we need to refresh everything below the
|
// number of lines did change, we need to refresh everything below the
|
||||||
// start line
|
// start line
|
||||||
RefreshLineRange(lineStart + 1);
|
RefreshLineRange(lineStart + 1);
|
||||||
|
|
||||||
|
// the vert scrollbar might [dis]appear
|
||||||
|
m_updateScrollbarY = TRUE;
|
||||||
}
|
}
|
||||||
#endif // 0/1
|
#endif // 0/1
|
||||||
|
|
||||||
@@ -1043,10 +1082,37 @@ void wxTextCtrl::ShowPosition(long pos)
|
|||||||
{
|
{
|
||||||
ShowHorzPosition(GetCaretPosition(pos));
|
ShowHorzPosition(GetCaretPosition(pos));
|
||||||
}
|
}
|
||||||
else // multiline
|
else if ( m_scrollRangeX || m_scrollRangeY ) // multiline with scrollbars
|
||||||
{
|
{
|
||||||
// TODO
|
int xStart, yStart;
|
||||||
|
GetViewStart(&xStart, &yStart);
|
||||||
|
|
||||||
|
if ( m_scrollRangeY )
|
||||||
|
{
|
||||||
|
// scroll the position vertically into view: if it is currently
|
||||||
|
// above it, make it the first one, otherwise the last one
|
||||||
|
if ( m_curRow < yStart )
|
||||||
|
{
|
||||||
|
Scroll(0, m_curRow);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int yEnd = yStart + GetClientSize().y / GetCharHeight() - 1;
|
||||||
|
if ( yEnd < m_curRow )
|
||||||
|
{
|
||||||
|
// scroll down: the current item should appear at the
|
||||||
|
// bottom of the view
|
||||||
|
Scroll(0, m_curRow - (yEnd - yStart));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_scrollRangeX )
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
//else: multiline but no scrollbars, hence nothing to do
|
||||||
|
|
||||||
ShowCaret();
|
ShowCaret();
|
||||||
}
|
}
|
||||||
@@ -1306,6 +1372,9 @@ void wxTextCtrl::OnSize(wxSizeEvent& event)
|
|||||||
{
|
{
|
||||||
UpdateTextRect();
|
UpdateTextRect();
|
||||||
|
|
||||||
|
m_updateScrollbarX =
|
||||||
|
m_updateScrollbarY = TRUE;
|
||||||
|
|
||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1671,6 +1740,103 @@ void wxTextCtrl::DoPrepareDC(wxDC& dc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxTextCtrl::UpdateMaxWidth(long line)
|
||||||
|
{
|
||||||
|
wxCoord width;
|
||||||
|
GetTextExtent(GetLineText(line), &width, NULL);
|
||||||
|
|
||||||
|
// GetMaxWidth() and not m_widthMax as it might be not calculated yet
|
||||||
|
if ( width > GetMaxWidth() )
|
||||||
|
{
|
||||||
|
m_widthMax = width;
|
||||||
|
|
||||||
|
m_updateScrollbarX = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wxCoord wxTextCtrl::GetMaxWidth() const
|
||||||
|
{
|
||||||
|
if ( m_widthMax == -1 )
|
||||||
|
{
|
||||||
|
// recalculate it
|
||||||
|
|
||||||
|
// OPT: should we remember the widths of all the lines?
|
||||||
|
|
||||||
|
wxTextCtrl *self = wxConstCast(this, wxTextCtrl);
|
||||||
|
wxClientDC dc(self);
|
||||||
|
dc.SetFont(GetFont());
|
||||||
|
|
||||||
|
size_t count = m_lines.GetCount();
|
||||||
|
for ( size_t n = 0; n < count; n++ )
|
||||||
|
{
|
||||||
|
wxCoord width;
|
||||||
|
dc.GetTextExtent(m_lines[n], &width, NULL);
|
||||||
|
if ( width > m_widthMax )
|
||||||
|
{
|
||||||
|
self->m_widthMax = width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_widthMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxTextCtrl::UpdateScrollbars()
|
||||||
|
{
|
||||||
|
wxSize size = GetClientSize();
|
||||||
|
|
||||||
|
// is our height enough to show all items?
|
||||||
|
int nLines = GetNumberOfLines();
|
||||||
|
wxCoord lineHeight = GetCharHeight();
|
||||||
|
bool showScrollbarY = nLines*lineHeight > size.y;
|
||||||
|
|
||||||
|
// is our width enough to show the longest line?
|
||||||
|
wxCoord charWidth, maxWidth;
|
||||||
|
bool showScrollbarX;
|
||||||
|
if ( GetWindowStyle() && wxHSCROLL )
|
||||||
|
{
|
||||||
|
charWidth = GetCharWidth();
|
||||||
|
maxWidth = GetMaxWidth();
|
||||||
|
showScrollbarX = maxWidth > size.x;
|
||||||
|
}
|
||||||
|
else // never show the horz scrollbar
|
||||||
|
{
|
||||||
|
// just to suppress compiler warnings about using uninit vars below
|
||||||
|
charWidth = maxWidth = 0;
|
||||||
|
|
||||||
|
showScrollbarX = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calc the scrollbars ranges
|
||||||
|
int scrollRangeX = showScrollbarX
|
||||||
|
? (maxWidth + 2*charWidth - 1) / charWidth
|
||||||
|
: 0;
|
||||||
|
int scrollRangeY = showScrollbarY ? nLines : 0;
|
||||||
|
|
||||||
|
if ( (scrollRangeY != m_scrollRangeY) || (scrollRangeX != m_scrollRangeX) )
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
GetViewStart(&x, &y);
|
||||||
|
SetScrollbars(charWidth, lineHeight,
|
||||||
|
scrollRangeX, scrollRangeY,
|
||||||
|
x, y);
|
||||||
|
|
||||||
|
m_scrollRangeX = scrollRangeX;
|
||||||
|
m_scrollRangeY = scrollRangeY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxTextCtrl::OnIdle(wxIdleEvent& event)
|
||||||
|
{
|
||||||
|
if ( m_updateScrollbarX || m_updateScrollbarY )
|
||||||
|
{
|
||||||
|
UpdateScrollbars();
|
||||||
|
|
||||||
|
m_updateScrollbarX =
|
||||||
|
m_updateScrollbarY = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// refresh
|
// refresh
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -85,6 +85,8 @@ bool wxWindow::Create(wxWindow *parent,
|
|||||||
long style,
|
long style,
|
||||||
const wxString& name)
|
const wxString& name)
|
||||||
{
|
{
|
||||||
|
// we add wxCLIP_CHILDREN and wxNO_FULL_REPAINT_ON_RESIZE because without
|
||||||
|
// these styles we can't get rid of flicker on wxMSW
|
||||||
if ( !wxWindowNative::Create(parent, id, pos, size,
|
if ( !wxWindowNative::Create(parent, id, pos, size,
|
||||||
style | wxCLIP_CHILDREN, name) )
|
style | wxCLIP_CHILDREN, name) )
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user