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