From 79d6c01818cafa1d95973955c8c55519d9550cf1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Sat, 25 Aug 2001 23:14:21 +0000 Subject: [PATCH] beginnings of HTML4 tables layouter git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@11487 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/html/htmlcell.h | 8 +- src/html/htmlcell.cpp | 33 +++++++ src/html/m_tables.cpp | 181 ++++++++++++++++++++++++------------- 3 files changed, 159 insertions(+), 63 deletions(-) diff --git a/include/wx/html/htmlcell.h b/include/wx/html/htmlcell.h index 17e108a08d..166f9be9d9 100644 --- a/include/wx/html/htmlcell.h +++ b/include/wx/html/htmlcell.h @@ -110,8 +110,13 @@ public: // Sets cell's behaviour on pagebreaks (see AdjustPagebreak). Default // 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: wxHtmlCell *m_Next; @@ -204,6 +209,7 @@ public: virtual wxHtmlLinkInfo* GetLink(int x = 0, int y = 0) 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 GetHorizontalConstraints(int *left, int *right) const; // returns pointer to the first cell in container or NULL wxHtmlCell* GetFirstCell() const {return m_Cells;} diff --git a/src/html/htmlcell.cpp b/src/html/htmlcell.cpp index dcd3b4b4cf..135e85544d 100644 --- a/src/html/htmlcell.cpp +++ b/src/html/htmlcell.cpp @@ -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 { 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; +} + + + //-------------------------------------------------------------------------------- diff --git a/src/html/m_tables.cpp b/src/html/m_tables.cpp index 7f2f90ff8b..4f9af45eeb 100644 --- a/src/html/m_tables.cpp +++ b/src/html/m_tables.cpp @@ -47,69 +47,84 @@ FORCE_LINK_ME(m_tables) //----------------------------------------------------------------------------- -typedef struct { - int width, units; - // universal - int leftpos, pixwidth, maxrealwidth; - // temporary (depends on width of table) - } colStruct; - -typedef enum { - cellSpan, - cellUsed, - cellFree - } cellState; - -typedef struct { - wxHtmlContainerCell *cont; - int colspan, rowspan; - int minheight, valign; - cellState flag; - } cellStruct; +struct colStruct +{ + int width, units; + // 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; + // temporary (depends on actual width of table) +}; + +enum cellState +{ + cellSpan, + cellUsed, + cellFree +}; + +struct cellStruct +{ + wxHtmlContainerCell *cont; + int colspan, rowspan; + int minheight, valign; + cellState flag; +}; class wxHtmlTableCell : public wxHtmlContainerCell { - protected: - /* 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: - /* ...and these are valid only during parsing of table: */ - int m_ActualCol, m_ActualRow; - // number of actual column (ranging from 0..m_NumCols) - - // default values (for table and row): - wxColour m_tBkg, m_rBkg; - wxString m_tValign, m_rValign; - - double m_PixelScale; - - - public: - wxHtmlTableCell(wxHtmlContainerCell *parent, const wxHtmlTag& tag, double pixel_scale = 1.0); - ~wxHtmlTableCell(); - virtual void Layout(int w); - - void AddRow(const wxHtmlTag& tag); - void AddCell(wxHtmlContainerCell *cell, const wxHtmlTag& tag); - private: - void ReallocCols(int cols); - void ReallocRows(int rows); - // reallocates memory to given number of cols/rows - // and changes m_NumCols/m_NumRows value to reflect this change - // NOTE! You CAN'T change m_NumCols/m_NumRows before calling this!! +protected: + /* These are real attributes: */ + + // should we draw borders or not? + bool m_HasBorders; + // number of columns; rows + 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; + +private: + /* ...and these are valid only when parsing the table: */ + + // 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: + wxHtmlTableCell(wxHtmlContainerCell *parent, const wxHtmlTag& tag, double pixel_scale = 1.0); + ~wxHtmlTableCell(); + virtual void Layout(int w); + + void AddRow(const wxHtmlTag& tag); + void AddCell(wxHtmlContainerCell *cell, const wxHtmlTag& tag); + +private: + // Reallocates memory to given number of cols/rows + // and changes m_NumCols/m_NumRows value to reflect this change + // 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].units = wxHTML_UNITS_PERCENT; + m_ColsInfo[j].minWidth = m_ColsInfo[j].maxWidth = -1; } 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) { + ComputeMinMaxWidths(); + /* WIDTH ADJUSTING : @@ -353,17 +402,25 @@ void wxHtmlTableCell::Layout(int w) { int wpix = m_Width - (m_NumCols + 1) * m_Spacing; int i, j; - int wtemp = 0; // 1a. setup fixed-width columns: for (i = 0; i < m_NumCols; i++) 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: + int wtemp = 0; for (i = 0; i < m_NumCols; i++) 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; // 1c. setup defalut columns (no width specification supplied): -- 2.45.2