]> git.saurik.com Git - wxWidgets.git/blob - src/html/htmlcell.cpp
imagemap support (html)
[wxWidgets.git] / src / html / htmlcell.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: htmlcell.cpp
3 // Purpose: wxHtmlCell - basic element of HTML output
4 // Author: Vaclav Slavik
5 // Copyright: (c) 1999 Vaclav Slavik
6 // Licence: wxWindows Licence
7 /////////////////////////////////////////////////////////////////////////////
8
9
10 #ifdef __GNUG__
11 #pragma implementation
12 #endif
13
14 #include <wx/wxprec.h>
15
16 #include "wx/defs.h"
17 #if wxUSE_HTML
18
19 #ifdef __BORDLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WXPRECOMP
24 #include <wx/wx.h>
25 #endif
26
27 #include <wx/html/htmlcell.h>
28 #include <wx/html/htmlwin.h>
29 #include <stdlib.h>
30
31
32
33
34 //-----------------------------------------------------------------------------
35 // wxHtmlCell
36 //-----------------------------------------------------------------------------
37
38
39 void wxHtmlCell::OnMouseClick(wxWindow *parent, int x, int y, bool left, bool middle, bool right)
40 {
41 wxString lnk = GetLink(x, y);
42 if (lnk != wxEmptyString)
43 ((wxHtmlWindow*)parent) -> OnLinkClicked(lnk);
44 // note : this overcasting is legal because parent is *always* wxHtmlWindow
45 }
46
47
48
49 //-----------------------------------------------------------------------------
50 // wxHtmlWordCell
51 //-----------------------------------------------------------------------------
52
53 wxHtmlWordCell::wxHtmlWordCell(const wxString& word, wxDC& dc) : wxHtmlCell()
54 {
55 m_Word = word;
56 m_Word.Replace("&nbsp;", " ", TRUE);
57 m_Word.Replace("&quot;", "\"", TRUE);
58 m_Word.Replace("&lt;", "<", TRUE);
59 m_Word.Replace("&gt;", ">", TRUE);
60 m_Word.Replace("&amp;", "&", TRUE);
61 dc.GetTextExtent(m_Word, &m_Width, &m_Height, &m_Descent);
62 }
63
64
65
66 void wxHtmlWordCell::Draw(wxDC& dc, int x, int y, int view_y1, int view_y2)
67 {
68 dc.DrawText(m_Word, x + m_PosX, y + m_PosY);
69 wxHtmlCell::Draw(dc, x, y, view_y1, view_y2);
70 }
71
72
73
74
75
76
77
78 //-----------------------------------------------------------------------------
79 // wxHtmlContainerCell
80 //-----------------------------------------------------------------------------
81
82
83 wxHtmlContainerCell::wxHtmlContainerCell(wxHtmlContainerCell *parent) : wxHtmlCell()
84 {
85 m_Cells = m_LastCell = NULL;
86 m_Parent = parent;
87 if (m_Parent) m_Parent -> InsertCell(this);
88 m_AlignHor = HTML_ALIGN_LEFT;
89 m_AlignVer = HTML_ALIGN_BOTTOM;
90 m_IndentLeft = m_IndentRight = m_IndentTop = m_IndentBottom = 0;
91 m_WidthFloat = 100; m_WidthFloatUnits = HTML_UNITS_PERCENT;
92 m_UseBkColour = FALSE;
93 m_UseBorder = FALSE;
94 m_MinHeight = m_MaxLineWidth = 0;
95 m_MinHeightAlign = HTML_ALIGN_TOP;
96 }
97
98
99
100 void wxHtmlContainerCell::SetIndent(int i, int what, int units)
101 {
102 int val = (units == HTML_UNITS_PIXELS) ? i : -i;
103 if (what & HTML_INDENT_LEFT) m_IndentLeft = val;
104 if (what & HTML_INDENT_RIGHT) m_IndentRight = val;
105 if (what & HTML_INDENT_TOP) m_IndentTop = val;
106 if (what & HTML_INDENT_BOTTOM) m_IndentBottom = val;
107 }
108
109
110
111 int wxHtmlContainerCell::GetIndent(int ind) const
112 {
113 if (ind & HTML_INDENT_LEFT) return m_IndentLeft;
114 else if (ind & HTML_INDENT_RIGHT) return m_IndentRight;
115 else if (ind & HTML_INDENT_TOP) return m_IndentTop;
116 else if (ind & HTML_INDENT_BOTTOM) return m_IndentBottom;
117 else return -1; /* BUG! Should not be called... */
118 }
119
120
121
122
123 int wxHtmlContainerCell::GetIndentUnits(int ind) const
124 {
125 bool p = FALSE;
126 if (ind & HTML_INDENT_LEFT) p = m_IndentLeft < 0;
127 else if (ind & HTML_INDENT_RIGHT) p = m_IndentRight < 0;
128 else if (ind & HTML_INDENT_TOP) p = m_IndentTop < 0;
129 else if (ind & HTML_INDENT_BOTTOM) p = m_IndentBottom < 0;
130 if (p) return HTML_UNITS_PERCENT;
131 else return HTML_UNITS_PIXELS;
132 }
133
134
135
136 void wxHtmlContainerCell::Layout(int w)
137 {
138 wxHtmlCell *cell = m_Cells, *line = m_Cells;
139 long xpos = 0, ypos = m_IndentTop;
140 int xdelta = 0, ybasicpos = 0, ydiff;
141 int s_width, s_indent;
142 int ysizeup = 0, ysizedown = 0;
143
144 /*
145
146 WIDTH ADJUSTING :
147
148 */
149
150 if (m_WidthFloatUnits == HTML_UNITS_PERCENT) {
151 if (m_WidthFloat < 0) m_Width = (100 + m_WidthFloat) * w / 100;
152 else m_Width = m_WidthFloat * w / 100;
153 }
154 else {
155 if (m_WidthFloat < 0) m_Width = w + m_WidthFloat;
156 else m_Width = m_WidthFloat;
157 }
158
159 if (m_Cells) {
160 int l = (m_IndentLeft < 0) ? (-m_IndentLeft * m_Width / 100) : m_IndentLeft;
161 int r = (m_IndentRight < 0) ? (-m_IndentRight * m_Width / 100) : m_IndentRight;
162 m_Cells -> Layout(m_Width - (l + r));
163 }
164
165 /*
166
167 LAYOUTING :
168
169 */
170
171 // adjust indentation:
172 s_indent = (m_IndentLeft < 0) ? (-m_IndentLeft * m_Width / 100) : m_IndentLeft;
173 s_width = m_Width - s_indent - ((m_IndentRight < 0) ? (-m_IndentRight * m_Width / 100) : m_IndentRight);
174
175 m_MaxLineWidth = 0;
176
177 // my own layouting:
178 while (cell != NULL) {
179 switch (m_AlignVer) {
180 case HTML_ALIGN_TOP : ybasicpos = 0; break;
181 case HTML_ALIGN_BOTTOM : ybasicpos = - cell -> GetHeight(); break;
182 case HTML_ALIGN_CENTER : ybasicpos = - cell -> GetHeight() / 2; break;
183 }
184 ydiff = cell -> GetHeight() + ybasicpos;
185
186 if (cell -> GetDescent() + ydiff > ysizedown) ysizedown = cell -> GetDescent() + ydiff;
187 if (ybasicpos + cell -> GetDescent() < -ysizeup) ysizeup = - (ybasicpos + cell -> GetDescent());
188
189 cell -> SetPos(xpos, ybasicpos + cell -> GetDescent());
190 xpos += cell -> GetWidth();
191 cell = cell -> GetNext();
192
193 // force new line if occured:
194 if ((cell == NULL) || (xpos + cell -> GetWidth() > s_width)) {
195 if (xpos > m_MaxLineWidth) m_MaxLineWidth = xpos;
196 if (ysizeup < 0) ysizeup = 0;
197 if (ysizedown < 0) ysizedown = 0;
198 switch (m_AlignHor) {
199 case HTML_ALIGN_LEFT : xdelta = 0; break;
200 case HTML_ALIGN_RIGHT : xdelta = 0 + (s_width - xpos); break;
201 case HTML_ALIGN_CENTER : xdelta = 0 + (s_width - xpos) / 2; break;
202 }
203 if (xdelta < 0) xdelta = 0;
204 xdelta += s_indent;
205
206 ypos += ysizeup;
207 while (line != cell) {
208 line -> SetPos(line -> GetPosX() + xdelta, ypos + line -> GetPosY());
209 line = line -> GetNext();
210 }
211
212 ypos += ysizedown;
213 xpos = 0;
214 ysizeup = ysizedown = 0;
215 line = cell;
216 }
217 }
218
219 // setup height & width, depending on container layout:
220 m_Height = ypos + (ysizedown + ysizeup) + m_IndentBottom;
221
222 if (m_Height < m_MinHeight) {
223 if (m_MinHeightAlign != HTML_ALIGN_TOP) {
224 int diff = m_MinHeight - m_Height;
225 if (m_MinHeightAlign == HTML_ALIGN_CENTER) diff /= 2;
226 cell = m_Cells;
227 while (cell) {
228 cell -> SetPos(cell -> GetPosX(), cell -> GetPosY() + diff);
229 cell = cell -> GetNext();
230 }
231 }
232 m_Height = m_MinHeight;
233 }
234
235 m_MaxLineWidth += s_indent + ((m_IndentRight < 0) ? (-m_IndentRight * m_Width / 100) : m_IndentRight);
236 if (m_Width < m_MaxLineWidth) m_Width = m_MaxLineWidth;
237
238 wxHtmlCell::Layout(w);
239 }
240
241
242 #define mMin(a, b) (((a) < (b)) ? (a) : (b))
243 #define mMax(a, b) (((a) < (b)) ? (b) : (a))
244
245 void wxHtmlContainerCell::Draw(wxDC& dc, int x, int y, int view_y1, int view_y2)
246 {
247 // container visible, draw it:
248 if ((y + m_PosY < view_y2) && (y + m_PosY + m_Height > view_y1)) {
249
250 if (m_UseBkColour) {
251 wxBrush myb = wxBrush(m_BkColour, wxSOLID);
252
253 int real_y1 = mMax(y + m_PosY, view_y1);
254 int real_y2 = mMin(y + m_PosY + m_Height - 1, view_y2);
255
256 dc.SetBrush(myb);
257 dc.SetPen(*wxTRANSPARENT_PEN);
258 dc.DrawRectangle(x + m_PosX, real_y1, m_Width, real_y2 - real_y1 + 1);
259 }
260
261 if (m_UseBorder) {
262 wxPen mypen1(m_BorderColour1, 1, wxSOLID);
263 wxPen mypen2(m_BorderColour2, 1, wxSOLID);
264
265 dc.SetPen(mypen1);
266 dc.DrawLine(x + m_PosX, y + m_PosY, x + m_PosX, y + m_PosY + m_Height - 1);
267 dc.DrawLine(x + m_PosX, y + m_PosY, x + m_PosX + m_Width - 1, y + m_PosY);
268 dc.SetPen(mypen2);
269 dc.DrawLine(x + m_PosX + m_Width - 1, y + m_PosY, x + m_PosX + m_Width - 1, y + m_PosY + m_Height - 1);
270 dc.DrawLine(x + m_PosX, y + m_PosY + m_Height - 1, x + m_PosX + m_Width - 1, y + m_PosY + m_Height - 1);
271 }
272
273 if (m_Cells) m_Cells -> Draw(dc, x + m_PosX, y + m_PosY, view_y1, view_y2);
274 }
275 // container invisible, just proceed font+color changing:
276 else {
277 if (m_Cells) m_Cells -> DrawInvisible(dc, x + m_PosX, y + m_PosY);
278 }
279
280 wxHtmlCell::Draw(dc, x, y, view_y1, view_y2);
281 }
282
283
284
285 void wxHtmlContainerCell::DrawInvisible(wxDC& dc, int x, int y)
286 {
287 if (m_Cells) m_Cells -> DrawInvisible(dc, x + m_PosX, y + m_PosY);
288 wxHtmlCell::DrawInvisible(dc, x, y);
289 }
290
291
292
293 wxString wxHtmlContainerCell::GetLink(int x, int y) const
294 {
295 wxHtmlCell *c = m_Cells;
296 int cx, cy, cw, ch;
297
298 while (c) {
299 cx = c -> GetPosX(), cy = c -> GetPosY();
300 cw = c -> GetWidth(), ch = c -> GetHeight();
301 if ((x >= cx) && (x < cx + cw) && (y >= cy) && (y < cy + ch))
302 return c -> GetLink(x - cx, y - cy);
303 c = c -> GetNext();
304 }
305 return wxEmptyString;
306 }
307
308
309
310 void wxHtmlContainerCell::InsertCell(wxHtmlCell *f)
311 {
312 if (!m_Cells) m_Cells = m_LastCell = f;
313 else {
314 m_LastCell -> SetNext(f);
315 m_LastCell = f;
316 if (m_LastCell) while (m_LastCell -> GetNext()) m_LastCell = m_LastCell -> GetNext();
317 }
318 f -> SetParent(this);
319 }
320
321
322
323 void wxHtmlContainerCell::SetAlign(const wxHtmlTag& tag)
324 {
325 if (tag.HasParam("ALIGN")) {
326 wxString alg = tag.GetParam("ALIGN");
327 alg.MakeUpper();
328 if (alg == "CENTER")
329 SetAlignHor(HTML_ALIGN_CENTER);
330 else if (alg == "LEFT")
331 SetAlignHor(HTML_ALIGN_LEFT);
332 else if (alg == "RIGHT")
333 SetAlignHor(HTML_ALIGN_RIGHT);
334 }
335 }
336
337
338
339 void wxHtmlContainerCell::SetWidthFloat(const wxHtmlTag& tag)
340 {
341 if (tag.HasParam("WIDTH")) {
342 int wdi;
343 wxString wd = tag.GetParam("WIDTH");
344
345 if (wd[wd.Length()-1] == '%') {
346 sscanf(wd.c_str(), "%i%%", &wdi);
347 SetWidthFloat(wdi, HTML_UNITS_PERCENT);
348 }
349 else {
350 sscanf(wd.c_str(), "%i", &wdi);
351 SetWidthFloat(wdi, HTML_UNITS_PIXELS);
352 }
353 }
354 }
355
356
357
358 const wxHtmlCell* wxHtmlContainerCell::Find(int condition, const void* param) const
359 {
360 const wxHtmlCell *r = NULL;
361
362 if (m_Cells) {
363 r = m_Cells -> Find(condition, param);
364 if (r) return r;
365 }
366
367 return wxHtmlCell::Find(condition, param);
368 }
369
370
371
372 void wxHtmlContainerCell::OnMouseClick(wxWindow *parent, int x, int y, bool left, bool middle, bool right)
373 {
374 if (m_Cells) {
375 wxHtmlCell *c = m_Cells;
376 while (c) {
377 if ( (c -> GetPosX() <= x) &&
378 (c -> GetPosY() <= y) &&
379 (c -> GetPosX() + c -> GetWidth() > x) &&
380 (c -> GetPosY() + c -> GetHeight() > y)) {
381 c -> OnMouseClick(parent, x - c -> GetPosX(), y - c -> GetPosY(), left, middle, right);
382 break;
383 }
384 c = c -> GetNext();
385 }
386 }
387 }
388
389
390
391
392
393 //--------------------------------------------------------------------------------
394 // wxHtmlColourCell
395 //--------------------------------------------------------------------------------
396
397 void wxHtmlColourCell::Draw(wxDC& dc, int x, int y, int view_y1, int view_y2)
398 {
399 if (m_Flags & HTML_CLR_FOREGROUND)
400 dc.SetTextForeground(m_Colour);
401 if (m_Flags & HTML_CLR_BACKGROUND) {
402 dc.SetBackground(wxBrush(m_Colour, wxSOLID));
403 dc.SetTextBackground(m_Colour);
404 }
405 wxHtmlCell::Draw(dc, x, y, view_y1, view_y2);
406 }
407
408 void wxHtmlColourCell::DrawInvisible(wxDC& dc, int x, int y)
409 {
410 if (m_Flags & HTML_CLR_FOREGROUND)
411 dc.SetTextForeground(m_Colour);
412 if (m_Flags & HTML_CLR_BACKGROUND) {
413 dc.SetBackground(wxBrush(m_Colour, wxSOLID));
414 dc.SetTextBackground(m_Colour);
415 }
416 wxHtmlCell::DrawInvisible(dc, x, y);
417 }
418
419
420
421
422 //--------------------------------------------------------------------------------
423 // wxHtmlFontCell
424 //--------------------------------------------------------------------------------
425
426 void wxHtmlFontCell::Draw(wxDC& dc, int x, int y, int view_y1, int view_y2)
427 {
428 dc.SetFont(*m_Font);
429 wxHtmlCell::Draw(dc, x, y, view_y1, view_y2);
430 }
431
432 void wxHtmlFontCell::DrawInvisible(wxDC& dc, int x, int y)
433 {
434 dc.SetFont(*m_Font);
435 wxHtmlCell::DrawInvisible(dc, x, y);
436 }
437
438
439
440
441
442
443
444
445 //--------------------------------------------------------------------------------
446 // wxHtmlWidgetCell
447 //--------------------------------------------------------------------------------
448
449 wxHtmlWidgetCell::wxHtmlWidgetCell(wxWindow *wnd, int w)
450 {
451 int sx, sy;
452 m_Wnd = wnd;
453 m_Wnd -> GetSize(&sx, &sy);
454 m_Width = sx, m_Height = sy;
455 m_WidthFloat = w;
456 }
457
458
459 void wxHtmlWidgetCell::Draw(wxDC& dc, int x, int y, int view_y1, int view_y2)
460 {
461 int absx = 0, absy = 0, stx, sty;
462 wxHtmlCell *c = this;
463
464 while (c) {
465 absx += c -> GetPosX();
466 absy += c -> GetPosY();
467 c = c -> GetParent();
468 }
469
470 ((wxScrolledWindow*)(m_Wnd -> GetParent())) -> ViewStart(&stx, &sty);
471
472 m_Wnd -> SetSize(absx - HTML_SCROLL_STEP * stx, absy - HTML_SCROLL_STEP * sty, m_Width, m_Height);
473 // m_Wnd -> Refresh();
474
475 wxHtmlCell::Draw(dc, x, y, view_y1, view_y2);
476 }
477
478
479
480 void wxHtmlWidgetCell::DrawInvisible(wxDC& dc, int x, int y)
481 {
482 int absx = 0, absy = 0, stx, sty;
483 wxHtmlCell *c = this;
484
485 while (c) {
486 absx += c -> GetPosX();
487 absy += c -> GetPosY();
488 c = c -> GetParent();
489 }
490 ((wxScrolledWindow*)(m_Wnd -> GetParent())) -> ViewStart(&stx, &sty);
491
492 m_Wnd -> SetSize(absx - HTML_SCROLL_STEP * stx, absy - HTML_SCROLL_STEP * sty, m_Width, m_Height);
493 wxHtmlCell::DrawInvisible(dc, x, y);
494 }
495
496
497
498 void wxHtmlWidgetCell::Layout(int w)
499 {
500 if (m_WidthFloat != 0) {
501 m_Width = (w * m_WidthFloat) / 100;
502 m_Wnd -> SetSize(m_Width, m_Height);
503 }
504
505 wxHtmlCell::Layout(w);
506 }
507
508 #endif