| 1 | ///////////////////////////////////////////////////////////////////////////// |
| 2 | // Name: gbsizer.h |
| 3 | // Purpose: wxGridBagSizer: A sizer that can lay out items in a grid, |
| 4 | // with items at specified cells, and with the option of row |
| 5 | // and/or column spanning |
| 6 | // |
| 7 | // Author: Robin Dunn |
| 8 | // Created: 03-Nov-2003 |
| 9 | // RCS-ID: $Id$ |
| 10 | // Copyright: (c) Robin Dunn |
| 11 | // Licence: wxWindows licence |
| 12 | ///////////////////////////////////////////////////////////////////////////// |
| 13 | |
| 14 | #ifndef __WXGBSIZER_H__ |
| 15 | #define __WXGBSIZER_H__ |
| 16 | |
| 17 | #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) |
| 18 | #pragma interface "gbsizer.h" |
| 19 | #endif |
| 20 | |
| 21 | #include "wx/sizer.h" |
| 22 | |
| 23 | |
| 24 | //--------------------------------------------------------------------------- |
| 25 | // Classes to represent a position in the grid and a size of an item in the |
| 26 | // grid, IOW, the number of rows and columns it occupies. I chose to use these |
| 27 | // instead of wxPoint and wxSize because they are (x,y) and usually pixel |
| 28 | // oriented while grids and tables are usually thought of as (row,col) so some |
| 29 | // confusion would definitely result in using wxPoint... |
| 30 | // |
| 31 | // NOTE: This should probably be refactored to a common RowCol data type which |
| 32 | // is used for this and also for wxGridCellCoords. |
| 33 | //--------------------------------------------------------------------------- |
| 34 | |
| 35 | class WXDLLEXPORT wxGBPosition |
| 36 | { |
| 37 | public: |
| 38 | wxGBPosition() : m_row(0), m_col(0) {} |
| 39 | wxGBPosition(int row, int col) : m_row(row), m_col(col) {} |
| 40 | |
| 41 | // default copy ctor and assignment operator are okay. |
| 42 | |
| 43 | int GetRow() const { return m_row; } |
| 44 | int GetCol() const { return m_col; } |
| 45 | void SetRow(int row) { m_row = row; } |
| 46 | void SetCol(int col) { m_col = col; } |
| 47 | |
| 48 | bool operator==(const wxGBPosition& p) const { return m_row == p.m_row && m_col == p.m_col; } |
| 49 | bool operator!=(const wxGBPosition& p) const { return !(*this == p); } |
| 50 | |
| 51 | private: |
| 52 | int m_row; |
| 53 | int m_col; |
| 54 | }; |
| 55 | |
| 56 | |
| 57 | class WXDLLEXPORT wxGBSpan |
| 58 | { |
| 59 | public: |
| 60 | wxGBSpan() : m_rowspan(1), m_colspan(1) {} |
| 61 | wxGBSpan(int rowspan, int colspan) : m_rowspan(rowspan), m_colspan(colspan) {} |
| 62 | |
| 63 | // default copy ctor and assignment operator are okay. |
| 64 | |
| 65 | int GetRowspan() const { return m_rowspan; } |
| 66 | int GetColspan() const { return m_colspan; } |
| 67 | void SetRowspan(int rowspan) { m_rowspan = rowspan; } |
| 68 | void SetColspan(int colspan) { m_colspan = colspan; } |
| 69 | |
| 70 | bool operator==(const wxGBSpan& o) const { return m_rowspan == o.m_rowspan && m_colspan == o.m_colspan; } |
| 71 | bool operator!=(const wxGBSpan& o) const { return !(*this == o); } |
| 72 | |
| 73 | private: |
| 74 | int m_rowspan; |
| 75 | int m_colspan; |
| 76 | }; |
| 77 | |
| 78 | |
| 79 | extern WXDLLEXPORT_DATA(const wxGBSpan) wxDefaultSpan; |
| 80 | |
| 81 | |
| 82 | //--------------------------------------------------------------------------- |
| 83 | // wxGBSizerItem |
| 84 | //--------------------------------------------------------------------------- |
| 85 | |
| 86 | class WXDLLEXPORT wxGridBagSizer; |
| 87 | |
| 88 | |
| 89 | class WXDLLEXPORT wxGBSizerItem : public wxSizerItem |
| 90 | { |
| 91 | public: |
| 92 | // spacer |
| 93 | wxGBSizerItem( int width, |
| 94 | int height, |
| 95 | const wxGBPosition& pos, |
| 96 | const wxGBSpan& span, |
| 97 | int flag, |
| 98 | int border, |
| 99 | wxObject* userData); |
| 100 | |
| 101 | // window |
| 102 | wxGBSizerItem( wxWindow *window, |
| 103 | const wxGBPosition& pos, |
| 104 | const wxGBSpan& span, |
| 105 | int flag, |
| 106 | int border, |
| 107 | wxObject* userData ); |
| 108 | |
| 109 | // subsizer |
| 110 | wxGBSizerItem( wxSizer *sizer, |
| 111 | const wxGBPosition& pos, |
| 112 | const wxGBSpan& span, |
| 113 | int flag, |
| 114 | int border, |
| 115 | wxObject* userData ); |
| 116 | |
| 117 | // default ctor |
| 118 | wxGBSizerItem(); |
| 119 | |
| 120 | |
| 121 | // Get the grid position of the item |
| 122 | wxGBPosition GetPos() const { return m_pos; } |
| 123 | void GetPos(int& row, int& col) const; |
| 124 | |
| 125 | // Get the row and column spanning of the item |
| 126 | wxGBSpan GetSpan() const { return m_span; } |
| 127 | void GetSpan(int& rowspan, int& colspan) const; |
| 128 | |
| 129 | // If the item is already a member of a sizer then first ensure that there |
| 130 | // is no other item that would intersect with this one at the new |
| 131 | // position, then set the new position. Returns true if the change is |
| 132 | // successful and after the next Layout the item will be moved. |
| 133 | bool SetPos( const wxGBPosition& pos ); |
| 134 | |
| 135 | // If the item is already a member of a sizer then first ensure that there |
| 136 | // is no other item that would intersect with this one with its new |
| 137 | // spanning size, then set the new spanning. Returns true if the change |
| 138 | // is successful and after the next Layout the item will be resized. |
| 139 | bool SetSpan( const wxGBSpan& span ); |
| 140 | |
| 141 | // Returns true if this item and the other item instersect |
| 142 | bool Intersects(const wxGBSizerItem& other); |
| 143 | |
| 144 | // Returns true if the given pos/span would intersect with this item. |
| 145 | bool Intersects(const wxGBPosition& pos, const wxGBSpan& span); |
| 146 | |
| 147 | // Get the row and column of the endpoint of this item |
| 148 | void GetEndPos(int& row, int& col); |
| 149 | |
| 150 | |
| 151 | wxGridBagSizer* GetGBSizer() const { return m_gbsizer; } |
| 152 | void SetGBSizer(wxGridBagSizer* sizer) { m_gbsizer = sizer; } |
| 153 | |
| 154 | |
| 155 | protected: |
| 156 | wxGBPosition m_pos; |
| 157 | wxGBSpan m_span; |
| 158 | wxGridBagSizer* m_gbsizer; // so SetPos/SetSpan can check for intersects |
| 159 | |
| 160 | |
| 161 | private: |
| 162 | DECLARE_DYNAMIC_CLASS(wxGBSizerItem) |
| 163 | DECLARE_NO_COPY_CLASS(wxGBSizerItem) |
| 164 | }; |
| 165 | |
| 166 | |
| 167 | //--------------------------------------------------------------------------- |
| 168 | // wxGridBagSizer |
| 169 | //--------------------------------------------------------------------------- |
| 170 | |
| 171 | |
| 172 | class WXDLLEXPORT wxGridBagSizer : public wxFlexGridSizer |
| 173 | { |
| 174 | public: |
| 175 | wxGridBagSizer(int vgap = 0, int hgap = 0 ); |
| 176 | |
| 177 | // The Add methods return true if the item was successfully placed at the |
| 178 | // given position, false if something was already there. |
| 179 | wxSizerItem* Add( wxWindow *window, |
| 180 | const wxGBPosition& pos, |
| 181 | const wxGBSpan& span = wxDefaultSpan, |
| 182 | int flag = 0, |
| 183 | int border = 0, |
| 184 | wxObject* userData = NULL ); |
| 185 | wxSizerItem* Add( wxSizer *sizer, |
| 186 | const wxGBPosition& pos, |
| 187 | const wxGBSpan& span = wxDefaultSpan, |
| 188 | int flag = 0, |
| 189 | int border = 0, |
| 190 | wxObject* userData = NULL ); |
| 191 | wxSizerItem* Add( int width, |
| 192 | int height, |
| 193 | const wxGBPosition& pos, |
| 194 | const wxGBSpan& span = wxDefaultSpan, |
| 195 | int flag = 0, |
| 196 | int border = 0, |
| 197 | wxObject* userData = NULL ); |
| 198 | wxSizerItem* Add( wxGBSizerItem *item ); |
| 199 | |
| 200 | |
| 201 | // Get/Set the size used for cells in the grid with no item. |
| 202 | wxSize GetEmptyCellSize() const { return m_emptyCellSize; } |
| 203 | void SetEmptyCellSize(const wxSize& sz) { m_emptyCellSize = sz; } |
| 204 | |
| 205 | // Get the size of the specified cell, including hgap and vgap. Only |
| 206 | // valid after a Layout. |
| 207 | wxSize GetCellSize(int row, int col) const; |
| 208 | |
| 209 | // Get the grid position of the specified item (non-recursive) |
| 210 | wxGBPosition GetItemPosition(wxWindow *window); |
| 211 | wxGBPosition GetItemPosition(wxSizer *sizer); |
| 212 | wxGBPosition GetItemPosition(size_t index); |
| 213 | |
| 214 | // Set the grid position of the specified item. Returns true on success. |
| 215 | // If the move is not allowed (because an item is already there) then |
| 216 | // false is returned. (non-recursive) |
| 217 | bool SetItemPosition(wxWindow *window, const wxGBPosition& pos); |
| 218 | bool SetItemPosition(wxSizer *sizer, const wxGBPosition& pos); |
| 219 | bool SetItemPosition(size_t index, const wxGBPosition& pos); |
| 220 | |
| 221 | // Get the row/col spanning of the specified item (non-recursive) |
| 222 | wxGBSpan GetItemSpan(wxWindow *window); |
| 223 | wxGBSpan GetItemSpan(wxSizer *sizer); |
| 224 | wxGBSpan GetItemSpan(size_t index); |
| 225 | |
| 226 | // Set the row/col spanning of the specified item. Returns true on |
| 227 | // success. If the move is not allowed (because an item is already there) |
| 228 | // then false is returned. (non-recursive) |
| 229 | bool SetItemSpan(wxWindow *window, const wxGBSpan& span); |
| 230 | bool SetItemSpan(wxSizer *sizer, const wxGBSpan& span); |
| 231 | bool SetItemSpan(size_t index, const wxGBSpan& span); |
| 232 | |
| 233 | |
| 234 | // Find the sizer item for the given window or subsizer, returns NULL if |
| 235 | // not found. (non-recursive) |
| 236 | wxGBSizerItem* FindItem(wxWindow* window); |
| 237 | wxGBSizerItem* FindItem(wxSizer* sizer); |
| 238 | |
| 239 | |
| 240 | // Return the sizer item for the given grid cell, or NULL if there is no |
| 241 | // item at that position. (non-recursive) |
| 242 | wxGBSizerItem* FindItemAtPosition(const wxGBPosition& pos); |
| 243 | |
| 244 | |
| 245 | // Return the sizer item located at the point given in pt, or NULL if |
| 246 | // there is no item at that point. The (x,y) coordinates in pt correspond |
| 247 | // to the client coordinates of the window using the sizer for |
| 248 | // layout. (non-recursive) |
| 249 | wxGBSizerItem* FindItemAtPoint(const wxPoint& pt); |
| 250 | |
| 251 | |
| 252 | // Return the sizer item that has a matching user data (it only compares |
| 253 | // pointer values) or NULL if not found. (non-recursive) |
| 254 | wxGBSizerItem* FindItemWithData(const wxObject* userData); |
| 255 | |
| 256 | |
| 257 | // These are what make the sizer do size calculations and layout |
| 258 | virtual void RecalcSizes(); |
| 259 | virtual wxSize CalcMin(); |
| 260 | |
| 261 | |
| 262 | // Look at all items and see if any intersect (or would overlap) the given |
| 263 | // item. Returns true if so, false if there would be no overlap. If an |
| 264 | // excludeItem is given then it will not be checked for intersection, for |
| 265 | // example it may be the item we are checking the position of. |
| 266 | bool CheckForIntersection(wxGBSizerItem* item, wxGBSizerItem* excludeItem = NULL); |
| 267 | bool CheckForIntersection(const wxGBPosition& pos, const wxGBSpan& span, wxGBSizerItem* excludeItem = NULL); |
| 268 | |
| 269 | |
| 270 | // The Add base class virtuals should not be used with this class, but |
| 271 | // we'll try to make them automatically select a location for the item |
| 272 | // anyway. |
| 273 | virtual wxSizerItem* Add( wxWindow *window, int proportion = 0, int flag = 0, int border = 0, wxObject* userData = NULL ); |
| 274 | virtual wxSizerItem* Add( wxSizer *sizer, int proportion = 0, int flag = 0, int border = 0, wxObject* userData = NULL ); |
| 275 | virtual wxSizerItem* Add( int width, int height, int proportion = 0, int flag = 0, int border = 0, wxObject* userData = NULL ); |
| 276 | |
| 277 | // The Insert and Prepend base class virtuals that are not appropriate for |
| 278 | // this class and should not be used. Their implementation in this class |
| 279 | // simply fails. |
| 280 | virtual wxSizerItem* Add( wxSizerItem *item ); |
| 281 | virtual wxSizerItem* Insert( size_t index, wxWindow *window, int proportion = 0, int flag = 0, int border = 0, wxObject* userData = NULL ); |
| 282 | virtual wxSizerItem* Insert( size_t index, wxSizer *sizer, int proportion = 0, int flag = 0, int border = 0, wxObject* userData = NULL ); |
| 283 | virtual wxSizerItem* Insert( size_t index, int width, int height, int proportion = 0, int flag = 0, int border = 0, wxObject* userData = NULL ); |
| 284 | virtual wxSizerItem* Insert( size_t index, wxSizerItem *item ); |
| 285 | virtual wxSizerItem* Prepend( wxWindow *window, int proportion = 0, int flag = 0, int border = 0, wxObject* userData = NULL ); |
| 286 | virtual wxSizerItem* Prepend( wxSizer *sizer, int proportion = 0, int flag = 0, int border = 0, wxObject* userData = NULL ); |
| 287 | virtual wxSizerItem* Prepend( int width, int height, int proportion = 0, int flag = 0, int border = 0, wxObject* userData = NULL ); |
| 288 | virtual wxSizerItem* Prepend( wxSizerItem *item ); |
| 289 | |
| 290 | |
| 291 | protected: |
| 292 | wxGBPosition FindEmptyCell(); |
| 293 | |
| 294 | wxSize m_emptyCellSize; |
| 295 | |
| 296 | |
| 297 | private: |
| 298 | |
| 299 | DECLARE_CLASS(wxGridBagSizer) |
| 300 | DECLARE_NO_COPY_CLASS(wxGridBagSizer) |
| 301 | }; |
| 302 | |
| 303 | //--------------------------------------------------------------------------- |
| 304 | #endif |