Changed the way invisble HTML cells are NOT
[wxWidgets.git] / src / html / m_list.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: m_list.cpp
3 // Purpose: wxHtml module for lists
4 // Author: Vaclav Slavik
5 // RCS-ID: $Id$
6 // Copyright: (c) 1999 Vaclav Slavik
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
10 #pragma implementation
11 #endif
12
13 #include "wx/wxprec.h"
14
15
16 #include "wx/defs.h"
17 #if wxUSE_HTML && wxUSE_STREAMS
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WXPRECOMP
24 #include "wx/brush.h"
25 #include "wx/dc.h"
26 #endif
27
28 #include "wx/html/forcelnk.h"
29 #include "wx/html/m_templ.h"
30
31 #include "wx/html/htmlcell.h"
32
33 FORCE_LINK_ME(m_list)
34
35
36 //-----------------------------------------------------------------------------
37 // wxHtmlListmarkCell
38 //-----------------------------------------------------------------------------
39
40 class wxHtmlListmarkCell : public wxHtmlCell
41 {
42 private:
43 wxBrush m_Brush;
44 public:
45 wxHtmlListmarkCell(wxDC *dc, const wxColour& clr);
46 void Draw(wxDC& dc, int x, int y, int view_y1, int view_y2,
47 wxHtmlRenderingInfo& info);
48
49 DECLARE_NO_COPY_CLASS(wxHtmlListmarkCell)
50 };
51
52 wxHtmlListmarkCell::wxHtmlListmarkCell(wxDC* dc, const wxColour& clr) : wxHtmlCell(), m_Brush(clr, wxSOLID)
53 {
54 m_Width = dc->GetCharHeight();
55 m_Height = dc->GetCharHeight();
56 m_Descent = 0;
57 }
58
59
60
61 void wxHtmlListmarkCell::Draw(wxDC& dc, int x, int y,
62 int WXUNUSED(view_y1), int view_y2,
63 wxHtmlRenderingInfo& WXUNUSED(info))
64 {
65 if (y+m_PosY+m_Height > view_y2) return;
66
67 dc.SetBrush(m_Brush);
68 dc.DrawEllipse(x + m_PosX + m_Width / 3, y + m_PosY + m_Height / 3,
69 (m_Width / 3), (m_Width / 3));
70 }
71
72 //-----------------------------------------------------------------------------
73 // wxHtmlListCell
74 //-----------------------------------------------------------------------------
75
76 struct wxHtmlListItemStruct
77 {
78 wxHtmlContainerCell *mark;
79 wxHtmlContainerCell *cont;
80 int minWidth;
81 int maxWidth;
82 };
83
84 class wxHtmlListCell : public wxHtmlContainerCell
85 {
86 private:
87 wxBrush m_Brush;
88
89 int m_NumRows;
90 wxHtmlListItemStruct *m_RowInfo;
91 void ReallocRows(int rows);
92 void ComputeMinMaxWidths();
93 int m_ListmarkWidth;
94
95 public:
96 wxHtmlListCell(wxHtmlContainerCell *parent);
97 virtual ~wxHtmlListCell();
98 void AddRow(wxHtmlContainerCell *mark, wxHtmlContainerCell *cont);
99 virtual void Layout(int w);
100
101 DECLARE_NO_COPY_CLASS(wxHtmlListCell)
102 };
103
104 wxHtmlListCell::wxHtmlListCell(wxHtmlContainerCell *parent) : wxHtmlContainerCell(parent)
105 {
106 m_NumRows = 0;
107 m_RowInfo = 0;
108 m_ListmarkWidth = 0;
109 }
110
111 wxHtmlListCell::~wxHtmlListCell()
112 {
113 if (m_RowInfo) free(m_RowInfo);
114 }
115
116 void wxHtmlListCell::Layout(int w)
117 {
118 wxHtmlCell::Layout(w);
119
120 ComputeMinMaxWidths();
121 m_Width = wxMax(m_Width, wxMin(w, GetMaxTotalWidth()));
122
123 int s_width = m_Width - m_IndentLeft;
124
125 int vpos = 0;
126 for (int r = 0; r < m_NumRows; r++)
127 {
128 m_RowInfo[r].mark->Layout(m_ListmarkWidth);
129 m_RowInfo[r].mark->SetPos(m_IndentLeft, vpos);
130 m_RowInfo[r].cont->Layout(s_width - m_ListmarkWidth);
131 m_RowInfo[r].cont->SetPos(m_IndentLeft + m_ListmarkWidth, vpos);
132 vpos += wxMax(m_RowInfo[r].cont->GetHeight(), m_RowInfo[r].mark->GetHeight());
133 }
134 m_Height = vpos;
135 }
136
137 void wxHtmlListCell::AddRow(wxHtmlContainerCell *mark, wxHtmlContainerCell *cont)
138 {
139 ReallocRows(++m_NumRows);
140 m_RowInfo[m_NumRows - 1].mark = mark;
141 m_RowInfo[m_NumRows - 1].cont = cont;
142 }
143
144 void wxHtmlListCell::ReallocRows(int rows)
145 {
146 m_RowInfo = (wxHtmlListItemStruct*) realloc(m_RowInfo, sizeof(wxHtmlListItemStruct) * rows);
147 m_RowInfo[rows - 1].mark = 0;
148 m_RowInfo[rows - 1].cont = 0;
149 m_RowInfo[rows - 1].minWidth = 0;
150 m_RowInfo[rows - 1].maxWidth = 0;
151
152 m_NumRows = rows;
153 }
154
155 void wxHtmlListCell::ComputeMinMaxWidths()
156 {
157 if (m_NumRows == 0) return;
158
159 m_MaxTotalWidth = 0;
160 m_Width = 0;
161
162 for (int r = 0; r < m_NumRows; r++)
163 {
164 wxHtmlListItemStruct& row = m_RowInfo[r];
165 row.mark->Layout(1);
166 row.cont->Layout(1);
167 int maxWidth = row.cont->GetMaxTotalWidth();
168 int width = row.cont->GetWidth();
169 if (row.mark->GetWidth() > m_ListmarkWidth)
170 m_ListmarkWidth = row.mark->GetWidth();
171 if (maxWidth > m_MaxTotalWidth)
172 m_MaxTotalWidth = maxWidth;
173 if (width > m_Width)
174 m_Width = width;
175 }
176 m_Width += m_ListmarkWidth + m_IndentLeft;
177 m_MaxTotalWidth += m_ListmarkWidth + m_IndentLeft;
178 }
179
180 //-----------------------------------------------------------------------------
181 // wxHtmlListcontentCell
182 //-----------------------------------------------------------------------------
183
184 class wxHtmlListcontentCell : public wxHtmlContainerCell
185 {
186 public:
187 wxHtmlListcontentCell(wxHtmlContainerCell *p) : wxHtmlContainerCell(p) {}
188 virtual void Layout(int w) {
189 // Reset top indentation, fixes <li><p>
190 SetIndent(0, wxHTML_INDENT_TOP);
191 wxHtmlContainerCell::Layout(w);
192 }
193 };
194
195 //-----------------------------------------------------------------------------
196 // The list handler:
197 //-----------------------------------------------------------------------------
198
199
200 TAG_HANDLER_BEGIN(OLULLI, "OL,UL,LI")
201
202 TAG_HANDLER_VARS
203 wxHtmlListCell *m_List;
204 int m_Numbering;
205 // this is number of actual item of list or 0 for dots
206
207 TAG_HANDLER_CONSTR(OLULLI)
208 {
209 m_List = NULL;
210 m_Numbering = 0;
211 }
212
213 TAG_HANDLER_PROC(tag)
214 {
215 wxHtmlContainerCell *c;
216
217 // List Item:
218 if (m_List && tag.GetName() == wxT("LI"))
219 {
220 c = m_WParser->SetContainer(new wxHtmlContainerCell(m_List));
221 c->SetAlignVer(wxHTML_ALIGN_TOP);
222
223 wxHtmlContainerCell *mark = c;
224 c->SetWidthFloat(2 * m_WParser->GetCharWidth(), wxHTML_UNITS_PIXELS);
225 if (m_Numbering == 0)
226 {
227 // Centering gives more space after the bullet
228 c->SetAlignHor(wxHTML_ALIGN_CENTER);
229 c->InsertCell(new wxHtmlListmarkCell(m_WParser->GetDC(), m_WParser->GetActualColor()));
230 }
231 else
232 {
233 c->SetAlignHor(wxHTML_ALIGN_RIGHT);
234 wxString mark;
235 mark.Printf(wxT("%i."), m_Numbering);
236 c->InsertCell(new wxHtmlWordCell(mark, *(m_WParser->GetDC())));
237 }
238 m_WParser->CloseContainer();
239
240 c = m_WParser->OpenContainer();
241
242 m_List->AddRow(mark, c);
243 c = m_WParser->OpenContainer();
244 m_WParser->SetContainer(new wxHtmlListcontentCell(c));
245
246 if (m_Numbering != 0) m_Numbering++;
247 }
248
249 // Begin of List (not-numbered): "UL", "OL"
250 else if (tag.GetName() == wxT("UL") || tag.GetName() == wxT("OL"))
251 {
252 int oldnum = m_Numbering;
253
254 if (tag.GetName() == wxT("UL")) m_Numbering = 0;
255 else m_Numbering = 1;
256
257 wxHtmlContainerCell *oldcont;
258 oldcont = c = m_WParser->OpenContainer();
259
260 wxHtmlListCell *oldList = m_List;
261 m_List = new wxHtmlListCell(c);
262 m_List->SetIndent(2 * m_WParser->GetCharWidth(), wxHTML_INDENT_LEFT);
263
264 ParseInner(tag);
265
266 m_WParser->SetContainer(oldcont);
267 m_WParser->CloseContainer();
268
269 m_Numbering = oldnum;
270 m_List = oldList;
271 return true;
272 }
273 return false;
274
275 }
276
277 TAG_HANDLER_END(OLULLI)
278
279
280 TAGS_MODULE_BEGIN(List)
281
282 TAGS_MODULE_ADD(OLULLI)
283
284 TAGS_MODULE_END(List)
285
286 #endif