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

@@ -110,8 +110,13 @@ public:
// Sets cell's behaviour on pagebreaks (see AdjustPagebreak). Default // Sets cell's behaviour on pagebreaks (see AdjustPagebreak). Default
// 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,69 +47,84 @@ FORCE_LINK_ME(m_tables)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
typedef struct { struct colStruct
int width, units; {
// universal int width, units;
int leftpos, pixwidth, maxrealwidth; // width of the column either in pixels or percents
// temporary (depends on width of table) // ('width' is the number, 'units' determines its meaning)
} colStruct; 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;
// temporary (depends on actual width of table)
};
typedef enum { enum cellState
cellSpan, {
cellUsed, cellSpan,
cellFree cellUsed,
} cellState; cellFree
};
typedef struct { struct cellStruct
wxHtmlContainerCell *cont; {
int colspan, rowspan; wxHtmlContainerCell *cont;
int minheight, valign; int colspan, rowspan;
cellState flag; int minheight, valign;
} cellStruct; cellState flag;
};
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?
int m_NumCols, m_NumRows;
// number of columns; rows
colStruct *m_ColsInfo;
// array of column information
cellStruct **m_CellInfo;
// 2D array of all cells in the table : m_CellInfo[row][column]
int m_Spacing;
// spaces between cells
int m_Padding;
// cells internal indentation
private: // should we draw borders or not?
/* ...and these are valid only during parsing of table: */ bool m_HasBorders;
int m_ActualCol, m_ActualRow; // number of columns; rows
// number of actual column (ranging from 0..m_NumCols) int m_NumCols, m_NumRows;
// array of column information
colStruct *m_ColsInfo;
// 2D array of all cells in the table : m_CellInfo[row][column]
cellStruct **m_CellInfo;
// spaces between cells
int m_Spacing;
// cells internal indentation
int m_Padding;
// default values (for table and row): private:
wxColour m_tBkg, m_rBkg; /* ...and these are valid only when parsing the table: */
wxString m_tValign, m_rValign;
double m_PixelScale; // number of actual column (ranging from 0..m_NumCols)
int m_ActualCol, m_ActualRow;
// default values (for table and row):
wxColour m_tBkg, m_rBkg;
wxString m_tValign, m_rValign;
double m_PixelScale;
public: public:
wxHtmlTableCell(wxHtmlContainerCell *parent, const wxHtmlTag& tag, double pixel_scale = 1.0); wxHtmlTableCell(wxHtmlContainerCell *parent, const wxHtmlTag& tag, double pixel_scale = 1.0);
~wxHtmlTableCell(); ~wxHtmlTableCell();
virtual void Layout(int w); virtual void Layout(int w);
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:
void ReallocCols(int cols); private:
void ReallocRows(int rows); // Reallocates memory to given number of cols/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):