]> git.saurik.com Git - wxWidgets.git/commitdiff
Countless (some half-finished) optimisations.
authorKarsten Ballüder <ballueder@usa.net>
Mon, 12 Apr 1999 20:06:46 +0000 (20:06 +0000)
committerKarsten Ballüder <ballueder@usa.net>
Mon, 12 Apr 1999 20:06:46 +0000 (20:06 +0000)
Started implementing selections.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2106 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

user/wxLayout/TODO
user/wxLayout/wxllist.cpp
user/wxLayout/wxllist.h
user/wxLayout/wxlwindow.cpp
user/wxLayout/wxlwindow.h

index e7a6b8a1e39c5c3ace8010b7b739eee186fbaa38..4561575910b65b88bc3c724397bbc305466c186e 100644 (file)
@@ -15,27 +15,32 @@ BUGS
 
 TODO
 =====================================================================
-- replacement of llist in window
-- undo
 
-- Selections!!!
+RECENTLY FIXED (?)
+  - fix(simplify) cursor size calculation
+  - delete in empty line doesn't work
+  - fix horiz scrollbar size OK here, a Mahogany problem?
+  
 
-- More optimisations:
-
-- let each line have a pointer to the last layoutcommand and let that
-  one only store the settings that changed, then we no longer need to
-  recalculate all the lines
-
-  - update rectangle (needs support in wxllist and wxWindows)
 
-- fix(simplify) cursor size calculation: don't use icon cursor if there
-  is no cursor object
+- update rectangle (needs support in wxllist and wxWindows)
+  --> needs a bit of fixing still
+      some code bits are commented out in wxlwindow.cpp
+      offset handling seems a bit dodgy, white shadow to top/left of cursor
 
+  - replacement of llist in window
+  - undo
+  - font optimisations(!)
   - copy/cut/selections
+  - occasionally wraps lines wongly (twice) ??
   - UNDO
+  later:
+    - DragNDrop ... broken in wxGTK at present
+    - cut&paste ... broken in wxGTK at present, Paste already implemented
+    - Selections
 
-- cut&paste (paste is there but broken in wxGTK)
-  The current paste in wxGTK is broken, support is there.
-  Once selections are there, add copy (trivial).
-
-- DragNDrop (waiting for wxGTK/gtk1.2 & GNOME 1.0 / Debian Slink)
+- More optimisations:
+  - let each line have a pointer to the last layoutcommand and let that
+    one only store the settings that changed, then we no longer need to
+    recalculate all the lines
+  
index bad247830333a6f465da4627d01fa7e9db07980b..6e972e3ebceea49aabf39ccb4fafa856057130c9 100644 (file)
 #pragma implementation "wxllist.h"
 #endif
 
+//#include "Mpch.h"
+
+
 #include "wx/wxprec.h"
 #ifdef __BORLANDC__
 #  pragma hdrstop
 #endif
 
-//#include "Mpch.h"
 #ifdef M_PREFIX
 #   include "gui/wxllist.h"
 #else
@@ -78,9 +80,16 @@ bool operator !=(wxPoint const &p1, wxPoint const &p2)
    return p1.x != p2.x || p1.y != p2.y;
 }
 
+/// allows me to compare to wxPoints
+bool operator <=(wxPoint const &p1, wxPoint const &p2)
+{
+   return p1.y < p2.y || (p1.y == p2.y && p1.x <= p2.x);
+}
+
 /// grows a wxRect so that it includes the given point
 
-static void GrowRect(wxRect &r, const wxPoint & p)
+static
+void GrowRect(wxRect &r, const wxPoint & p)
 {
    if(r.x > p.x)
       r.x = p.x;
@@ -92,6 +101,13 @@ static void GrowRect(wxRect &r, const wxPoint & p)
    else if(r.y + r.height < p.y)
       r.height = p.y - r.y;
 }
+
+/// returns true if the point is in the rectangle
+static
+bool Contains(const wxRect &r, const wxPoint &p)
+{
+   return r.x <= p.x && r.y <= p.y && (r.x+r.width) >= p.x && (r.y + r.height) >= p.y;
+}
 //@}
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
@@ -234,7 +250,7 @@ wxLayoutObjectIcon::GetSize(CoordType *top, CoordType *bottom) const
 
 wxLayoutObjectCmd::wxLayoutObjectCmd(int size, int family, int style, int
                                      weight, bool underline,
-                                     wxColour const *fg, wxColour const *bg)
+                                     wxColour &fg, wxColour &bg)
    
 {
    m_font = new wxFont(size,family,style,weight,underline);
@@ -270,12 +286,12 @@ wxLayoutObjectCmd::GetStyle(wxLayoutStyleInfo *si) const
    si->underline = m_font->GetUnderlined();
    si->weight = m_font->GetWeight();
 
-   si->fg_red = m_ColourFG->Red();
-   si->fg_green = m_ColourFG->Green();
-   si->fg_blue = m_ColourFG->Blue();
-   si->bg_red = m_ColourBG->Red();
-   si->bg_green = m_ColourBG->Green();
-   si->bg_blue = m_ColourBG->Blue();
+   si->fg_red = m_ColourFG.Red();
+   si->fg_green = m_ColourFG.Green();
+   si->fg_blue = m_ColourFG.Blue();
+   si->bg_red = m_ColourBG.Red();
+   si->bg_green = m_ColourBG.Green();
+   si->bg_blue = m_ColourBG.Blue();
 }
 
 void
@@ -283,10 +299,8 @@ wxLayoutObjectCmd::Draw(wxDC &dc, wxPoint const & /* coords */)
 {
    wxASSERT(m_font);
    dc.SetFont(*m_font);
-   if(m_ColourFG)
-      dc.SetTextForeground(*m_ColourFG);
-   if(m_ColourBG)
-      dc.SetTextBackground(*m_ColourBG);
+   dc.SetTextForeground(m_ColourFG);
+   dc.SetTextBackground(m_ColourBG);
 }
 
 void
@@ -303,7 +317,7 @@ wxLayoutObjectCmd::Layout(wxDC &dc)
 
    * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
