]> git.saurik.com Git - wxWidgets.git/commitdiff
beginnings of HTML4 tables layouter
authorVáclav Slavík <vslavik@fastmail.fm>
Sat, 25 Aug 2001 23:14:21 +0000 (23:14 +0000)
committerVáclav Slavík <vslavik@fastmail.fm>
Sat, 25 Aug 2001 23:14:21 +0000 (23:14 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@11487 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/html/htmlcell.h
src/html/htmlcell.cpp
src/html/m_tables.cpp

index 17e108a08da987433d3fed6dfd2cca86656fb9cd..166f9be9d9ef47d5a38aff21d78e33b11ec54dc8 100644 (file)
@@ -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;}
index dcd3b4b4cff37fe155e7bb1e6c24829b46c7ee0b..135e85544d8f498fc08a44ecf7826702448d6e4e 100644 (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
 {
     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;
+}
+
+
+
 
 
 //--------------------------------------------------------------------------------
index 7f2f90ff8b97c9140aec8e435f5db1c434b58e23..4f9af45eeb90552c6bd239db1f7b2e1b8ed8d868 100644 (file)
@@ -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):