]>
git.saurik.com Git - wxWidgets.git/blob - src/html/m_list.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/html/m_list.cpp
3 // Purpose: wxHtml module for lists
4 // Author: Vaclav Slavik
5 // Copyright: (c) 1999 Vaclav Slavik
6 // Licence: wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
15 #if wxUSE_HTML && wxUSE_STREAMS
22 #include "wx/html/forcelnk.h"
23 #include "wx/html/m_templ.h"
25 #include "wx/html/htmlcell.h"
30 //-----------------------------------------------------------------------------
32 //-----------------------------------------------------------------------------
34 class wxHtmlListmarkCell
: public wxHtmlCell
39 wxHtmlListmarkCell(wxDC
*dc
, const wxColour
& clr
);
40 void Draw(wxDC
& dc
, int x
, int y
, int view_y1
, int view_y2
,
41 wxHtmlRenderingInfo
& info
);
43 wxDECLARE_NO_COPY_CLASS(wxHtmlListmarkCell
);
46 wxHtmlListmarkCell::wxHtmlListmarkCell(wxDC
* dc
, const wxColour
& clr
) : wxHtmlCell(), m_Brush(clr
, wxBRUSHSTYLE_SOLID
)
48 m_Width
= dc
->GetCharHeight();
49 m_Height
= dc
->GetCharHeight();
50 // bottom of list mark is lined with bottom of letters in next cell
51 m_Descent
= m_Height
/ 3;
56 void wxHtmlListmarkCell::Draw(wxDC
& dc
, int x
, int y
,
57 int WXUNUSED(view_y1
), int WXUNUSED(view_y2
),
58 wxHtmlRenderingInfo
& WXUNUSED(info
))
61 dc
.DrawEllipse(x
+ m_PosX
+ m_Width
/ 3, y
+ m_PosY
+ m_Height
/ 3,
62 (m_Width
/ 3), (m_Width
/ 3));
65 //-----------------------------------------------------------------------------
67 //-----------------------------------------------------------------------------
69 struct wxHtmlListItemStruct
71 wxHtmlContainerCell
*mark
;
72 wxHtmlContainerCell
*cont
;
77 class wxHtmlListCell
: public wxHtmlContainerCell
83 wxHtmlListItemStruct
*m_RowInfo
;
84 void ReallocRows(int rows
);
85 void ComputeMinMaxWidths();
86 int ComputeMaxBase(wxHtmlCell
*cell
);
90 wxHtmlListCell(wxHtmlContainerCell
*parent
);
91 virtual ~wxHtmlListCell();
92 void AddRow(wxHtmlContainerCell
*mark
, wxHtmlContainerCell
*cont
);
93 virtual void Layout(int w
);
95 wxDECLARE_NO_COPY_CLASS(wxHtmlListCell
);
98 wxHtmlListCell::wxHtmlListCell(wxHtmlContainerCell
*parent
) : wxHtmlContainerCell(parent
)
105 wxHtmlListCell::~wxHtmlListCell()
107 if (m_RowInfo
) free(m_RowInfo
);
110 int wxHtmlListCell::ComputeMaxBase(wxHtmlCell
*cell
)
115 wxHtmlCell
*child
= cell
->GetFirstChild();
119 int base
= ComputeMaxBase( child
);
120 if ( base
> 0 ) return base
+ child
->GetPosY();
121 child
= child
->GetNext();
124 return cell
->GetHeight() - cell
->GetDescent();
127 void wxHtmlListCell::Layout(int w
)
129 wxHtmlCell::Layout(w
);
131 ComputeMinMaxWidths();
132 m_Width
= wxMax(m_Width
, wxMin(w
, GetMaxTotalWidth()));
134 int s_width
= m_Width
- m_IndentLeft
;
137 for (int r
= 0; r
< m_NumRows
; r
++)
139 // do layout first time to layout contents and adjust pos
140 m_RowInfo
[r
].mark
->Layout(m_ListmarkWidth
);
141 m_RowInfo
[r
].cont
->Layout(s_width
- m_ListmarkWidth
);
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);
148 m_RowInfo
[r
].mark
->SetPos(m_IndentLeft
, adjust_mark
);
149 m_RowInfo
[r
].cont
->SetPos(m_IndentLeft
+ m_ListmarkWidth
, adjust_cont
);
151 vpos
= wxMax(adjust_mark
+ m_RowInfo
[r
].mark
->GetHeight(),
152 adjust_cont
+ m_RowInfo
[r
].cont
->GetHeight());
157 void wxHtmlListCell::AddRow(wxHtmlContainerCell
*mark
, wxHtmlContainerCell
*cont
)
159 ReallocRows(++m_NumRows
);
160 m_RowInfo
[m_NumRows
- 1].mark
= mark
;
161 m_RowInfo
[m_NumRows
- 1].cont
= cont
;
164 void wxHtmlListCell::ReallocRows(int rows
)
166 m_RowInfo
= (wxHtmlListItemStruct
*) realloc(m_RowInfo
, sizeof(wxHtmlListItemStruct
) * rows
);
167 m_RowInfo
[rows
- 1].mark
= NULL
;
168 m_RowInfo
[rows
- 1].cont
= NULL
;
169 m_RowInfo
[rows
- 1].minWidth
= 0;
170 m_RowInfo
[rows
- 1].maxWidth
= 0;
175 void wxHtmlListCell::ComputeMinMaxWidths()
177 if (m_NumRows
== 0) return;
182 for (int r
= 0; r
< m_NumRows
; r
++)
184 wxHtmlListItemStruct
& row
= m_RowInfo
[r
];
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
;
196 m_Width
+= m_ListmarkWidth
+ m_IndentLeft
;
197 m_MaxTotalWidth
+= m_ListmarkWidth
+ m_IndentLeft
;
200 //-----------------------------------------------------------------------------
201 // wxHtmlListcontentCell
202 //-----------------------------------------------------------------------------
204 class wxHtmlListcontentCell
: public wxHtmlContainerCell
207 wxHtmlListcontentCell(wxHtmlContainerCell
*p
) : wxHtmlContainerCell(p
) {}
208 virtual void Layout(int w
) {
209 // Reset top indentation, fixes <li><p>
210 SetIndent(0, wxHTML_INDENT_TOP
);
211 wxHtmlContainerCell::Layout(w
);
215 //-----------------------------------------------------------------------------
217 //-----------------------------------------------------------------------------
220 TAG_HANDLER_BEGIN(OLULLI
, "OL,UL,LI")
223 wxHtmlListCell
*m_List
;
225 // this is number of actual item of list or 0 for dots
227 TAG_HANDLER_CONSTR(OLULLI
)
233 TAG_HANDLER_PROC(tag
)
235 wxHtmlContainerCell
*c
;
238 if (m_List
&& tag
.GetName() == wxT("LI"))
240 c
= m_WParser
->SetContainer(new wxHtmlContainerCell(m_List
));
241 c
->SetAlignVer(wxHTML_ALIGN_TOP
);
243 wxHtmlContainerCell
*mark
= c
;
244 c
->SetWidthFloat(2 * m_WParser
->GetCharWidth(), wxHTML_UNITS_PIXELS
);
245 if (m_Numbering
== 0)
247 // Centering gives more space after the bullet
248 c
->SetAlignHor(wxHTML_ALIGN_CENTER
);
249 c
->InsertCell(new wxHtmlListmarkCell(m_WParser
->GetDC(), m_WParser
->GetActualColor()));
253 c
->SetAlignHor(wxHTML_ALIGN_RIGHT
);
255 markStr
.Printf(wxT("%i. "), m_Numbering
);
256 c
->InsertCell(new wxHtmlWordCell(markStr
, *(m_WParser
->GetDC())));
258 m_WParser
->CloseContainer();
260 c
= m_WParser
->OpenContainer();
262 m_List
->AddRow(mark
, c
);
263 c
= m_WParser
->OpenContainer();
264 m_WParser
->SetContainer(new wxHtmlListcontentCell(c
));
266 if (m_Numbering
!= 0) m_Numbering
++;
269 // Begin of List (not-numbered): "UL", "OL"
270 else if (tag
.GetName() == wxT("UL") || tag
.GetName() == wxT("OL"))
272 int oldnum
= m_Numbering
;
274 if (tag
.GetName() == wxT("UL")) m_Numbering
= 0;
275 else m_Numbering
= 1;
277 wxHtmlContainerCell
*oldcont
;
278 oldcont
= c
= m_WParser
->OpenContainer();
280 wxHtmlListCell
*oldList
= m_List
;
281 m_List
= new wxHtmlListCell(c
);
282 m_List
->SetIndent(2 * m_WParser
->GetCharWidth(), wxHTML_INDENT_LEFT
);
286 m_WParser
->SetContainer(oldcont
);
287 m_WParser
->CloseContainer();
289 m_Numbering
= oldnum
;
297 TAG_HANDLER_END(OLULLI
)
300 TAGS_MODULE_BEGIN(List
)
302 TAGS_MODULE_ADD(OLULLI
)
304 TAGS_MODULE_END(List
)