From dd59841c337611841bf6e9317f2730d48163b08c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Karsten=20Ball=C3=BCder?= Date: Mon, 29 Mar 1999 09:56:44 +0000 Subject: [PATCH] Merged in latest wxLayout code from Mahogany Mail. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1995 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- user/wxLayout/wxllist.cpp | 79 +++++++++++++++++++-------- user/wxLayout/wxllist.h | 14 ++++- user/wxLayout/wxlparser.cpp | 106 ++++++++++++++++++------------------ user/wxLayout/wxlparser.h | 21 ++++--- user/wxLayout/wxlwindow.cpp | 77 +++++++++++++++++++++----- user/wxLayout/wxlwindow.h | 25 +++++++-- 6 files changed, 217 insertions(+), 105 deletions(-) diff --git a/user/wxLayout/wxllist.cpp b/user/wxLayout/wxllist.cpp index 5357810c50..3e783aa27d 100644 --- a/user/wxLayout/wxllist.cpp +++ b/user/wxLayout/wxllist.cpp @@ -6,10 +6,6 @@ * $Id$ *******************************************************************/ -/* - - */ - #ifdef __GNUG__ #pragma implementation "wxllist.h" #endif @@ -59,19 +55,35 @@ /// 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; diff --git a/user/wxLayout/wxllist.h b/user/wxLayout/wxllist.h index 03f979732e..dc9a23ff71 100644 --- a/user/wxLayout/wxllist.h +++ b/user/wxLayout/wxllist.h @@ -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. diff --git a/user/wxLayout/wxlparser.cpp b/user/wxLayout/wxlparser.cpp index 08c2c61fb2..e078883b7c 100644 --- a/user/wxLayout/wxlparser.cpp +++ b/user/wxLayout/wxlparser.cpp @@ -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 += "
"; + 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 += "
"; - 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; diff --git a/user/wxLayout/wxlparser.h b/user/wxLayout/wxlparser.h index 2a65688cb0..2ccb5eeba8 100644 --- a/user/wxLayout/wxlparser.h +++ b/user/wxLayout/wxlparser.h @@ -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 diff --git a/user/wxLayout/wxlwindow.cpp b/user/wxLayout/wxlwindow.cpp index 90cf075e50..03d1a6bd09 100644 --- a/user/wxLayout/wxlwindow.cpp +++ b/user/wxLayout/wxlwindow.cpp @@ -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 @@ -26,16 +28,24 @@ # undef GetCharWidth # undef StartDoc # endif + # include "wxlwindow.h" # include "wxlparser.h" #endif -#include #include +#include + +#include +/// 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); diff --git a/user/wxLayout/wxlwindow.h b/user/wxLayout/wxlwindow.h index 22df9e617b..a5f7a7ee8d 100644 --- a/user/wxLayout/wxlwindow.h +++ b/user/wxLayout/wxlwindow.h @@ -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() }; -- 2.45.2