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