]> git.saurik.com Git - wxWidgets.git/blame - src/html/htmlcell.cpp
serbase.cpp added to the list of files
[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
964688d8
VZ
35void wxHtmlCell::OnMouseClick(wxWindow *parent, int x, int y,
36 bool WXUNUSED(left),
37 bool WXUNUSED(middle),
38 bool WXUNUSED(right))
5526e819 39{
25082126
VS
40 wxString lnk = GetLink(x, y);
41 if (lnk != wxEmptyString)
42 ((wxHtmlWindow*)parent) -> OnLinkClicked(lnk);
5526e819
VS
43 // note : this overcasting is legal because parent is *always* wxHtmlWindow
44}
45
46
47
48//-----------------------------------------------------------------------------
49// wxHtmlWordCell
50//-----------------------------------------------------------------------------
51
52wxHtmlWordCell::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
65void 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
5526e819
VS
73//-----------------------------------------------------------------------------
74// wxHtmlContainerCell
75//-----------------------------------------------------------------------------
76
77
78wxHtmlContainerCell::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
95void 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
106int 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
118int 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
131void 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
240void 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
280void 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
288wxString 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
305void 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
318void 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
334void 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
353const 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
367void 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
392void 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
403void 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
421void 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
427void 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
444wxHtmlWidgetCell::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
454void 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
475void 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
493void 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