1 /* 2 Open Tracker License 3 4 Terms and Conditions 5 6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved. 7 8 Permission is hereby granted, free of charge, to any person obtaining a copy of 9 this software and associated documentation files (the "Software"), to deal in 10 the Software without restriction, including without limitation the rights to 11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 12 of the Software, and to permit persons to whom the Software is furnished to do 13 so, subject to the following conditions: 14 15 The above copyright notice and this permission notice applies to all licensees 16 and shall be included in all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION 23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 25 Except as contained in this notice, the name of Be Incorporated shall not be 26 used in advertising or otherwise to promote the sale, use or other dealings in 27 this Software without prior written authorization from Be Incorporated. 28 29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks 30 of Be Incorporated in the United States and other countries. Other brand product 31 names are registered trademarks or trademarks of their respective holders. 32 All rights reserved. 33 */ 34 35 36 #include "DialogPane.h" 37 38 #include <ControlLook.h> 39 #include <LayoutUtils.h> 40 41 #include "Utilities.h" 42 #include "Window.h" 43 44 45 const rgb_color kNormalColor = {150, 150, 150, 255}; 46 const rgb_color kHighlightColor = {100, 100, 0, 255}; 47 48 49 // #pragma mark - PaneSwitch 50 51 52 PaneSwitch::PaneSwitch(BRect frame, const char* name, bool leftAligned, 53 uint32 resizeMask, uint32 flags) 54 : 55 BControl(frame, name, "", 0, resizeMask, flags), 56 fLeftAligned(leftAligned), 57 fPressing(false), 58 fLabelOn(NULL), 59 fLabelOff(NULL) 60 { 61 } 62 63 64 PaneSwitch::PaneSwitch(const char* name, bool leftAligned, uint32 flags) 65 : 66 BControl(name, "", 0, flags), 67 fLeftAligned(leftAligned), 68 fPressing(false), 69 fLabelOn(NULL), 70 fLabelOff(NULL) 71 { 72 } 73 74 75 PaneSwitch::~PaneSwitch() 76 { 77 free(fLabelOn); 78 free(fLabelOff); 79 } 80 81 82 void 83 PaneSwitch::Draw(BRect) 84 { 85 BRect bounds(Bounds()); 86 87 // Draw the label, if any 88 const char* label = fLabelOff; 89 if (fLabelOn != NULL && Value() == B_CONTROL_ON) 90 label = fLabelOn; 91 92 if (label != NULL) { 93 BPoint point; 94 float latchSize = be_plain_font->Size(); 95 float labelDist = latchSize + ceilf(latchSize / 2.0); 96 if (fLeftAligned) 97 point.x = labelDist; 98 else 99 point.x = bounds.right - labelDist - StringWidth(label); 100 101 SetHighUIColor(B_PANEL_TEXT_COLOR); 102 font_height fontHeight; 103 GetFontHeight(&fontHeight); 104 point.y = (bounds.top + bounds.bottom 105 - ceilf(fontHeight.ascent) - ceilf(fontHeight.descent)) / 2 106 + ceilf(fontHeight.ascent); 107 108 DrawString(label, point); 109 } 110 111 // draw the latch 112 if (fPressing) 113 DrawInState(kPressed); 114 else if (Value()) 115 DrawInState(kExpanded); 116 else 117 DrawInState(kCollapsed); 118 119 // ...and the focus indication 120 if (!IsFocus() || !Window()->IsActive()) 121 return; 122 123 rgb_color markColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 124 125 BeginLineArray(2); 126 AddLine(BPoint(bounds.left + 2, bounds.bottom - 1), 127 BPoint(bounds.right - 2, bounds.bottom - 1), markColor); 128 AddLine(BPoint(bounds.left + 2, bounds.bottom), 129 BPoint(bounds.right - 2, bounds.bottom), kWhite); 130 EndLineArray(); 131 } 132 133 134 void 135 PaneSwitch::MouseDown(BPoint) 136 { 137 if (!IsEnabled()) 138 return; 139 140 fPressing = true; 141 SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY); 142 Invalidate(); 143 } 144 145 146 void 147 PaneSwitch::MouseMoved(BPoint point, uint32 code, const BMessage* message) 148 { 149 int32 buttons; 150 BMessage* currentMessage = Window()->CurrentMessage(); 151 if (currentMessage == NULL 152 || currentMessage->FindInt32("buttons", &buttons) != B_OK) { 153 buttons = 0; 154 } 155 156 if (buttons != 0) { 157 BRect bounds(Bounds()); 158 bounds.InsetBy(-3, -3); 159 160 bool newPressing = bounds.Contains(point); 161 if (newPressing != fPressing) { 162 fPressing = newPressing; 163 Invalidate(); 164 } 165 } 166 167 BControl::MouseMoved(point, code, message); 168 } 169 170 171 void 172 PaneSwitch::MouseUp(BPoint point) 173 { 174 BRect bounds(Bounds()); 175 bounds.InsetBy(-3, -3); 176 177 fPressing = false; 178 Invalidate(); 179 if (bounds.Contains(point)) { 180 SetValue(!Value()); 181 Invoke(); 182 } 183 184 BControl::MouseUp(point); 185 } 186 187 188 void 189 PaneSwitch::GetPreferredSize(float* _width, float* _height) 190 { 191 BSize size = MinSize(); 192 if (_width != NULL) 193 *_width = size.width; 194 195 if (_height != NULL) 196 *_height = size.height; 197 } 198 199 200 BSize 201 PaneSwitch::MinSize() 202 { 203 BSize size; 204 float onLabelWidth = StringWidth(fLabelOn); 205 float offLabelWidth = StringWidth(fLabelOff); 206 float labelWidth = max_c(onLabelWidth, offLabelWidth); 207 float latchSize = be_plain_font->Size(); 208 size.width = latchSize; 209 if (labelWidth > 0.0) 210 size.width += ceilf(latchSize / 2.0) + labelWidth; 211 212 font_height fontHeight; 213 GetFontHeight(&fontHeight); 214 size.height = ceilf(fontHeight.ascent) + ceilf(fontHeight.descent); 215 size.height = max_c(size.height, latchSize); 216 217 return BLayoutUtils::ComposeSize(ExplicitMinSize(), size); 218 } 219 220 221 BSize 222 PaneSwitch::MaxSize() 223 { 224 return BLayoutUtils::ComposeSize(ExplicitMaxSize(), MinSize()); 225 } 226 227 228 BSize 229 PaneSwitch::PreferredSize() 230 { 231 return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), MinSize()); 232 } 233 234 235 void 236 PaneSwitch::SetLabels(const char* labelOn, const char* labelOff) 237 { 238 free(fLabelOn); 239 free(fLabelOff); 240 241 if (labelOn != NULL) 242 fLabelOn = strdup(labelOn); 243 else 244 fLabelOn = NULL; 245 246 if (labelOff != NULL) 247 fLabelOff = strdup(labelOff); 248 else 249 fLabelOff = NULL; 250 251 Invalidate(); 252 InvalidateLayout(); 253 } 254 255 256 void 257 PaneSwitch::DrawInState(PaneSwitch::State state) 258 { 259 BRect rect(0, 0, be_plain_font->Size(), be_plain_font->Size()); 260 rect.OffsetBy(1, 1); 261 262 rgb_color arrowColor = state == kPressed ? kHighlightColor : kNormalColor; 263 int32 arrowDirection = BControlLook::B_RIGHT_ARROW; 264 float tint = IsEnabled() && Window()->IsActive() ? B_DARKEN_3_TINT 265 : B_DARKEN_1_TINT; 266 267 switch (state) { 268 case kCollapsed: 269 arrowDirection = BControlLook::B_RIGHT_ARROW; 270 break; 271 272 case kPressed: 273 arrowDirection = BControlLook::B_RIGHT_DOWN_ARROW; 274 break; 275 276 case kExpanded: 277 arrowDirection = BControlLook::B_DOWN_ARROW; 278 break; 279 } 280 281 SetDrawingMode(B_OP_COPY); 282 be_control_look->DrawArrowShape(this, rect, rect, arrowColor, 283 arrowDirection, 0, tint); 284 } 285