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