compilation fixes for !USE_PCH
[wxWidgets.git] / src / generic / htmllbox.cpp
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
28 #include "wx/dcclient.h"
29 #endif //WX_PRECOMP
30
31 #include "wx/htmllbox.h"
32
33 #include "wx/html/htmlcell.h"
34 #include "wx/html/winpars.h"
35
36 // ----------------------------------------------------------------------------
37 // private classes
38 // ----------------------------------------------------------------------------
39
40 // this class is used by wxHtmlListBox to cache the parsed representation of
41 // the items to avoid doing it anew each time an item must be drawn
42 //
43 // TODO: extend the class to cache more than item
44 class wxHtmlListBoxCache
45 {
46 public:
47 wxHtmlListBoxCache() { m_cell = NULL; }
48 ~wxHtmlListBoxCache() { delete m_cell; }
49
50 // returns true if we already have this item cached
51 bool Has(size_t n) const { return m_cell && n == m_item; }
52
53 // ensure that the item is cached
54 void Store(size_t n, wxHtmlCell *cell)
55 {
56 m_item = n;
57
58 delete m_cell;
59 m_cell = cell;
60 }
61
62 // return the cached cell for this index or NULL if none
63 wxHtmlCell *Get(size_t n) const
64 {
65 // we could be reading uninitialized m_item here but the code is still
66 // correct
67 return n == m_item ? m_cell : NULL;
68 }
69
70 private:
71 // the parsed representation of the cached item or NULL
72 wxHtmlCell *m_cell;
73
74 // the index of the currently cached item (only valid if m_cell != NULL)
75 size_t m_item;
76 };
77
78 // ============================================================================
79 // implementation
80 // ============================================================================
81
82 // ----------------------------------------------------------------------------
83 // wxHtmlListBox creation
84 // ----------------------------------------------------------------------------
85
86 void wxHtmlListBox::Init()
87 {
88 m_htmlParser = NULL;
89 m_cache = new wxHtmlListBoxCache;
90 }
91
92 bool wxHtmlListBox::Create(wxWindow *parent,
93 wxWindowID id,
94 const wxPoint& pos,
95 const wxSize& size,
96 size_t countItems,
97 long style,
98 const wxString& name)
99 {
100 return wxVListBox::Create(parent, id, pos, size, countItems, style, name);
101 }
102
103 wxHtmlListBox::~wxHtmlListBox()
104 {
105 delete m_cache;
106 if ( m_htmlParser )
107 {
108 delete m_htmlParser->GetDC();
109 delete m_htmlParser;
110 }
111 }
112
113 // ----------------------------------------------------------------------------
114 // wxHtmlListBox items markup
115 // ----------------------------------------------------------------------------
116
117 wxString wxHtmlListBox::OnGetItemMarkup(size_t n) const
118 {
119 // we don't even need to wrap the value returned by OnGetItem() inside
120 // "<html><body>" and "</body></html>" because wxHTML can parse it even
121 // without these tags
122 return OnGetItem(n);
123 }
124
125 void wxHtmlListBox::CacheItem(size_t n) const
126 {
127 if ( !m_cache->Has(n) )
128 {
129 if ( !m_htmlParser )
130 {
131 wxHtmlListBox *self = wxConstCast(this, wxHtmlListBox);
132
133 self->m_htmlParser = new wxHtmlWinParser;
134 m_htmlParser->SetDC(new wxClientDC(self));
135 }
136
137 wxHtmlContainerCell *cell = (wxHtmlContainerCell *)m_htmlParser->
138 Parse(OnGetItemMarkup(n));
139 wxCHECK_RET( cell, _T("wxHtmlParser::Parse() returned NULL?") );
140
141 cell->Layout(GetClientSize().x);
142
143 m_cache->Store(n, cell);
144 }
145 }
146
147 // ----------------------------------------------------------------------------
148 // wxHtmlListBox implementation of wxVListBox pure virtuals
149 // ----------------------------------------------------------------------------
150
151 void wxHtmlListBox::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const
152 {
153 CacheItem(n);
154
155 wxHtmlCell *cell = m_cache->Get(n);
156 wxCHECK_RET( cell, _T("this cell should be cached!") );
157
158 // draw the selected cell in selected state
159 if ( IsSelected(n) )
160 {
161 wxHtmlSelection htmlSel;
162 htmlSel.Set(wxPoint(0, 0), cell, wxPoint(INT_MAX, INT_MAX), cell);
163 wxHtmlRenderingState htmlRendState(&htmlSel);
164 htmlRendState.SetSelectionState(wxHTML_SEL_IN);
165 cell->Draw(dc, rect.x, rect.y, 0, INT_MAX, htmlRendState);
166 }
167 else
168 {
169 // note that we can't stop drawing exactly at the window boundary as then
170 // even the visible cells part could be not drawn, so always draw the
171 // entire cell
172 wxHtmlRenderingState htmlRendState(NULL);
173 cell->Draw(dc, rect.x, rect.y, 0, INT_MAX, htmlRendState);
174 }
175 }
176
177 wxCoord wxHtmlListBox::OnMeasureItem(size_t n) const
178 {
179 CacheItem(n);
180
181 wxHtmlCell *cell = m_cache->Get(n);
182 wxCHECK_MSG( cell, 0, _T("this cell should be cached!") );
183
184 return cell->GetHeight() + cell->GetDescent();
185 }
186