1 /* 2 * Copyright 2006, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Stephan Aßmus <superstippi@gmx.de> 7 */ 8 9 #include "Group.h" 10 11 #include <stdio.h> 12 13 // constructor 14 Group::Group(BRect frame, const char* name, orientation direction) 15 : BView(frame, name, B_FOLLOW_ALL, B_FRAME_EVENTS), 16 fOrientation(direction), 17 fInset(4.0), 18 fSpacing(0.0) 19 { 20 SetViewUIColor(B_PANEL_BACKGROUND_COLOR); 21 } 22 23 // destructor 24 Group::~Group() 25 { 26 } 27 28 // AttachedToWindow 29 void 30 Group::AttachedToWindow() 31 { 32 // trigger a layout 33 FrameResized(Bounds().Width(), Bounds().Height()); 34 } 35 36 // FrameResized 37 void 38 Group::FrameResized(float width, float height) 39 { 40 // layout controls 41 BRect r(Bounds()); 42 r.InsetBy(fInset, fInset); 43 _LayoutControls(r); 44 } 45 46 // GetPreferredSize 47 void 48 Group::GetPreferredSize(float* width, float* height) 49 { 50 BRect r(_MinFrame()); 51 52 if (width) 53 *width = r.Width(); 54 if (height) 55 *height = r.Height(); 56 } 57 58 // #pragma mark - 59 60 void 61 Group::SetSpacing(float insetFromBorder, float childSpacing) 62 { 63 if (fSpacing == childSpacing && fInset == insetFromBorder) 64 return; 65 66 fInset = insetFromBorder; 67 fSpacing = childSpacing; 68 // trigger a layout 69 FrameResized(Bounds().Width(), Bounds().Height()); 70 } 71 72 // #pragma mark - 73 74 // _LayoutControls 75 void 76 Group::_LayoutControls(BRect r) const 77 { 78 if (fOrientation == B_HORIZONTAL) { 79 r.left -= fSpacing; 80 for (int32 i = 0; BView* child = ChildAt(i); i++) { 81 r.right = r.left + child->Bounds().Width() + 2 * fSpacing; 82 _LayoutControl(child, r); 83 r.left = r.right + 1.0 - fSpacing; 84 } 85 } else { 86 r.top -= fSpacing; 87 for (int32 i = 0; BView* child = ChildAt(i); i++) { 88 r.bottom = r.top + child->Bounds().Height() + 2 * fSpacing; 89 _LayoutControl(child, r); 90 r.top = r.bottom + 1.0 - fSpacing; 91 } 92 } 93 } 94 95 // _MinFrame 96 BRect 97 Group::_MinFrame() const 98 { 99 float minWidth = fInset * 2.0; 100 float minHeight = fInset * 2.0; 101 102 if (fOrientation == B_HORIZONTAL) { 103 minWidth += fSpacing; 104 for (int32 i = 0; BView* child = ChildAt(i); i++) { 105 minWidth += child->Bounds().Width() + 1 + fSpacing; 106 minHeight = max_c(minHeight, 107 child->Bounds().Height() + 1 + fInset * 2.0); 108 } 109 } else { 110 minHeight += fSpacing; 111 for (int32 i = 0; BView* child = ChildAt(i); i++) { 112 minHeight += child->Bounds().Height() + 1 + fSpacing; 113 minWidth = max_c(minWidth, 114 child->Bounds().Width() + 1 + fInset * 2.0); 115 } 116 } 117 118 return BRect(0.0, 0.0, minWidth - 1.0, minHeight - 1.0); 119 } 120 121 // _LayoutControl 122 void 123 Group::_LayoutControl(BView* view, BRect frame, 124 bool resizeWidth, bool resizeHeight) const 125 { 126 if (!resizeHeight) 127 // center vertically 128 frame.top = (frame.top + frame.bottom) / 2.0 - view->Bounds().Height() / 2.0; 129 if (!resizeWidth) 130 // center horizontally 131 frame.left = (frame.left + frame.right) / 2.0 - view->Bounds().Width() / 2.0; 132 view->MoveTo(frame.LeftTop()); 133 float width = resizeWidth ? frame.Width() : view->Bounds().Width(); 134 float height = resizeHeight ? frame.Height() : view->Bounds().Height(); 135 if (resizeWidth || resizeHeight) 136 view->ResizeTo(width, height); 137 } 138 139