xref: /haiku/src/libs/alm/Area.cpp (revision 893988af824e65e49e55f517b157db8386e8002b)
1 /*
2  * Copyright 2007-2008, Christof Lutteroth, lutteroth@cs.auckland.ac.nz
3  * Copyright 2007-2008, James Kim, jkim202@ec.auckland.ac.nz
4  * Distributed under the terms of the MIT License.
5  */
6 
7 #include "Area.h"
8 #include "Column.h"
9 #include "BALMLayout.h"
10 #include "OperatorType.h"
11 #include "Row.h"
12 #include "XTab.h"
13 #include "YTab.h"
14 
15 #include <Button.h>
16 #include <RadioButton.h>
17 #include <CheckBox.h>
18 #include <StringView.h>
19 #include <PictureButton.h>
20 #include <StatusBar.h>
21 
22 #include <algorithm>	// for max
23 
24 using namespace std;
25 
26 BSize Area::kMaxSize(INT_MAX, INT_MAX);
27 BSize Area::kMinSize(0, 0);
28 BSize Area::kUndefinedSize(-1, -1);
29 
30 
31 /**
32  * Gets the auto preferred content size.
33  *
34  * @return the auto preferred content size
35  */
36 bool
37 Area::AutoPrefContentSize() const
38 {
39 	return fAutoPrefContentSize;
40 }
41 
42 
43 /**
44  * Sets the auto preferred content size true or false.
45  *
46  * @param value	the auto preferred content size
47  */
48 void
49 Area::SetAutoPrefContentSize(bool value)
50 {
51 	fAutoPrefContentSize = value;
52 }
53 
54 
55 /**
56  * Gets the left tab of the area.
57  *
58  * @return the left tab of the area
59  */
60 XTab*
61 Area::Left() const
62 {
63 	return fLeft;
64 }
65 
66 
67 /**
68  * Sets the left tab of the area.
69  *
70  * @param left	the left tab of the area
71  */
72 void
73 Area::SetLeft(XTab* left)
74 {
75 	fLeft = left;
76 
77 	fColumn = NULL;
78 
79 	if (fChildArea == NULL) {
80 		fMinContentWidth->SetLeftSide(-1.0, fLeft, 1.0, fRight);
81 
82 		if (fMaxContentWidth != NULL)
83 			fMaxContentWidth->SetLeftSide(-1.0, fLeft, 1.0, fRight);
84 	} else
85 		UpdateHorizontal();
86 	fLS->InvalidateLayout();
87 }
88 
89 
90 /**
91  * Gets the right tab of the area.
92  *
93  * @return the right tab of the area
94  */
95 XTab*
96 Area::Right() const
97 {
98 	return fRight;
99 }
100 
101 
102 /**
103  * Sets the right tab of the area.
104  *
105  * @param right	the right tab of the area
106  */
107 void
108 Area::SetRight(XTab* right)
109 {
110 	fRight = right;
111 
112 	fColumn = NULL;
113 
114 	if (fChildArea == NULL) {
115 		fMinContentWidth->SetLeftSide(-1.0, fLeft, 1.0, fRight);
116 
117 		if (fMaxContentWidth != NULL)
118 			fMaxContentWidth->SetLeftSide(-1.0, fLeft, 1.0, fRight);
119 	} else
120 		UpdateHorizontal();
121 	fLS->InvalidateLayout();
122 }
123 
124 
125 /**
126  * Gets the top tab of the area.
127  */
128 YTab*
129 Area::Top() const
130 {
131 	return fTop;
132 }
133 
134 
135 /**
136  * Sets the top tab of the area.
137  */
138 void
139 Area::SetTop(YTab* top)
140 {
141 	fTop = top;
142 
143 	fRow = NULL;
144 
145 	if (fChildArea == NULL) {
146 		fMinContentHeight->SetLeftSide(-1.0, fTop, 1.0, fBottom);
147 
148 		if (fMaxContentHeight != NULL)
149 			fMaxContentHeight->SetLeftSide(-1.0, fTop, 1.0, fBottom);
150 	} else
151 		UpdateVertical();
152 	fLS->InvalidateLayout();
153 }
154 
155 
156 /**
157  * Gets the bottom tab of the area.
158  */
159 YTab*
160 Area::Bottom() const
161 {
162 	return fBottom;
163 }
164 
165 
166 /**
167  * Sets the bottom tab of the area.
168  */
169 void
170 Area::SetBottom(YTab* bottom)
171 {
172 	fBottom = bottom;
173 
174 	fRow = NULL;
175 
176 	if (fChildArea == NULL) {
177 		fMinContentHeight->SetLeftSide(-1.0, fTop, 1.0, fBottom);
178 
179 		if (fMaxContentHeight != NULL)
180 			fMaxContentHeight->SetLeftSide(-1.0, fTop, 1.0, fBottom);
181 	} else
182 		UpdateVertical();
183 	fLS->InvalidateLayout();
184 }
185 
186 
187 /**
188  * Gets the row that defines the top and bottom tabs.
189  */
190 Row*
191 Area::GetRow() const
192 {
193 	return fRow;
194 }
195 
196 
197 /**
198  * Sets the row that defines the top and bottom tabs.
199  * May be null.
200  */
201 void
202 Area::SetRow(Row* row)
203 {
204 	SetTop(row->Top());
205 	SetBottom(row->Bottom());
206 	fRow = row;
207 	fLS->InvalidateLayout();
208 }
209 
210 
211 /**
212  * Gets the column that defines the left and right tabs.
213  */
214 Column*
215 Area::GetColumn() const
216 {
217 	return fColumn;
218 }
219 
220 
221 /**
222  * Sets the column that defines the left and right tabs.
223  * May be null.
224  */
225 void
226 Area::SetColumn(Column* column)
227 {
228 	SetLeft(column->Left());
229 	SetRight(column->Right());
230 	fColumn = column;
231 	fLS->InvalidateLayout();
232 }
233 
234 
235 /**
236  * Gets the control that is the content of the area.
237  */
238 BView*
239 Area::Content() const
240 {
241 	return (fChildArea == NULL) ? fContent : fChildArea->Content();
242 }
243 
244 
245 /**
246  * Sets the control that is the content of the area.
247  */
248 void
249 Area::SetContent(BView* content)
250 {
251 	if (fChildArea == NULL) fContent = content;
252 	else fChildArea->fContent = content;
253 	fLS->InvalidateLayout();
254 }
255 
256 
257 /**
258  * Left tab of the area's content. May be different from the left tab of the area.
259  */
260 XTab*
261 Area::ContentLeft() const
262 {
263 	return (fChildArea == NULL) ? fLeft : fChildArea->fLeft;
264 }
265 
266 
267 /**
268  * Top tab of the area's content. May be different from the top tab of the area.
269  */
270 YTab*
271 Area::ContentTop() const
272 {
273 	return (fChildArea == NULL) ? fTop : fChildArea->fTop;
274 }
275 
276 
277 /**
278  * Right tab of the area's content. May be different from the right tab of the area.
279  */
280 XTab*
281 Area::ContentRight() const
282 {
283 	return (fChildArea == NULL) ? fRight : fChildArea->fRight;
284 }
285 
286 
287 /**
288  * Bottom tab of the area's content. May be different from the bottom tab of the area.
289  */
290 YTab*
291 Area::ContentBottom() const
292 {
293 	return (fChildArea == NULL) ? fBottom : fChildArea->fBottom;
294 }
295 
296 
297 /**
298  * Gets minimum size of the area's content.
299  */
300 BSize
301 Area::MinContentSize() const
302 {
303 	return (fChildArea == NULL) ? fMinContentSize : fChildArea->fMinContentSize;
304 }
305 
306 
307 /**
308  * Sets minimum size of the area's content.
309  * May be different from the minimum size of the area.
310  */
311 void
312 Area::SetMinContentSize(BSize min)
313 {
314 	if (fChildArea == NULL) {
315 		fMinContentSize = min;
316 		fMinContentWidth->SetRightSide(fMinContentSize.Width());
317 		fMinContentHeight->SetRightSide(fMinContentSize.Height());
318 	} else
319 		fChildArea->SetMinContentSize(min);
320 	fLS->InvalidateLayout();
321 }
322 
323 
324 /**
325  * Gets maximum size of the area's content.
326  */
327 BSize Area::MaxContentSize() const {
328 	return (fChildArea == NULL) ? fMaxContentSize : fChildArea->fMaxContentSize;
329 }
330 
331 
332 /**
333  * Sets maximum size of the area's content.
334  * May be different from the maximum size of the area.
335  */
336 void
337 Area::SetMaxContentSize(BSize max)
338 {
339 	if (fChildArea == NULL) {
340 		fMaxContentSize = max;
341 		if (fMaxContentWidth == NULL) {
342 			fMaxContentWidth = fLS->AddConstraint(-1.0, fLeft, 1.0, fRight, OperatorType(LE),
343 					fMaxContentSize.Width());
344 			fConstraints->AddItem(fMaxContentWidth);
345 
346 			fMaxContentHeight = fLS->AddConstraint(-1.0, fTop, 1.0, fBottom, OperatorType(LE),
347 					fMaxContentSize.Height());
348 			fConstraints->AddItem(fMaxContentHeight);
349 		} else {
350 			fMaxContentWidth->SetRightSide(fMaxContentSize.Width());
351 			fMaxContentHeight->SetRightSide(fMaxContentSize.Height());
352 		}
353 	} else
354 		fChildArea->SetMaxContentSize(max);
355 	fLS->InvalidateLayout();
356 }
357 
358 
359 /**
360  * Gets Preferred size of the area's content.
361  */
362 BSize
363 Area::PrefContentSize() const
364 {
365 	return (fChildArea == NULL) ? fPrefContentSize : fChildArea->fPrefContentSize;
366 }
367 
368 
369 /**
370  * Sets Preferred size of the area's content.
371  * May be different from the preferred size of the area.
372  * Manual changes of PrefContentSize are ignored unless autoPrefContentSize is set to false.
373  */
374 void
375 Area::SetPrefContentSize(BSize pref)
376 {
377 	if (fChildArea == NULL) {
378 		fPrefContentSize = pref;
379 		if (fPrefContentWidth == NULL) {
380 			fPrefContentWidth = fLS->AddConstraint(-1.0, fLeft, 1.0, fRight, OperatorType(EQ),
381 					fPrefContentSize.Width(), fShrinkRigidity.Width(),
382 					fExpandRigidity.Width());
383 			fConstraints->AddItem(fPrefContentWidth);
384 
385 			fPrefContentHeight = fLS->AddConstraint(-1.0, fTop, 1.0, fBottom, OperatorType(EQ),
386 					fPrefContentSize.Height(), fShrinkRigidity.Height(),
387 					fExpandRigidity.Height());
388 			fConstraints->AddItem(fPrefContentHeight);
389 		} else {
390 			fPrefContentWidth->SetRightSide(pref.Width());
391 			fPrefContentHeight->SetRightSide(pref.Height());
392 		}
393 	} else
394 		fChildArea->SetPrefContentSize(pref);
395 	fLS->InvalidateLayout();
396 }
397 
398 
399 /**
400  * The reluctance with which the area's content shrinks below its preferred size.
401  * The bigger the less likely is such shrinking.
402  */
403 BSize
404 Area::ShrinkRigidity() const
405 {
406 	return (fChildArea == NULL) ? fShrinkRigidity : fChildArea->fShrinkRigidity;
407 }
408 
409 
410 void Area::SetShrinkRigidity(BSize shrink) {
411 	if (fChildArea == NULL) {
412 		fShrinkRigidity = shrink;
413 		if (fPrefContentWidth != NULL) {
414 			fPrefContentWidth->SetPenaltyNeg(shrink.Width());
415 			fPrefContentHeight->SetPenaltyNeg(shrink.Height());
416 		}
417 	} else
418 		fChildArea->SetShrinkRigidity(shrink);
419 	fLS->InvalidateLayout();
420 }
421 
422 
423 /**
424  * The reluctance with which the area's content expands over its preferred size.
425  * The bigger the less likely is such expansion.
426  */
427 BSize
428 Area::ExpandRigidity() const
429 {
430 	return (fChildArea == NULL) ? fExpandRigidity : fChildArea->fExpandRigidity;
431 }
432 
433 
434 void
435 Area::SetExpandRigidity(BSize expand)
436 {
437 	if (fChildArea == NULL) {
438 		fExpandRigidity = expand;
439 		if (fPrefContentWidth != NULL) {
440 			fPrefContentWidth->SetPenaltyPos(expand.Width());
441 			fPrefContentHeight->SetPenaltyPos(expand.Height());
442 		}
443 	} else
444 		fChildArea->SetExpandRigidity(expand);
445 	fLS->InvalidateLayout();
446 }
447 
448 
449 /**
450  * Gets aspect ratio of the area's content.
451  */
452 double
453 Area::ContentAspectRatio() const
454 {
455 	return (fChildArea == NULL) ? fContentAspectRatio : fChildArea->fContentAspectRatio;
456 }
457 
458 
459 /**
460  * Sets aspect ratio of the area's content.
461  * May be different from the aspect ratio of the area.
462  */
463 void
464 Area::SetContentAspectRatio(double ratio)
465 {
466 	if (fChildArea == NULL) {
467 		fContentAspectRatio = ratio;
468 		if (fContentAspectRatioC == NULL) {
469 			fContentAspectRatioC = fLS->AddConstraint(
470 				-1.0, fLeft, 1.0, fRight, ratio, fTop, -ratio, fBottom,
471 				OperatorType(EQ), 0.0);
472 			fConstraints->AddItem(fContentAspectRatioC);
473 		} else {
474 			fContentAspectRatioC->SetLeftSide(
475 				-1.0, fLeft, 1.0, fRight, ratio, fTop, -ratio, fBottom);
476 		}
477 	} else
478 		fChildArea->SetContentAspectRatio(ratio);
479 	fLS->InvalidateLayout();
480 }
481 
482 
483 /**
484  * Gets alignment of the content in its area.
485  */
486 BAlignment
487 Area::Alignment() const
488 {
489 	return fAlignment;
490 }
491 
492 
493 /**
494  * Sets alignment of the content in its area.
495  */
496 void
497 Area::SetAlignment(BAlignment alignment)
498 {
499 	fAlignment = alignment;
500 	UpdateHorizontal();
501 	UpdateVertical();
502 	fLS->InvalidateLayout();
503 }
504 
505 
506 /**
507  * Sets horizontal alignment of the content in its area.
508  */
509 void Area::SetHAlignment(alignment horizontal) {
510 	fAlignment.SetHorizontal(horizontal);
511 	UpdateHorizontal();
512 	fLS->InvalidateLayout();
513 }
514 
515 
516 /**
517  * Sets vertical alignment of the content in its area.
518  */
519 void
520 Area::SetVAlignment(vertical_alignment vertical)
521 {
522 	fAlignment.SetVertical(vertical);
523 	UpdateVertical();
524 	fLS->InvalidateLayout();
525 }
526 
527 
528 /**
529  * Gets left inset between area and its content.
530  */
531 int32
532 Area::LeftInset() const
533 {
534 	return fLeftInset;
535 }
536 
537 
538 /**
539  * Sets left inset between area and its content.
540  */
541 void
542 Area::SetLeftInset(int32 left)
543 {
544 	fLeftInset = left;
545 	UpdateHorizontal();
546 	fLS->InvalidateLayout();
547 }
548 
549 
550 /**
551  * Gets top inset between area and its content.
552  */
553 int32
554 Area::TopInset() const
555 {
556 	return fTopInset;
557 }
558 
559 
560 /**
561  * Sets top inset between area and its content.
562  */
563 void
564 Area::SetTopInset(int32 top)
565 {
566 	fTopInset = top;
567 	UpdateVertical();
568 	fLS->InvalidateLayout();
569 }
570 
571 
572 /**
573  * Gets right inset between area and its content.
574  */
575 int32
576 Area::RightInset() const
577 {
578 	return fRightInset;
579 }
580 
581 
582 /**
583  * Sets right inset between area and its content.
584  */
585 void
586 Area::SetRightInset(int32 right)
587 {
588 	fRightInset = right;
589 	UpdateHorizontal();
590 }
591 
592 
593 /**
594  * Gets bottom inset between area and its content.
595  */
596 int32
597 Area::BottomInset() const
598 {
599 	return fBottomInset;
600 }
601 
602 
603 /**
604  * Sets bottom inset between area and its content.
605  */
606 void
607 Area::SetBottomInset(int32 bottom)
608 {
609 	fBottomInset = bottom;
610 	UpdateVertical();
611 }
612 
613 
614 /**
615  * Sets the preferred size according to the content's PreferredSize method,
616  * and the rigidities according to heuristics.
617  */
618 void
619 Area::SetDefaultPrefContentSize()
620 {
621 	if (Content() == NULL) {
622 		SetPrefContentSize(BSize(0, 0));
623 		SetShrinkRigidity(BSize(0, 0));
624 		SetExpandRigidity(BSize(0, 0));
625 		return;
626 	}
627 
628 	if (PrefContentSize() != Content()->PreferredSize()){
629 		SetPrefContentSize(Content()->PreferredSize());
630 		fLS->InvalidateLayout();
631 	}
632 
633 	if (dynamic_cast<BButton*>(Content()) != NULL
634 		|| dynamic_cast<BRadioButton*>(Content()) != NULL
635 		|| dynamic_cast<BCheckBox*>(Content()) != NULL
636 		|| dynamic_cast<BStringView*>(Content()) != NULL
637 		|| dynamic_cast<BPictureButton*>(Content()) != NULL
638 		|| dynamic_cast<BStatusBar*>(Content()) != NULL) {
639 		//~ || Content is LinkLabel
640 		//~ || Content is NumericUpDown) {
641 		fShrinkRigidity = BSize(4, 4);
642 		fExpandRigidity = BSize(3, 3);
643 	} else {
644 		fShrinkRigidity = BSize(2, 2);
645 		fExpandRigidity = BSize(1, 1);
646 	}
647 }
648 
649 
650 //~ string Area::ToString() {
651 	//~ return "Area(" + fLeft->ToString() + "," + fTop->ToString() + ","
652 			//~ + fRight->ToString() + "," + fBottom->ToString() + ")";
653 //~ }
654 
655 
656 /**
657  * Sets the width of the area to be the same as the width of the given area.
658  *
659  * @param area	the area that should have the same width
660  * @return the same-width constraint
661  */
662 Constraint*
663 Area::HasSameWidthAs(Area* area)
664 {
665 	return fLS->AddConstraint(
666 		-1.0, fLeft, 1.0, fRight, 1.0, area->fLeft, -1.0, area->fRight,
667 		OperatorType(EQ), 0.0);
668 }
669 
670 
671 /**
672  * Sets the height of the area to be the same as the height of the given area.
673  *
674  * @param area	the area that should have the same height
675  * @return the same-height constraint
676  */
677 Constraint*
678 Area::HasSameHeightAs(Area* area)
679 {
680 	return fLS->AddConstraint(
681 		-1.0, fTop, 1.0, fBottom, 1.0, area->fTop, -1.0, area->fBottom,
682 		OperatorType(EQ), 0.0);
683 }
684 
685 
686 /**
687  * Sets the size of the area to be the same as the size of the given area.
688  *
689  * @param area	the area that should have the same size
690  * @return a list containing a same-width and same-height constraint
691  */
692 BList*
693 Area::HasSameSizetAs(Area* area)
694 {
695 	BList* constraints = new BList(2);
696 	constraints->AddItem(this->HasSameWidthAs(area));
697 	constraints->AddItem(this->HasSameHeightAs(area));
698 	return constraints;
699 }
700 
701 
702 /**
703  * Destructor.
704  * Removes the area from its specification.
705  */
706 Area::~Area()
707 {
708 	if (fChildArea != NULL) delete fChildArea;
709 	for (int32 i = 0; i < fConstraints->CountItems(); i++)
710 		delete (Constraint*)fConstraints->ItemAt(i);
711 	fLS->Areas()->RemoveItem(this);
712 }
713 
714 
715 /**
716  * Constructor.
717  * Uses XTabs and YTabs.
718  */
719 Area::Area(BALMLayout* ls, XTab* left, YTab* top, XTab* right, YTab* bottom,
720 	BView* content, BSize minContentSize)
721 {
722 	Init(ls, left, top, right, bottom, content, minContentSize);
723 }
724 
725 
726 /**
727  * Constructor.
728  * Uses Rows and Columns.
729  */
730 Area::Area(BALMLayout* ls, Row* row, Column* column, BView* content,
731 	BSize minContentSize)
732 {
733 
734 	Init(ls, column->Left(), row->Top(), column->Right(), row->Bottom(),
735 			content, minContentSize);
736 	fRow = row;
737 	fColumn = column;
738 }
739 
740 
741 /**
742  * Initialize variables.
743  */
744 void
745 Area::Init(BALMLayout* ls, XTab* left, YTab* top, XTab* right, YTab* bottom,
746 	BView* content, BSize minContentSize)
747 {
748 
749 	fConstraints = new BList(2);
750 	fMaxContentSize = kMaxSize;
751 
752 	fMaxContentWidth = NULL;
753 	fMaxContentHeight = NULL;
754 
755 	fPrefContentSize = kUndefinedSize;
756 	fShrinkRigidity = BSize(2, 2);
757 	fExpandRigidity = BSize(1, 1);
758 	fContentAspectRatio = 0;
759 	fContentAspectRatioC = NULL;
760 
761 	fAutoPrefContentSize = false;
762 
763 	fPrefContentWidth = NULL;
764 	fPrefContentHeight = NULL;
765 
766 	fChildArea = NULL;
767 
768 	fAlignment = BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT);
769 	fLeftInset = 0;
770 	fTopInset = 0;
771 	fRightInset = 0;
772 	fBottomInset = 0;
773 
774 	fLeftConstraint = NULL;
775 	fTopConstraint = NULL;
776 	fRightConstraint = NULL;
777 	fBottomConstraint = NULL;
778 
779 	fLS = ls;
780 	fLeft = left;
781 	fRight = right;
782 	fTop = top;
783 	fBottom = bottom;
784 	SetContent(content);
785 	fMinContentSize = minContentSize;
786 
787 	// adds the two essential constraints of the area that make sure that the left x-tab is
788 	// really to the left of the right x-tab, and the top y-tab really above the bottom y-tab
789 	fMinContentWidth = ls->AddConstraint(-1.0, left, 1.0, right, OperatorType(GE),
790 			minContentSize.Width());
791 	fConstraints->AddItem(fMinContentWidth);
792 
793 	fMinContentHeight = ls->AddConstraint(-1.0, top, 1.0, bottom, OperatorType(GE),
794 			minContentSize.Height());
795 	fConstraints->AddItem(fMinContentHeight);
796 }
797 
798 
799 /**
800  * Perform layout on the area.
801  */
802 void Area::DoLayout()
803 {
804 	if (Content() == NULL)
805 		return; // empty areas need no layout
806 
807 	// if there is a childArea, then it is the childArea that actually contains the content
808 	Area* area = (fChildArea != NULL) ? fChildArea : this;
809 
810 	// set content location and size
811 	area->Content()->MoveTo(floor(area->Left()->Value() + 0.5),
812 			floor(area->Top()->Value() + 0.5));
813 	int32 width = (int32)floor(area->Right()->Value() - area->Left()->Value() + 0.5);
814 	int32 height = (int32)floor(area->Bottom()->Value() - area->Top()->Value() + 0.5);
815 	area->Content()->ResizeTo(width, height);
816 }
817 
818 
819 /**
820  * Adds a childArea to this area, together with constraints that specify the relative location
821  * of the childArea within this area. It is called when such a childArea becomes necessary,
822  * i.e. when the user requests insets or special alignment.
823  */
824 void
825 Area::InitChildArea()
826 {
827 	// add a child area with new tabs,
828 	// and add constraints that set its tabs to be equal to the
829 	// coresponding tabs of this area (for a start)
830 	fChildArea = new Area(fLS, new XTab(fLS), new YTab(fLS), new XTab(fLS),
831 			new YTab(fLS), fContent, BSize(0, 0));
832 	fLeftConstraint = fLeft->IsEqual(fChildArea->Left());
833 	fConstraints->AddItem(fLeftConstraint);
834 	fTopConstraint = fTop->IsEqual(fChildArea->Top());
835 	fConstraints->AddItem(fTopConstraint);
836 	fRightConstraint = fRight->IsEqual(fChildArea->Right());
837 	fConstraints->AddItem(fRightConstraint);
838 	fBottomConstraint = fBottom->IsEqual(fChildArea->Bottom());
839 	fConstraints->AddItem(fBottomConstraint);
840 
841 	// remove the minimum content size constraints from this area
842 	// and copy the minimum content size setting to the childArea
843 	fConstraints->RemoveItem(fMinContentWidth);
844 	delete fMinContentWidth;
845 	fMinContentWidth = fChildArea->fMinContentWidth;
846 	fConstraints->RemoveItem(fMinContentHeight);
847 	delete fMinContentHeight;
848 	fMinContentHeight = fChildArea->fMinContentHeight;
849 	fChildArea->SetMinContentSize(fMinContentSize);
850 
851 	// if there are maximum content size constraints on this area,
852 	// change them so that they refer to the tabs of the childArea
853 	// and copy the minimum content size settings to the childArea
854 	if (fMaxContentWidth != NULL) {
855 		fChildArea->fMaxContentSize = fMaxContentSize;
856 
857 		fChildArea->fMaxContentWidth = fMaxContentWidth;
858 		fMaxContentWidth->SetLeftSide(-1.0, fChildArea->Left(), 1.0, fChildArea->Right());
859 
860 		fChildArea->fMaxContentHeight = fMaxContentHeight;
861 		fMaxContentHeight->SetLeftSide(-1.0, fChildArea->Top(), 1.0, fChildArea->Bottom());
862 	}
863 
864 	// if there are preferred content size constraints on this area,
865 	// change them so that they refer to the tabs of the childArea
866 	// and copy the preferred content size settings to the childArea
867 	if (fPrefContentHeight != NULL) {
868 		fChildArea->fPrefContentSize = fPrefContentSize;
869 		fChildArea->fShrinkRigidity = fShrinkRigidity;
870 		fChildArea->fExpandRigidity = fExpandRigidity;
871 
872 		fChildArea->fPrefContentWidth = fPrefContentWidth;
873 		fPrefContentWidth->SetLeftSide(-1.0, fChildArea->Left(), 1.0, fChildArea->Right());
874 
875 		fChildArea->fPrefContentHeight = fPrefContentHeight;
876 		fPrefContentHeight->SetLeftSide(-1.0, fChildArea->Top(), 1.0, fChildArea->Bottom());
877 	}
878 }
879 
880 
881 /**
882  * Update the constraints for horizontal insets and alignment.
883  */
884 void
885 Area::UpdateHorizontal()
886 {
887 	// if the area does not have a childAdrea yet, this is the time to add it
888 	if (fChildArea == NULL)
889 		InitChildArea();
890 
891 	// change the constraints leftConstraint and rightConstraint so that the horizontal
892 	// alignment and insets of the childArea within this area are as specified by the user
893 	if (fAlignment.Horizontal() == B_ALIGN_LEFT) {
894 		fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left());
895 		fLeftConstraint->SetOp(OperatorType(EQ));
896 		fLeftConstraint->SetRightSide(fLeftInset);
897 
898 		fRightConstraint->SetLeftSide(-1.0, fChildArea->Right(), 1.0, fRight);
899 		fRightConstraint->SetOp(OperatorType(GE));
900 		fRightConstraint->SetRightSide(fRightInset);
901 	} else if (fAlignment.Horizontal() == B_ALIGN_RIGHT) {
902 		fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left());
903 		fLeftConstraint->SetOp(OperatorType(GE));
904 		fLeftConstraint->SetRightSide(fLeftInset);
905 
906 		fRightConstraint->SetLeftSide(-1.0, fChildArea->Right(), 1.0, fRight);
907 		fRightConstraint->SetOp(OperatorType(EQ));
908 		fRightConstraint->SetRightSide(fRightInset);
909 	} else if (fAlignment.Horizontal() == B_ALIGN_HORIZONTAL_CENTER) {
910 		fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left());
911 		fLeftConstraint->SetOp(OperatorType(GE));
912 		fLeftConstraint->SetRightSide(max(fLeftInset, fRightInset));
913 
914 		fRightConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left(), 1.0, fChildArea->Right(), -1.0, fRight);
915 		fRightConstraint->SetOp(OperatorType(EQ));
916 		fRightConstraint->SetRightSide(0);
917 	} else if (fAlignment.Horizontal() == B_ALIGN_USE_FULL_WIDTH) {
918 		fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left());
919 		fLeftConstraint->SetOp(OperatorType(EQ));
920 		fLeftConstraint->SetRightSide(fLeftInset);
921 
922 		fRightConstraint->SetLeftSide(-1.0, fChildArea->Right(), 1.0, fRight);
923 		fRightConstraint->SetOp(OperatorType(EQ));
924 		fRightConstraint->SetRightSide(fRightInset);
925 	} else if (fAlignment.Horizontal() == B_ALIGN_HORIZONTAL_UNSET) {
926 		fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left());
927 		fLeftConstraint->SetOp(OperatorType(GE));
928 		fLeftConstraint->SetRightSide(fLeftInset);
929 
930 		fRightConstraint->SetLeftSide(-1.0, fChildArea->Right(), 1.0, fRight);
931 		fRightConstraint->SetOp(OperatorType(GE));
932 		fRightConstraint->SetRightSide(fRightInset);
933 	}
934 }
935 
936 
937 /**
938  * Update the constraints for vertical insets and alignment.
939  */
940 void Area::UpdateVertical() {
941 	// if the area does not have a childAdrea yet, this is the time to add it
942 	if (fChildArea == NULL)
943 		InitChildArea();
944 
945 	// change the constraints topConstraint and bottomConstraint so that the vertical
946 	// alignment and insets of the childArea within this area are as specified by the user
947 	if (fAlignment.Vertical() == B_ALIGN_TOP) {
948 		fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top());
949 		fTopConstraint->SetOp(OperatorType(EQ));
950 		fTopConstraint->SetRightSide(fTopInset);
951 
952 		fBottomConstraint->SetLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom);
953 		fBottomConstraint->SetOp(OperatorType(GE));
954 		fBottomConstraint->SetRightSide(fBottomInset);
955 	} else if (fAlignment.Vertical() == B_ALIGN_BOTTOM) {
956 		fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top());
957 		fTopConstraint->SetOp(OperatorType(GE));
958 		fTopConstraint->SetRightSide(fTopInset);
959 
960 		fBottomConstraint->SetLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom);
961 		fBottomConstraint->SetOp(OperatorType(EQ));
962 		fBottomConstraint->SetRightSide(fBottomInset);
963 	} else if (fAlignment.Vertical() == B_ALIGN_VERTICAL_CENTER) {
964 		fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top());
965 		fTopConstraint->SetOp(OperatorType(GE));
966 		fTopConstraint->SetRightSide(max(fTopInset, fBottomInset));
967 
968 		fBottomConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top(), 1.0, fChildArea->Bottom(), -1.0, fBottom);
969 		fBottomConstraint->SetOp(OperatorType(EQ));
970 		fBottomConstraint->SetRightSide(0);
971 	} else if (fAlignment.Vertical() == B_ALIGN_USE_FULL_HEIGHT) {
972 		fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top());
973 		fTopConstraint->SetOp(OperatorType(EQ));
974 		fTopConstraint->SetRightSide(fTopInset);
975 
976 		fBottomConstraint->SetLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom);
977 		fBottomConstraint->SetOp(OperatorType(EQ));
978 		fBottomConstraint->SetRightSide(fBottomInset);
979 	} else if (fAlignment.Vertical() == B_ALIGN_VERTICAL_UNSET) {
980 		fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top());
981 		fTopConstraint->SetOp(OperatorType(GE));
982 		fTopConstraint->SetRightSide(fTopInset);
983 
984 		fBottomConstraint->SetLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom);
985 		fBottomConstraint->SetOp(OperatorType(GE));
986 		fBottomConstraint->SetRightSide(fBottomInset);
987 	}
988 }
989 
990