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 14Group::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 24Group::~Group() 25{ 26} 27 28// AttachedToWindow 29void 30Group::AttachedToWindow() 31{ 32 // trigger a layout 33 FrameResized(Bounds().Width(), Bounds().Height()); 34} 35 36// FrameResized 37void 38Group::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 47void 48Group::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 60void 61Group::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 75void 76Group::_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 96BRect 97Group::_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 122void 123Group::_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