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