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