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::AutoPreferredContentSize() const 38 { 39 return fAutoPreferredContentSize; 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::SetAutoPreferredContentSize(bool value) 50 { 51 fAutoPreferredContentSize = 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::PreferredContentSize() const 364 { 365 return (fChildArea == NULL) ? fPreferredContentSize 366 : fChildArea->fPreferredContentSize; 367 } 368 369 370 /** 371 * Sets Preferred size of the area's content. 372 * May be different from the preferred size of the area. 373 * Manual changes of PreferredContentSize are ignored unless 374 * autoPreferredContentSize is set to false. 375 */ 376 void 377 Area::SetPreferredContentSize(BSize preferred) 378 { 379 if (fChildArea == NULL) { 380 fPreferredContentSize = preferred; 381 if (fPreferredContentWidth == NULL) { 382 fPreferredContentWidth = fLS->AddConstraint( 383 -1.0, fLeft, 1.0, fRight, OperatorType(EQ), 384 fPreferredContentSize.Width(), fShrinkPenalties.Width(), 385 fGrowPenalties.Width()); 386 fConstraints->AddItem(fPreferredContentWidth); 387 388 fPreferredContentHeight = fLS->AddConstraint( 389 -1.0, fTop, 1.0, fBottom, OperatorType(EQ), 390 fPreferredContentSize.Height(), fShrinkPenalties.Height(), 391 fGrowPenalties.Height()); 392 fConstraints->AddItem(fPreferredContentHeight); 393 } else { 394 fPreferredContentWidth->SetRightSide(preferred.Width()); 395 fPreferredContentHeight->SetRightSide(preferred.Height()); 396 } 397 } else 398 fChildArea->SetPreferredContentSize(preferred); 399 fLS->InvalidateLayout(); 400 } 401 402 403 /** 404 * The reluctance with which the area's content shrinks below its preferred size. 405 * The bigger the less likely is such shrinking. 406 */ 407 BSize 408 Area::ShrinkPenalties() const 409 { 410 return (fChildArea == NULL) ? fShrinkPenalties : fChildArea->fShrinkPenalties; 411 } 412 413 414 void Area::SetShrinkPenalties(BSize shrink) { 415 if (fChildArea == NULL) { 416 fShrinkPenalties = shrink; 417 if (fPreferredContentWidth != NULL) { 418 fPreferredContentWidth->SetPenaltyNeg(shrink.Width()); 419 fPreferredContentHeight->SetPenaltyNeg(shrink.Height()); 420 } 421 } else 422 fChildArea->SetShrinkPenalties(shrink); 423 fLS->InvalidateLayout(); 424 } 425 426 427 /** 428 * The reluctance with which the area's content grows over its preferred size. 429 * The bigger the less likely is such growth. 430 */ 431 BSize 432 Area::GrowPenalties() const 433 { 434 return (fChildArea == NULL) ? fGrowPenalties : fChildArea->fGrowPenalties; 435 } 436 437 438 void 439 Area::SetGrowPenalties(BSize grow) 440 { 441 if (fChildArea == NULL) { 442 fGrowPenalties = grow; 443 if (fPreferredContentWidth != NULL) { 444 fPreferredContentWidth->SetPenaltyPos(grow.Width()); 445 fPreferredContentHeight->SetPenaltyPos(grow.Height()); 446 } 447 } else 448 fChildArea->SetGrowPenalties(grow); 449 fLS->InvalidateLayout(); 450 } 451 452 453 /** 454 * Gets aspect ratio of the area's content. 455 */ 456 double 457 Area::ContentAspectRatio() const 458 { 459 return (fChildArea == NULL) ? fContentAspectRatio : fChildArea->fContentAspectRatio; 460 } 461 462 463 /** 464 * Sets aspect ratio of the area's content. 465 * May be different from the aspect ratio of the area. 466 */ 467 void 468 Area::SetContentAspectRatio(double ratio) 469 { 470 if (fChildArea == NULL) { 471 fContentAspectRatio = ratio; 472 if (fContentAspectRatioC == NULL) { 473 fContentAspectRatioC = fLS->AddConstraint( 474 -1.0, fLeft, 1.0, fRight, ratio, fTop, -ratio, fBottom, 475 OperatorType(EQ), 0.0); 476 fConstraints->AddItem(fContentAspectRatioC); 477 } else { 478 fContentAspectRatioC->SetLeftSide( 479 -1.0, fLeft, 1.0, fRight, ratio, fTop, -ratio, fBottom); 480 } 481 } else 482 fChildArea->SetContentAspectRatio(ratio); 483 fLS->InvalidateLayout(); 484 } 485 486 487 /** 488 * Gets alignment of the content in its area. 489 */ 490 BAlignment 491 Area::Alignment() const 492 { 493 return fAlignment; 494 } 495 496 497 /** 498 * Sets alignment of the content in its area. 499 */ 500 void 501 Area::SetAlignment(BAlignment alignment) 502 { 503 fAlignment = alignment; 504 UpdateHorizontal(); 505 UpdateVertical(); 506 fLS->InvalidateLayout(); 507 } 508 509 510 /** 511 * Sets horizontal alignment of the content in its area. 512 */ 513 void Area::SetHorizontalAlignment(alignment horizontal) { 514 fAlignment.SetHorizontal(horizontal); 515 UpdateHorizontal(); 516 fLS->InvalidateLayout(); 517 } 518 519 520 /** 521 * Sets vertical alignment of the content in its area. 522 */ 523 void 524 Area::SetVerticalAlignment(vertical_alignment vertical) 525 { 526 fAlignment.SetVertical(vertical); 527 UpdateVertical(); 528 fLS->InvalidateLayout(); 529 } 530 531 532 /** 533 * Gets left inset between area and its content. 534 */ 535 int32 536 Area::LeftInset() const 537 { 538 return fLeftInset; 539 } 540 541 542 /** 543 * Sets left inset between area and its content. 544 */ 545 void 546 Area::SetLeftInset(int32 left) 547 { 548 fLeftInset = left; 549 UpdateHorizontal(); 550 fLS->InvalidateLayout(); 551 } 552 553 554 /** 555 * Gets top inset between area and its content. 556 */ 557 int32 558 Area::TopInset() const 559 { 560 return fTopInset; 561 } 562 563 564 /** 565 * Sets top inset between area and its content. 566 */ 567 void 568 Area::SetTopInset(int32 top) 569 { 570 fTopInset = top; 571 UpdateVertical(); 572 fLS->InvalidateLayout(); 573 } 574 575 576 /** 577 * Gets right inset between area and its content. 578 */ 579 int32 580 Area::RightInset() const 581 { 582 return fRightInset; 583 } 584 585 586 /** 587 * Sets right inset between area and its content. 588 */ 589 void 590 Area::SetRightInset(int32 right) 591 { 592 fRightInset = right; 593 UpdateHorizontal(); 594 } 595 596 597 /** 598 * Gets bottom inset between area and its content. 599 */ 600 int32 601 Area::BottomInset() const 602 { 603 return fBottomInset; 604 } 605 606 607 /** 608 * Sets bottom inset between area and its content. 609 */ 610 void 611 Area::SetBottomInset(int32 bottom) 612 { 613 fBottomInset = bottom; 614 UpdateVertical(); 615 } 616 617 618 /** 619 * Sets the preferred size according to the content's PreferredSize method, 620 * and the penalties according to heuristics. 621 */ 622 void 623 Area::SetDefaultBehavior() 624 { 625 if (Content() == NULL) { 626 SetPreferredContentSize(BSize(0, 0)); 627 SetShrinkPenalties(BSize(0, 0)); 628 SetGrowPenalties(BSize(0, 0)); 629 return; 630 } 631 632 if (PreferredContentSize() != Content()->PreferredSize()){ 633 SetPreferredContentSize(Content()->PreferredSize()); 634 fLS->InvalidateLayout(); 635 } 636 637 if (dynamic_cast<BButton*>(Content()) != NULL 638 || dynamic_cast<BRadioButton*>(Content()) != NULL 639 || dynamic_cast<BCheckBox*>(Content()) != NULL 640 || dynamic_cast<BStringView*>(Content()) != NULL 641 || dynamic_cast<BPictureButton*>(Content()) != NULL 642 || dynamic_cast<BStatusBar*>(Content()) != NULL) { 643 fShrinkPenalties = BSize(4, 4); 644 fGrowPenalties = BSize(3, 3); 645 } else { 646 fShrinkPenalties = BSize(2, 2); 647 fGrowPenalties = BSize(1, 1); 648 } 649 } 650 651 652 Area::operator BString() const 653 { 654 BString string; 655 GetString(string); 656 return string; 657 } 658 659 660 void 661 Area::GetString(BString& string) const 662 { 663 string << "Area("; 664 fLeft->GetString(string); 665 string << ", "; 666 fTop->GetString(string); 667 string << ", "; 668 fRight->GetString(string); 669 string << ", "; 670 fBottom->GetString(string); 671 string << ")"; 672 } 673 674 675 /** 676 * Sets the width of the area to be the same as the width of the given area. 677 * 678 * @param area the area that should have the same width 679 * @return the same-width constraint 680 */ 681 Constraint* 682 Area::HasSameWidthAs(Area* area) 683 { 684 return fLS->AddConstraint( 685 -1.0, fLeft, 1.0, fRight, 1.0, area->fLeft, -1.0, area->fRight, 686 OperatorType(EQ), 0.0); 687 } 688 689 690 /** 691 * Sets the height of the area to be the same as the height of the given area. 692 * 693 * @param area the area that should have the same height 694 * @return the same-height constraint 695 */ 696 Constraint* 697 Area::HasSameHeightAs(Area* area) 698 { 699 return fLS->AddConstraint( 700 -1.0, fTop, 1.0, fBottom, 1.0, area->fTop, -1.0, area->fBottom, 701 OperatorType(EQ), 0.0); 702 } 703 704 705 /** 706 * Sets the size of the area to be the same as the size of the given area. 707 * 708 * @param area the area that should have the same size 709 * @return a list containing a same-width and same-height constraint 710 */ 711 BList* 712 Area::HasSameSizeAs(Area* area) 713 { 714 BList* constraints = new BList(2); 715 constraints->AddItem(this->HasSameWidthAs(area)); 716 constraints->AddItem(this->HasSameHeightAs(area)); 717 return constraints; 718 } 719 720 721 /** 722 * Destructor. 723 * Removes the area from its specification. 724 */ 725 Area::~Area() 726 { 727 if (fChildArea != NULL) delete fChildArea; 728 for (int32 i = 0; i < fConstraints->CountItems(); i++) 729 delete (Constraint*)fConstraints->ItemAt(i); 730 fLS->Areas()->RemoveItem(this); 731 } 732 733 734 /** 735 * Constructor. 736 * Uses XTabs and YTabs. 737 */ 738 Area::Area(BALMLayout* ls, XTab* left, YTab* top, XTab* right, YTab* bottom, 739 BView* content, BSize minContentSize) 740 { 741 Init(ls, left, top, right, bottom, content, minContentSize); 742 } 743 744 745 /** 746 * Constructor. 747 * Uses Rows and Columns. 748 */ 749 Area::Area(BALMLayout* ls, Row* row, Column* column, BView* content, 750 BSize minContentSize) 751 { 752 753 Init(ls, column->Left(), row->Top(), column->Right(), row->Bottom(), 754 content, minContentSize); 755 fRow = row; 756 fColumn = column; 757 } 758 759 760 /** 761 * Initialize variables. 762 */ 763 void 764 Area::Init(BALMLayout* ls, XTab* left, YTab* top, XTab* right, YTab* bottom, 765 BView* content, BSize minContentSize) 766 { 767 768 fConstraints = new BList(2); 769 fMaxContentSize = kMaxSize; 770 771 fMaxContentWidth = NULL; 772 fMaxContentHeight = NULL; 773 774 fPreferredContentSize = kUndefinedSize; 775 fShrinkPenalties = BSize(2, 2); 776 fGrowPenalties = BSize(1, 1); 777 fContentAspectRatio = 0; 778 fContentAspectRatioC = NULL; 779 780 fAutoPreferredContentSize = false; 781 782 fPreferredContentWidth = NULL; 783 fPreferredContentHeight = NULL; 784 785 fChildArea = NULL; 786 787 fAlignment = BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT); 788 fLeftInset = 0; 789 fTopInset = 0; 790 fRightInset = 0; 791 fBottomInset = 0; 792 793 fLeftConstraint = NULL; 794 fTopConstraint = NULL; 795 fRightConstraint = NULL; 796 fBottomConstraint = NULL; 797 798 fLS = ls; 799 fLeft = left; 800 fRight = right; 801 fTop = top; 802 fBottom = bottom; 803 SetContent(content); 804 fMinContentSize = minContentSize; 805 806 // adds the two essential constraints of the area that make sure that the left x-tab is 807 // really to the left of the right x-tab, and the top y-tab really above the bottom y-tab 808 fMinContentWidth = ls->AddConstraint(-1.0, left, 1.0, right, OperatorType(GE), 809 minContentSize.Width()); 810 fConstraints->AddItem(fMinContentWidth); 811 812 fMinContentHeight = ls->AddConstraint(-1.0, top, 1.0, bottom, OperatorType(GE), 813 minContentSize.Height()); 814 fConstraints->AddItem(fMinContentHeight); 815 } 816 817 818 /** 819 * Perform layout on the area. 820 */ 821 void Area::DoLayout() 822 { 823 if (Content() == NULL) 824 return; // empty areas need no layout 825 826 // if there is a childArea, then it is the childArea that actually contains the content 827 Area* area = (fChildArea != NULL) ? fChildArea : this; 828 829 // set content location and size 830 area->Content()->MoveTo(floor(area->Left()->Value() + 0.5), 831 floor(area->Top()->Value() + 0.5)); 832 int32 width = (int32)floor(area->Right()->Value() - area->Left()->Value() + 0.5); 833 int32 height = (int32)floor(area->Bottom()->Value() - area->Top()->Value() + 0.5); 834 area->Content()->ResizeTo(width, height); 835 } 836 837 838 /** 839 * Adds a childArea to this area, together with constraints that specify the relative location 840 * of the childArea within this area. It is called when such a childArea becomes necessary, 841 * i.e. when the user requests insets or special alignment. 842 */ 843 void 844 Area::InitChildArea() 845 { 846 // add a child area with new tabs, 847 // and add constraints that set its tabs to be equal to the 848 // coresponding tabs of this area (for a start) 849 fChildArea = new Area(fLS, new XTab(fLS), new YTab(fLS), new XTab(fLS), 850 new YTab(fLS), fContent, BSize(0, 0)); 851 fLeftConstraint = fLeft->IsEqual(fChildArea->Left()); 852 fConstraints->AddItem(fLeftConstraint); 853 fTopConstraint = fTop->IsEqual(fChildArea->Top()); 854 fConstraints->AddItem(fTopConstraint); 855 fRightConstraint = fRight->IsEqual(fChildArea->Right()); 856 fConstraints->AddItem(fRightConstraint); 857 fBottomConstraint = fBottom->IsEqual(fChildArea->Bottom()); 858 fConstraints->AddItem(fBottomConstraint); 859 860 // remove the minimum content size constraints from this area 861 // and copy the minimum content size setting to the childArea 862 fConstraints->RemoveItem(fMinContentWidth); 863 delete fMinContentWidth; 864 fMinContentWidth = fChildArea->fMinContentWidth; 865 fConstraints->RemoveItem(fMinContentHeight); 866 delete fMinContentHeight; 867 fMinContentHeight = fChildArea->fMinContentHeight; 868 fChildArea->SetMinContentSize(fMinContentSize); 869 870 // if there are maximum content size constraints on this area, 871 // change them so that they refer to the tabs of the childArea 872 // and copy the minimum content size settings to the childArea 873 if (fMaxContentWidth != NULL) { 874 fChildArea->fMaxContentSize = fMaxContentSize; 875 876 fChildArea->fMaxContentWidth = fMaxContentWidth; 877 fMaxContentWidth->SetLeftSide( 878 -1.0, fChildArea->Left(), 1.0, fChildArea->Right()); 879 880 fChildArea->fMaxContentHeight = fMaxContentHeight; 881 fMaxContentHeight->SetLeftSide( 882 -1.0, fChildArea->Top(), 1.0, fChildArea->Bottom()); 883 } 884 885 // if there are preferred content size constraints on this area, 886 // change them so that they refer to the tabs of the childArea 887 // and copy the preferred content size settings to the childArea 888 if (fPreferredContentHeight != NULL) { 889 fChildArea->fPreferredContentSize = fPreferredContentSize; 890 fChildArea->fShrinkPenalties = fShrinkPenalties; 891 fChildArea->fGrowPenalties = fGrowPenalties; 892 893 fChildArea->fPreferredContentWidth = fPreferredContentWidth; 894 fPreferredContentWidth->SetLeftSide( 895 -1.0, fChildArea->Left(), 1.0, fChildArea->Right()); 896 897 fChildArea->fPreferredContentHeight = fPreferredContentHeight; 898 fPreferredContentHeight->SetLeftSide( 899 -1.0, fChildArea->Top(), 1.0, fChildArea->Bottom()); 900 } 901 } 902 903 904 /** 905 * Update the constraints for horizontal insets and alignment. 906 */ 907 void 908 Area::UpdateHorizontal() 909 { 910 // if the area does not have a childAdrea yet, this is the time to add it 911 if (fChildArea == NULL) 912 InitChildArea(); 913 914 // change the constraints leftConstraint and rightConstraint so that the horizontal 915 // alignment and insets of the childArea within this area are as specified by the user 916 if (fAlignment.Horizontal() == B_ALIGN_LEFT) { 917 fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left()); 918 fLeftConstraint->SetOp(OperatorType(EQ)); 919 fLeftConstraint->SetRightSide(fLeftInset); 920 921 fRightConstraint->SetLeftSide(-1.0, fChildArea->Right(), 1.0, fRight); 922 fRightConstraint->SetOp(OperatorType(GE)); 923 fRightConstraint->SetRightSide(fRightInset); 924 } else if (fAlignment.Horizontal() == B_ALIGN_RIGHT) { 925 fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left()); 926 fLeftConstraint->SetOp(OperatorType(GE)); 927 fLeftConstraint->SetRightSide(fLeftInset); 928 929 fRightConstraint->SetLeftSide(-1.0, fChildArea->Right(), 1.0, fRight); 930 fRightConstraint->SetOp(OperatorType(EQ)); 931 fRightConstraint->SetRightSide(fRightInset); 932 } else if (fAlignment.Horizontal() == B_ALIGN_HORIZONTAL_CENTER) { 933 fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left()); 934 fLeftConstraint->SetOp(OperatorType(GE)); 935 fLeftConstraint->SetRightSide(max(fLeftInset, fRightInset)); 936 937 fRightConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left(), 1.0, fChildArea->Right(), -1.0, fRight); 938 fRightConstraint->SetOp(OperatorType(EQ)); 939 fRightConstraint->SetRightSide(0); 940 } else if (fAlignment.Horizontal() == B_ALIGN_USE_FULL_WIDTH) { 941 fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left()); 942 fLeftConstraint->SetOp(OperatorType(EQ)); 943 fLeftConstraint->SetRightSide(fLeftInset); 944 945 fRightConstraint->SetLeftSide(-1.0, fChildArea->Right(), 1.0, fRight); 946 fRightConstraint->SetOp(OperatorType(EQ)); 947 fRightConstraint->SetRightSide(fRightInset); 948 } else if (fAlignment.Horizontal() == B_ALIGN_HORIZONTAL_UNSET) { 949 fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left()); 950 fLeftConstraint->SetOp(OperatorType(GE)); 951 fLeftConstraint->SetRightSide(fLeftInset); 952 953 fRightConstraint->SetLeftSide(-1.0, fChildArea->Right(), 1.0, fRight); 954 fRightConstraint->SetOp(OperatorType(GE)); 955 fRightConstraint->SetRightSide(fRightInset); 956 } 957 } 958 959 960 /** 961 * Update the constraints for vertical insets and alignment. 962 */ 963 void Area::UpdateVertical() { 964 // if the area does not have a childAdrea yet, this is the time to add it 965 if (fChildArea == NULL) 966 InitChildArea(); 967 968 // change the constraints topConstraint and bottomConstraint so that the vertical 969 // alignment and insets of the childArea within this area are as specified by the user 970 if (fAlignment.Vertical() == B_ALIGN_TOP) { 971 fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top()); 972 fTopConstraint->SetOp(OperatorType(EQ)); 973 fTopConstraint->SetRightSide(fTopInset); 974 975 fBottomConstraint->SetLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom); 976 fBottomConstraint->SetOp(OperatorType(GE)); 977 fBottomConstraint->SetRightSide(fBottomInset); 978 } else if (fAlignment.Vertical() == B_ALIGN_BOTTOM) { 979 fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top()); 980 fTopConstraint->SetOp(OperatorType(GE)); 981 fTopConstraint->SetRightSide(fTopInset); 982 983 fBottomConstraint->SetLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom); 984 fBottomConstraint->SetOp(OperatorType(EQ)); 985 fBottomConstraint->SetRightSide(fBottomInset); 986 } else if (fAlignment.Vertical() == B_ALIGN_VERTICAL_CENTER) { 987 fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top()); 988 fTopConstraint->SetOp(OperatorType(GE)); 989 fTopConstraint->SetRightSide(max(fTopInset, fBottomInset)); 990 991 fBottomConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top(), 1.0, fChildArea->Bottom(), -1.0, fBottom); 992 fBottomConstraint->SetOp(OperatorType(EQ)); 993 fBottomConstraint->SetRightSide(0); 994 } else if (fAlignment.Vertical() == B_ALIGN_USE_FULL_HEIGHT) { 995 fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top()); 996 fTopConstraint->SetOp(OperatorType(EQ)); 997 fTopConstraint->SetRightSide(fTopInset); 998 999 fBottomConstraint->SetLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom); 1000 fBottomConstraint->SetOp(OperatorType(EQ)); 1001 fBottomConstraint->SetRightSide(fBottomInset); 1002 } else if (fAlignment.Vertical() == B_ALIGN_VERTICAL_UNSET) { 1003 fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top()); 1004 fTopConstraint->SetOp(OperatorType(GE)); 1005 fTopConstraint->SetRightSide(fTopInset); 1006 1007 fBottomConstraint->SetLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom); 1008 fBottomConstraint->SetOp(OperatorType(GE)); 1009 fBottomConstraint->SetRightSide(fBottomInset); 1010 } 1011 } 1012 1013