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 #include "Window.h" 36 #include "DialogPane.h" 37 #include "Thread.h" 38 #include "Utilities.h" 39 40 41 const uint32 kValueChanged = 'swch'; 42 43 const rgb_color kNormalColor = {150, 150, 150, 255}; 44 const rgb_color kHighlightColor = {100, 100, 0, 255}; 45 46 47 static void 48 AddSelf(BView *self, BView *to) 49 { 50 to->AddChild(self); 51 } 52 53 54 void 55 ViewList::RemoveAll(BView *) 56 { 57 EachListItemIgnoreResult(this, &BView::RemoveSelf); 58 } 59 60 61 void 62 ViewList::AddAll(BView *toParent) 63 { 64 EachListItem(this, &AddSelf, toParent); 65 } 66 67 68 // #pragma mark - 69 70 71 DialogPane::DialogPane(BRect mode1Frame, BRect mode2Frame, int32 initialMode, 72 const char *name, uint32 followFlags, uint32 flags) 73 : BView(FrameForMode(initialMode, mode1Frame, mode2Frame, mode2Frame), 74 name, followFlags, flags), 75 fMode(initialMode), 76 fMode1Frame(mode1Frame), 77 fMode2Frame(mode2Frame), 78 fMode3Frame(mode2Frame) 79 { 80 SetMode(fMode, true); 81 } 82 83 84 DialogPane::DialogPane(BRect mode1Frame, BRect mode2Frame, BRect mode3Frame, 85 int32 initialMode, const char *name, uint32 followFlags, uint32 flags) 86 : BView(FrameForMode(initialMode, mode1Frame, mode2Frame, mode3Frame), 87 name, followFlags, flags), 88 fMode(initialMode), 89 fMode1Frame(mode1Frame), 90 fMode2Frame(mode2Frame), 91 fMode3Frame(mode3Frame) 92 { 93 SetMode(fMode, true); 94 } 95 96 97 DialogPane::~DialogPane() 98 { 99 fMode3Items.RemoveAll(this); 100 fMode2Items.RemoveAll(this); 101 } 102 103 104 void 105 DialogPane::SetMode(int32 mode, bool initialSetup) 106 { 107 ASSERT(mode < 3 && mode >= 0); 108 109 if (!initialSetup && mode == fMode) 110 return; 111 112 int32 oldMode = fMode; 113 fMode = mode; 114 115 bool followBottom = (ResizingMode() & B_FOLLOW_BOTTOM) != 0; 116 // if we are follow bottom, we will move ourselves, need to place us back 117 float bottomOffset = 0; 118 if (followBottom && Window() != NULL) 119 bottomOffset = Window()->Bounds().bottom - Frame().bottom; 120 121 BRect newBounds(BoundsForMode(fMode)); 122 if (!initialSetup) 123 ResizeParentWindow(fMode, oldMode); 124 125 ResizeTo(newBounds.Width(), newBounds.Height()); 126 127 float delta = 0; 128 if (followBottom && Window() != NULL) 129 delta = (Window()->Bounds().bottom - Frame().bottom) - bottomOffset; 130 131 if (delta != 0) { 132 MoveBy(0, delta); 133 if (fLatch && (fLatch->ResizingMode() & B_FOLLOW_BOTTOM)) 134 fLatch->MoveBy(0, delta); 135 } 136 137 switch (fMode) { 138 case 0: 139 { 140 if (oldMode > 1) 141 fMode3Items.RemoveAll(this); 142 if (oldMode > 0) 143 fMode2Items.RemoveAll(this); 144 145 BView *separator = FindView("separatorLine"); 146 if (separator) { 147 BRect frame(separator->Frame()); 148 frame.InsetBy(-1, -1); 149 RemoveChild(separator); 150 Invalidate(); 151 } 152 153 AddChild(new SeparatorLine(BPoint(newBounds.left, newBounds.top 154 + newBounds.Height() / 2), newBounds.Width(), false, 155 "separatorLine")); 156 break; 157 } 158 case 1: 159 { 160 if (oldMode > 1) 161 fMode3Items.RemoveAll(this); 162 else 163 fMode2Items.AddAll(this); 164 165 BView *separator = FindView("separatorLine"); 166 if (separator) { 167 BRect frame(separator->Frame()); 168 frame.InsetBy(-1, -1); 169 RemoveChild(separator); 170 Invalidate(); 171 } 172 break; 173 } 174 case 2: 175 { 176 fMode3Items.AddAll(this); 177 if (oldMode < 1) 178 fMode2Items.AddAll(this); 179 180 BView *separator = FindView("separatorLine"); 181 if (separator) { 182 BRect frame(separator->Frame()); 183 frame.InsetBy(-1, -1); 184 RemoveChild(separator); 185 Invalidate(); 186 } 187 break; 188 } 189 } 190 } 191 192 193 void 194 DialogPane::AttachedToWindow() 195 { 196 BView *parent = Parent(); 197 if (parent) { 198 SetViewColor(parent->ViewColor()); 199 SetLowColor(parent->LowColor()); 200 } 201 } 202 203 204 void 205 DialogPane::ResizeParentWindow(int32 from, int32 to) 206 { 207 if (!Window()) 208 return; 209 210 BRect oldBounds = BoundsForMode(from); 211 BRect newBounds = BoundsForMode(to); 212 213 BPoint by = oldBounds.RightBottom() - newBounds.RightBottom(); 214 if (by != BPoint(0, 0)) 215 Window()->ResizeBy(by.x, by.y); 216 } 217 218 219 void 220 DialogPane::AddItem(BView *view, int32 toMode) 221 { 222 if (toMode == 1) 223 fMode2Items.AddItem(view); 224 else if (toMode == 2) 225 fMode3Items.AddItem(view); 226 if (fMode >= toMode) 227 AddChild(view); 228 } 229 230 231 BRect 232 DialogPane::FrameForMode(int32 mode) 233 { 234 switch (mode) { 235 case 0: 236 return fMode1Frame; 237 case 1: 238 return fMode2Frame; 239 case 2: 240 return fMode3Frame; 241 } 242 return fMode1Frame; 243 } 244 245 246 BRect 247 DialogPane::BoundsForMode(int32 mode) 248 { 249 BRect result; 250 switch (mode) { 251 case 0: 252 result = fMode1Frame; 253 break; 254 case 1: 255 result = fMode2Frame; 256 break; 257 case 2: 258 result = fMode3Frame; 259 break; 260 } 261 result.OffsetTo(0, 0); 262 return result; 263 } 264 265 266 BRect 267 DialogPane::FrameForMode(int32 mode, BRect mode1Frame, BRect mode2Frame, 268 BRect mode3Frame) 269 { 270 switch (mode) { 271 case 0: 272 return mode1Frame; 273 case 1: 274 return mode2Frame; 275 case 2: 276 return mode3Frame; 277 } 278 return mode1Frame; 279 } 280 281 282 void 283 DialogPane::SetSwitch(BControl *control) 284 { 285 fLatch = control; 286 control->SetMessage(new BMessage(kValueChanged)); 287 control->SetTarget(this); 288 } 289 290 291 void 292 DialogPane::MessageReceived(BMessage *message) 293 { 294 if (message->what == kValueChanged) { 295 int32 value; 296 if (message->FindInt32("be:value", &value) == B_OK) 297 SetMode(value); 298 } else 299 _inherited::MessageReceived(message); 300 } 301 302 303 // #pragma mark - 304 305 306 PaneSwitch::PaneSwitch(BRect frame, const char *name, bool leftAligned, 307 uint32 resizeMask, uint32 flags) 308 : BControl(frame, name, "", 0, resizeMask, flags), 309 fLeftAligned(leftAligned), 310 fPressing(false) 311 { 312 } 313 314 315 void 316 PaneSwitch::DoneTracking(BPoint point) 317 { 318 BRect bounds(Bounds()); 319 bounds.InsetBy(-3, -3); 320 321 fPressing = false; 322 Invalidate(); 323 if (bounds.Contains(point)) { 324 SetValue(!Value()); 325 Invoke(); 326 } 327 } 328 329 330 void 331 PaneSwitch::Track(BPoint point, uint32) 332 { 333 BRect bounds(Bounds()); 334 bounds.InsetBy(-3, -3); 335 336 bool newPressing = bounds.Contains(point); 337 if (newPressing != fPressing) { 338 fPressing = newPressing; 339 Invalidate(); 340 } 341 } 342 343 344 void 345 PaneSwitch::MouseDown(BPoint) 346 { 347 if (!IsEnabled()) 348 return; 349 350 fPressing = true; 351 MouseDownThread<PaneSwitch>::TrackMouse(this, &PaneSwitch::DoneTracking, 352 &PaneSwitch::Track); 353 Invalidate(); 354 } 355 356 357 void 358 PaneSwitch::Draw(BRect) 359 { 360 if (fPressing) 361 DrawInState(kPressed); 362 else if (Value()) 363 DrawInState(kExpanded); 364 else 365 DrawInState(kCollapsed); 366 367 rgb_color markColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 368 369 bool focused = IsFocus() && Window()->IsActive(); 370 BRect bounds(Bounds()); 371 BeginLineArray(2); 372 AddLine(BPoint(bounds.left + 2, bounds.bottom - 1), 373 BPoint(bounds.right - 2, bounds.bottom - 1), focused ? markColor : ViewColor()); 374 AddLine(BPoint(bounds.left + 2, bounds.bottom), 375 BPoint(bounds.right - 2, bounds.bottom), focused ? kWhite : ViewColor()); 376 EndLineArray(); 377 } 378 379 380 void 381 PaneSwitch::DrawInState(PaneSwitch::State state) 382 { 383 BRect rect(0, 0, 10, 10); 384 385 rgb_color outlineColor = {0, 0, 0, 255}; 386 rgb_color middleColor = state == kPressed ? kHighlightColor : kNormalColor; 387 388 SetDrawingMode(B_OP_COPY); 389 390 switch (state) { 391 case kCollapsed: 392 BeginLineArray(6); 393 394 if (fLeftAligned) { 395 AddLine(BPoint(rect.left + 3, rect.top + 1), 396 BPoint(rect.left + 3, rect.bottom - 1), outlineColor); 397 AddLine(BPoint(rect.left + 3, rect.top + 1), 398 BPoint(rect.left + 7, rect.top + 5), outlineColor); 399 AddLine(BPoint(rect.left + 7, rect.top + 5), 400 BPoint(rect.left + 3, rect.bottom - 1), outlineColor); 401 402 AddLine(BPoint(rect.left + 4, rect.top + 3), 403 BPoint(rect.left + 4, rect.bottom - 3), middleColor); 404 AddLine(BPoint(rect.left + 5, rect.top + 4), 405 BPoint(rect.left + 5, rect.bottom - 4), middleColor); 406 AddLine(BPoint(rect.left + 5, rect.top + 5), 407 BPoint(rect.left + 6, rect.top + 5), middleColor); 408 } else { 409 AddLine(BPoint(rect.right - 3, rect.top + 1), 410 BPoint(rect.right - 3, rect.bottom - 1), outlineColor); 411 AddLine(BPoint(rect.right - 3, rect.top + 1), 412 BPoint(rect.right - 7, rect.top + 5), outlineColor); 413 AddLine(BPoint(rect.right - 7, rect.top + 5), 414 BPoint(rect.right - 3, rect.bottom - 1), outlineColor); 415 416 AddLine(BPoint(rect.right - 4, rect.top + 3), 417 BPoint(rect.right - 4, rect.bottom - 3), middleColor); 418 AddLine(BPoint(rect.right - 5, rect.top + 4), 419 BPoint(rect.right - 5, rect.bottom - 4), middleColor); 420 AddLine(BPoint(rect.right - 5, rect.top + 5), 421 BPoint(rect.right - 6, rect.top + 5), middleColor); 422 } 423 EndLineArray(); 424 break; 425 426 case kPressed: 427 BeginLineArray(7); 428 if (fLeftAligned) { 429 AddLine(BPoint(rect.left + 1, rect.top + 7), 430 BPoint(rect.left + 7, rect.top + 7), outlineColor); 431 AddLine(BPoint(rect.left + 7, rect.top + 1), 432 BPoint(rect.left + 7, rect.top + 7), outlineColor); 433 AddLine(BPoint(rect.left + 1, rect.top + 7), 434 BPoint(rect.left + 7, rect.top + 1), outlineColor); 435 436 AddLine(BPoint(rect.left + 3, rect.top + 6), 437 BPoint(rect.left + 6, rect.top + 6), middleColor); 438 AddLine(BPoint(rect.left + 4, rect.top + 5), 439 BPoint(rect.left + 6, rect.top + 5), middleColor); 440 AddLine(BPoint(rect.left + 5, rect.top + 4), 441 BPoint(rect.left + 6, rect.top + 4), middleColor); 442 AddLine(BPoint(rect.left + 6, rect.top + 3), 443 BPoint(rect.left + 6, rect.top + 4), middleColor); 444 } else { 445 AddLine(BPoint(rect.right - 1, rect.top + 7), 446 BPoint(rect.right - 7, rect.top + 7), outlineColor); 447 AddLine(BPoint(rect.right - 7, rect.top + 1), 448 BPoint(rect.right - 7, rect.top + 7), outlineColor); 449 AddLine(BPoint(rect.right - 1, rect.top + 7), 450 BPoint(rect.right - 7, rect.top + 1), outlineColor); 451 452 AddLine(BPoint(rect.right - 3, rect.top + 6), 453 BPoint(rect.right - 6, rect.top + 6), middleColor); 454 AddLine(BPoint(rect.right - 4, rect.top + 5), 455 BPoint(rect.right - 6, rect.top + 5), middleColor); 456 AddLine(BPoint(rect.right - 5, rect.top + 4), 457 BPoint(rect.right - 6, rect.top + 4), middleColor); 458 AddLine(BPoint(rect.right - 6, rect.top + 3), 459 BPoint(rect.right - 6, rect.top + 4), middleColor); 460 } 461 EndLineArray(); 462 break; 463 464 case kExpanded: 465 BeginLineArray(6); 466 AddLine(BPoint(rect.left + 1, rect.top + 3), 467 BPoint(rect.right - 1, rect.top + 3), outlineColor); 468 AddLine(BPoint(rect.left + 1, rect.top + 3), 469 BPoint(rect.left + 5, rect.top + 7), outlineColor); 470 AddLine(BPoint(rect.left + 5, rect.top + 7), 471 BPoint(rect.right - 1, rect.top + 3), outlineColor); 472 473 AddLine(BPoint(rect.left + 3, rect.top + 4), 474 BPoint(rect.right - 3, rect.top + 4), middleColor); 475 AddLine(BPoint(rect.left + 4, rect.top + 5), 476 BPoint(rect.right - 4, rect.top + 5), middleColor); 477 AddLine(BPoint(rect.left + 5, rect.top + 5), 478 BPoint(rect.left + 5, rect.top + 6), middleColor); 479 EndLineArray(); 480 break; 481 } 482 } 483 484