]> git.saurik.com Git - wxWidgets.git/blame - src/generic/htmllbox.cpp
Added support for delayed deactivation of windows (for MDI)
[wxWidgets.git] / src / generic / htmllbox.cpp
CommitLineData
e0c6027b
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: generic/htmllbox.cpp
3// Purpose: implementation of wxHtmlListBox
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 31.05.03
7// RCS-ID: $Id$
8// Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
9// License: wxWindows license
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27#ifndef WX_PRECOMP
bb178b29 28 #include "wx/dcclient.h"
e0c6027b
VZ
29#endif //WX_PRECOMP
30
31#include "wx/htmllbox.h"
32
33#include "wx/html/htmlcell.h"
34#include "wx/html/winpars.h"
35
5ecdc7ab
VZ
36// this hack forces the linker to always link in m_* files
37#include "wx/html/forcelnk.h"
38FORCE_WXHTML_MODULES()
39
e0c6027b
VZ
40// ----------------------------------------------------------------------------
41// private classes
42// ----------------------------------------------------------------------------
43
44// this class is used by wxHtmlListBox to cache the parsed representation of
45// the items to avoid doing it anew each time an item must be drawn
e0c6027b
VZ
46class wxHtmlListBoxCache
47{
48public:
5ecdc7ab
VZ
49 wxHtmlListBoxCache()
50 {
51 for ( size_t n = 0; n < SIZE; n++ )
52 {
53 m_items[n] = (size_t)-1;
54 m_cells[n] = NULL;
55 }
e0c6027b 56
5ecdc7ab
VZ
57 m_next = 0;
58 }
e0c6027b 59
5ecdc7ab 60 ~wxHtmlListBoxCache()
e0c6027b 61 {
5ecdc7ab
VZ
62 for ( size_t n = 0; n < SIZE; n++ )
63 {
64 delete m_cells[n];
65 }
66 }
e0c6027b 67
5ecdc7ab
VZ
68 // completely invalidate the cache
69 void Clear()
70 {
71 for ( size_t n = 0; n < SIZE; n++ )
72 {
73 m_items[n] = (size_t)-1;
74 delete m_cells[n];
75 m_cells[n] = NULL;
76 }
e0c6027b
VZ
77 }
78
79 // return the cached cell for this index or NULL if none
5ecdc7ab
VZ
80 wxHtmlCell *Get(size_t item) const
81 {
82 for ( size_t n = 0; n < SIZE; n++ )
83 {
84 if ( m_items[n] == item )
85 return m_cells[n];
86 }
87
88 return NULL;
89 }
90
91 // returns true if we already have this item cached
92 bool Has(size_t item) const { return Get(item) != NULL; }
93
94 // ensure that the item is cached
95 void Store(size_t item, wxHtmlCell *cell)
e0c6027b 96 {
5ecdc7ab
VZ
97 delete m_cells[m_next];
98 m_cells[m_next] = cell;
99 m_items[m_next] = item;
100
101 // advance to the next item wrapping around if there are no more
102 if ( ++m_next == SIZE )
103 m_next = 0;
e0c6027b
VZ
104 }
105
106private:
5ecdc7ab
VZ
107 // the max number of the items we cache
108 enum { SIZE = 50 };
109
110 // the index of the LRU (oldest) cell
111 size_t m_next;
112
e0c6027b 113 // the parsed representation of the cached item or NULL
5ecdc7ab 114 wxHtmlCell *m_cells[SIZE];
e0c6027b 115
5ecdc7ab
VZ
116 // the index of the currently cached item (only valid if m_cells != NULL)
117 size_t m_items[SIZE];
e0c6027b
VZ
118};
119
5ecdc7ab
VZ
120// ----------------------------------------------------------------------------
121// event tables
122// ----------------------------------------------------------------------------
123
124BEGIN_EVENT_TABLE(wxHtmlListBox, wxVListBox)
125 EVT_SIZE(wxHtmlListBox::OnSize)
126END_EVENT_TABLE()
127
e0c6027b
VZ
128// ============================================================================
129// implementation
130// ============================================================================
131
132// ----------------------------------------------------------------------------
133// wxHtmlListBox creation
134// ----------------------------------------------------------------------------
135
136void wxHtmlListBox::Init()
137{
138 m_htmlParser = NULL;
139 m_cache = new wxHtmlListBoxCache;
140}
141
142bool wxHtmlListBox::Create(wxWindow *parent,
143 wxWindowID id,
144 const wxPoint& pos,
145 const wxSize& size,
e0c6027b
VZ
146 long style,
147 const wxString& name)
148{
43e319a3 149 return wxVListBox::Create(parent, id, pos, size, style, name);
e0c6027b
VZ
150}
151
152wxHtmlListBox::~wxHtmlListBox()
153{
154 delete m_cache;
155 if ( m_htmlParser )
156 {
157 delete m_htmlParser->GetDC();
158 delete m_htmlParser;
159 }
160}
161
162// ----------------------------------------------------------------------------
163// wxHtmlListBox items markup
164// ----------------------------------------------------------------------------
165
166wxString wxHtmlListBox::OnGetItemMarkup(size_t n) const
167{
168 // we don't even need to wrap the value returned by OnGetItem() inside
169 // "<html><body>" and "</body></html>" because wxHTML can parse it even
170 // without these tags
171 return OnGetItem(n);
172}
173
5ecdc7ab
VZ
174// ----------------------------------------------------------------------------
175// wxHtmlListBox cache handling
176// ----------------------------------------------------------------------------
177
e0c6027b
VZ
178void wxHtmlListBox::CacheItem(size_t n) const
179{
180 if ( !m_cache->Has(n) )
181 {
182 if ( !m_htmlParser )
183 {
184 wxHtmlListBox *self = wxConstCast(this, wxHtmlListBox);
185
186 self->m_htmlParser = new wxHtmlWinParser;
187 m_htmlParser->SetDC(new wxClientDC(self));
188 }
189
190 wxHtmlContainerCell *cell = (wxHtmlContainerCell *)m_htmlParser->
191 Parse(OnGetItemMarkup(n));
192 wxCHECK_RET( cell, _T("wxHtmlParser::Parse() returned NULL?") );
193
5ecdc7ab 194 cell->Layout(GetClientSize().x - 2*GetMargins().x);
e0c6027b
VZ
195
196 m_cache->Store(n, cell);
197 }
198}
199
5ecdc7ab
VZ
200void wxHtmlListBox::OnSize(wxSizeEvent& event)
201{
202 // we need to relayout all the cached cells
203 m_cache->Clear();
204
205 event.Skip();
206}
207
208void wxHtmlListBox::RefreshAll()
209{
210 m_cache->Clear();
211
212 wxVListBox::RefreshAll();
213}
214
e0c6027b
VZ
215// ----------------------------------------------------------------------------
216// wxHtmlListBox implementation of wxVListBox pure virtuals
217// ----------------------------------------------------------------------------
218
219void wxHtmlListBox::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const
220{
221 CacheItem(n);
222
223 wxHtmlCell *cell = m_cache->Get(n);
224 wxCHECK_RET( cell, _T("this cell should be cached!") );
225
901b583c 226 wxHtmlRenderingInfo htmlRendInfo;
5ecdc7ab 227
e0c6027b
VZ
228 // draw the selected cell in selected state
229 if ( IsSelected(n) )
230 {
231 wxHtmlSelection htmlSel;
232 htmlSel.Set(wxPoint(0, 0), cell, wxPoint(INT_MAX, INT_MAX), cell);
901b583c
VZ
233 htmlRendInfo.SetSelection(&htmlSel);
234 //htmlRendInfo.SetSelectionState(wxHTML_SEL_IN);
e0c6027b 235 }
5ecdc7ab
VZ
236
237 // note that we can't stop drawing exactly at the window boundary as then
238 // even the visible cells part could be not drawn, so always draw the
239 // entire cell
901b583c 240 cell->Draw(dc, rect.x, rect.y, 0, INT_MAX, htmlRendInfo);
e0c6027b
VZ
241}
242
243wxCoord wxHtmlListBox::OnMeasureItem(size_t n) const
244{
245 CacheItem(n);
246
247 wxHtmlCell *cell = m_cache->Get(n);
248 wxCHECK_MSG( cell, 0, _T("this cell should be cached!") );
249
250 return cell->GetHeight() + cell->GetDescent();
251}
252