-wxLayoutLine::wxLayoutLine(wxLayoutLine *prev)
+wxLayoutLine::wxLayoutLine(wxLayoutLine *prev, wxLayoutList *llist)
 {
    m_LineNumber = 0;
    m_Width = m_Height = 0;
@@ -311,7 +325,7 @@ wxLayoutLine::wxLayoutLine(wxLayoutLine *prev)
    m_Dirty = true;
    m_Previous = prev;
    m_Next = NULL;
-   RecalculatePosition();
+   RecalculatePosition(llist);
    if(m_Previous)
    {
       m_LineNumber = m_Previous->GetLineNumber()+1;
@@ -323,7 +337,7 @@ wxLayoutLine::wxLayoutLine(wxLayoutLine *prev)
    {
       m_Next->m_Previous = this;
       m_Next->MoveLines(+1);
-      m_Next->RecalculatePositions(1);
+      m_Next->RecalculatePositions(1,llist);
    }
 }
 
@@ -333,33 +347,32 @@ wxLayoutLine::~wxLayoutLine()
 }
 
 wxPoint
-wxLayoutLine::RecalculatePosition(void)
+wxLayoutLine::RecalculatePosition(wxLayoutList *llist)
 {
    if(m_Previous)
       m_Position = m_Previous->GetPosition() +
          wxPoint(0,m_Previous->GetHeight());
    else
       m_Position = wxPoint(0,0);
+   llist->SetUpdateRect(m_Position);
    return m_Position;
 }
 
 void
-wxLayoutLine::RecalculatePositions(int recurse)
+wxLayoutLine::RecalculatePositions(int recurse, wxLayoutList *llist)
 {
    wxASSERT(recurse >= 0);
    wxPoint pos = m_Position;
    CoordType height = m_Height;
    
 //   WXLO_TRACE("RecalculatePositions()");
-   RecalculatePosition();
+   RecalculatePosition(llist);
    if(m_Next)
    {
       if(recurse > 0)
-      {
-         if(m_Next) m_Next->RecalculatePositions(--recurse);
-      }
+         m_Next->RecalculatePositions(--recurse, llist);
       else if(pos != m_Position || m_Height != height)
-         if(m_Next) m_Next->RecalculatePositions();         
+         m_Next->RecalculatePositions(0, llist);         
    }
 }
 
@@ -368,21 +381,29 @@ wxLayoutLine::FindObject(CoordType xpos, CoordType *offset) const
 {
    wxASSERT(xpos >= 0);
    wxASSERT(offset);
-   wxLayoutObjectList::iterator i;
+   wxLayoutObjectList::iterator
+      i,
+      found = NULLIT;
    CoordType x = 0, len;
    
-
+   /* We search through the objects. As we don't like returning the
+      object that the cursor is behind, we just remember such an
+      object in "found" so we can return it if there is really no
+      further object following it. */
    for(i = m_ObjectList.begin(); i != NULLIT; i++)
    {
       len = (**i).GetLength();
       if( x <= xpos && xpos <= x + len )
       {
          *offset = xpos-x;
-         return i;
+         if(xpos == x + len) // is there another object behind?
+            found = i;
+         else  // we are really inside this object
+            return i;
       }
       x += (**i).GetLength();
    }
-   return NULLIT;
+   return found;  // ==NULL if really none found
 }
 
 wxLayoutObjectList::iterator
@@ -586,14 +607,14 @@ wxLayoutLine::DeleteWord(CoordType xpos)
 }
 
 wxLayoutLine *
-wxLayoutLine::DeleteLine(bool update)
+wxLayoutLine::DeleteLine(bool update, wxLayoutList *llist)
 {
    if(m_Next) m_Next->m_Previous = m_Previous;
    if(m_Previous) m_Previous->m_Next = m_Next;
    if(update)
    {
       m_Next->MoveLines(-1);
-      m_Next->RecalculatePositions(1);
+      m_Next->RecalculatePositions(1, llist);
    }
    wxLayoutLine *next = m_Next;
    delete this;
@@ -601,7 +622,9 @@ wxLayoutLine::DeleteLine(bool update)
 }
 
 void
-wxLayoutLine::Draw(wxDC &dc, const wxPoint & offset) const
+wxLayoutLine::Draw(wxDC &dc,
+                   wxLayoutList *llist,
+                   const wxPoint & offset) const
 {
    wxLayoutObjectList::iterator i;
    wxPoint pos = offset;
@@ -617,7 +640,9 @@ wxLayoutLine::Draw(wxDC &dc, const wxPoint & offset) const
 }
 
 void
