From 5ecdc7ab6d10222bcf88610198771b5f3aee10a7 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 2 Jun 2003 23:02:12 +0000 Subject: [PATCH] refresh cache on size/margins change; expanded cache to contain N elements, not just one git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@20873 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/htmllbox.h | 11 ++++ src/generic/htmllbox.cpp | 125 ++++++++++++++++++++++++++++++--------- 2 files changed, 107 insertions(+), 29 deletions(-) diff --git a/include/wx/htmllbox.h b/include/wx/htmllbox.h index c3764c399d..1b77758faf 100644 --- a/include/wx/htmllbox.h +++ b/include/wx/htmllbox.h @@ -62,6 +62,10 @@ public: // destructor cleans up whatever resources we use virtual ~wxHtmlListBox(); + // refresh everything + virtual void RefreshAll(); + + protected: // this method must be implemented in the derived class and should return // the body (i.e. without ) of the HTML for the given item @@ -77,6 +81,10 @@ protected: virtual wxCoord OnMeasureItem(size_t n) const; + // event handlers + void OnSize(wxSizeEvent& event); + + // common part of all ctors void Init(); @@ -88,6 +96,9 @@ private: // HTML parser we use wxHtmlWinParser *m_htmlParser; + + + DECLARE_EVENT_TABLE() }; #endif // _WX_HTMLLBOX_H_ diff --git a/src/generic/htmllbox.cpp b/src/generic/htmllbox.cpp index 876181f218..d3b96e0353 100644 --- a/src/generic/htmllbox.cpp +++ b/src/generic/htmllbox.cpp @@ -33,48 +33,98 @@ #include "wx/html/htmlcell.h" #include "wx/html/winpars.h" +// this hack forces the linker to always link in m_* files +#include "wx/html/forcelnk.h" +FORCE_WXHTML_MODULES() + // ---------------------------------------------------------------------------- // private classes // ---------------------------------------------------------------------------- // this class is used by wxHtmlListBox to cache the parsed representation of // the items to avoid doing it anew each time an item must be drawn -// -// TODO: extend the class to cache more than item class wxHtmlListBoxCache { public: - wxHtmlListBoxCache() { m_cell = NULL; } - ~wxHtmlListBoxCache() { delete m_cell; } + wxHtmlListBoxCache() + { + for ( size_t n = 0; n < SIZE; n++ ) + { + m_items[n] = (size_t)-1; + m_cells[n] = NULL; + } - // returns true if we already have this item cached - bool Has(size_t n) const { return m_cell && n == m_item; } + m_next = 0; + } - // ensure that the item is cached - void Store(size_t n, wxHtmlCell *cell) + ~wxHtmlListBoxCache() { - m_item = n; + for ( size_t n = 0; n < SIZE; n++ ) + { + delete m_cells[n]; + } + } - delete m_cell; - m_cell = cell; + // completely invalidate the cache + void Clear() + { + for ( size_t n = 0; n < SIZE; n++ ) + { + m_items[n] = (size_t)-1; + delete m_cells[n]; + m_cells[n] = NULL; + } } // return the cached cell for this index or NULL if none - wxHtmlCell *Get(size_t n) const + wxHtmlCell *Get(size_t item) const + { + for ( size_t n = 0; n < SIZE; n++ ) + { + if ( m_items[n] == item ) + return m_cells[n]; + } + + return NULL; + } + + // returns true if we already have this item cached + bool Has(size_t item) const { return Get(item) != NULL; } + + // ensure that the item is cached + void Store(size_t item, wxHtmlCell *cell) { - // we could be reading uninitialized m_item here but the code is still - // correct - return n == m_item ? m_cell : NULL; + delete m_cells[m_next]; + m_cells[m_next] = cell; + m_items[m_next] = item; + + // advance to the next item wrapping around if there are no more + if ( ++m_next == SIZE ) + m_next = 0; } private: + // the max number of the items we cache + enum { SIZE = 50 }; + + // the index of the LRU (oldest) cell + size_t m_next; + // the parsed representation of the cached item or NULL - wxHtmlCell *m_cell; + wxHtmlCell *m_cells[SIZE]; - // the index of the currently cached item (only valid if m_cell != NULL) - size_t m_item; + // the index of the currently cached item (only valid if m_cells != NULL) + size_t m_items[SIZE]; }; +// ---------------------------------------------------------------------------- +// event tables +// ---------------------------------------------------------------------------- + +BEGIN_EVENT_TABLE(wxHtmlListBox, wxVListBox) + EVT_SIZE(wxHtmlListBox::OnSize) +END_EVENT_TABLE() + // ============================================================================ // implementation // ============================================================================ @@ -122,6 +172,10 @@ wxString wxHtmlListBox::OnGetItemMarkup(size_t n) const return OnGetItem(n); } +// ---------------------------------------------------------------------------- +// wxHtmlListBox cache handling +// ---------------------------------------------------------------------------- + void wxHtmlListBox::CacheItem(size_t n) const { if ( !m_cache->Has(n) ) @@ -138,12 +192,27 @@ void wxHtmlListBox::CacheItem(size_t n) const Parse(OnGetItemMarkup(n)); wxCHECK_RET( cell, _T("wxHtmlParser::Parse() returned NULL?") ); - cell->Layout(GetClientSize().x); + cell->Layout(GetClientSize().x - 2*GetMargins().x); m_cache->Store(n, cell); } } +void wxHtmlListBox::OnSize(wxSizeEvent& event) +{ + // we need to relayout all the cached cells + m_cache->Clear(); + + event.Skip(); +} + +void wxHtmlListBox::RefreshAll() +{ + m_cache->Clear(); + + wxVListBox::RefreshAll(); +} + // ---------------------------------------------------------------------------- // wxHtmlListBox implementation of wxVListBox pure virtuals // ---------------------------------------------------------------------------- @@ -155,23 +224,21 @@ void wxHtmlListBox::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const wxHtmlCell *cell = m_cache->Get(n); wxCHECK_RET( cell, _T("this cell should be cached!") ); + wxHtmlRenderingState htmlRendState; + // draw the selected cell in selected state if ( IsSelected(n) ) { wxHtmlSelection htmlSel; htmlSel.Set(wxPoint(0, 0), cell, wxPoint(INT_MAX, INT_MAX), cell); - wxHtmlRenderingState htmlRendState(&htmlSel); + htmlRendState.SetSelection(&htmlSel); htmlRendState.SetSelectionState(wxHTML_SEL_IN); - cell->Draw(dc, rect.x, rect.y, 0, INT_MAX, htmlRendState); - } - else - { - // note that we can't stop drawing exactly at the window boundary as then - // even the visible cells part could be not drawn, so always draw the - // entire cell - wxHtmlRenderingState htmlRendState(NULL); - cell->Draw(dc, rect.x, rect.y, 0, INT_MAX, htmlRendState); } + + // note that we can't stop drawing exactly at the window boundary as then + // even the visible cells part could be not drawn, so always draw the + // entire cell + cell->Draw(dc, rect.x, rect.y, 0, INT_MAX, htmlRendState); } wxCoord wxHtmlListBox::OnMeasureItem(size_t n) const -- 2.45.2