beginnings of HTML4 tables layouter

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@11487 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík
2001-08-25 23:14:21 +00:00
parent bb0e27ee5a
commit 79d6c01818
3 changed files with 151 additions and 55 deletions

View File

@@ -112,6 +112,11 @@ public:
// is true - the cell can be split on two pages // is true - the cell can be split on two pages
void SetCanLiveOnPagebreak(bool can) { m_CanLiveOnPagebreak = can; } void SetCanLiveOnPagebreak(bool can) { m_CanLiveOnPagebreak = can; }
// Returns y-coordinates that contraint the cell, i.e. left is highest
// and right lowest coordinate such that the cell lays between then.
// Note: this method does not return meaningful values if you haven't
// called Layout() before!
virtual void GetHorizontalConstraints(int *left, int *right) const;
protected: protected:
wxHtmlCell *m_Next; wxHtmlCell *m_Next;
@@ -204,6 +209,7 @@ public:
virtual wxHtmlLinkInfo* GetLink(int x = 0, int y = 0) const; virtual wxHtmlLinkInfo* GetLink(int x = 0, int y = 0) const;
virtual const wxHtmlCell* Find(int condition, const void* param) const; virtual const wxHtmlCell* Find(int condition, const void* param) const;
virtual void OnMouseClick(wxWindow *parent, int x, int y, const wxMouseEvent& event); virtual void OnMouseClick(wxWindow *parent, int x, int y, const wxMouseEvent& event);
virtual void GetHorizontalConstraints(int *left, int *right) const;
// returns pointer to the first cell in container or NULL // returns pointer to the first cell in container or NULL
wxHtmlCell* GetFirstCell() const {return m_Cells;} wxHtmlCell* GetFirstCell() const {return m_Cells;}

View File

