c0c133e13b
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58757 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
308 lines
8.4 KiB
C++
308 lines
8.4 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/html/m_list.cpp
|
|
// Purpose: wxHtml module for lists
|
|
// Author: Vaclav Slavik
|
|
// RCS-ID: $Id$
|
|
// Copyright: (c) 1999 Vaclav Slavik
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#if wxUSE_HTML && wxUSE_STREAMS
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/brush.h"
|
|
#include "wx/dc.h"
|
|
#endif
|
|
|
|
#include "wx/html/forcelnk.h"
|
|
#include "wx/html/m_templ.h"
|
|
|
|
#include "wx/html/htmlcell.h"
|
|
|
|
FORCE_LINK_ME(m_list)
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// wxHtmlListmarkCell
|
|
//-----------------------------------------------------------------------------
|
|
|
|
class wxHtmlListmarkCell : public wxHtmlCell
|
|
{
|
|
private:
|
|
wxBrush m_Brush;
|
|
public:
|
|
wxHtmlListmarkCell(wxDC *dc, const wxColour& clr);
|
|
void Draw(wxDC& dc, int x, int y, int view_y1, int view_y2,
|
|
wxHtmlRenderingInfo& info);
|
|
|
|
wxDECLARE_NO_COPY_CLASS(wxHtmlListmarkCell);
|
|
};
|
|
|
|
wxHtmlListmarkCell::wxHtmlListmarkCell(wxDC* dc, const wxColour& clr) : wxHtmlCell(), m_Brush(clr, wxBRUSHSTYLE_SOLID)
|
|
{
|
|
m_Width = dc->GetCharHeight();
|
|
m_Height = dc->GetCharHeight();
|
|
// bottom of list mark is lined with bottom of letters in next cell
|
|
m_Descent = m_Height / 3;
|
|
}
|
|
|
|
|
|
|
|
void wxHtmlListmarkCell::Draw(wxDC& dc, int x, int y,
|
|
int WXUNUSED(view_y1), int WXUNUSED(view_y2),
|
|
wxHtmlRenderingInfo& WXUNUSED(info))
|
|
{
|
|
dc.SetBrush(m_Brush);
|
|
dc.DrawEllipse(x + m_PosX + m_Width / 3, y + m_PosY + m_Height / 3,
|
|
(m_Width / 3), (m_Width / 3));
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// wxHtmlListCell
|
|
//-----------------------------------------------------------------------------
|
|
|
|
struct wxHtmlListItemStruct
|
|
{
|
|
wxHtmlContainerCell *mark;
|
|
wxHtmlContainerCell *cont;
|
|
int minWidth;
|
|
int maxWidth;
|
|
};
|
|
|
|
class wxHtmlListCell : public wxHtmlContainerCell
|
|
{
|
|
private:
|
|
wxBrush m_Brush;
|
|
|
|
int m_NumRows;
|
|
wxHtmlListItemStruct *m_RowInfo;
|
|
void ReallocRows(int rows);
|
|
void ComputeMinMaxWidths();
|
|
int ComputeMaxBase(wxHtmlCell *cell);
|
|
int m_ListmarkWidth;
|
|
|
|
public:
|
|
wxHtmlListCell(wxHtmlContainerCell *parent);
|
|
virtual ~wxHtmlListCell();
|
|
void AddRow(wxHtmlContainerCell *mark, wxHtmlContainerCell *cont);
|
|
virtual void Layout(int w);
|
|
|
|
wxDECLARE_NO_COPY_CLASS(wxHtmlListCell);
|
|
};
|
|
|
|
wxHtmlListCell::wxHtmlListCell(wxHtmlContainerCell *parent) : wxHtmlContainerCell(parent)
|
|
{
|
|
m_NumRows = 0;
|
|
m_RowInfo = 0;
|
|
m_ListmarkWidth = 0;
|
|
}
|
|
|
|
wxHtmlListCell::~wxHtmlListCell()
|
|
{
|
|
if (m_RowInfo) free(m_RowInfo);
|
|
}
|
|
|
|
int wxHtmlListCell::ComputeMaxBase(wxHtmlCell *cell)
|
|
{
|
|
if(!cell)
|
|
return 0;
|
|
|
|
wxHtmlCell *child = cell->GetFirstChild();
|
|
|
|
while(child)
|
|
{
|
|
int base = ComputeMaxBase( child );
|
|
if ( base > 0 ) return base + child->GetPosY();
|
|
child = child->GetNext();
|
|
}
|
|
|
|
return cell->GetHeight() - cell->GetDescent();
|
|
}
|
|
|
|
void wxHtmlListCell::Layout(int w)
|
|
{
|
|
wxHtmlCell::Layout(w);
|
|
|
|
ComputeMinMaxWidths();
|
|
m_Width = wxMax(m_Width, wxMin(w, GetMaxTotalWidth()));
|
|
|
|
int s_width = m_Width - m_IndentLeft;
|
|
|
|
int vpos = 0;
|
|
for (int r = 0; r < m_NumRows; r++)
|
|
{
|
|
// do layout first time to layout contents and adjust pos
|
|
m_RowInfo[r].mark->Layout(m_ListmarkWidth);
|
|
m_RowInfo[r].cont->Layout(s_width - m_ListmarkWidth);
|
|
|
|
const int base_mark = ComputeMaxBase( m_RowInfo[r].mark );
|
|
const int base_cont = ComputeMaxBase( m_RowInfo[r].cont );
|
|
const int adjust_mark = vpos + wxMax(base_cont-base_mark,0);
|
|
const int adjust_cont = vpos + wxMax(base_mark-base_cont,0);
|
|
|
|
m_RowInfo[r].mark->SetPos(m_IndentLeft, adjust_mark);
|
|
m_RowInfo[r].cont->SetPos(m_IndentLeft + m_ListmarkWidth, adjust_cont);
|
|
|
|
vpos = wxMax(adjust_mark + m_RowInfo[r].mark->GetHeight(),
|
|
adjust_cont + m_RowInfo[r].cont->GetHeight());
|
|
}
|
|
m_Height = vpos;
|
|
}
|
|
|
|
void wxHtmlListCell::AddRow(wxHtmlContainerCell *mark, wxHtmlContainerCell *cont)
|
|
{
|
|
ReallocRows(++m_NumRows);
|
|
m_RowInfo[m_NumRows - 1].mark = mark;
|
|
m_RowInfo[m_NumRows - 1].cont = cont;
|
|
}
|
|
|
|
void wxHtmlListCell::ReallocRows(int rows)
|
|
{
|
|
m_RowInfo = (wxHtmlListItemStruct*) realloc(m_RowInfo, sizeof(wxHtmlListItemStruct) * rows);
|
|
m_RowInfo[rows - 1].mark = NULL;
|
|
m_RowInfo[rows - 1].cont = NULL;
|
|
m_RowInfo[rows - 1].minWidth = 0;
|
|
m_RowInfo[rows - 1].maxWidth = 0;
|
|
|
|
m_NumRows = rows;
|
|
}
|
|
|
|
void wxHtmlListCell::ComputeMinMaxWidths()
|
|
{
|
|
if (m_NumRows == 0) return;
|
|
|
|
m_MaxTotalWidth = 0;
|
|
m_Width = 0;
|
|
|
|
for (int r = 0; r < m_NumRows; r++)
|
|
{
|
|
wxHtmlListItemStruct& row = m_RowInfo[r];
|
|
row.mark->Layout(1);
|
|
row.cont->Layout(1);
|
|
int maxWidth = row.cont->GetMaxTotalWidth();
|
|
int width = row.cont->GetWidth();
|
|
if (row.mark->GetWidth() > m_ListmarkWidth)
|
|
m_ListmarkWidth = row.mark->GetWidth();
|
|
if (maxWidth > m_MaxTotalWidth)
|
|
m_MaxTotalWidth = maxWidth;
|
|
if (width > m_Width)
|
|
m_Width = width;
|
|
}
|
|
m_Width += m_ListmarkWidth + m_IndentLeft;
|
|
m_MaxTotalWidth += m_ListmarkWidth + m_IndentLeft;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// wxHtmlListcontentCell
|
|
//-----------------------------------------------------------------------------
|
|
|
|
class wxHtmlListcontentCell : public wxHtmlContainerCell
|
|
{
|
|
public:
|
|
wxHtmlListcontentCell(wxHtmlContainerCell *p) : wxHtmlContainerCell(p) {}
|
|
virtual void Layout(int w) {
|
|
// Reset top indentation, fixes <li><p>
|
|
SetIndent(0, wxHTML_INDENT_TOP);
|
|
wxHtmlContainerCell::Layout(w);
|
|
}
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// The list handler:
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
TAG_HANDLER_BEGIN(OLULLI, "OL,UL,LI")
|
|
|
|
TAG_HANDLER_VARS
|
|
wxHtmlListCell *m_List;
|
|
int m_Numbering;
|
|
// this is number of actual item of list or 0 for dots
|
|
|
|
TAG_HANDLER_CONSTR(OLULLI)
|
|
{
|
|
m_List = NULL;
|
|
m_Numbering = 0;
|
|
}
|
|
|
|
TAG_HANDLER_PROC(tag)
|
|
{
|
|
wxHtmlContainerCell *c;
|
|
|
|
// List Item:
|
|
if (m_List && tag.GetName() == wxT("LI"))
|
|
{
|
|
c = m_WParser->SetContainer(new wxHtmlContainerCell(m_List));
|
|
c->SetAlignVer(wxHTML_ALIGN_TOP);
|
|
|
|
wxHtmlContainerCell *mark = c;
|
|
c->SetWidthFloat(2 * m_WParser->GetCharWidth(), wxHTML_UNITS_PIXELS);
|
|
if (m_Numbering == 0)
|
|
{
|
|
// Centering gives more space after the bullet
|
|
c->SetAlignHor(wxHTML_ALIGN_CENTER);
|
|
c->InsertCell(new wxHtmlListmarkCell(m_WParser->GetDC(), m_WParser->GetActualColor()));
|
|
}
|
|
else
|
|
{
|
|
c->SetAlignHor(wxHTML_ALIGN_RIGHT);
|
|
wxString markStr;
|
|
markStr.Printf(wxT("%i. "), m_Numbering);
|
|
c->InsertCell(new wxHtmlWordCell(markStr, *(m_WParser->GetDC())));
|
|
}
|
|
m_WParser->CloseContainer();
|
|
|
|
c = m_WParser->OpenContainer();
|
|
|
|
m_List->AddRow(mark, c);
|
|
c = m_WParser->OpenContainer();
|
|
m_WParser->SetContainer(new wxHtmlListcontentCell(c));
|
|
|
|
if (m_Numbering != 0) m_Numbering++;
|
|
}
|
|
|
|
// Begin of List (not-numbered): "UL", "OL"
|
|
else if (tag.GetName() == wxT("UL") || tag.GetName() == wxT("OL"))
|
|
{
|
|
int oldnum = m_Numbering;
|
|
|
|
if (tag.GetName() == wxT("UL")) m_Numbering = 0;
|
|
else m_Numbering = 1;
|
|
|
|
wxHtmlContainerCell *oldcont;
|
|
oldcont = c = m_WParser->OpenContainer();
|
|
|
|
wxHtmlListCell *oldList = m_List;
|
|
m_List = new wxHtmlListCell(c);
|
|
m_List->SetIndent(2 * m_WParser->GetCharWidth(), wxHTML_INDENT_LEFT);
|
|
|
|
ParseInner(tag);
|
|
|
|
m_WParser->SetContainer(oldcont);
|
|
m_WParser->CloseContainer();
|
|
|
|
m_Numbering = oldnum;
|
|
m_List = oldList;
|
|
return true;
|
|
}
|
|
return false;
|
|
|
|
}
|
|
|
|
TAG_HANDLER_END(OLULLI)
|
|
|
|
|
|
TAGS_MODULE_BEGIN(List)
|
|
|
|
TAGS_MODULE_ADD(OLULLI)
|
|
|
|
TAGS_MODULE_END(List)
|
|
|
|
#endif
|