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