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