1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/gbsizer.cpp
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 // Copyright: (c) Robin Dunn
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
12
13 // For compilers that support precompilation, includes "wx.h".
14 #include "wx/wxprec.h"
15
16
17 #include "wx/gbsizer.h"
18
19 //---------------------------------------------------------------------------
20
21 wxIMPLEMENT_DYNAMIC_CLASS(wxGBSizerItem, wxSizerItem);
22 wxIMPLEMENT_CLASS(wxGridBagSizer, wxFlexGridSizer);
23
24 const wxGBSpan wxDefaultSpan;
25
26 //---------------------------------------------------------------------------
27 // wxGBSizerItem
28 //---------------------------------------------------------------------------
29
wxGBSizerItem(int width,int height,const wxGBPosition & pos,const wxGBSpan & span,int flag,int border,wxObject * userData)30 wxGBSizerItem::wxGBSizerItem( int width,
31 int height,
32 const wxGBPosition& pos,
33 const wxGBSpan& span,
34 int flag,
35 int border,
36 wxObject* userData)
37 : wxSizerItem(width, height, 0, flag, border, userData),
38 m_pos(pos),
39 m_span(span),
40 m_gbsizer(NULL)
41 {
42 }
43
44
wxGBSizerItem(wxWindow * window,const wxGBPosition & pos,const wxGBSpan & span,int flag,int border,wxObject * userData)45 wxGBSizerItem::wxGBSizerItem( wxWindow *window,
46 const wxGBPosition& pos,
47 const wxGBSpan& span,
48 int flag,
49 int border,
50 wxObject* userData )
51 : wxSizerItem(window, 0, flag, border, userData),
52 m_pos(pos),
53 m_span(span),
54 m_gbsizer(NULL)
55 {
56 }
57
58
wxGBSizerItem(wxSizer * sizer,const wxGBPosition & pos,const wxGBSpan & span,int flag,int border,wxObject * userData)59 wxGBSizerItem::wxGBSizerItem( wxSizer *sizer,
60 const wxGBPosition& pos,
61 const wxGBSpan& span,
62 int flag,
63 int border,
64 wxObject* userData )
65 : wxSizerItem(sizer, 0, flag, border, userData),
66 m_pos(pos),
67 m_span(span),
68 m_gbsizer(NULL)
69 {
70 }
71
wxGBSizerItem()72 wxGBSizerItem::wxGBSizerItem()
73 : wxSizerItem(),
74 m_pos(-1,-1),
75 m_gbsizer(NULL)
76 {
77 }
78
79 //---------------------------------------------------------------------------
80
81
GetPos(int & row,int & col) const82 void wxGBSizerItem::GetPos(int& row, int& col) const
83 {
84 row = m_pos.GetRow();
85 col = m_pos.GetCol();
86 }
87
GetSpan(int & rowspan,int & colspan) const88 void wxGBSizerItem::GetSpan(int& rowspan, int& colspan) const
89 {
90 rowspan = m_span.GetRowspan();
91 colspan = m_span.GetColspan();
92 }
93
94
SetPos(const wxGBPosition & pos)95 bool wxGBSizerItem::SetPos( const wxGBPosition& pos )
96 {
97 if (m_gbsizer)
98 {
99 wxCHECK_MSG( !m_gbsizer->CheckForIntersection(pos, m_span, this), false,
100 wxT("An item is already at that position") );
101 }
102 m_pos = pos;
103 return true;
104 }
105
SetSpan(const wxGBSpan & span)106 bool wxGBSizerItem::SetSpan( const wxGBSpan& span )
107 {
108 if (m_gbsizer)
109 {
110 wxCHECK_MSG( !m_gbsizer->CheckForIntersection(m_pos, span, this), false,
111 wxT("An item is already at that position") );
112 }
113 m_span = span;
114 return true;
115 }
116
117
InRange(int val,int min,int max)118 inline bool InRange(int val, int min, int max)
119 {
120 return (val >= min && val <= max);
121 }
122
Intersects(const wxGBSizerItem & other)123 bool wxGBSizerItem::Intersects(const wxGBSizerItem& other)
124 {
125 return Intersects(other.GetPos(), other.GetSpan());
126 }
127
Intersects(const wxGBPosition & pos,const wxGBSpan & span)128 bool wxGBSizerItem::Intersects(const wxGBPosition& pos, const wxGBSpan& span)
129 {
130
131 int row, col, endrow, endcol;
132 int otherrow, othercol, otherendrow, otherendcol;
133
134 GetPos(row, col);
135 GetEndPos(endrow, endcol);
136
137 otherrow = pos.GetRow();
138 othercol = pos.GetCol();
139 otherendrow = otherrow + span.GetRowspan() - 1;
140 otherendcol = othercol + span.GetColspan() - 1;
141
142 // is the other item's start or end in the range of this one?
143 if (( InRange(otherrow, row, endrow) && InRange(othercol, col, endcol) ) ||
144 ( InRange(otherendrow, row, endrow) && InRange(otherendcol, col, endcol) ))
145 return true;
146
147 // is this item's start or end in the range of the other one?
148 if (( InRange(row, otherrow, otherendrow) && InRange(col, othercol, otherendcol) ) ||
149 ( InRange(endrow, otherrow, otherendrow) && InRange(endcol, othercol, otherendcol) ))
150 return true;
151
152 return false;
153 }
154
155
GetEndPos(int & row,int & col)156 void wxGBSizerItem::GetEndPos(int& row, int& col)
157 {
158 row = m_pos.GetRow() + m_span.GetRowspan() - 1;
159 col = m_pos.GetCol() + m_span.GetColspan() - 1;
160 }
161
162
163 //---------------------------------------------------------------------------
164 // wxGridBagSizer
165 //---------------------------------------------------------------------------
166
wxGridBagSizer(int vgap,int hgap)167 wxGridBagSizer::wxGridBagSizer(int vgap, int hgap )
168 : wxFlexGridSizer(1, vgap, hgap),
169 m_emptyCellSize(10,20)
170
171 {
172 }
173
174
Add(wxWindow * window,const wxGBPosition & pos,const wxGBSpan & span,int flag,int border,wxObject * userData)175 wxSizerItem* wxGridBagSizer::Add( wxWindow *window,
176 const wxGBPosition& pos, const wxGBSpan& span,
177 int flag, int border, wxObject* userData )
178 {
179 wxGBSizerItem* item = new wxGBSizerItem(window, pos, span, flag, border, userData);
180 if ( Add(item) )
181 return item;
182
183 delete item;
184 return NULL;
185 }
186
Add(wxSizer * sizer,const wxGBPosition & pos,const wxGBSpan & span,int flag,int border,wxObject * userData)187 wxSizerItem* wxGridBagSizer::Add( wxSizer *sizer,
188 const wxGBPosition& pos, const wxGBSpan& span,
189 int flag, int border, wxObject* userData )
190 {
191 wxGBSizerItem* item = new wxGBSizerItem(sizer, pos, span, flag, border, userData);
192 if ( Add(item) )
193 return item;
194
195 delete item;
196 return NULL;
197 }
198
Add(int width,int height,const wxGBPosition & pos,const wxGBSpan & span,int flag,int border,wxObject * userData)199 wxSizerItem* wxGridBagSizer::Add( int width, int height,
200 const wxGBPosition& pos, const wxGBSpan& span,
201 int flag, int border, wxObject* userData )
202 {
203 wxGBSizerItem* item = new wxGBSizerItem(width, height, pos, span, flag, border, userData);
204 if ( Add(item) )
205 return item;
206
207 delete item;
208 return NULL;
209 }
210
Add(wxGBSizerItem * item)211 wxSizerItem* wxGridBagSizer::Add( wxGBSizerItem *item )
212 {
213 wxCHECK_MSG( !CheckForIntersection(item), NULL,
214 wxT("An item is already at that position") );
215 m_children.Append(item);
216 item->SetGBSizer(this);
217 if ( item->GetWindow() )
218 item->GetWindow()->SetContainingSizer( this );
219
220 // extend the number of rows/columns of the underlying wxFlexGridSizer if
221 // necessary
222 int row, col;
223 item->GetEndPos(row, col);
224 row++;
225 col++;
226
227 if ( row > GetRows() )
228 SetRows(row);
229 if ( col > GetCols() )
230 SetCols(col);
231
232 return item;
233 }
234
235
236
237 //---------------------------------------------------------------------------
238
GetCellSize(int row,int col) const239 wxSize wxGridBagSizer::GetCellSize(int row, int col) const
240 {
241 wxCHECK_MSG( (row < m_rows) && (col < m_cols),
242 wxDefaultSize,
243 wxT("Invalid cell."));
244 return wxSize( m_colWidths[col], m_rowHeights[row] );
245 }
246
247
GetItemPosition(wxWindow * window)248 wxGBPosition wxGridBagSizer::GetItemPosition(wxWindow *window)
249 {
250 wxGBPosition badpos(-1,-1);
251 wxGBSizerItem* item = FindItem(window);
252 wxCHECK_MSG(item, badpos, wxT("Failed to find item."));
253 return item->GetPos();
254 }
255
256
GetItemPosition(wxSizer * sizer)257 wxGBPosition wxGridBagSizer::GetItemPosition(wxSizer *sizer)
258 {
259 wxGBPosition badpos(-1,-1);
260 wxGBSizerItem* item = FindItem(sizer);
261 wxCHECK_MSG(item, badpos, wxT("Failed to find item."));
262 return item->GetPos();
263 }
264
265
GetItemPosition(size_t index)266 wxGBPosition wxGridBagSizer::GetItemPosition(size_t index)
267 {
268 wxGBPosition badpos(-1,-1);
269 wxSizerItemList::compatibility_iterator node = m_children.Item( index );
270 wxCHECK_MSG( node, badpos, wxT("Failed to find item.") );
271 wxGBSizerItem* item = (wxGBSizerItem*)node->GetData();
272 return item->GetPos();
273 }
274
275
276
SetItemPosition(wxWindow * window,const wxGBPosition & pos)277 bool wxGridBagSizer::SetItemPosition(wxWindow *window, const wxGBPosition& pos)
278 {
279 wxGBSizerItem* item = FindItem(window);
280 wxCHECK_MSG(item, false, wxT("Failed to find item."));
281 return item->SetPos(pos);
282 }
283
284
SetItemPosition(wxSizer * sizer,const wxGBPosition & pos)285 bool wxGridBagSizer::SetItemPosition(wxSizer *sizer, const wxGBPosition& pos)
286 {
287 wxGBSizerItem* item = FindItem(sizer);
288 wxCHECK_MSG(item, false, wxT("Failed to find item."));
289 return item->SetPos(pos);
290 }
291
292
SetItemPosition(size_t index,const wxGBPosition & pos)293 bool wxGridBagSizer::SetItemPosition(size_t index, const wxGBPosition& pos)
294 {
295 wxSizerItemList::compatibility_iterator node = m_children.Item( index );
296 wxCHECK_MSG( node, false, wxT("Failed to find item.") );
297 wxGBSizerItem* item = (wxGBSizerItem*)node->GetData();
298 return item->SetPos(pos);
299 }
300
301
302
GetItemSpan(wxWindow * window)303 wxGBSpan wxGridBagSizer::GetItemSpan(wxWindow *window)
304 {
305 wxGBSizerItem* item = FindItem(window);
306 wxCHECK_MSG( item, wxGBSpan::Invalid(), wxT("Failed to find item.") );
307 return item->GetSpan();
308 }
309
310
GetItemSpan(wxSizer * sizer)311 wxGBSpan wxGridBagSizer::GetItemSpan(wxSizer *sizer)
312 {
313 wxGBSizerItem* item = FindItem(sizer);
314 wxCHECK_MSG( item, wxGBSpan::Invalid(), wxT("Failed to find item.") );
315 return item->GetSpan();
316 }
317
318
GetItemSpan(size_t index)319 wxGBSpan wxGridBagSizer::GetItemSpan(size_t index)
320 {
321 wxSizerItemList::compatibility_iterator node = m_children.Item( index );
322 wxCHECK_MSG( node, wxGBSpan::Invalid(), wxT("Failed to find item.") );
323 wxGBSizerItem* item = (wxGBSizerItem*)node->GetData();
324 return item->GetSpan();
325 }
326
327
328
SetItemSpan(wxWindow * window,const wxGBSpan & span)329 bool wxGridBagSizer::SetItemSpan(wxWindow *window, const wxGBSpan& span)
330 {
331 wxGBSizerItem* item = FindItem(window);
332 wxCHECK_MSG(item, false, wxT("Failed to find item."));
333 return item->SetSpan(span);
334 }
335
336
SetItemSpan(wxSizer * sizer,const wxGBSpan & span)337 bool wxGridBagSizer::SetItemSpan(wxSizer *sizer, const wxGBSpan& span)
338 {
339 wxGBSizerItem* item = FindItem(sizer);
340 wxCHECK_MSG(item, false, wxT("Failed to find item."));
341 return item->SetSpan(span);
342 }
343
344
SetItemSpan(size_t index,const wxGBSpan & span)345 bool wxGridBagSizer::SetItemSpan(size_t index, const wxGBSpan& span)
346 {
347 wxSizerItemList::compatibility_iterator node = m_children.Item( index );
348 wxCHECK_MSG( node, false, wxT("Failed to find item.") );
349 wxGBSizerItem* item = (wxGBSizerItem*)node->GetData();
350 return item->SetSpan(span);
351 }
352
353
354
355
FindItem(wxWindow * window)356 wxGBSizerItem* wxGridBagSizer::FindItem(wxWindow* window)
357 {
358 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
359 while (node)
360 {
361 wxGBSizerItem* item = (wxGBSizerItem*)node->GetData();
362 if ( item->GetWindow() == window )
363 return item;
364 node = node->GetNext();
365 }
366 return NULL;
367 }
368
369
FindItem(wxSizer * sizer)370 wxGBSizerItem* wxGridBagSizer::FindItem(wxSizer* sizer)
371 {
372 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
373 while (node)
374 {
375 wxGBSizerItem* item = (wxGBSizerItem*)node->GetData();
376 if ( item->GetSizer() == sizer )
377 return item;
378 node = node->GetNext();
379 }
380 return NULL;
381 }
382
383
384
385
FindItemAtPosition(const wxGBPosition & pos)386 wxGBSizerItem* wxGridBagSizer::FindItemAtPosition(const wxGBPosition& pos)
387 {
388 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
389 while (node)
390 {
391 wxGBSizerItem* item = (wxGBSizerItem*)node->GetData();
392 if ( item->Intersects(pos, wxDefaultSpan) )
393 return item;
394 node = node->GetNext();
395 }
396 return NULL;
397 }
398
399
400
401
FindItemAtPoint(const wxPoint & pt)402 wxGBSizerItem* wxGridBagSizer::FindItemAtPoint(const wxPoint& pt)
403 {
404 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
405 while (node)
406 {
407 wxGBSizerItem* item = (wxGBSizerItem*)node->GetData();
408 wxRect rect(item->GetPosition(), item->GetSize());
409 rect.Inflate(m_hgap, m_vgap);
410 if ( rect.Contains(pt) )
411 return item;
412 node = node->GetNext();
413 }
414 return NULL;
415 }
416
417
418
419
FindItemWithData(const wxObject * userData)420 wxGBSizerItem* wxGridBagSizer::FindItemWithData(const wxObject* userData)
421 {
422 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
423 while (node)
424 {
425 wxGBSizerItem* item = (wxGBSizerItem*)node->GetData();
426 if ( item->GetUserData() == userData )
427 return item;
428 node = node->GetNext();
429 }
430 return NULL;
431 }
432
433
434
435
436 //---------------------------------------------------------------------------
437
438 // Figure out what all the min row heights and col widths are, and calculate
439 // min size from that.
CalcMin()440 wxSize wxGridBagSizer::CalcMin()
441 {
442 int idx;
443
444 if (m_children.GetCount() == 0)
445 return m_emptyCellSize;
446
447 m_rowHeights.Empty();
448 m_colWidths.Empty();
449
450 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
451 while (node)
452 {
453 wxGBSizerItem* item = (wxGBSizerItem*)node->GetData();
454 if ( item->IsShown() )
455 {
456 int row, col, endrow, endcol;
457
458 item->GetPos(row, col);
459 item->GetEndPos(endrow, endcol);
460
461 // fill heights and widths up to this item if needed
462 while ( (int)m_rowHeights.GetCount() <= endrow )
463 m_rowHeights.Add(m_emptyCellSize.GetHeight());
464 while ( (int)m_colWidths.GetCount() <= endcol )
465 m_colWidths.Add(m_emptyCellSize.GetWidth());
466
467 // See if this item increases the size of its row(s) or col(s)
468 wxSize size(item->CalcMin());
469 for (idx=row; idx <= endrow; idx++)
470 m_rowHeights[idx] = wxMax(m_rowHeights[idx], size.GetHeight() / (endrow-row+1));
471 for (idx=col; idx <= endcol; idx++)
472 m_colWidths[idx] = wxMax(m_colWidths[idx], size.GetWidth() / (endcol-col+1));
473 }
474 node = node->GetNext();
475 }
476
477 AdjustForOverflow();
478 AdjustForFlexDirection();
479
480 // Now traverse the heights and widths arrays calcing the totals, including gaps
481 int width = 0;
482 m_cols = m_colWidths.GetCount();
483 for (idx=0; idx < m_cols; idx++)
484 width += m_colWidths[idx] + ( idx == m_cols-1 ? 0 : m_hgap );
485
486 int height = 0;
487 m_rows = m_rowHeights.GetCount();
488 for (idx=0; idx < m_rows; idx++)
489 height += m_rowHeights[idx] + ( idx == m_rows-1 ? 0 : m_vgap );
490
491 return wxSize(width, height);
492 }
493
494
495
RepositionChildren(const wxSize & minSize)496 void wxGridBagSizer::RepositionChildren(const wxSize& minSize)
497 {
498 // We can't lay out our elements if we don't have at least a single row and
499 // a single column. Notice that this may happen even if we have some
500 // children but all of them are hidden, so checking for m_children being
501 // non-empty is not enough, see #15475.
502 if ( m_rowHeights.empty() || m_colWidths.empty() )
503 return;
504
505 wxPoint pt( GetPosition() );
506 wxSize sz( GetSize() );
507
508 m_rows = m_rowHeights.GetCount();
509 m_cols = m_colWidths.GetCount();
510 int idx, width, height;
511
512 AdjustForGrowables(sz, minSize);
513
514 // Find the start positions on the window of the rows and columns
515 wxArrayInt rowpos;
516 rowpos.Add(0, m_rows);
517 int y = pt.y;
518 for (idx=0; idx < m_rows; idx++)
519 {
520 height = m_rowHeights[idx] + m_vgap;
521 rowpos[idx] = y;
522 y += height;
523 }
524
525 wxArrayInt colpos;
526 colpos.Add(0, m_cols);
527 int x = pt.x;
528 for (idx=0; idx < m_cols; idx++)
529 {
530 width = m_colWidths[idx] + m_hgap;
531 colpos[idx] = x;
532 x += width;
533 }
534
535
536 // Now iterate the children, setting each child's dimensions
537 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
538 while (node)
539 {
540 wxGBSizerItem* item = (wxGBSizerItem*)node->GetData();
541
542 if ( item->IsShown() )
543 {
544 int row, col, endrow, endcol;
545 item->GetPos(row, col);
546 item->GetEndPos(endrow, endcol);
547
548 height = 0;
549 for(idx=row; idx <= endrow; idx++)
550 height += m_rowHeights[idx];
551 height += (endrow - row) * m_vgap; // add a vgap for every row spanned
552
553 width = 0;
554 for (idx=col; idx <= endcol; idx++)
555 width += m_colWidths[idx];
556 width += (endcol - col) * m_hgap; // add a hgap for every col spanned
557
558 SetItemBounds(item, colpos[col], rowpos[row], width, height);
559 }
560
561 node = node->GetNext();
562 }
563 }
564
565
566 // Sometimes CalcMin can result in some rows or cols having too much space in
567 // them because as it traverses the items it makes some assumptions when
568 // items span to other cells. But those assumptions can become invalid later
569 // on when other items are fitted into the same rows or columns that the
570 // spanning item occupies. This method tries to find those situations and
571 // fixes them.
AdjustForOverflow()572 void wxGridBagSizer::AdjustForOverflow()
573 {
574 int row, col;
575
576 for (row=0; row<(int)m_rowHeights.GetCount(); row++)
577 {
578 int rowExtra=INT_MAX;
579 int rowHeight = m_rowHeights[row];
580 for (col=0; col<(int)m_colWidths.GetCount(); col++)
581 {
582 wxGBPosition pos(row,col);
583 wxGBSizerItem* item = FindItemAtPosition(pos);
584 if ( !item || !item->IsShown() )
585 continue;
586
587 int endrow, endcol;
588 item->GetEndPos(endrow, endcol);
589
590 // If the item starts in this position and doesn't span rows, then
591 // just look at the whole item height
592 if ( item->GetPos() == pos && endrow == row )
593 {
594 int itemHeight = item->CalcMin().GetHeight();
595 rowExtra = wxMin(rowExtra, rowHeight - itemHeight);
596 continue;
597 }
598
599 // Otherwise, only look at spanning items if they end on this row
600 if ( endrow == row )
601 {
602 // first deduct the portions of the item that are on prior rows
603 int itemHeight = item->CalcMin().GetHeight();
604 for (int r=item->GetPos().GetRow(); r<row; r++)
605 itemHeight -= (m_rowHeights[r] + GetHGap());
606
607 if ( itemHeight < 0 )
608 itemHeight = 0;
609
610 // and check how much is left
611 rowExtra = wxMin(rowExtra, rowHeight - itemHeight);
612 }
613 }
614 if ( rowExtra && rowExtra != INT_MAX )
615 m_rowHeights[row] -= rowExtra;
616 }
617
618 // Now do the same thing for columns
619 for (col=0; col<(int)m_colWidths.GetCount(); col++)
620 {
621 int colExtra=INT_MAX;
622 int colWidth = m_colWidths[col];
623 for (row=0; row<(int)m_rowHeights.GetCount(); row++)
624 {
625 wxGBPosition pos(row,col);
626 wxGBSizerItem* item = FindItemAtPosition(pos);
627 if ( !item || !item->IsShown() )
628 continue;
629
630 int endrow, endcol;
631 item->GetEndPos(endrow, endcol);
632
633 if ( item->GetPos() == pos && endcol == col )
634 {
635 int itemWidth = item->CalcMin().GetWidth();
636 colExtra = wxMin(colExtra, colWidth - itemWidth);
637 continue;
638 }
639
640 if ( endcol == col )
641 {
642 int itemWidth = item->CalcMin().GetWidth();
643 for (int c=item->GetPos().GetCol(); c<col; c++)
644 itemWidth -= (m_colWidths[c] + GetVGap());
645
646 if ( itemWidth < 0 )
647 itemWidth = 0;
648
649 colExtra = wxMin(colExtra, colWidth - itemWidth);
650 }
651 }
652 if ( colExtra && colExtra != INT_MAX )
653 m_colWidths[col] -= colExtra;
654 }
655
656
657 }
658
659 //---------------------------------------------------------------------------
660
CheckForIntersection(wxGBSizerItem * item,wxGBSizerItem * excludeItem)661 bool wxGridBagSizer::CheckForIntersection(wxGBSizerItem* item, wxGBSizerItem* excludeItem)
662 {
663 return CheckForIntersection(item->GetPos(), item->GetSpan(), excludeItem);
664 }
665
CheckForIntersection(const wxGBPosition & pos,const wxGBSpan & span,wxGBSizerItem * excludeItem)666 bool wxGridBagSizer::CheckForIntersection(const wxGBPosition& pos, const wxGBSpan& span, wxGBSizerItem* excludeItem)
667 {
668 wxSizerItemList::compatibility_iterator node = m_children.GetFirst();
669 while (node)
670 {
671 wxGBSizerItem* item = (wxGBSizerItem*)node->GetData();
672 node = node->GetNext();
673
674 if ( excludeItem && item == excludeItem )
675 continue;
676
677 if ( item->Intersects(pos, span) )
678 return true;
679
680 }
681 return false;
682 }
683
684
685 // Assumes a 10x10 grid, and returns the first empty cell found. This is
686 // really stupid but it is only used by the Add methods that match the base
687 // class virtuals, which should normally not be used anyway...
FindEmptyCell()688 wxGBPosition wxGridBagSizer::FindEmptyCell()
689 {
690 int row, col;
691
692 for (row=0; row<10; row++)
693 for (col=0; col<10; col++)
694 {
695 wxGBPosition pos(row, col);
696 if ( !CheckForIntersection(pos, wxDefaultSpan) )
697 return pos;
698 }
699 return wxGBPosition(-1, -1);
700 }
701
702
703 //---------------------------------------------------------------------------
704
705 // The Add base class virtuals should not be used with this class, but
706 // we'll try to make them automatically select a location for the item
707 // anyway.
708
Add(wxWindow * window,int,int flag,int border,wxObject * userData)709 wxSizerItem* wxGridBagSizer::Add( wxWindow *window, int, int flag, int border, wxObject* userData )
710 {
711 return Add(window, FindEmptyCell(), wxDefaultSpan, flag, border, userData);
712 }
713
Add(wxSizer * sizer,int,int flag,int border,wxObject * userData)714 wxSizerItem* wxGridBagSizer::Add( wxSizer *sizer, int, int flag, int border, wxObject* userData )
715 {
716 return Add(sizer, FindEmptyCell(), wxDefaultSpan, flag, border, userData);
717 }
718
Add(int width,int height,int,int flag,int border,wxObject * userData)719 wxSizerItem* wxGridBagSizer::Add( int width, int height, int, int flag, int border, wxObject* userData )
720 {
721 return Add(width, height, FindEmptyCell(), wxDefaultSpan, flag, border, userData);
722 }
723
724
725
726 // The Insert nad Prepend base class virtuals that are not appropriate for
727 // this class and should not be used. Their implementation in this class
728 // simply fails.
729
Add(wxSizerItem *)730 wxSizerItem* wxGridBagSizer::Add( wxSizerItem * )
731 {
732 wxFAIL_MSG(wxT("Invalid Add form called."));
733 return NULL;
734 }
735
Prepend(wxWindow *,int,int,int,wxObject *)736 wxSizerItem* wxGridBagSizer::Prepend( wxWindow *, int, int, int, wxObject* )
737 {
738 wxFAIL_MSG(wxT("Prepend should not be used with wxGridBagSizer."));
739 return NULL;
740 }
741
Prepend(wxSizer *,int,int,int,wxObject *)742 wxSizerItem* wxGridBagSizer::Prepend( wxSizer *, int, int, int, wxObject* )
743 {
744 wxFAIL_MSG(wxT("Prepend should not be used with wxGridBagSizer."));
745 return NULL;
746 }
747
Prepend(int,int,int,int,int,wxObject *)748 wxSizerItem* wxGridBagSizer::Prepend( int, int, int, int, int, wxObject* )
749 {
750 wxFAIL_MSG(wxT("Prepend should not be used with wxGridBagSizer."));
751 return NULL;
752 }
753
Prepend(wxSizerItem *)754 wxSizerItem* wxGridBagSizer::Prepend( wxSizerItem * )
755 {
756 wxFAIL_MSG(wxT("Prepend should not be used with wxGridBagSizer."));
757 return NULL;
758 }
759
760
Insert(size_t,wxWindow *,int,int,int,wxObject *)761 wxSizerItem* wxGridBagSizer::Insert( size_t, wxWindow *, int, int, int, wxObject* )
762 {
763 wxFAIL_MSG(wxT("Insert should not be used with wxGridBagSizer."));
764 return NULL;
765 }
766
Insert(size_t,wxSizer *,int,int,int,wxObject *)767 wxSizerItem* wxGridBagSizer::Insert( size_t, wxSizer *, int, int, int, wxObject* )
768 {
769 wxFAIL_MSG(wxT("Insert should not be used with wxGridBagSizer."));
770 return NULL;
771 }
772
Insert(size_t,int,int,int,int,int,wxObject *)773 wxSizerItem* wxGridBagSizer::Insert( size_t, int, int, int, int, int, wxObject* )
774 {
775 wxFAIL_MSG(wxT("Insert should not be used with wxGridBagSizer."));
776 return NULL;
777 }
778
Insert(size_t,wxSizerItem *)779 wxSizerItem* wxGridBagSizer::Insert( size_t, wxSizerItem * )
780 {
781 wxFAIL_MSG(wxT("Insert should not be used with wxGridBagSizer."));
782 return NULL;
783 }
784
785
786 //---------------------------------------------------------------------------
787 //---------------------------------------------------------------------------
788