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:
Vadim Zeitlin
2000-10-15 21:15:27 +00:00
parent 7e29723b0f
commit facdb39467
6 changed files with 206 additions and 4 deletions

View File

@@ -84,7 +84,10 @@ static inline void OrderPositions(long& from, long& to)
BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
EVT_CHAR(OnChar)
EVT_SIZE(OnSize)
EVT_IDLE(OnIdle)
END_EVENT_TABLE()
IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
@@ -112,6 +115,17 @@ void wxTextCtrl::Init()
m_curPos =
m_curCol =
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,
@@ -131,10 +145,25 @@ bool wxTextCtrl::Create(wxWindow *parent,
SetCursor(wxCURSOR_IBEAM);
// we should always have at least one line in a multiline control
if ( style & wxTE_MULTILINE )
{
// we should always have at least one line in a multiline control
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);
@@ -161,6 +190,9 @@ bool wxTextCtrl::SetFont(const wxFont& font)
// and refresh everything, of course
InitInsertionPoint();
ClearSelection();
m_widthMax = -1;
Refresh();
return TRUE;
@@ -523,6 +555,8 @@ void wxTextCtrl::Replace(long from, long to, const wxString& text)
{
// we have the replacement line for this one
m_lines[line] = lines[nReplaceLine];
UpdateMaxWidth(line);
}
else // no more replacement lines
{
@@ -538,6 +572,8 @@ void wxTextCtrl::Replace(long from, long to, const wxString& text)
while ( nReplaceLine < nReplaceCount )
{
m_lines.Insert(lines[nReplaceLine++], ++lineEnd);
UpdateMaxWidth(lineEnd);
}
// (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
// start line
RefreshLineRange(lineStart + 1);
// the vert scrollbar might [dis]appear
m_updateScrollbarY = TRUE;
}
#endif // 0/1
@@ -1043,10 +1082,37 @@ void wxTextCtrl::ShowPosition(long 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();
}
@@ -1306,6 +1372,9 @@ void wxTextCtrl::OnSize(wxSizeEvent& event)
{
UpdateTextRect();
m_updateScrollbarX =
m_updateScrollbarY = TRUE;
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
// ----------------------------------------------------------------------------