1 /* 2 * Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>. 3 * All rights reserved. Distributed under the terms of the MIT License. 4 */ 5 6 #include <LayoutUtils.h> 7 8 #include <View.h> 9 10 11 // // AddSizesFloat 12 // float 13 // BLayoutUtils::AddSizesFloat(float a, float b) 14 // { 15 // float sum = a + b + 1; 16 // if (sum >= B_SIZE_UNLIMITED) 17 // return B_SIZE_UNLIMITED; 18 // 19 // return sum; 20 // } 21 // 22 // // AddSizesFloat 23 // float 24 // BLayoutUtils::AddSizesFloat(float a, float b, float c) 25 // { 26 // return AddSizesFloat(AddSizesFloat(a, b), c); 27 // } 28 29 30 // AddSizesInt32 31 int32 32 BLayoutUtils::AddSizesInt32(int32 a, int32 b) 33 { 34 if (a >= B_SIZE_UNLIMITED - b) 35 return B_SIZE_UNLIMITED; 36 return a + b; 37 } 38 39 40 // AddSizesInt32 41 int32 42 BLayoutUtils::AddSizesInt32(int32 a, int32 b, int32 c) 43 { 44 return AddSizesInt32(AddSizesInt32(a, b), c); 45 } 46 47 48 // AddDistances 49 float 50 BLayoutUtils::AddDistances(float a, float b) 51 { 52 float sum = a + b + 1; 53 if (sum >= B_SIZE_UNLIMITED) 54 return B_SIZE_UNLIMITED; 55 56 return sum; 57 } 58 59 60 // AddDistances 61 float 62 BLayoutUtils::AddDistances(float a, float b, float c) 63 { 64 return AddDistances(AddDistances(a, b), c); 65 } 66 67 68 // // SubtractSizesFloat 69 // float 70 // BLayoutUtils::SubtractSizesFloat(float a, float b) 71 // { 72 // if (a < b) 73 // return -1; 74 // return a - b - 1; 75 // } 76 77 78 // SubtractSizesInt32 79 int32 80 BLayoutUtils::SubtractSizesInt32(int32 a, int32 b) 81 { 82 if (a < b) 83 return 0; 84 return a - b; 85 } 86 87 88 // SubtractDistances 89 float 90 BLayoutUtils::SubtractDistances(float a, float b) 91 { 92 if (a < b) 93 return -1; 94 return a - b - 1; 95 } 96 97 98 // FixSizeConstraints 99 void 100 BLayoutUtils::FixSizeConstraints(float& min, float& max, float& preferred) 101 { 102 if (max < min) 103 max = min; 104 if (preferred < min) 105 preferred = min; 106 else if (preferred > max) 107 preferred = max; 108 } 109 110 111 // FixSizeConstraints 112 void 113 BLayoutUtils::FixSizeConstraints(BSize& min, BSize& max, BSize& preferred) 114 { 115 FixSizeConstraints(min.width, max.width, preferred.width); 116 FixSizeConstraints(min.height, max.height, preferred.height); 117 } 118 119 120 // ComposeSize 121 BSize 122 BLayoutUtils::ComposeSize(BSize size, BSize layoutSize) 123 { 124 if (!size.IsWidthSet()) 125 size.width = layoutSize.width; 126 if (!size.IsHeightSet()) 127 size.height = layoutSize.height; 128 129 return size; 130 } 131 132 133 // ComposeAlignment 134 BAlignment 135 BLayoutUtils::ComposeAlignment(BAlignment alignment, BAlignment layoutAlignment) 136 { 137 if (!alignment.IsHorizontalSet()) 138 alignment.horizontal = layoutAlignment.horizontal; 139 if (!alignment.IsVerticalSet()) 140 alignment.vertical = layoutAlignment.vertical; 141 142 return alignment; 143 } 144 145 146 // AlignInFrame 147 BRect 148 BLayoutUtils::AlignInFrame(BRect frame, BSize maxSize, BAlignment alignment) 149 { 150 // align according to the given alignment 151 if (maxSize.width < frame.Width() 152 && alignment.horizontal != B_ALIGN_USE_FULL_WIDTH) { 153 frame.left += (int)((frame.Width() - maxSize.width) 154 * alignment.RelativeHorizontal()); 155 frame.right = frame.left + maxSize.width; 156 } 157 if (maxSize.height < frame.Height() 158 && alignment.vertical != B_ALIGN_USE_FULL_HEIGHT) { 159 frame.top += (int)((frame.Height() - maxSize.height) 160 * alignment.RelativeVertical()); 161 frame.bottom = frame.top + maxSize.height; 162 } 163 164 return frame; 165 } 166 167 168 // AlignInFrame 169 void 170 BLayoutUtils::AlignInFrame(BView* view, BRect frame) 171 { 172 BSize maxSize = view->MaxSize(); 173 BAlignment alignment = view->LayoutAlignment(); 174 175 if (view->HasHeightForWidth()) { 176 // The view has height for width, so we do the horizontal alignment 177 // ourselves and restrict the height max constraint respectively. 178 179 if (maxSize.width < frame.Width() 180 && alignment.horizontal != B_ALIGN_USE_FULL_WIDTH) { 181 frame.OffsetBy(floor((frame.Width() - maxSize.width) 182 * alignment.RelativeHorizontal()), 0); 183 frame.right = frame.left + maxSize.width; 184 } 185 alignment.horizontal = B_ALIGN_USE_FULL_WIDTH; 186 187 float minHeight; 188 float maxHeight; 189 float preferredHeight; 190 view->GetHeightForWidth(frame.Width(), &minHeight, &maxHeight, 191 &preferredHeight); 192 193 frame.bottom = frame.top + max_c(frame.Height(), minHeight); 194 maxSize.height = minHeight; 195 } 196 197 frame = AlignInFrame(frame, maxSize, alignment); 198 view->MoveTo(frame.LeftTop()); 199 view->ResizeTo(frame.Size()); 200 } 201 202