@@ -97,6 +97,17 @@ void wxHtmlCell::Layout(int WXUNUSED(w))
} }
void wxHtmlCell::GetHorizontalConstraints(int *left, int *right) const
{
if (left)
*left = m_PosX;
if (right)
*right = m_PosX + m_Width - 1;
}
const wxHtmlCell* wxHtmlCell::Find(int WXUNUSED(condition), const void* WXUNUSED(param)) const const wxHtmlCell* wxHtmlCell::Find(int WXUNUSED(condition), const void* WXUNUSED(param)) const
{ {
return NULL; return NULL;
@@ -551,6 +562,28 @@ void wxHtmlContainerCell::OnMouseClick(wxWindow *parent, int x, int y, const wxM
void wxHtmlContainerCell::GetHorizontalConstraints(int *left, int *right) const
{
int cleft = m_PosX + m_Width, cright = m_PosX; // worst case
int l, r;
for (wxHtmlCell *cell = m_Cells; cell; cell = cell->GetNext())
{
cell->GetHorizontalConstraints(&l, &r);
if (l < cleft)
cleft = l;
if (r > cright)
cright = r;
}
if (left)
*left = cleft;
if (right)
*right = cright;
}
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------

View File

@@ -47,48 +47,58 @@ FORCE_LINK_ME(m_tables)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
typedef struct { struct colStruct
{
int width, units; int width, units;
// universal // width of the column either in pixels or percents
// ('width' is the number, 'units' determines its meaning)
int minWidth, maxWidth;
// minimal/maximal column width. This is needed by HTML 4.0
// layouting algorithm and can be determined by trying to
// layout table cells with width=1 and width=infinity
int leftpos, pixwidth, maxrealwidth; int leftpos, pixwidth, maxrealwidth;
// temporary (depends on width of table) // temporary (depends on actual width of table)
} colStruct; };
typedef enum { enum cellState
{
cellSpan, cellSpan,
cellUsed, cellUsed,
cellFree cellFree
} cellState; };
typedef struct { struct cellStruct
{
wxHtmlContainerCell *cont; wxHtmlContainerCell *cont;
int colspan, rowspan; int colspan, rowspan;
int minheight, valign; int minheight, valign;
cellState flag; cellState flag;
} cellStruct; };
class wxHtmlTableCell : public wxHtmlContainerCell class wxHtmlTableCell : public wxHtmlContainerCell
{ {
protected: protected:
/* These are real attributes: */ /* These are real attributes: */
bool m_HasBorders;
// should we draw borders or not? // should we draw borders or not?
int m_NumCols, m_NumRows; bool m_HasBorders;
// number of columns; rows // number of columns; rows
colStruct *m_ColsInfo; int m_NumCols, m_NumRows;
// array of column information // array of column information
cellStruct **m_CellInfo; colStruct *m_ColsInfo;
// 2D array of all cells in the table : m_CellInfo[row][column] // 2D array of all cells in the table : m_CellInfo[row][column]
int m_Spacing; cellStruct **m_CellInfo;
// spaces between cells // spaces between cells
int m_Padding; int m_Spacing;
// cells internal indentation // cells internal indentation
int m_Padding;
private: private:
/* ...and these are valid only during parsing of table: */ /* ...and these are valid only when parsing the table: */
int m_ActualCol, m_ActualRow;
// number of actual column (ranging from 0..m_NumCols) // number of actual column (ranging from 0..m_NumCols)
int m_ActualCol, m_ActualRow;
// default values (for table and row): // default values (for table and row):
wxColour m_tBkg, m_rBkg; wxColour m_tBkg, m_rBkg;
@@ -104,12 +114,17 @@ class wxHtmlTableCell : public wxHtmlContainerCell
void AddRow(const wxHtmlTag& tag); void AddRow(const wxHtmlTag& tag);
void AddCell(wxHtmlContainerCell *cell, const wxHtmlTag& tag); void AddCell(wxHtmlContainerCell *cell, const wxHtmlTag& tag);
private: private:
void ReallocCols(int cols); // Reallocates memory to given number of cols/rows
void ReallocRows(int rows);
// reallocates memory to given number of cols/rows
// and changes m_NumCols/m_NumRows value to reflect this change // and changes m_NumCols/m_NumRows value to reflect this change
// NOTE! You CAN'T change m_NumCols/m_NumRows before calling this!! // NOTE! You CAN'T change m_NumCols/m_NumRows before calling this!!
void ReallocCols(int cols);
void ReallocRows(int rows);
// Computes minimal and maximal widths of columns. Needs to be called
// only once, before first Layout().
void ComputeMinMaxWidths();
}; };
@@ -174,6 +189,7 @@ void wxHtmlTableCell::ReallocCols(int cols)
{ {
m_ColsInfo[j].width = 0; m_ColsInfo[j].width = 0;
m_ColsInfo[j].units = wxHTML_UNITS_PERCENT; m_ColsInfo[j].units = wxHTML_UNITS_PERCENT;
m_ColsInfo[j].minWidth = m_ColsInfo[j].maxWidth = -1;
} }
m_NumCols = cols; m_NumCols = cols;
@@ -321,10 +337,43 @@ void wxHtmlTableCell::AddCell(wxHtmlContainerCell *cell, const wxHtmlTag& tag)
void wxHtmlTableCell::ComputeMinMaxWidths()
{
if (m_NumCols == 0 || m_ColsInfo[0].minWidth != -1) return;
int left, right, width;
m_ColsInfo[0].minWidth = 0; // avoid recursion
Layout(1);
for (int c = 0; c < m_NumCols; c++)
{
for (int r = 0; r < m_NumRows; r++)
{
cellStruct& cell = m_CellInfo[r][c];
if (cell.flag == cellUsed)
{
cell.cont->GetHorizontalConstraints(&left, &right);
width = right - left + 1;
// HTML 4.0 says it is acceptable to distribute min/max
// width of spanning cells evently
width /= cell.colspan;
width += m_Spacing + 2*m_Padding;
for (int j = 0; j < cell.colspan; j++)
if (width > m_ColsInfo[c+j].minWidth)
m_ColsInfo[c+j].minWidth = width;
}
}
}
// FIXME -- compute maxWidth as well. Not needed yet, so there's no
// point in computing it.
}
void wxHtmlTableCell::Layout(int w) void wxHtmlTableCell::Layout(int w)
{ {
ComputeMinMaxWidths();
/* /*
WIDTH ADJUSTING : WIDTH ADJUSTING :
@@ -353,17 +402,25 @@ void wxHtmlTableCell::Layout(int w)
{ {
int wpix = m_Width - (m_NumCols + 1) * m_Spacing; int wpix = m_Width - (m_NumCols + 1) * m_Spacing;
int i, j; int i, j;
int wtemp = 0;
// 1a. setup fixed-width columns: // 1a. setup fixed-width columns:
for (i = 0; i < m_NumCols; i++) for (i = 0; i < m_NumCols; i++)
if (m_ColsInfo[i].units == wxHTML_UNITS_PIXELS) if (m_ColsInfo[i].units == wxHTML_UNITS_PIXELS)
wpix -= (m_ColsInfo[i].pixwidth = m_ColsInfo[i].width); {
m_ColsInfo[i].pixwidth = wxMax(m_ColsInfo[i].width,
m_ColsInfo[i].minWidth);
wpix -= m_ColsInfo[i].pixwidth;
}
// 1b. setup floating-width columns: // 1b. setup floating-width columns:
int wtemp = 0;
for (i = 0; i < m_NumCols; i++) for (i = 0; i < m_NumCols; i++)
if ((m_ColsInfo[i].units == wxHTML_UNITS_PERCENT) && (m_ColsInfo[i].width != 0)) if ((m_ColsInfo[i].units == wxHTML_UNITS_PERCENT) && (m_ColsInfo[i].width != 0))
wtemp += (m_ColsInfo[i].pixwidth = m_ColsInfo[i].width * wpix / 100); {
m_ColsInfo[i].pixwidth = wxMax(m_ColsInfo[i].width * wpix / 100,
m_ColsInfo[i].minWidth);
wtemp += m_ColsInfo[i].pixwidth;
}
wpix -= wtemp; wpix -= wtemp;
// 1c. setup defalut columns (no width specification supplied): // 1c. setup defalut columns (no width specification supplied):