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