]> git.saurik.com Git - wxWidgets.git/blame - src/html/htmlcell.cpp
wxHW_* flags, fixed client area problem
[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
5// Copyright: (c) 1999 Vaclav Slavik
6// Licence: wxWindows Licence
7/////////////////////////////////////////////////////////////////////////////
8
5526e819 9#ifdef __GNUG__
4dcaf11a 10#pragma implementation "htmlcell.h"
5526e819
VS
11#endif
12
4dcaf11a 13#include "wx/wxprec.h"
5526e819 14
5526e819
VS
15#if wxUSE_HTML
16
17#ifdef __BORDLANDC__
18#pragma hdrstop
19#endif
20
21#ifndef WXPRECOMP
4dcaf11a 22#include "wx/wx.h"
5526e819
VS
23#endif
24
4dcaf11a
RR
25#include "wx/html/htmlcell.h"
26#include "wx/html/htmlwin.h"
5526e819
VS
27#include <stdlib.h>
28
29
5526e819
VS
30//-----------------------------------------------------------------------------
31// wxHtmlCell
32//-----------------------------------------------------------------------------
33
34
35void wxHtmlCell::OnMouseClick(wxWindow *parent, int x, int y, bool left, bool middle, bool right)
36{
25082126
VS
37 wxString lnk = GetLink(x, y);
38 if (lnk != wxEmptyString)
39 ((wxHtmlWindow*)parent) -> OnLinkClicked(lnk);
5526e819
VS
40 // note : this overcasting is legal because parent is *always* wxHtmlWindow
41}
42
43
44
45//-----------------------------------------------------------------------------
46// wxHtmlWordCell
47//-----------------------------------------------------------------------------
48
49wxHtmlWordCell::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
62void 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
5526e819
VS
70//-----------------------------------------------------------------------------
71// wxHtmlContainerCell
72//-----------------------------------------------------------------------------
73
74
75wxHtmlContainerCell::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
92void 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
103int 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
115int 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
128void 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
237void 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
277void 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
285wxString 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
302void 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
315void 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
331void 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
350const 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
364void 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
389void 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
400void 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
418void 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
424void 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
441wxHtmlWidgetCell::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
451void 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
472void 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
490void 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