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