-wxLayoutLine::Layout(wxDC &dc, wxPoint *cursorPos,
+wxLayoutLine::Layout(wxDC &dc,
+                     wxLayoutList *llist,
+                     wxPoint *cursorPos,
                      wxPoint *cursorSize,
                      int cx) 
 {
@@ -641,6 +666,7 @@ wxLayoutLine::Layout(wxDC &dc, wxPoint *cursorPos,
    if(cursorPos)
    {
       *cursorPos = m_Position;
+      if(cursorSize) *cursorSize = wxPoint(0,0);
    }
    
    for(i = m_ObjectList.begin(); i != NULLIT; i++)
@@ -718,7 +744,7 @@ wxLayoutLine::Layout(wxDC &dc, wxPoint *cursorPos,
    
    // tell next line about coordinate change
    if(m_Next && objHeight != oldHeight)
-      m_Next->RecalculatePositions();
+      m_Next->RecalculatePositions(0, llist);
 
    // We need to check whether we found a valid cursor size:
    if(cursorPos)
@@ -727,18 +753,10 @@ wxLayoutLine::Layout(wxDC &dc, wxPoint *cursorPos,
       // line or on a command object:
       if(cursorSize->y < WXLO_MINIMUM_CURSOR_WIDTH)
       {
-         if(m_BaseLine > 0)
-         {
-            cursorSize->y = m_BaseLine;
-            if(cursorSize->x < WXLO_MINIMUM_CURSOR_WIDTH) cursorSize->x = WXLO_MINIMUM_CURSOR_WIDTH;
-         }
-         else // empty line
-         {
-            CoordType width, height, descent;
-            dc.GetTextExtent(WXLO_CURSORCHAR, &width, &height, &descent);
-            cursorSize->x = width;
-            cursorSize->y = height;
-         }
+         CoordType width, height, descent;
+         dc.GetTextExtent(WXLO_CURSORCHAR, &width, &height, &descent);
+         cursorSize->x = width;
+         cursorSize->y = height;
       }
       if(m_BaseLine >= cursorSize->y) // the normal case anyway
          cursorPos->y += m_BaseLine-cursorSize->y;
@@ -747,13 +765,13 @@ wxLayoutLine::Layout(wxDC &dc, wxPoint *cursorPos,
 
 
 wxLayoutLine *
-wxLayoutLine::Break(CoordType xpos)
+wxLayoutLine::Break(CoordType xpos, wxLayoutList *llist)
 {
    wxASSERT(xpos >= 0);
    
    if(xpos == 0)
    { // insert an empty line before this one
-      wxLayoutLine *prev = new wxLayoutLine(m_Previous);
+      wxLayoutLine *prev = new wxLayoutLine(m_Previous, llist);
       if(m_Previous == NULL)
       {  // We were in first line, need to link in new empty line
          // before this.
@@ -763,7 +781,7 @@ wxLayoutLine::Break(CoordType xpos)
       }
       MoveLines(+1);
       if(m_Next)
-         m_Next->RecalculatePositions(1);
+         m_Next->RecalculatePositions(1, llist);
       return this;
    }
    
@@ -771,10 +789,10 @@ wxLayoutLine::Break(CoordType xpos)
    wxLOiterator i = FindObject(xpos, &offset);
    if(i == NULLIT)
       // must be at the end of the line then
-      return new wxLayoutLine(this);
+      return new wxLayoutLine(this, llist);
    // split this line:
 
-   wxLayoutLine *newLine = new wxLayoutLine(this);
+   wxLayoutLine *newLine = new wxLayoutLine(this, llist);
    // split object at i:
    if((**i).GetType() == WXLO_TYPE_TEXT && offset != 0)
    {
@@ -799,13 +817,13 @@ wxLayoutLine::Break(CoordType xpos)
       m_ObjectList.remove(i); // remove without deleting it
    }
    if(m_Next)
-      m_Next->RecalculatePositions(2);
+      m_Next->RecalculatePositions(2, llist);
    return newLine;
 }
    
 
 void
-wxLayoutLine::MergeNextLine(void)
+wxLayoutLine::MergeNextLine(wxLayoutList *llist)
 {
    wxASSERT(GetNextLine());
    wxLayoutObjectList &list = GetNextLine()->m_ObjectList;
@@ -820,7 +838,7 @@ wxLayoutLine::MergeNextLine(void)
    wxLayoutLine *oldnext = GetNextLine();
    SetNext(GetNextLine()->GetNextLine());
    delete oldnext;
-   RecalculatePositions(1);
+   RecalculatePositions(1, llist);
 }
 
 CoordType
@@ -890,6 +908,8 @@ wxLayoutList::wxLayoutList()
 {
    m_DefaultSetting = NULL;
    m_FirstLine = NULL;
+   m_ColourFG = *wxBLACK;
+   m_ColourBG = *wxWHITE;
    InvalidateUpdateRect();
    Clear();
 }
@@ -897,20 +917,21 @@ wxLayoutList::wxLayoutList()
 wxLayoutList::~wxLayoutList()
 {
    InternalClear();
-   m_FirstLine->DeleteLine(false);
+   m_FirstLine->DeleteLine(false, this);
 }
 
 void
 wxLayoutList::Empty(void)
 {
    while(m_FirstLine)
-      m_FirstLine = m_FirstLine->DeleteLine(false);
+      m_FirstLine = m_FirstLine->DeleteLine(false, this);
 
    m_CursorPos = wxPoint(0,0);
    m_CursorScreenPos = wxPoint(0,0);
    m_CursorSize = wxPoint(0,0);
-   m_FirstLine = new wxLayoutLine(NULL); // empty first line
+   m_FirstLine = new wxLayoutLine(NULL, this); // empty first line
    m_CursorLine = m_FirstLine;
+   InvalidateUpdateRect();
 }
 
 
@@ -927,8 +948,8 @@ wxLayoutList::InternalClear(void)
 
 void
 wxLayoutList::SetFont(int family, int size, int style, int weight,
-                      int underline, wxColour const *fg,
-                      wxColour const *bg)
+                      int underline, wxColour *fg,
+                      wxColour *bg)
 {
    if(family != -1)    m_FontFamily = family;
    if(size != -1)      m_FontPtSize = size;
@@ -936,8 +957,8 @@ wxLayoutList::SetFont(int family, int size, int style, int weight,
    if(weight != -1)    m_FontWeight = weight;
    if(underline != -1) m_FontUnderline = underline != 0;
 
-   if(fg != NULL)     m_ColourFG = fg;
-   if(bg != NULL)     m_ColourBG = bg;
+   if(fg != NULL)     m_ColourFG = *fg;
+   if(bg != NULL)     m_ColourBG = *bg;
    
    Insert(
       new wxLayoutObjectCmd(m_FontPtSize,m_FontFamily,m_FontStyle,m_FontWeight,m_FontUnderline,
@@ -949,9 +970,9 @@ wxLayoutList::SetFont(int family, int size, int style, int weight,
                       int underline, char const *fg, char const *bg)
 
 {
-   wxColour const
-      * cfg = NULL,
-      * cbg = NULL;
+   wxColour
+      *cfg = NULL,
+      *cbg = NULL;
 
    if( fg )
       cfg = wxTheColourDatabase->FindColour(fg);
@@ -963,7 +984,7 @@ wxLayoutList::SetFont(int family, int size, int style, int weight,
 
 void
 wxLayoutList::Clear(int family, int size, int style, int weight,
-                    int /* underline */, char const *fg, char const *bg)
+                    int /* underline */, wxColour *fg, wxColour *bg)
 {
    InternalClear();
    
@@ -973,11 +994,11 @@ wxLayoutList::Clear(int family, int size, int style, int weight,
    m_FontFamily = family;
    m_FontStyle = style;
    m_FontWeight = weight;
-   m_ColourFG = wxTheColourDatabase->FindColour(fg);
-   m_ColourBG = wxTheColourDatabase->FindColour(bg);
+   if(fg) m_ColourFG = *fg;
+   if(bg) m_ColourBG = *bg;
 
-   if(! m_ColourFG) m_ColourFG = wxBLACK;
-   if(! m_ColourBG) m_ColourBG = wxWHITE;
+   m_ColourFG = *wxBLACK;
+   m_ColourBG = *wxWHITE;
    
    if(m_DefaultSetting)
       delete m_DefaultSetting;
@@ -993,6 +1014,8 @@ wxLayoutList::Clear(int family, int size, int style, int weight,
 bool
 wxLayoutList::MoveCursorTo(wxPoint const &p)
 {
+   SetUpdateRect(m_CursorScreenPos);
+   SetUpdateRect(m_CursorScreenPos+m_CursorSize);
    wxLayoutLine *line = m_FirstLine;
    while(line && line->GetLineNumber() != p.y)
       line = line->GetNextLine();
@@ -1018,6 +1041,9 @@ wxLayoutList::MoveCursorTo(wxPoint const &p)
 bool
 wxLayoutList::MoveCursorVertically(int n)
 {
+   SetUpdateRect(m_CursorScreenPos);
+   SetUpdateRect(m_CursorScreenPos+m_CursorSize);
+   bool rc;
    if(n  < 0) // move up
    {
       if(m_CursorLine == m_FirstLine) return false;
@@ -1031,13 +1057,13 @@ wxLayoutList::MoveCursorVertically(int n)
       {
          m_CursorLine = m_FirstLine;
          m_CursorPos.y = 0;
-         return false;
+         rc = false;
       }
       else
       {
          if(m_CursorPos.x > m_CursorLine->GetLength())
             m_CursorPos.x = m_CursorLine->GetLength();
-         return true;
+         rc = true;
       }
    }
    else // move down
@@ -1054,20 +1080,23 @@ wxLayoutList::MoveCursorVertically(int n)
       {
          m_CursorLine = last;
          m_CursorPos.y ++;
-         return false;
+         rc = false;
       }
       else
       {
          if(m_CursorPos.x > m_CursorLine->GetLength())
             m_CursorPos.x = m_CursorLine->GetLength();
-         return true;
+         rc = true;
       }
    }
+   return rc;
 }
 
 bool
 wxLayoutList::MoveCursorHorizontally(int n)
 {
+   SetUpdateRect(m_CursorScreenPos);
+   SetUpdateRect(m_CursorScreenPos+m_CursorSize);
    int move;
    while(n < 0)
    {
@@ -1107,6 +1136,8 @@ bool
 wxLayoutList::Insert(wxString const &text)
 {
    wxASSERT(m_CursorLine);
+   SetUpdateRect(m_CursorScreenPos);
+   SetUpdateRect(m_CursorScreenPos+m_CursorSize);
    m_CursorLine->Insert(m_CursorPos.x, text);
    m_CursorPos.x += text.Length();
    return true;
@@ -1116,6 +1147,8 @@ bool
 wxLayoutList::Insert(wxLayoutObject *obj)
 {
    wxASSERT(m_CursorLine);
+   SetUpdateRect(m_CursorScreenPos);
+   SetUpdateRect(m_CursorScreenPos+m_CursorSize);
    m_CursorLine->Insert(m_CursorPos.x, obj);
    m_CursorPos.x += obj->GetLength();
    return true;
@@ -1125,9 +1158,10 @@ bool
 wxLayoutList::LineBreak(void)
 {
    wxASSERT(m_CursorLine);
-
    bool setFirst = (m_CursorLine == m_FirstLine && m_CursorPos.x == 0);
-   m_CursorLine = m_CursorLine->Break(m_CursorPos.x);
+   SetUpdateRect(m_CursorScreenPos);
+   SetUpdateRect(m_CursorScreenPos+m_CursorSize);
+   m_CursorLine = m_CursorLine->Break(m_CursorPos.x, this);
    if(setFirst) // we were at beginning of first line
       m_FirstLine = m_CursorLine->GetPreviousLine();
    m_CursorPos.y++;
@@ -1148,6 +1182,8 @@ wxLayoutList::WrapLine(CoordType column)
       //else:
       CoordType newpos = m_CursorPos.x - xpos - 1;
       m_CursorPos.x = xpos;
+      SetUpdateRect(m_CursorScreenPos);
+      SetUpdateRect(m_CursorScreenPos+m_CursorSize);
       LineBreak();
       Delete(1); // delete the space
       m_CursorPos.x = newpos;
@@ -1159,6 +1195,8 @@ bool
 wxLayoutList::Delete(CoordType npos)
 {
    wxASSERT(m_CursorLine);
+   SetUpdateRect(m_CursorScreenPos);
+   SetUpdateRect(m_CursorScreenPos+m_CursorSize);
    CoordType left;
    do
    {
@@ -1184,7 +1222,7 @@ wxLayoutList::Delete(CoordType npos)
             break; // cannot
          else
          {
-            m_CursorLine->MergeNextLine();
+            m_CursorLine->MergeNextLine(this);
             left--;
          }
       }
@@ -1198,6 +1236,8 @@ wxLayoutList::DeleteLines(int n)
 {
    wxASSERT(m_CursorLine);
    wxLayoutLine *line;
+   SetUpdateRect(m_CursorScreenPos);
+   SetUpdateRect(m_CursorScreenPos+m_CursorSize);
    while(n > 0)
    {
       if(!m_CursorLine->GetNextLine())
@@ -1208,18 +1248,18 @@ wxLayoutList::DeleteLines(int n)
       }
       //else:
       line = m_CursorLine;
-      m_CursorLine = m_CursorLine->DeleteLine(true);
+      m_CursorLine = m_CursorLine->DeleteLine(true, this);
       n--;
       if(line == m_FirstLine) m_FirstLine = m_CursorLine;
       wxASSERT(m_FirstLine);
       wxASSERT(m_CursorLine);
    }
-   m_CursorLine->RecalculatePositions(2);
+   m_CursorLine->RecalculatePositions(2, this);
    return n;
 }
 
 void
-wxLayoutList::Recalculate(wxDC &dc, CoordType bottom) const
+wxLayoutList::Recalculate(wxDC &dc, CoordType bottom)
 {
    wxLayoutLine *line = m_FirstLine;
 
@@ -1228,7 +1268,7 @@ wxLayoutList::Recalculate(wxDC &dc, CoordType bottom) const
    m_DefaultSetting->Layout(dc);
    while(line)
    {
-      line->RecalculatePosition(); // so we don't need to do it all the time
+      line->RecalculatePosition(this); // so we don't need to do it all the time
       // little condition to speed up redrawing:
       if(bottom != -1 && line->GetPosition().y > bottom) break;
       line = line->GetNextLine();
@@ -1236,7 +1276,21 @@ wxLayoutList::Recalculate(wxDC &dc, CoordType bottom) const
 }
 
 void
-wxLayoutList::Layout(wxDC &dc, CoordType bottom) const
+wxLayoutList::UpdateCursorScreenPos(wxDC &dc)
+{
+   wxASSERT(m_CursorLine);
+   m_CursorLine->Layout(dc, this, (wxPoint *)&m_CursorScreenPos, (wxPoint *)&m_CursorSize, m_CursorPos.x);
+}
+
+wxPoint
+wxLayoutList::GetCursorScreenPos(wxDC &dc)
+{
+   UpdateCursorScreenPos(dc);
+   return m_CursorScreenPos;
+}
+
+void
+wxLayoutList::Layout(wxDC &dc, CoordType bottom)
 {
    wxLayoutLine *line = m_FirstLine;
 
@@ -1246,9 +1300,9 @@ wxLayoutList::Layout(wxDC &dc, CoordType bottom) const
    while(line)
    {
       if(line == m_CursorLine)
-         line->Layout(dc, (wxPoint *)&m_CursorScreenPos, (wxPoint *)&m_CursorSize, m_CursorPos.x);
+         line->Layout(dc, this, (wxPoint *)&m_CursorScreenPos, (wxPoint *)&m_CursorSize, m_CursorPos.x);
       else
-         line->Layout(dc);
+         line->Layout(dc, this);
       // little condition to speed up redrawing:
       if(bottom != -1 && line->GetPosition().y > bottom) break;
       line = line->GetNextLine();
@@ -1261,25 +1315,26 @@ wxLayoutList::Layout(wxDC &dc, CoordType bottom) const
                                     m_CursorLine->GetNextLine() == NULL &&
                                     m_CursorLine == m_FirstLine));
 #endif
+   SetUpdateRect(m_CursorScreenPos);
+   SetUpdateRect(m_CursorScreenPos+m_CursorSize);
 }
 
 void
 wxLayoutList::Draw(wxDC &dc, wxPoint const &offset,
-                   CoordType top, CoordType bottom) const
+                   CoordType top, CoordType bottom)
 {
    wxLayoutLine *line = m_FirstLine;
 
    Layout(dc, bottom);
    m_DefaultSetting->Draw(dc, wxPoint(0,0));
-   wxBrush *brush = new wxBrush(*m_ColourBG, wxSOLID);
-   dc.SetBrush(*brush);
-   delete brush;
+   wxBrush brush(m_ColourBG, wxSOLID);
+   dc.SetBrush(brush);
    
    while(line)
    {
       // only draw if between top and bottom:
       if((top == -1 || line->GetPosition().y >= top))
-         line->Draw(dc, offset);
+         line->Draw(dc, this, offset);
       // little condition to speed up redrawing:
       if(bottom != -1 && line->GetPosition().y + line->GetHeight() > bottom) break;
       line = line->GetNextLine();
@@ -1288,6 +1343,7 @@ wxLayoutList::Draw(wxDC &dc, wxPoint const &offset,
    wxASSERT(m_CursorSize.x != 0 || (m_CursorLine &&
                                     m_CursorLine->GetNextLine() == NULL &&
                                     m_CursorLine == m_FirstLine));
+   InvalidateUpdateRect();
 }
 
 wxLayoutObject *
@@ -1304,7 +1360,7 @@ wxLayoutList::FindObjectScreen(wxDC &dc, wxPoint const pos, wxPoint *cursorPos)
       p = line->GetPosition();
       if(p.y <= pos.y && p.y+line->GetHeight() >= pos.y)
          break;
-      line->Layout(dc);
+      line->Layout(dc, this);
       line = line->GetNextLine();
    }
    if(line == NULL) return NULL; // not found
@@ -1387,6 +1443,27 @@ wxLayoutList::SetUpdateRect(const wxPoint &p)
    }
 }
 
+void
+wxLayoutList::StartSelection(void)
+{
+   wxLogDebug("Starting selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y);
+   m_Selection.m_CursorA = m_CursorPos;
+}
+
+void
+wxLayoutList::EndSelection(void)
+{
+   wxLogDebug("Ending selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y);
+   m_Selection.m_CursorB = m_CursorPos;
+}
+
+bool
+wxLayoutList::IsSelected(const wxPoint &cursor)
+{
+   return m_Selection.m_CursorA <= cursor
+      && cursor <= m_Selection.m_CursorB;
+}
+
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
 
index dc9a23ff71f9fcc04aab7702d8c3baa701c4c08b..919211ffeb7112a9a2f07efe2aa73627280d09a9 100644 (file)
@@ -291,12 +291,12 @@ public:
    virtual void Draw(wxDC &dc, wxPoint const &coords);
    wxLayoutObjectCmd(int size, int family, int style, int weight,
                 bool underline,
-                wxColour const *fg, wxColour const *bg);
+                wxColour &fg, wxColour &bg);
    ~wxLayoutObjectCmd();
    /** Stores the current style in the styleinfo structure */
    void GetStyle(wxLayoutStyleInfo *si) const;
    /// return the background colour for setting colour of window
-   wxColour const *GetBGColour(void) const { return m_ColourBG; }
+   wxColour &GetBGColour(void) { return m_ColourBG; }
    /** Makes a copy of this object.
     */
    virtual wxLayoutObject *Copy(void);
@@ -304,9 +304,9 @@ private:
    /// the font to use
    wxFont *m_font;
    /// foreground colour
-   wxColour const *m_ColourFG;
+   wxColour m_ColourFG;
    /// background colour
-   wxColour const *m_ColourBG;
+   wxColour m_ColourBG;
 };
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
@@ -315,6 +315,9 @@ private:
 
    * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
+/// forward declaration
+class wxLayoutList;
+
 /** This class represents a single line of objects to be displayed.
     It knows its height and total size and whether it needs to be
     redrawn or not.
@@ -327,8 +330,9 @@ public:
    /** Constructor.
        @param prev pointer to previous line or NULL
        @param next pointer to following line or NULL
+       @param llist pointer to layout list
    */
-   wxLayoutLine(wxLayoutLine *prev);
+   wxLayoutLine(wxLayoutLine *prev, wxLayoutList *llist);
    /** This function inserts a new object at cursor position xpos.
        @param xpos where to insert new object
        @param obj  the object to insert
@@ -356,7 +360,7 @@ public:
    /** This function appens the next line to this, i.e. joins the two
        lines into one.
    */
-   void MergeNextLine(void);
+   void MergeNextLine(wxLayoutList *llist);
 
    /** This function deletes npos cursor positions from position xpos.
        @param xpos where to delete
@@ -369,7 +373,7 @@ public:
        @param xpos where to break it
        @return pointer to the new line object replacing the old one
    */
-   wxLayoutLine *Break(CoordType xpos);
+   wxLayoutLine *Break(CoordType xpos, wxLayoutList *llist);
 
    /** Deletes the next word from this position, including leading
        whitespace.
@@ -423,7 +427,7 @@ public:
    /** Deletes this line, returns pointer to next line.
        @param update If true, update all following lines.
    */
-   wxLayoutLine *DeleteLine(bool update);
+   wxLayoutLine *DeleteLine(bool update, wxLayoutList *llist);
 
    /**@name Cursor Management */
    //@{
@@ -441,18 +445,23 @@ public:
    //@{
    /** Draws the line on a wxDC.
        @param dc the wxDC to draw on
+       @param llist the wxLayoutList 
        @param offset an optional offset to shift printout
    */
-   void Draw(wxDC &dc, const wxPoint &offset = wxPoint(0,0)) const;
+   void Draw(wxDC &dc,
+             wxLayoutList *llist,
+             const wxPoint &offset = wxPoint(0,0)) const;
    
    /** Recalculates the positions of objects and the height of the
        line.
        @param dc the wxDC to draw on
+       @param llist th   e wxLayoutList 
        @param cursorPos if not NULL, set cursor screen position in there
        @param cursorSize if not cursorPos != NULL, set cursor size in there
        @param cx if cursorPos != NULL, the cursor x position
    */
    void Layout(wxDC &dc,
+               wxLayoutList *llist,
                wxPoint *cursorPos = NULL,
                wxPoint *cursorSize = NULL,
                int cx = 0);
@@ -493,9 +502,9 @@ public:
        minimum(!) recursion level, continue with all lines till the end of
        the list or until the coordinates no longer changed.
    */
-   void RecalculatePositions(int recurse = 0);
+   void RecalculatePositions(int recurse, wxLayoutList *llist);
    /// Recalculates the position of this line on the canvas.
-   wxPoint RecalculatePosition(void);
+   wxPoint RecalculatePosition(wxLayoutList *llist);
 private:
    /// Destructor is private. Use DeleteLine() to remove it.
    ~wxLayoutLine();
@@ -506,8 +515,8 @@ private:
        dirty.
        @param height new height
    */
-   void SetHeight(CoordType height)
-      { m_Height = height; RecalculatePositions(true); }
+   void SetHeight(CoordType height, wxLayoutList *llist)
+      { m_Height = height; RecalculatePositions(true, llist); }
 
    /** Moves the linenumbers one on, because a line has been inserted
        or deleted.
@@ -542,6 +551,8 @@ private:
    wxLayoutLine *m_Next;
    /// Just to suppress gcc compiler warnings.
    friend class dummy;
+private:
+   wxLayoutLine(const wxLayoutLine &);
 };
 
 
@@ -568,8 +579,8 @@ public:
               int style=wxNORMAL,
               int weight=wxNORMAL,
               int underline=0,
-              char const *fg="black",
-              char const *bg="white");
+              wxColour *fg=NULL,
+              wxColour *bg=NULL);
    /// Empty: clear the list but leave font settings.
    void Empty(void);
    
@@ -603,7 +614,7 @@ public:
       { MoveCursorHorizontally(-m_CursorPos.x); }
 
    /// Returns current cursor position.
-   wxPoint GetCursorPos(void) const { return m_CursorPos; }
+   wxPoint GetCursorPos(wxDC &dc) const { return m_CursorPos; }
    //@}
 
    /**@name Editing functions.
@@ -669,8 +680,8 @@ public:
    /// sets font parameters
    void SetFont(int family, int size, int style,
                 int weight, int underline,
-                wxColour const *fg,
-                wxColour const *bg);
+                wxColour *fg,
+                wxColour *bg);
    /// sets font parameters, colours by name
    void SetFont(int family=-1, int size = -1, int style=-1,
                 int weight=-1, int underline = -1,
@@ -701,7 +712,7 @@ public:
       anywhere.
       @return the default settings of the list
    */
-   wxLayoutObjectCmd const *GetDefaults(void) const { return m_DefaultSetting ; }
+   wxLayoutObjectCmd *GetDefaults(void) { return m_DefaultSetting ; }
    //@}
 
    /**@name Drawing */
@@ -713,21 +724,21 @@ public:
        @param bottom optional y coordinate where to stop drawing
    */
    void Draw(wxDC &dc, const wxPoint &offset = wxPoint(0,0),
-             CoordType top = -1, CoordType bottom = -1) const;
+             CoordType top = -1, CoordType bottom = -1);
 
    /** Calculates new layout for the list, like Draw() but does not
        actually draw it.
        @param dc the wxDC to draw on
        @param bottom optional y coordinate where to stop calculating
    */
-   void Layout(wxDC &dc, CoordType bottom = -1) const;
+   void Layout(wxDC &dc, CoordType bottom = -1);
 
    /** Calculates new sizes for everything in the list, like Layout()
        but this is needed after the list got changed.
        @param dc the wxDC to draw on
        @param bottom optional y coordinate where to stop calculating
    */
-   void Recalculate(wxDC &dc, CoordType bottom = -1) const;
+   void Recalculate(wxDC &dc, CoordType bottom = -1);
    
    /** Returns the size of the list in screen coordinates.
        The return value only makes sense after the list has been
@@ -740,8 +751,7 @@ public:
    /** Returns the cursor position on the screen.
        @return cursor position in pixels
    */
-   wxPoint GetCursorScreenPos(void) const
-      { return m_CursorScreenPos; }
+   wxPoint GetCursorScreenPos(wxDC &dc);
    
    /** Draws the cursor.
        @param active If true, draw a bold cursor to mark window as
@@ -781,9 +791,17 @@ public:
          return m_FirstLine;
       }
    //@}
+
+   void StartSelection(void);
+   void EndSelection(void);
+   bool IsSelected(const wxPoint &cursor);
+
 private:
    /// Clear the list.
    void InternalClear(void);
+   /** Calculates the cursor position on the screen.
+   */
+   void UpdateCursorScreenPos(wxDC &dc);
    
    /// The list of lines.
    wxLayoutLine *m_FirstLine;
@@ -803,14 +821,20 @@ private:
    wxLayoutLine *m_CursorLine;
    //@}   
 
+   /// A structure for the selection.
+   struct
+   {
+      bool m_valid;
+      wxPoint m_CursorA, m_CursorB;
+   }m_Selection;
    /** @name Font parameters. */
    //@{
    int m_FontFamily, m_FontStyle, m_FontWeight;
    int m_FontPtSize;
    bool m_FontUnderline;
    /// colours:
-   wxColour const * m_ColourFG;
-   wxColour const * m_ColourBG;
+   wxColour m_ColourFG;
+   wxColour m_ColourBG;
    /// the default setting:
    wxLayoutObjectCmd *m_DefaultSetting;
    //@}
index 84f94d626458ae4ee0a93e98bedd3d285628e23e..921d58fc0de17103652f93fde099a857c4a1bc5f 100644 (file)
@@ -78,11 +78,13 @@ wxLayoutWindow::wxLayoutWindow(wxWindow *parent)
    m_bitmapSize = wxPoint(4,4);
    m_llist = new wxLayoutList();
    m_BGbitmap = NULL;
+   m_ScrollToCursor = false;
    SetWrapMargin(0);
    wxPoint max = m_llist->GetSize();
    SetScrollbars(10, 20 /*lineHeight*/, max.x/10+1, max.y/20+1);
    EnableScrolling(true,true);
    m_maxx = max.x; m_maxy = max.y;
+   m_Selecting = false;
    SetCursor(wxCURSOR_IBEAM);
    SetDirty();
 }
@@ -144,7 +146,7 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
    if(obj && eventId == WXLOWIN_MENU_LCLICK)
    {
       m_llist->MoveCursorTo(cursorPos);
-      DoPaint(false); 
+      m_ScrollToCursor = true; //FIXME: needed? DoPaint(m_llist->GetUpdateRect()); 
    }
    if(!m_doSendEvents) // nothing to do
       return;
@@ -181,11 +183,18 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
    }
    
    long keyCode = event.KeyCode();
-
+   if(event.ShiftDown())
+      m_Selecting = true;
+   else
+   {
+      if(m_Selecting)
+         m_llist->EndSelection();
+      m_Selecting = false;
+   }
    /* First, handle control keys */
    if(event.ControlDown() && ! event.AltDown())
    {
-      switch(event.KeyCode())
+      switch(keyCode)
       {
       case WXK_DELETE :
       case 'd':
@@ -215,7 +224,7 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
    // ALT only:
    else if( event.AltDown() && ! event.ControlDown() )
    {
-      switch(event.KeyCode())
+      switch(keyCode)
       {
       case WXK_DELETE:
       case 'd':
@@ -228,30 +237,38 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
    // no control keys:
    else if ( ! event.AltDown() && ! event.ControlDown())
    {
-      switch(event.KeyCode())
+      switch(keyCode)
       {
       case WXK_RIGHT:
+         if(m_Selecting) m_llist->StartSelection();
          m_llist->MoveCursorHorizontally(1);
          break;
       case WXK_LEFT:
+         if(m_Selecting) m_llist->StartSelection();
          m_llist->MoveCursorHorizontally(-1);
          break;
       case WXK_UP:
+         if(m_Selecting) m_llist->StartSelection();
          m_llist->MoveCursorVertically(-1);
          break;
       case WXK_DOWN:
+         if(m_Selecting) m_llist->StartSelection();
          m_llist->MoveCursorVertically(1);
          break;
       case WXK_PRIOR:
+         if(m_Selecting) m_llist->StartSelection();
          m_llist->MoveCursorVertically(-20);
          break;
       case WXK_NEXT:
+         if(m_Selecting) m_llist->StartSelection();
          m_llist->MoveCursorVertically(20);
          break;
       case WXK_HOME:
+         if(m_Selecting) m_llist->StartSelection();
          m_llist->MoveCursorToBeginOfLine();
          break;
       case WXK_END:
+         if(m_Selecting) m_llist->StartSelection();
          m_llist->MoveCursorToEndOfLine();
          break;
       case WXK_DELETE :
@@ -281,29 +298,32 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
    }
    SetDirty();
    SetModified();
-   DoPaint(true); // paint and scroll to cursor
+   m_ScrollToCursor = true;
+   //DoPaint(true); // paint and scroll to cursor
+   wxRect r = *m_llist->GetUpdateRect();
+   r.x -= WXLO_XOFFSET; r.y -= WXLO_YOFFSET;
+   Refresh( FALSE, &r);
 }
 
 void
 wxLayoutWindow::OnPaint( wxPaintEvent &WXUNUSED(event))  // or: OnDraw(wxDC& dc)
 {
-   m_ScrollToCursor = false;
-   InternalPaint();
+   wxRect region = GetUpdateRegion().GetBox();
+   InternalPaint(& region);
 }
 
 void
-wxLayoutWindow::DoPaint(bool scrollToCursor)
+wxLayoutWindow::DoPaint(const wxRect *updateRect)
 {
-   m_ScrollToCursor = scrollToCursor;
 #ifdef __WXGTK__
-   InternalPaint();
+   InternalPaint(updateRect);
 #else
-   Refresh(FALSE); // Causes bad flicker under wxGTK!!!
+   Refresh(FALSE, updateRect); // Causes bad flicker under wxGTK!!!
 #endif
 }
 
 void
-wxLayoutWindow::InternalPaint(void)
+wxLayoutWindow::InternalPaint(const wxRect *updateRect)
 {
    wxPaintDC dc( this );
    PrepareDC( dc );
@@ -324,12 +344,26 @@ wxLayoutWindow::InternalPaint(void)
    if(x1 > m_maxx) m_maxx = x1;  
    if(y1 > m_maxy) m_maxy = y1;
 
-   // Maybe we need to change the scrollbar sizes or positions,
+
+   m_llist->InvalidateUpdateRect();
+   const wxRect *r = m_llist->GetUpdateRect();
+   wxLogDebug("Update rect before calling Layout: %ld,%ld / %ld,%ld",
+              r->x, r->y, r->x+r->width, r->y+r->height);
+
+#if 0
+   //FIXME: we should never need to call Layout at all because the
+   //       list does it automatically.
+// Maybe we need to change the scrollbar sizes or positions,
    // so layout the list and check:
    if(IsDirty())
       m_llist->Layout(dc);
+   wxLogDebug("Update rect after calling Layout: %ld,%ld / %ld,%ld",
+              r->x, r->y, r->x+r->width, r->y+r->height);
    // this is needed even when only the cursor moved
    m_llist->Layout(dc,y0+y1);
+   wxLogDebug("Update rect after calling Layout again: %ld,%ld / %ld,%ld",
+              r->x, r->y, r->x+r->width, r->y+r->height);
+#endif
    
    if(IsDirty())
       ResizeScrollbars();
@@ -337,9 +371,10 @@ wxLayoutWindow::InternalPaint(void)
    /* Make sure that the scrollbars are at a position so that the
       cursor is visible if we are editing. */
       /** Scroll so that cursor is visible! */
+   wxLogDebug("m_ScrollToCursor = %d", (int) m_ScrollToCursor);
    if(IsEditable() && m_ScrollToCursor)
    {
-      wxPoint cc = m_llist->GetCursorScreenPos();
+      wxPoint cc = m_llist->GetCursorScreenPos(*m_memDC);
       if(cc.x < x0 || cc.y < y0
          || cc.x >= x0+(9*x1)/10 || cc.y >= y0+(9*y1/10))  // (9*x)/10 ==  90%
       {
@@ -368,8 +403,8 @@ wxLayoutWindow::InternalPaint(void)
    // with the translate parameter of Draw().
    m_memDC->SetDeviceOrigin(0,0);
    m_memDC->SetBackgroundMode(wxTRANSPARENT);
-   m_memDC->SetBrush(wxBrush(*m_llist->GetDefaults()->GetBGColour(), wxSOLID));                                  
-   m_memDC->SetPen(wxPen(*m_llist->GetDefaults()->GetBGColour(),0,wxTRANSPARENT));                               
+   m_memDC->SetBrush(wxBrush(m_llist->GetDefaults()->GetBGColour(), wxSOLID));                                  
+   m_memDC->SetPen(wxPen(m_llist->GetDefaults()->GetBGColour(),0,wxTRANSPARENT));                               
    m_memDC->SetLogicalFunction(wxCOPY);
    if(m_BGbitmap)
    {
@@ -391,15 +426,23 @@ wxLayoutWindow::InternalPaint(void)
       m_llist->DrawCursor(*m_memDC,m_HaveFocus,offset);
 
    // Now copy everything to the screen:
+#if 0
+   //FIXME:
+   //   1. the update region as calculated by the list is wrong
+   //   2. we get wrong values here
+   //   3. how about the offset? 
    wxRegionIterator ri ( GetUpdateRegion() );
    if(ri)
       while(ri)
       {
+         wxLogDebug("UpdateRegion: %ld,%ld, %ld,%ld",
+                    ri.GetX(),ri.GetY(),ri.GetW(),ri.GetH());
          dc.Blit(x0+ri.GetX(),y0+ri.GetY(),ri.GetW(),ri.GetH(),
                  m_memDC,ri.GetX(),ri.GetY(),wxCOPY,FALSE);
          ri++;
       }
    else
+#endif
       // If there are no update rectangles, we got called to reflect 
       // a change in the list. Currently there is no mechanism to
       // easily find out which bits need updating, so we update
@@ -408,6 +451,7 @@ wxLayoutWindow::InternalPaint(void)
       dc.Blit(x0,y0,x1,y1,m_memDC,0,0,wxCOPY,FALSE);
 
    ResetDirty();
+   m_ScrollToCursor = false;
 }
 
 // change the range and position of scroll bars
@@ -522,12 +566,12 @@ void
 wxLayoutWindow::OnSetFocus(wxFocusEvent &ev)
 {
    m_HaveFocus = true;
-   DoPaint(); // to repaint the cursor
+//FIXME   DoPaint(); // to repaint the cursor
 }
 
 void
 wxLayoutWindow::OnKillFocus(wxFocusEvent &ev)
 {
    m_HaveFocus = false;
-   DoPaint(); // to repaint the cursor
+//FIXME   DoPaint(); // to repaint the cursor
 }
index a5f7a7ee8d13ceac843d822580f8085e6f8f5952..98d0d61903362d126d2ca04dfeafeea4550486a9 100644 (file)
@@ -63,15 +63,20 @@ public:
               int style=wxNORMAL,
               int weight=wxNORMAL,
               int underline=0,
-              char const *fg="black",
-              char const *bg="white")
+              wxColour *fg=NULL,
+              wxColour *bg=NULL)
       {
          GetLayoutList()->Clear(family,size,style,weight,underline,fg,bg);
-         SetBackgroundColour(*GetLayoutList()->GetDefaults()->GetBGColour());
+         SetBackgroundColour(GetLayoutList()->GetDefaults()->GetBGColour());
          ResizeScrollbars(true);
          SetDirty();
          SetModified(false);
-         DoPaint();
+         wxRect r;
+         int w,h;
+         r.x = r.y = 0; GetSize(&w,&h);
+         r.width = w;
+         r.height = h;
+         DoPaint(&r);
       }
    /** Sets a background image, only used on screen, not on printouts.
        @param bitmap a pointer to a wxBitmap or NULL to remove it
@@ -100,10 +105,8 @@ public:
    /** Redraws the window.
        Internally, this stores the parameter and calls a refresh on
        wxMSW, draws directly on wxGTK.
-       @param scrollToCursor if true, scroll the window so that the
-       cursor becomes visible
    */
-   void DoPaint(bool scrollToCursor = false);
+   void DoPaint(const wxRect *updateRect);
 
 #ifdef __WXMSW__
    virtual long MSWGetDlgCode();
@@ -144,7 +147,7 @@ public:
    void ResetDirty(void) { m_Dirty = false; }
    //@}
    /// Redraws the window, used by DoPaint() or OnPaint().
-   void InternalPaint(void);
+   void InternalPaint(const wxRect *updateRect);
 
    /// Has list been modified/edited?
    bool IsModified(void) const { return m_Modified; }
@@ -180,6 +183,8 @@ private:
    wxLayoutList *m_llist;
    /// Can user edit the window?
    bool m_Editable;
+   /// Are we currently building a selection with the keyboard?
+   bool m_Selecting;
    /// wrap margin
    CoordType    m_WrapMargin;
    /// Is list dirty (for redraws, internal use)?