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