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