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