]> git.saurik.com Git - wxWidgets.git/commitdiff
Merged in latest wxLayout code from Mahogany Mail.
authorKarsten Ballüder <ballueder@usa.net>
Mon, 29 Mar 1999 09:56:44 +0000 (09:56 +0000)
committerKarsten Ballüder <ballueder@usa.net>
Mon, 29 Mar 1999 09:56:44 +0000 (09:56 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1995 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

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

index 5357810c50b822d588a8099b01e3bc7e958ad392..3e783aa27d41e7669f9869901a4b948c44118fbd 100644 (file)
@@ -6,10 +6,6 @@
  * $Id$
  *******************************************************************/
 
-/*
-  
- */
 #ifdef __GNUG__
 #pragma implementation "wxllist.h"
 #endif
 
 /// Use this character to estimate a cursor size when none is available.
 #define WXLO_CURSORCHAR   "E"
-
-/// Helper function, allows me to compare to wxPoints
+/** @name Helper functions */
+//@{
+/// allows me to compare to wxPoints
 bool operator ==(wxPoint const &p1, wxPoint const &p2)
 {
    return p1.x == p2.x && p1.y == p2.y;
 }
 
-/// Helper function, allows me to compare to wxPoints
+/// allows me to compare to wxPoints
 bool operator !=(wxPoint const &p1, wxPoint const &p2)
 {
    return p1.x != p2.x || p1.y != p2.y;
 }
 
+/// grows a wxRect so that it includes the given point
+
+static void GrowRect(wxRect &r, const wxPoint & p)
+{
+   if(r.x > p.x)
+      r.x = p.x;
+   else if(r.x + r.width < p.x)
+      r.width = p.x - r.x;
+   
+   if(r.y > p.y)
+      r.y = p.y;
+   else if(r.y + r.height < p.y)
+      r.height = p.y - r.y;
+}
+//@}
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
 
@@ -367,7 +379,7 @@ wxLayoutObjectList::iterator
 wxLayoutLine::FindObjectScreen(wxDC &dc, CoordType xpos, CoordType *cxpos) const
 {
    wxASSERT(cxpos);
-   wxASSERT(xpos);
+   wxASSERT(cxpos);
    wxLayoutObjectList::iterator i;
    CoordType x = 0, cx = 0, width;
    
@@ -698,6 +710,7 @@ wxLayoutLine::Layout(wxDC &dc, wxPoint *cursorPos,
    if(m_Next && objHeight != oldHeight)
       m_Next->RecalculatePositions();
 
+   // We need to check whether we found a valid cursor size:
    if(cursorPos)
    {
       // this might be the case if the cursor is at the end of the
@@ -814,7 +827,7 @@ wxLayoutLine::GetWrapPosition(CoordType column)
       {
          do
          {
-            if( isspace(((wxLayoutObjectText*)*i)->GetText()[offset]))
+            if( isspace(((wxLayoutObjectText*)*i)->GetText()[(size_t)offset]))
                return column;
             else
             {
@@ -867,6 +880,7 @@ wxLayoutList::wxLayoutList()
 {
    m_DefaultSetting = NULL;
    m_FirstLine = NULL;
+   InvalidateUpdateRect();
    Clear();
 }
 
@@ -1228,10 +1242,14 @@ wxLayoutList::Layout(wxDC &dc, CoordType bottom) const
       if(bottom != -1 && line->GetPosition().y > bottom) break;
       line = line->GetNextLine();
    }
+
+///FIXME: disabled for now
+#if 0
    // can only be 0 if we are on the first line and have no next line
    wxASSERT(m_CursorSize.x != 0 || (m_CursorLine &&
                                     m_CursorLine->GetNextLine() == NULL &&
                                     m_CursorLine == m_FirstLine));
+#endif
 }
 
 void
@@ -1242,13 +1260,17 @@ wxLayoutList::Draw(wxDC &dc, wxPoint const &offset,
 
    Layout(dc, bottom);
    m_DefaultSetting->Draw(dc, wxPoint(0,0));
+   wxBrush *brush = new wxBrush(*m_ColourBG, wxSOLID);
+   dc.SetBrush(*brush);
+   delete brush;
+   
    while(line)
    {
       // only draw if between top and bottom:
       if((top == -1 || line->GetPosition().y >= top))
          line->Draw(dc, offset);
       // little condition to speed up redrawing:
-      if(bottom != -1 && line->GetPosition().y > bottom) break;
+      if(bottom != -1 && line->GetPosition().y + line->GetHeight() > bottom) break;
       line = line->GetNextLine();
    }
    // can only be 0 if we are on the first line and have no next line
@@ -1291,18 +1313,19 @@ wxLayoutList::GetSize(void) const
    if(! line)
       return wxPoint(0,0);
 
-   wxPoint max(0,0);
+   wxPoint maxPoint(0,0);
    
    // find last line:
    while(line)
    {
-      if(line->GetWidth() > max.x) max.x = line->GetWidth();
+      if(line->GetWidth() > maxPoint.x)
+          maxPoint.x = line->GetWidth();
       last = line;
       line = line->GetNextLine();
    }
 
-   max.y = last->GetPosition().y + last->GetHeight();
-   return max;
+   maxPoint.y = last->GetPosition().y + last->GetHeight();
+   return maxPoint;
 }
 
 void
@@ -1325,7 +1348,6 @@ wxLayoutList::DrawCursor(wxDC &dc, bool active, wxPoint const &translate)
    dc.SetBrush(*wxBLACK_BRUSH);
    dc.SetLogicalFunction(wxXOR);
    dc.SetPen(wxPen(*wxBLACK,1,wxSOLID));
-   dc.SetLogicalFunction(wxXOR);
    if(active)
       dc.DrawRectangle(coords.x, coords.y, m_CursorSize.x,
                        m_CursorSize.y);
@@ -1333,9 +1355,26 @@ wxLayoutList::DrawCursor(wxDC &dc, bool active, wxPoint const &translate)
       dc.DrawLine(coords.x, coords.y+m_CursorSize.y-1,
                   coords.x+m_CursorSize.x, coords.y+m_CursorSize.y-1);
    dc.SetLogicalFunction(wxCOPY);
-   dc.SetBrush(wxNullBrush);
+   //dc.SetBrush(wxNullBrush);
 }
 
+/** Called by the objects to update the update rectangle.
+    @param p a point to include in it
+*/
+void
+wxLayoutList::SetUpdateRect(const wxPoint &p)
+{
+   if(m_UpdateRectValid)
+      GrowRect(m_UpdateRect, p);
+   else
+   {
+      m_UpdateRect.x = p.x;
+      m_UpdateRect.y = p.y;
+      m_UpdateRect.width = 4; // large enough to avoid surprises from
+      m_UpdateRect.height = 4;// wxGTK :-)
+      m_UpdateRectValid = true;
+   }
+}
 
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
@@ -1445,13 +1484,9 @@ void wxLayoutPrintout::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom,
    m_PrintoutHeight = (int)( m_PrintoutHeight / scale); // we want to use the real paper height
    
    
-   m_NumOfPages = (int)( m_llist->GetSize().y / (float)(m_PrintoutHeight) + 0.5);
+   m_NumOfPages = 1 +
+      (int)( m_llist->GetSize().y / (float)(m_PrintoutHeight));
 
-   // This is a crude hack to get it right for very small
-   // printouts. No idea why this is required, I thought +0.5 would do 
-   // the job. :-(
-   if(m_NumOfPages == 0 && m_llist->GetSize().y > 0)
-      m_NumOfPages = 1;
    *minPage = 1;
    *maxPage = m_NumOfPages;
 
index 03f979732e0a9cc024bf415f97c96ca88aad1ee0..dc9a23ff71f9fcc04aab7702d8c3baa701c4c08b 100644 (file)
@@ -160,7 +160,7 @@ public:
    /** Makes a copy of this object.
     */
    virtual wxLayoutObject *Copy(void) = 0;
-private:
+protected:
    /// optional data for application's use
    UserData *m_UserData;
 };
@@ -762,6 +762,14 @@ public:
                                      wxPoint const pos,
                                      wxPoint *cursorPos = NULL);
 
+   /** Called by the objects to update the update rectangle.
+       @param p a point to include in it
+   */
+   void SetUpdateRect(const wxPoint &p);
+   /// Invalidates the update rectangle.
+   void InvalidateUpdateRect(void) { m_UpdateRectValid = false; }
+   /// Returns the update rectangle.
+   const wxRect *GetUpdateRect(void) const { return &m_UpdateRect; }
    //@}
 
    /**@name For exporting one object after another. */
@@ -779,6 +787,10 @@ private:
    
    /// The list of lines.
    wxLayoutLine *m_FirstLine;
+   /// The update rectangle which needs to be refreshed:
+   wxRect  m_UpdateRect;
+   /// Is the update rectangle valid?
+   bool    m_UpdateRectValid;
    /**@name Cursor Management */
    //@{
    /// Where the text cursor (column,line) is.
index 08c2c61fb20283a055bdb9da09b7f9f6cf8074f3..e078883b7cb3afc62974b5c5e45a7b6bd3180f6d 100644 (file)
@@ -26,7 +26,7 @@ inline static bool IsEndOfLine(const char *p, int mode)
    // in addition to Unix EOL convention we also (but not instead) understand
    // the DOS one under Windows
    return
-      ((mode & WXLO_EXPORT_WITH_MASK) == WXLO_EXPORT_WITH_CRLF) ?
+      (mode == WXLO_EXPORT_WITH_CRLF) ?
       ((*p == '\r') && (*(p + 1) == '\n')) 
       :
       (((*p == '\r') && (*(p + 1) == '\n'))||(*p == '\n'));
@@ -149,65 +149,82 @@ wxString wxLayoutExportCmdAsHTML(wxLayoutObjectCmd const & cmd,
 #define   WXLO_IS_TEXT(type) \
 ( type == WXLO_TYPE_TEXT \
   || (type == WXLO_TYPE_CMD \
-      && (mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_HTML))
+      && mode == WXLO_EXPORT_AS_HTML))
 
 
   
 wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status,
-                                     int mode)
+                                     int mode, int flags)
 {
    wxASSERT(status);
    wxLayoutExportObject * export;
    
    if(status->m_iterator == NULLIT) // end of line
    {
-      if(!status->m_line || status->m_line->GetNextLine() == NULL) // reached end of list
+      if(!status->m_line || status->m_line->GetNextLine() == NULL)
+         // reached end of list
          return NULL;
-      else
+   }
+   export = new wxLayoutExportObject();
+   wxLayoutObjectType type;
+   if(status->m_iterator != NULLIT)
+   {
+      type = (** status->m_iterator).GetType();
+      if( mode == WXLO_EXPORT_AS_OBJECTS || ! WXLO_IS_TEXT(type)) // simple case
       {
-         status->m_line = status->m_line->GetNextLine();
-         status->m_iterator = status->m_line->GetFirstObject();
-         export = new wxLayoutExportObject();;
-      if( (mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_OBJECTS) // simple case
-         {
-            export->type = WXLO_EXPORT_OBJECT;
-            export->content.object = *status->m_iterator;
-            status->m_iterator++;
-            return export;
-         }
-         //else: text object:
-         export->type = ((mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_HTML)
-            ?  WXLO_EXPORT_HTML : WXLO_EXPORT_TEXT;
-         if((mode & WXLO_EXPORT_WITH_CRLF) == WXLO_EXPORT_WITH_CRLF)
-            export->content.text = new wxString("\r\n");
-         else
-            export->content.text = new wxString("\n");
+         export->type = WXLO_EXPORT_OBJECT;
+         export->content.object = *status->m_iterator;
+         status->m_iterator++;
          return export;
       }
    }
-   
-   export = new wxLayoutExportObject();
-   wxLayoutObjectType   type = (** status->m_iterator).GetType();
-   if( (mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_OBJECTS || ! WXLO_IS_TEXT(type)) // simple case
-   {
-      export->type = WXLO_EXPORT_OBJECT;
-      export->content.object = *status->m_iterator;
-      status->m_iterator++;
-      return export;
+   else
+   {  // iterator == NULLIT
+      if(mode == WXLO_EXPORT_AS_OBJECTS)
+      {
+         export->type = WXLO_EXPORT_EMPTYLINE;
+         export->content.object = NULL; //empty line
+         status->m_line = status->m_line->GetNextLine();
+         if(status->m_line)
+            status->m_iterator = status->m_line->GetFirstObject();
+         return export;
+      }
+      else
+         type = WXLO_TYPE_TEXT;
    }
 
-   // else: must be text
    wxString *str = new wxString();
    // text must be concatenated
-   do
+   int testf = WXLO_EXPORT_WITH_CRLF;
+   for(;;)
    {
+      while(status->m_iterator == NULLIT)
+      {
+         if(flags & WXLO_EXPORT_AS_HTML)
+            *str += "<br>";
+         if(flags & WXLO_EXPORT_WITH_CRLF)
+            *str += "\r\n";
+         else
+            *str += '\n';
+
+         status->m_line = status->m_line->GetNextLine();
+         if(status->m_line)
+            status->m_iterator = status->m_line->GetFirstObject();
+         else
+            break; // end of list
+      }
+      if(! status->m_line)  // reached end of list, fall through
+         break; 
+      type = (** status->m_iterator).GetType();
+      if(type == WXLO_TYPE_ICON)
+         break;
       switch(type)
       {
       case WXLO_TYPE_TEXT:
          *str += ((wxLayoutObjectText *)*status->m_iterator)->GetText();
          break;
       case WXLO_TYPE_CMD:
-         wxASSERT_MSG( (mode&WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_HTML,
+         wxASSERT_MSG( mode == WXLO_EXPORT_AS_HTML,
                        "reached cmd object in text mode" );
          
          *str += wxLayoutExportCmdAsHTML(*(wxLayoutObjectCmd const
@@ -217,28 +234,9 @@ wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status,
          ;
       }
       status->m_iterator++;
-      if(status->m_iterator == NULLIT) // end of line!
-      {
-         if((mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_HTML)
-            *str += "<br>";
-         if((mode & WXLO_EXPORT_WITH_CRLF) == WXLO_EXPORT_WITH_CRLF)
-            *str += "\r\n";
-         else
-            *str += '\n';
-         status->m_line = status->m_line->GetNextLine();
-         if(status->m_line)
-            status->m_iterator = status->m_line->GetFirstObject();
-         else
-            status->m_iterator = NULLIT;
-      }
-      if(status->m_iterator != NULLIT)
-         type = (** status->m_iterator).GetType();
-      else
-         break;
    }
-   while(WXLO_IS_TEXT(type));
 
-   export->type = ((mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_HTML)
+   export->type = (mode == WXLO_EXPORT_AS_HTML)
       ?  WXLO_EXPORT_HTML : WXLO_EXPORT_TEXT;
    export->content.text = str;
    return export;
index 2a65688cb02b076e7913b732035711f86ce6d21d..2ccb5eeba8d7915b1e251b1b96ecba5a76c710e3 100644 (file)
@@ -20,20 +20,21 @@ enum wxLayoutExportType
 {
    WXLO_EXPORT_TEXT,        
    WXLO_EXPORT_HTML,        
-   WXLO_EXPORT_OBJECT
+   WXLO_EXPORT_OBJECT,
+   // this can be caused by empty lines:
+   WXLO_EXPORT_EMPTYLINE
 };
 
 enum wxLayoutExportMode
 {
-   WXLO_EXPORT_AS_MASK = 0x0f,
    WXLO_EXPORT_AS_TEXT = 0x00,
    WXLO_EXPORT_AS_TEXT_AND_COMMANDS = 0x01,
    WXLO_EXPORT_AS_HTML = 0x02,
    WXLO_EXPORT_AS_OBJECTS = 0x03,
-   
-   WXLO_EXPORT_WITH_MASK = 0xf0,
-   WXLO_EXPORT_WITH_CRLF = 0x00,
-   WXLO_EXPORT_WITH_LF_ONLY = 0x10
+
+   // non 0:
+   WXLO_EXPORT_WITH_CRLF = 0x10,
+   WXLO_EXPORT_WITH_LF_ONLY = 0x20
 };
 
 struct wxLayoutExportObject
@@ -72,15 +73,17 @@ void wxLayoutImportText(wxLayoutList *list, wxString const &str,
                         int withflag = WXLO_EXPORT_WITH_CRLF);
 
 wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status,
-                               int mode = WXLO_EXPORT_AS_TEXT|WXLO_EXPORT_WITH_CRLF); 
+                                     int mode = WXLO_EXPORT_AS_TEXT,
+                                     int flags = WXLO_EXPORT_WITH_CRLF); 
 #else
 /// import text into a wxLayoutList (including linefeeds):
 void wxLayoutImportText(wxLayoutList *list, wxString const &str,
                         int withflag = WXLO_EXPORT_WITH_LF_ONLY);
 
-/// export text in a given format FIXME-MT: not thread safe, uses static variable
+/// export text in a given format
 wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status,
-                                     int mode = WXLO_EXPORT_AS_TEXT|WXLO_EXPORT_WITH_LF_ONLY
+                                     int mode = WXLO_EXPORT_AS_TEXT,
+                                     int flags = WXLO_EXPORT_WITH_LF_ONLY
                                      );
 #endif
 
index 90cf075e50aed4e07bb9669e2055214238a8137b..03d1a6bd09bdbc77f095ed9b5e6f769a7e598cee 100644 (file)
@@ -18,7 +18,9 @@
 #     include "gui/wxMenuDefs.h"
 #     include "gui/wxMApp.h"
 #   endif // USE_PCH
+
 #   include "gui/wxlwindow.h"
+#   include "gui/wxlparser.h"
 #else
 #   ifdef   __WXMSW__
 #       include <windows.h>
 #       undef GetCharWidth
 #       undef StartDoc
 #   endif
+
 #   include "wxlwindow.h"
 #   include "wxlparser.h"
 #endif
 
-#include <ctype.h>
 #include <wx/clipbrd.h>
+#include <wx/dataobj.h>
+
+#include <ctype.h>
 
+/// offsets to put a nice frame around text
 #define WXLO_XOFFSET   4
 #define WXLO_YOFFSET   4
 
+/// offset to the right and bottom for when to redraw scrollbars
+#define   WXLO_ROFFSET   20
+#define   WXLO_BOFFSET   20
+
 BEGIN_EVENT_TABLE(wxLayoutWindow,wxScrolledWindow)
    EVT_PAINT    (wxLayoutWindow::OnPaint)
    EVT_CHAR     (wxLayoutWindow::OnChar)
@@ -61,6 +71,7 @@ wxLayoutWindow::wxLayoutWindow(wxWindow *parent)
    m_bitmap = new wxBitmap(4,4);
    m_bitmapSize = wxPoint(4,4);
    m_llist = new wxLayoutList();
+   m_BGbitmap = NULL;
    SetWrapMargin(0);
    wxPoint max = m_llist->GetSize();
    SetScrollbars(10, 20 /*lineHeight*/, max.x/10+1, max.y/20+1);
@@ -75,7 +86,8 @@ wxLayoutWindow::~wxLayoutWindow()
    delete m_memDC; // deletes bitmap automatically (?)
    delete m_bitmap;
    delete m_llist;
-   delete m_PopupMenu; 
+   delete m_PopupMenu;
+   SetBackgroundBitmap(NULL);
 }
 
 #ifdef __WXMSW__
@@ -93,6 +105,7 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
    wxPaintDC dc( this );
    PrepareDC( dc );     
    SetFocus();
+
    
    wxPoint findPos;
    findPos.x = dc.DeviceToLogicalX(event.GetX());
@@ -103,13 +116,13 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
 
    if(findPos.x < 0) findPos.x = 0;
    if(findPos.y < 0) findPos.y = 0;
-   
+
+   m_ClickPosition = wxPoint(event.GetX(), event.GetY());
 #ifdef WXLAYOUT_DEBUG
    wxLogDebug("wxLayoutWindow::OnMouse: (%d, %d) -> (%d, %d)",
               event.GetX(), event.GetY(), findPos.x, findPos.y);
 #endif
 
-   m_ClickPosition = findPos;
    wxPoint cursorPos;
    wxLayoutObject *obj = m_llist->FindObjectScreen(dc, findPos, &cursorPos);
 
@@ -136,7 +149,7 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
       && (! obj || (obj && obj->GetUserData() == NULL))
       )
    {
-      PopupMenu(m_PopupMenu, event.GetX(), event.GetY());
+      PopupMenu(m_PopupMenu, m_ClickPosition.x, m_ClickPosition.y);
       return;
    }
    // find the object at this position
@@ -261,6 +274,7 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
       }
    }
    SetDirty();
+   SetModified();
    DoPaint(true); // paint and scroll to cursor
 }
 
@@ -278,7 +292,7 @@ wxLayoutWindow::DoPaint(bool scrollToCursor)
 #ifdef __WXGTK__
    InternalPaint();
 #else
-   Refresh();
+   Refresh(FALSE); // Causes bad flicker under wxGTK!!!
 #endif
 }
 
@@ -298,8 +312,11 @@ wxLayoutWindow::InternalPaint(void)
    // Get the size of the visible window:
    GetClientSize(&x1,&y1);
    wxASSERT(x1 > 0);
-
    wxASSERT(y1 > 0);
+   // As we have the values anyway, use them to avoid unnecessary
+   // scrollbar updates.
+   if(x1 > m_maxx) m_maxx = x1;  
+   if(y1 > m_maxy) m_maxy = y1;
 
    // Maybe we need to change the scrollbar sizes or positions,
    // so layout the list and check:
@@ -344,17 +361,46 @@ wxLayoutWindow::InternalPaint(void)
    // Device origins on the memDC are suspect, we translate manually
    // with the translate parameter of Draw().
    m_memDC->SetDeviceOrigin(0,0);
-   m_memDC->Clear();
+   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->SetLogicalFunction(wxCOPY);
+   if(m_BGbitmap)
+   {
+      CoordType
+         y, x,
+         w = m_BGbitmap->GetWidth(),
+         h = m_BGbitmap->GetHeight();
+      for(y = 0; y < y1; y+=h)
+         for(x = 0; x < x1; x+=w)
+            m_memDC->DrawBitmap(*m_BGbitmap, x, y);
+   }
+   else
+      m_memDC->DrawRectangle(0,0,x1, y1);
 
    // The offsets give the window a tiny border on the left and top, looks nice.
    wxPoint offset(-x0+WXLO_XOFFSET,-y0+WXLO_YOFFSET);
    m_llist->Draw(*m_memDC,offset);
    if(IsEditable())
       m_llist->DrawCursor(*m_memDC,m_HaveFocus,offset);
+
    // Now copy everything to the screen:
-   dc.Blit(x0,y0,x1,y1,m_memDC,0,0,wxCOPY,FALSE);
+   wxRegionIterator ri ( GetUpdateRegion() );
+   if(ri)
+      while(ri)
+      {
+         dc.Blit(x0+ri.GetX(),y0+ri.GetY(),ri.GetW(),ri.GetH(),
+                 m_memDC,ri.GetX(),ri.GetY(),wxCOPY,FALSE);
+         ri++;
+      }
+   else
+      // 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
+      // all. The wxLayoutList could handle this, creating a list or
+      // at least one large rectangle of changes. FIXME
+      dc.Blit(x0,y0,x1,y1,m_memDC,0,0,wxCOPY,FALSE);
 
-   
    ResetDirty();
 }
 
@@ -363,15 +409,16 @@ void
 wxLayoutWindow::ResizeScrollbars(bool exact)
 {
    wxPoint max = m_llist->GetSize();
-
+   
    if(max.x > m_maxx || max.y > m_maxy
-      || max.x < (7*m_maxx)/10 || max.y << (7*m_maxy)/10
+      || max.x > m_maxx-WXLO_ROFFSET || max.y > m_maxy-WXLO_BOFFSET
       || exact)
    {
-      if(! exact)  // add an extra 20% to the sizes to avoid future updates
+      if(! exact) 
       {
-         max.x = (12*max.x)/10;  // 12/20 = 120%
-         max.y = (12*max.y)/10;
+         // add an extra bit to the sizes to avoid future updates
+         max.x = max.x+WXLO_ROFFSET;  
+         max.y = max.y+WXLO_BOFFSET;
       }
       ViewStart(&m_ViewStartX, &m_ViewStartY);
       SetScrollbars(10, 20, max.x/10+1,max.y/20+1,m_ViewStartX,m_ViewStartY,true);
index 22df9e617bfabfa81d2e97f856b19aeea0453bc5..a5f7a7ee8d13ceac843d822580f8085e6f8f5952 100644 (file)
@@ -68,10 +68,19 @@ public:
       {
          GetLayoutList()->Clear(family,size,style,weight,underline,fg,bg);
          SetBackgroundColour(*GetLayoutList()->GetDefaults()->GetBGColour());
+         ResizeScrollbars(true);
          SetDirty();
+         SetModified(false);
          DoPaint();
       }
-
+   /** Sets a background image, only used on screen, not on printouts.
+       @param bitmap a pointer to a wxBitmap or NULL to remove it
+   */
+   void SetBackgroundBitmap(wxBitmap *bitmap = NULL)
+      {
+         if(m_BGbitmap) delete m_BGbitmap;
+         m_BGbitmap = bitmap;
+      }
    /// Enable or disable editing, i.e. processing of keystrokes.
    void SetEditable(bool toggle) { m_Editable = toggle; }
    /// Query whether list can be edited by user.
@@ -136,6 +145,12 @@ public:
    //@}
    /// Redraws the window, used by DoPaint() or OnPaint().
    void InternalPaint(void);
+
+   /// Has list been modified/edited?
+   bool IsModified(void) const { return m_Modified; }
+   /// Mark list as modified or unchanged.
+   void SetModified(bool modified = true) { m_Modified = modified; }
+
 protected:   
    /// generic function for mouse events processing
    void OnMouse(int eventId, wxMouseEvent& event);
@@ -163,17 +178,19 @@ protected:
 private:
    /// The layout list to be displayed.
    wxLayoutList *m_llist;
-
    /// Can user edit the window?
    bool m_Editable;
    /// wrap margin
    CoordType    m_WrapMargin;
-   /// Is list dirty?
+   /// Is list dirty (for redraws, internal use)?
    bool         m_Dirty;
+   /// Has list been edited?
+   bool         m_Modified;
    wxMemoryDC  *m_memDC;
    wxBitmap    *m_bitmap;
    wxPoint      m_bitmapSize;
-
+   /// a pointer to a bitmap for the background
+   wxBitmap    *m_BGbitmap;
    DECLARE_EVENT_TABLE()
 };