| 1 | ///////////////////////////////////////////////////////////////////////////// |
| 2 | // Name: htmlcell.cpp |
| 3 | // Purpose: wxHtmlCell - basic element of HTML output |
| 4 | // Author: Vaclav Slavik |
| 5 | // RCS-ID: $Id$ |
| 6 | // Copyright: (c) 1999 Vaclav Slavik |
| 7 | // Licence: wxWindows Licence |
| 8 | ///////////////////////////////////////////////////////////////////////////// |
| 9 | |
| 10 | #ifdef __GNUG__ |
| 11 | #pragma implementation "htmlcell.h" |
| 12 | #endif |
| 13 | |
| 14 | #include "wx/wxprec.h" |
| 15 | |
| 16 | #include "wx/defs.h" |
| 17 | |
| 18 | #if wxUSE_HTML && wxUSE_STREAMS |
| 19 | |
| 20 | #ifdef __BORLANDC__ |
| 21 | #pragma hdrstop |
| 22 | #endif |
| 23 | |
| 24 | #ifndef WXPRECOMP |
| 25 | #include "wx/brush.h" |
| 26 | #include "wx/colour.h" |
| 27 | #include "wx/dc.h" |
| 28 | #endif |
| 29 | |
| 30 | #include "wx/html/htmlcell.h" |
| 31 | #include "wx/html/htmlwin.h" |
| 32 | #include <stdlib.h> |
| 33 | |
| 34 | |
| 35 | //----------------------------------------------------------------------------- |
| 36 | // wxHtmlCell |
| 37 | //----------------------------------------------------------------------------- |
| 38 | |
| 39 | wxHtmlCell::wxHtmlCell() : wxObject() |
| 40 | { |
| 41 | m_Next = NULL; |
| 42 | m_Parent = NULL; |
| 43 | m_Width = m_Height = m_Descent = 0; |
| 44 | m_CanLiveOnPagebreak = TRUE; |
| 45 | m_Link = NULL; |
| 46 | } |
| 47 | |
| 48 | wxHtmlCell::~wxHtmlCell() |
| 49 | { |
| 50 | delete m_Link; |
| 51 | } |
| 52 | |
| 53 | |
| 54 | void wxHtmlCell::OnMouseClick(wxWindow *parent, int x, int y, |
| 55 | const wxMouseEvent& event) |
| 56 | { |
| 57 | wxHtmlLinkInfo *lnk = GetLink(x, y); |
| 58 | if (lnk != NULL) |
| 59 | { |
| 60 | wxHtmlLinkInfo lnk2(*lnk); |
| 61 | lnk2.SetEvent(&event); |
| 62 | lnk2.SetHtmlCell(this); |
| 63 | |
| 64 | // note : this cast is legal because parent is *always* wxHtmlWindow |
| 65 | wxStaticCast(parent, wxHtmlWindow)->OnLinkClicked(lnk2); |
| 66 | } |
| 67 | } |
| 68 | |
| 69 | |
| 70 | |
| 71 | bool wxHtmlCell::AdjustPagebreak(int *pagebreak, int* WXUNUSED(known_pagebreaks), int WXUNUSED(number_of_pages)) const |
| 72 | { |
| 73 | if ((!m_CanLiveOnPagebreak) && |
| 74 | m_PosY < *pagebreak && m_PosY + m_Height > *pagebreak) |
| 75 | { |
| 76 | *pagebreak = m_PosY; |
| 77 | return TRUE; |
| 78 | } |
| 79 | |
| 80 | return FALSE; |
| 81 | } |
| 82 | |
| 83 | |
| 84 | |
| 85 | void wxHtmlCell::SetLink(const wxHtmlLinkInfo& link) |
| 86 | { |
| 87 | if (m_Link) delete m_Link; |
| 88 | m_Link = NULL; |
| 89 | if (link.GetHref() != wxEmptyString) |
| 90 | m_Link = new wxHtmlLinkInfo(link); |
| 91 | } |
| 92 | |
| 93 | |
| 94 | |
| 95 | void wxHtmlCell::Layout(int WXUNUSED(w)) |
| 96 | { |
| 97 | SetPos(0, 0); |
| 98 | } |
| 99 | |
| 100 | |
| 101 | |
| 102 | void wxHtmlCell::GetHorizontalConstraints(int *left, int *right) const |
| 103 | { |
| 104 | if (left) |
| 105 | *left = m_PosX; |
| 106 | if (right) |
| 107 | *right = m_PosX + m_Width; |
| 108 | } |
| 109 | |
| 110 | |
| 111 | |
| 112 | const wxHtmlCell* wxHtmlCell::Find(int WXUNUSED(condition), const void* WXUNUSED(param)) const |
| 113 | { |
| 114 | return NULL; |
| 115 | } |
| 116 | |
| 117 | |
| 118 | wxHtmlCell *wxHtmlCell::FindCellByPos(wxCoord x, wxCoord y) const |
| 119 | { |
| 120 | if ( x >= 0 && x < m_Width && y >= 0 && y < m_Height ) |
| 121 | return wxConstCast(this, wxHtmlCell); |
| 122 | |
| 123 | return NULL; |
| 124 | } |
| 125 | |
| 126 | |
| 127 | //----------------------------------------------------------------------------- |
| 128 | // wxHtmlWordCell |
| 129 | //----------------------------------------------------------------------------- |
| 130 | |
| 131 | wxHtmlWordCell::wxHtmlWordCell(const wxString& word, wxDC& dc) : wxHtmlCell() |
| 132 | { |
| 133 | m_Word = word; |
| 134 | dc.GetTextExtent(m_Word, &m_Width, &m_Height, &m_Descent); |
| 135 | SetCanLiveOnPagebreak(FALSE); |
| 136 | } |
| 137 | |
| 138 | |
| 139 | |
| 140 | void wxHtmlWordCell::Draw(wxDC& dc, int x, int y, int WXUNUSED(view_y1), int WXUNUSED(view_y2)) |
| 141 | { |
| 142 | dc.DrawText(m_Word, x + m_PosX, y + m_PosY); |
| 143 | } |
| 144 | |
| 145 | |
| 146 | |
| 147 | //----------------------------------------------------------------------------- |
| 148 | // wxHtmlContainerCell |
| 149 | //----------------------------------------------------------------------------- |
| 150 | |
| 151 | |
| 152 | wxHtmlContainerCell::wxHtmlContainerCell(wxHtmlContainerCell *parent) : wxHtmlCell() |
| 153 | { |
| 154 | m_Cells = m_LastCell = NULL; |
| 155 | m_Parent = parent; |
| 156 | if (m_Parent) m_Parent->InsertCell(this); |
| 157 | m_AlignHor = wxHTML_ALIGN_LEFT; |
| 158 | m_AlignVer = wxHTML_ALIGN_BOTTOM; |
| 159 | m_IndentLeft = m_IndentRight = m_IndentTop = m_IndentBottom = 0; |
| 160 | m_WidthFloat = 100; m_WidthFloatUnits = wxHTML_UNITS_PERCENT; |
| 161 | m_UseBkColour = FALSE; |
| 162 | m_UseBorder = FALSE; |
| 163 | m_MinHeight = 0; |
| 164 | m_MinHeightAlign = wxHTML_ALIGN_TOP; |
| 165 | m_LastLayout = -1; |
| 166 | } |
| 167 | |
| 168 | wxHtmlContainerCell::~wxHtmlContainerCell() |
| 169 | { |
| 170 | wxHtmlCell *cell = m_Cells; |
| 171 | while ( cell ) |
| 172 | { |
| 173 | wxHtmlCell *cellNext = cell->GetNext(); |
| 174 | delete cell; |
| 175 | cell = cellNext; |
| 176 | } |
| 177 | } |
| 178 | |
| 179 | |
| 180 | |
| 181 | void wxHtmlContainerCell::SetIndent(int i, int what, int units) |
| 182 | { |
| 183 | int val = (units == wxHTML_UNITS_PIXELS) ? i : -i; |
| 184 | if (what & wxHTML_INDENT_LEFT) m_IndentLeft = val; |
| 185 | if (what & wxHTML_INDENT_RIGHT) m_IndentRight = val; |
| 186 | if (what & wxHTML_INDENT_TOP) m_IndentTop = val; |
| 187 | if (what & wxHTML_INDENT_BOTTOM) m_IndentBottom = val; |
| 188 | m_LastLayout = -1; |
| 189 | } |
| 190 | |
| 191 | |
| 192 | |
| 193 | int wxHtmlContainerCell::GetIndent(int ind) const |
| 194 | { |
| 195 | if (ind & wxHTML_INDENT_LEFT) return m_IndentLeft; |
| 196 | else if (ind & wxHTML_INDENT_RIGHT) return m_IndentRight; |
| 197 | else if (ind & wxHTML_INDENT_TOP) return m_IndentTop; |
| 198 | else if (ind & wxHTML_INDENT_BOTTOM) return m_IndentBottom; |
| 199 | else return -1; /* BUG! Should not be called... */ |
| 200 | } |
| 201 | |
| 202 | |
| 203 | |
| 204 | |
| 205 | int wxHtmlContainerCell::GetIndentUnits(int ind) const |
| 206 | { |
| 207 | bool p = FALSE; |
| 208 | if (ind & wxHTML_INDENT_LEFT) p = m_IndentLeft < 0; |
| 209 | else if (ind & wxHTML_INDENT_RIGHT) p = m_IndentRight < 0; |
| 210 | else if (ind & wxHTML_INDENT_TOP) p = m_IndentTop < 0; |
| 211 | else if (ind & wxHTML_INDENT_BOTTOM) p = m_IndentBottom < 0; |
| 212 | if (p) return wxHTML_UNITS_PERCENT; |
| 213 | else return wxHTML_UNITS_PIXELS; |
| 214 | } |
| 215 | |
| 216 | |
| 217 | |
| 218 | bool wxHtmlContainerCell::AdjustPagebreak(int *pagebreak, int* known_pagebreaks, int number_of_pages) const |
| 219 | { |
| 220 | if (!m_CanLiveOnPagebreak) |
| 221 | return wxHtmlCell::AdjustPagebreak(pagebreak, known_pagebreaks, number_of_pages); |
| 222 | |
| 223 | else |
| 224 | { |
| 225 | wxHtmlCell *c = GetFirstCell(); |
| 226 | bool rt = FALSE; |
| 227 | int pbrk = *pagebreak - m_PosY; |
| 228 | |
| 229 | while (c) |
| 230 | { |
| 231 | if (c->AdjustPagebreak(&pbrk, known_pagebreaks, number_of_pages)) |
| 232 | rt = TRUE; |
| 233 | c = c->GetNext(); |
| 234 | } |
| 235 | if (rt) |
| 236 | *pagebreak = pbrk + m_PosY; |
| 237 | return rt; |
| 238 | } |
| 239 | } |
| 240 | |
| 241 | |
| 242 | |
| 243 | void wxHtmlContainerCell::Layout(int w) |
| 244 | { |
| 245 | wxHtmlCell::Layout(w); |
| 246 | |
| 247 | if (m_LastLayout == w) return; |
| 248 | |
| 249 | // VS: Any attempt to layout with negative or zero width leads to hell, |
| 250 | // but we can't ignore such attempts completely, since it sometimes |
| 251 | // happen (e.g. when trying how small a table can be). The best thing we |
| 252 | // can do is to set the width of child cells to zero |
| 253 | if (w < 1) |
| 254 | { |
| 255 | m_Width = 0; |
| 256 | for (wxHtmlCell *cell = m_Cells; cell; cell = cell->GetNext()) |
| 257 | cell->Layout(0); |
| 258 | // this does two things: it recursively calls this code on all |
| 259 | // child contrainers and resets children's position to (0,0) |
| 260 | return; |
| 261 | } |
| 262 | |
| 263 | wxHtmlCell *cell = m_Cells, *line = m_Cells; |
| 264 | long xpos = 0, ypos = m_IndentTop; |
| 265 | int xdelta = 0, ybasicpos = 0, ydiff; |
| 266 | int s_width, s_indent; |
| 267 | int ysizeup = 0, ysizedown = 0; |
| 268 | int MaxLineWidth = 0; |
| 269 | int xcnt = 0; |
| 270 | |
| 271 | |
| 272 | /* |
| 273 | |
| 274 | WIDTH ADJUSTING : |
| 275 | |
| 276 | */ |
| 277 | |
| 278 | if (m_WidthFloatUnits == wxHTML_UNITS_PERCENT) |
| 279 | { |
| 280 | if (m_WidthFloat < 0) m_Width = (100 + m_WidthFloat) * w / 100; |
| 281 | else m_Width = m_WidthFloat * w / 100; |
| 282 | } |
| 283 | else |
| 284 | { |
| 285 | if (m_WidthFloat < 0) m_Width = w + m_WidthFloat; |
| 286 | else m_Width = m_WidthFloat; |
| 287 | } |
| 288 | |
| 289 | if (m_Cells) |
| 290 | { |
| 291 | int l = (m_IndentLeft < 0) ? (-m_IndentLeft * m_Width / 100) : m_IndentLeft; |
| 292 | int r = (m_IndentRight < 0) ? (-m_IndentRight * m_Width / 100) : m_IndentRight; |
| 293 | for (wxHtmlCell *cell = m_Cells; cell; cell = cell->GetNext()) |
| 294 | cell->Layout(m_Width - (l + r)); |
| 295 | } |
| 296 | |
| 297 | /* |
| 298 | |
| 299 | LAYOUTING : |
| 300 | |
| 301 | */ |
| 302 | |
| 303 | // adjust indentation: |
| 304 | s_indent = (m_IndentLeft < 0) ? (-m_IndentLeft * m_Width / 100) : m_IndentLeft; |
| 305 | s_width = m_Width - s_indent - ((m_IndentRight < 0) ? (-m_IndentRight * m_Width / 100) : m_IndentRight); |
| 306 | |
| 307 | // my own layouting: |
| 308 | while (cell != NULL) |
| 309 | { |
| 310 | switch (m_AlignVer) |
| 311 | { |
| 312 | case wxHTML_ALIGN_TOP : ybasicpos = 0; break; |
| 313 | case wxHTML_ALIGN_BOTTOM : ybasicpos = - cell->GetHeight(); break; |
| 314 | case wxHTML_ALIGN_CENTER : ybasicpos = - cell->GetHeight() / 2; break; |
| 315 | } |
| 316 | ydiff = cell->GetHeight() + ybasicpos; |
| 317 | |
| 318 | if (cell->GetDescent() + ydiff > ysizedown) ysizedown = cell->GetDescent() + ydiff; |
| 319 | if (ybasicpos + cell->GetDescent() < -ysizeup) ysizeup = - (ybasicpos + cell->GetDescent()); |
| 320 | |
| 321 | cell->SetPos(xpos, ybasicpos + cell->GetDescent()); |
| 322 | xpos += cell->GetWidth(); |
| 323 | cell = cell->GetNext(); |
| 324 | xcnt++; |
| 325 | |
| 326 | // force new line if occured: |
| 327 | if ((cell == NULL) || (xpos + cell->GetWidth() > s_width)) |
| 328 | { |
| 329 | if (xpos > MaxLineWidth) MaxLineWidth = xpos; |
| 330 | if (ysizeup < 0) ysizeup = 0; |
| 331 | if (ysizedown < 0) ysizedown = 0; |
| 332 | switch (m_AlignHor) { |
| 333 | case wxHTML_ALIGN_LEFT : |
| 334 | case wxHTML_ALIGN_JUSTIFY : |
| 335 | xdelta = 0; |
| 336 | break; |
| 337 | case wxHTML_ALIGN_RIGHT : |
| 338 | xdelta = 0 + (s_width - xpos); |
| 339 | break; |
| 340 | case wxHTML_ALIGN_CENTER : |
| 341 | xdelta = 0 + (s_width - xpos) / 2; |
| 342 | break; |
| 343 | } |
| 344 | if (xdelta < 0) xdelta = 0; |
| 345 | xdelta += s_indent; |
| 346 | |
| 347 | ypos += ysizeup; |
| 348 | |
| 349 | if (m_AlignHor != wxHTML_ALIGN_JUSTIFY || cell == NULL) |
| 350 | while (line != cell) |
| 351 | { |
| 352 | line->SetPos(line->GetPosX() + xdelta, |
| 353 | ypos + line->GetPosY()); |
| 354 | line = line->GetNext(); |
| 355 | } |
| 356 | else |
| 357 | { |
| 358 | int counter = 0; |
| 359 | int step = (s_width - xpos); |
| 360 | if (step < 0) step = 0; |
| 361 | xcnt--; |
| 362 | if (xcnt > 0) while (line != cell) |
| 363 | { |
| 364 | line->SetPos(line->GetPosX() + s_indent + |
| 365 | (counter++ * step / xcnt), |
| 366 | ypos + line->GetPosY()); |
| 367 | line = line->GetNext(); |
| 368 | } |
| 369 | xcnt++; |
| 370 | } |
| 371 | |
| 372 | ypos += ysizedown; |
| 373 | xpos = xcnt = 0; |
| 374 | ysizeup = ysizedown = 0; |
| 375 | line = cell; |
| 376 | } |
| 377 | } |
| 378 | |
| 379 | // setup height & width, depending on container layout: |
| 380 | m_Height = ypos + (ysizedown + ysizeup) + m_IndentBottom; |
| 381 | |
| 382 | if (m_Height < m_MinHeight) |
| 383 | { |
| 384 | if (m_MinHeightAlign != wxHTML_ALIGN_TOP) |
| 385 | { |
| 386 | int diff = m_MinHeight - m_Height; |
| 387 | if (m_MinHeightAlign == wxHTML_ALIGN_CENTER) diff /= 2; |
| 388 | cell = m_Cells; |
| 389 | while (cell) |
| 390 | { |
| 391 | cell->SetPos(cell->GetPosX(), cell->GetPosY() + diff); |
| 392 | cell = cell->GetNext(); |
| 393 | } |
| 394 | } |
| 395 | m_Height = m_MinHeight; |
| 396 | } |
| 397 | |
| 398 | MaxLineWidth += s_indent + ((m_IndentRight < 0) ? (-m_IndentRight * m_Width / 100) : m_IndentRight); |
| 399 | if (m_Width < MaxLineWidth) m_Width = MaxLineWidth; |
| 400 | |
| 401 | m_LastLayout = w; |
| 402 | } |
| 403 | |
| 404 | |
| 405 | #define mMin(a, b) (((a) < (b)) ? (a) : (b)) |
| 406 | #define mMax(a, b) (((a) < (b)) ? (b) : (a)) |
| 407 | |
| 408 | void wxHtmlContainerCell::Draw(wxDC& dc, int x, int y, int view_y1, int view_y2) |
| 409 | { |
| 410 | // container visible, draw it: |
| 411 | if ((y + m_PosY <= view_y2) && (y + m_PosY + m_Height > view_y1)) |
| 412 | { |
| 413 | if (m_UseBkColour) |
| 414 | { |
| 415 | wxBrush myb = wxBrush(m_BkColour, wxSOLID); |
| 416 | |
| 417 | int real_y1 = mMax(y + m_PosY, view_y1); |
| 418 | int real_y2 = mMin(y + m_PosY + m_Height - 1, view_y2); |
| 419 | |
| 420 | dc.SetBrush(myb); |
| 421 | dc.SetPen(*wxTRANSPARENT_PEN); |
| 422 | dc.DrawRectangle(x + m_PosX, real_y1, m_Width, real_y2 - real_y1 + 1); |
| 423 | } |
| 424 | |
| 425 | if (m_UseBorder) |
| 426 | { |
| 427 | wxPen mypen1(m_BorderColour1, 1, wxSOLID); |
| 428 | wxPen mypen2(m_BorderColour2, 1, wxSOLID); |
| 429 | |
| 430 | dc.SetPen(mypen1); |
| 431 | dc.DrawLine(x + m_PosX, y + m_PosY, x + m_PosX, y + m_PosY + m_Height - 1); |
| 432 | dc.DrawLine(x + m_PosX, y + m_PosY, x + m_PosX + m_Width, y + m_PosY); |
| 433 | dc.SetPen(mypen2); |
| 434 | dc.DrawLine(x + m_PosX + m_Width - 1, y + m_PosY, x + m_PosX + m_Width - 1, y + m_PosY + m_Height - 1); |
| 435 | dc.DrawLine(x + m_PosX, y + m_PosY + m_Height - 1, x + m_PosX + m_Width, y + m_PosY + m_Height - 1); |
| 436 | } |
| 437 | |
| 438 | if (m_Cells) |
| 439 | { |
| 440 | for (wxHtmlCell *cell = m_Cells; cell; cell = cell->GetNext()) |
| 441 | cell->Draw(dc, x + m_PosX, y + m_PosY, view_y1, view_y2); |
| 442 | } |
| 443 | } |
| 444 | // container invisible, just proceed font+color changing: |
| 445 | else |
| 446 | { |
| 447 | if (m_Cells) |
| 448 | { |
| 449 | for (wxHtmlCell *cell = m_Cells; cell; cell = cell->GetNext()) |
| 450 | cell->DrawInvisible(dc, x + m_PosX, y + m_PosY); |
| 451 | } |
| 452 | } |
| 453 | } |
| 454 | |
| 455 | |
| 456 | |
| 457 | void wxHtmlContainerCell::DrawInvisible(wxDC& dc, int x, int y) |
| 458 | { |
| 459 | if (m_Cells) |
| 460 | { |
| 461 | for (wxHtmlCell *cell = m_Cells; cell; cell = cell->GetNext()) |
| 462 | cell->DrawInvisible(dc, x + m_PosX, y + m_PosY); |
| 463 | } |
| 464 | } |
| 465 | |
| 466 | |
| 467 | wxColour wxHtmlContainerCell::GetBackgroundColour() |
| 468 | { |
| 469 | if (m_UseBkColour) |
| 470 | return m_BkColour; |
| 471 | else |
| 472 | return wxNullColour; |
| 473 | } |
| 474 | |
| 475 | |
| 476 | |
| 477 | wxHtmlLinkInfo *wxHtmlContainerCell::GetLink(int x, int y) const |
| 478 | { |
| 479 | wxHtmlCell *cell = FindCellByPos(x, y); |
| 480 | |
| 481 | // VZ: I don't know if we should pass absolute or relative coords to |
| 482 | // wxHtmlCell::GetLink()? As the base class version just ignores them |
| 483 | // anyhow, it hardly matters right now but should still be clarified |
| 484 | return cell ? cell->GetLink(x, y) : NULL; |
| 485 | } |
| 486 | |
| 487 | |
| 488 | |
| 489 | void wxHtmlContainerCell::InsertCell(wxHtmlCell *f) |
| 490 | { |
| 491 | if (!m_Cells) m_Cells = m_LastCell = f; |
| 492 | else |
| 493 | { |
| 494 | m_LastCell->SetNext(f); |
| 495 | m_LastCell = f; |
| 496 | if (m_LastCell) while (m_LastCell->GetNext()) m_LastCell = m_LastCell->GetNext(); |
| 497 | } |
| 498 | f->SetParent(this); |
| 499 | m_LastLayout = -1; |
| 500 | } |
| 501 | |
| 502 | |
| 503 | |
| 504 | void wxHtmlContainerCell::SetAlign(const wxHtmlTag& tag) |
| 505 | { |
| 506 | if (tag.HasParam(wxT("ALIGN"))) |
| 507 | { |
| 508 | wxString alg = tag.GetParam(wxT("ALIGN")); |
| 509 | alg.MakeUpper(); |
| 510 | if (alg == wxT("CENTER")) |
| 511 | SetAlignHor(wxHTML_ALIGN_CENTER); |
| 512 | else if (alg == wxT("LEFT")) |
| 513 | SetAlignHor(wxHTML_ALIGN_LEFT); |
| 514 | else if (alg == wxT("JUSTIFY")) |
| 515 | SetAlignHor(wxHTML_ALIGN_JUSTIFY); |
| 516 | else if (alg == wxT("RIGHT")) |
| 517 | SetAlignHor(wxHTML_ALIGN_RIGHT); |
| 518 | m_LastLayout = -1; |
| 519 | } |
| 520 | } |
| 521 | |
| 522 | |
| 523 | |
| 524 | void wxHtmlContainerCell::SetWidthFloat(const wxHtmlTag& tag, double pixel_scale) |
| 525 | { |
| 526 | if (tag.HasParam(wxT("WIDTH"))) |
| 527 | { |
| 528 | int wdi; |
| 529 | wxString wd = tag.GetParam(wxT("WIDTH")); |
| 530 | |
| 531 | if (wd[wd.Length()-1] == wxT('%')) |
| 532 | { |
| 533 | wxSscanf(wd.c_str(), wxT("%i%%"), &wdi); |
| 534 | SetWidthFloat(wdi, wxHTML_UNITS_PERCENT); |
| 535 | } |
| 536 | else |
| 537 | { |
| 538 | wxSscanf(wd.c_str(), wxT("%i"), &wdi); |
| 539 | SetWidthFloat((int)(pixel_scale * (double)wdi), wxHTML_UNITS_PIXELS); |
| 540 | } |
| 541 | m_LastLayout = -1; |
| 542 | } |
| 543 | } |
| 544 | |
| 545 | |
| 546 | |
| 547 | const wxHtmlCell* wxHtmlContainerCell::Find(int condition, const void* param) const |
| 548 | { |
| 549 | if (m_Cells) |
| 550 | { |
| 551 | const wxHtmlCell *r = NULL; |
| 552 | |
| 553 | for (wxHtmlCell *cell = m_Cells; cell; cell = cell->GetNext()) |
| 554 | { |
| 555 | r = cell->Find(condition, param); |
| 556 | if (r) return r; |
| 557 | } |
| 558 | } |
| 559 | return NULL; |
| 560 | } |
| 561 | |
| 562 | |
| 563 | wxHtmlCell *wxHtmlContainerCell::FindCellByPos(wxCoord x, wxCoord y) const |
| 564 | { |
| 565 | for ( const wxHtmlCell *cell = m_Cells; cell; cell = cell->GetNext() ) |
| 566 | { |
| 567 | int cx = cell->GetPosX(), |
| 568 | cy = cell->GetPosY(); |
| 569 | |
| 570 | if ( (cx <= x) && (cx + cell->GetWidth() > x) && |
| 571 | (cy <= y) && (cy + cell->GetHeight() > y) ) |
| 572 | { |
| 573 | return cell->FindCellByPos(x - cx, y - cy); |
| 574 | } |
| 575 | } |
| 576 | |
| 577 | return NULL; |
| 578 | } |
| 579 | |
| 580 | |
| 581 | void wxHtmlContainerCell::OnMouseClick(wxWindow *parent, int x, int y, const wxMouseEvent& event) |
| 582 | { |
| 583 | wxHtmlCell *cell = FindCellByPos(x, y); |
| 584 | if ( cell ) |
| 585 | cell->OnMouseClick(parent, x, y, event); |
| 586 | } |
| 587 | |
| 588 | |
| 589 | |
| 590 | void wxHtmlContainerCell::GetHorizontalConstraints(int *left, int *right) const |
| 591 | { |
| 592 | int cleft = m_PosX + m_Width, cright = m_PosX; // worst case |
| 593 | int l, r; |
| 594 | |
| 595 | for (wxHtmlCell *cell = m_Cells; cell; cell = cell->GetNext()) |
| 596 | { |
| 597 | cell->GetHorizontalConstraints(&l, &r); |
| 598 | if (l < cleft) |
| 599 | cleft = l; |
| 600 | if (r > cright) |
| 601 | cright = r; |
| 602 | } |
| 603 | |
| 604 | cleft -= (m_IndentLeft < 0) ? (-m_IndentLeft * m_Width / 100) : m_IndentLeft; |
| 605 | cright += (m_IndentRight < 0) ? (-m_IndentRight * m_Width / 100) : m_IndentRight; |
| 606 | |
| 607 | if (left) |
| 608 | *left = cleft; |
| 609 | if (right) |
| 610 | *right = cright; |
| 611 | } |
| 612 | |
| 613 | |
| 614 | |
| 615 | |
| 616 | |
| 617 | //-------------------------------------------------------------------------------- |
| 618 | // wxHtmlColourCell |
| 619 | //-------------------------------------------------------------------------------- |
| 620 | |
| 621 | void wxHtmlColourCell::Draw(wxDC& dc, int WXUNUSED(x), int WXUNUSED(y), int WXUNUSED(view_y1), int WXUNUSED(view_y2)) |
| 622 | { |
| 623 | if (m_Flags & wxHTML_CLR_FOREGROUND) |
| 624 | dc.SetTextForeground(m_Colour); |
| 625 | if (m_Flags & wxHTML_CLR_BACKGROUND) |
| 626 | { |
| 627 | dc.SetBackground(wxBrush(m_Colour, wxSOLID)); |
| 628 | dc.SetTextBackground(m_Colour); |
| 629 | } |
| 630 | } |
| 631 | |
| 632 | void wxHtmlColourCell::DrawInvisible(wxDC& dc, int WXUNUSED(x), int WXUNUSED(y)) |
| 633 | { |
| 634 | if (m_Flags & wxHTML_CLR_FOREGROUND) |
| 635 | dc.SetTextForeground(m_Colour); |
| 636 | if (m_Flags & wxHTML_CLR_BACKGROUND) |
| 637 | { |
| 638 | dc.SetBackground(wxBrush(m_Colour, wxSOLID)); |
| 639 | dc.SetTextBackground(m_Colour); |
| 640 | } |
| 641 | } |
| 642 | |
| 643 | |
| 644 | |
| 645 | |
| 646 | //-------------------------------------------------------------------------------- |
| 647 | // wxHtmlFontCell |
| 648 | //-------------------------------------------------------------------------------- |
| 649 | |
| 650 | void wxHtmlFontCell::Draw(wxDC& dc, int WXUNUSED(x), int WXUNUSED(y), int WXUNUSED(view_y1), int WXUNUSED(view_y2)) |
| 651 | { |
| 652 | dc.SetFont(m_Font); |
| 653 | } |
| 654 | |
| 655 | void wxHtmlFontCell::DrawInvisible(wxDC& dc, int WXUNUSED(x), int WXUNUSED(y)) |
| 656 | { |
| 657 | dc.SetFont(m_Font); |
| 658 | } |
| 659 | |
| 660 | |
| 661 | |
| 662 | |
| 663 | |
| 664 | |
| 665 | |
| 666 | |
| 667 | //-------------------------------------------------------------------------------- |
| 668 | // wxHtmlWidgetCell |
| 669 | //-------------------------------------------------------------------------------- |
| 670 | |
| 671 | wxHtmlWidgetCell::wxHtmlWidgetCell(wxWindow *wnd, int w) |
| 672 | { |
| 673 | int sx, sy; |
| 674 | m_Wnd = wnd; |
| 675 | m_Wnd->GetSize(&sx, &sy); |
| 676 | m_Width = sx, m_Height = sy; |
| 677 | m_WidthFloat = w; |
| 678 | } |
| 679 | |
| 680 | |
| 681 | void wxHtmlWidgetCell::Draw(wxDC& WXUNUSED(dc), int WXUNUSED(x), int WXUNUSED(y), int WXUNUSED(view_y1), int WXUNUSED(view_y2)) |
| 682 | { |
| 683 | int absx = 0, absy = 0, stx, sty; |
| 684 | wxHtmlCell *c = this; |
| 685 | |
| 686 | while (c) |
| 687 | { |
| 688 | absx += c->GetPosX(); |
| 689 | absy += c->GetPosY(); |
| 690 | c = c->GetParent(); |
| 691 | } |
| 692 | |
| 693 | ((wxScrolledWindow*)(m_Wnd->GetParent()))->GetViewStart(&stx, &sty); |
| 694 | m_Wnd->SetSize(absx - wxHTML_SCROLL_STEP * stx, absy - wxHTML_SCROLL_STEP * sty, m_Width, m_Height); |
| 695 | } |
| 696 | |
| 697 | |
| 698 | |
| 699 | void wxHtmlWidgetCell::DrawInvisible(wxDC& WXUNUSED(dc), int WXUNUSED(x), int WXUNUSED(y)) |
| 700 | { |
| 701 | int absx = 0, absy = 0, stx, sty; |
| 702 | wxHtmlCell *c = this; |
| 703 | |
| 704 | while (c) |
| 705 | { |
| 706 | absx += c->GetPosX(); |
| 707 | absy += c->GetPosY(); |
| 708 | c = c->GetParent(); |
| 709 | } |
| 710 | |
| 711 | ((wxScrolledWindow*)(m_Wnd->GetParent()))->GetViewStart(&stx, &sty); |
| 712 | m_Wnd->SetSize(absx - wxHTML_SCROLL_STEP * stx, absy - wxHTML_SCROLL_STEP * sty, m_Width, m_Height); |
| 713 | } |
| 714 | |
| 715 | |
| 716 | |
| 717 | void wxHtmlWidgetCell::Layout(int w) |
| 718 | { |
| 719 | if (m_WidthFloat != 0) |
| 720 | { |
| 721 | m_Width = (w * m_WidthFloat) / 100; |
| 722 | m_Wnd->SetSize(m_Width, m_Height); |
| 723 | } |
| 724 | |
| 725 | wxHtmlCell::Layout(w); |
| 726 | } |
| 727 | |
| 728 | #endif |