btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / kits / tracker / DialogPane.cpp
blob4e9957579e491dd52e5601e101dd9e43dd0f8a6a
1 /*
2 Open Tracker License
4 Terms and Conditions
6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
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:
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.
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.
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.
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.
36 #include "DialogPane.h"
38 #include <ControlLook.h>
39 #include <LayoutUtils.h>
41 #include "Thread.h"
42 #include "Utilities.h"
43 #include "Window.h"
46 const uint32 kValueChanged = 'swch';
48 const rgb_color kNormalColor = {150, 150, 150, 255};
49 const rgb_color kHighlightColor = {100, 100, 0, 255};
52 static void
53 AddSelf(BView* self, BView* to)
55 to->AddChild(self);
59 void
60 ViewList::RemoveAll(BView*)
62 EachListItemIgnoreResult(this, &BView::RemoveSelf);
66 void
67 ViewList::AddAll(BView* toParent)
69 EachListItem(this, &AddSelf, toParent);
73 // #pragma mark - DialogPane
76 DialogPane::DialogPane(BRect mode1Frame, BRect mode2Frame, int32 initialMode,
77 const char* name, uint32 followFlags, uint32 flags)
79 BView(FrameForMode(initialMode, mode1Frame, mode2Frame, mode2Frame),
80 name, followFlags, flags),
81 fMode(initialMode),
82 fMode1Frame(mode1Frame),
83 fMode2Frame(mode2Frame),
84 fMode3Frame(mode2Frame)
86 SetMode(fMode, true);
90 DialogPane::DialogPane(BRect mode1Frame, BRect mode2Frame, BRect mode3Frame,
91 int32 initialMode, const char* name, uint32 followFlags, uint32 flags)
93 BView(FrameForMode(initialMode, mode1Frame, mode2Frame, mode3Frame),
94 name, followFlags, flags),
95 fMode(initialMode),
96 fMode1Frame(mode1Frame),
97 fMode2Frame(mode2Frame),
98 fMode3Frame(mode3Frame)
100 SetMode(fMode, true);
104 DialogPane::~DialogPane()
106 fMode3Items.RemoveAll(this);
107 fMode2Items.RemoveAll(this);
111 void
112 DialogPane::SetMode(int32 mode, bool initialSetup)
114 ASSERT(mode < 3 && mode >= 0);
116 if (!initialSetup && mode == fMode)
117 return;
119 int32 oldMode = fMode;
120 fMode = mode;
122 bool followBottom = (ResizingMode() & B_FOLLOW_BOTTOM) != 0;
123 // if we are follow bottom, we will move ourselves, need to place us back
124 float bottomOffset = 0;
125 if (followBottom && Window() != NULL)
126 bottomOffset = Window()->Bounds().bottom - Frame().bottom;
128 BRect newBounds(BoundsForMode(fMode));
129 if (!initialSetup)
130 ResizeParentWindow(fMode, oldMode);
132 ResizeTo(newBounds.Width(), newBounds.Height());
134 float delta = 0;
135 if (followBottom && Window() != NULL)
136 delta = (Window()->Bounds().bottom - Frame().bottom) - bottomOffset;
138 if (delta != 0) {
139 MoveBy(0, delta);
140 if (fLatch && (fLatch->ResizingMode() & B_FOLLOW_BOTTOM))
141 fLatch->MoveBy(0, delta);
144 switch (fMode) {
145 case 0:
147 if (oldMode > 1)
148 fMode3Items.RemoveAll(this);
149 if (oldMode > 0)
150 fMode2Items.RemoveAll(this);
152 BView* separator = FindView("separatorLine");
153 if (separator) {
154 BRect frame(separator->Frame());
155 frame.InsetBy(-1, -1);
156 RemoveChild(separator);
157 Invalidate();
160 AddChild(new SeparatorLine(BPoint(newBounds.left, newBounds.top
161 + newBounds.Height() / 2), newBounds.Width(), false,
162 "separatorLine"));
163 break;
166 case 1:
168 if (oldMode > 1)
169 fMode3Items.RemoveAll(this);
170 else
171 fMode2Items.AddAll(this);
173 BView* separator = FindView("separatorLine");
174 if (separator) {
175 BRect frame(separator->Frame());
176 frame.InsetBy(-1, -1);
177 RemoveChild(separator);
178 Invalidate();
180 break;
183 case 2:
185 fMode3Items.AddAll(this);
186 if (oldMode < 1)
187 fMode2Items.AddAll(this);
189 BView* separator = FindView("separatorLine");
190 if (separator) {
191 BRect frame(separator->Frame());
192 frame.InsetBy(-1, -1);
193 RemoveChild(separator);
194 Invalidate();
196 break;
202 void
203 DialogPane::AttachedToWindow()
205 AdoptParentColors();
209 void
210 DialogPane::ResizeParentWindow(int32 from, int32 to)
212 if (Window() == NULL)
213 return;
215 BRect oldBounds = BoundsForMode(from);
216 BRect newBounds = BoundsForMode(to);
218 BPoint by = oldBounds.RightBottom() - newBounds.RightBottom();
219 if (by != BPoint(0, 0))
220 Window()->ResizeBy(by.x, by.y);
224 void
225 DialogPane::AddItem(BView* view, int32 toMode)
227 if (toMode == 1)
228 fMode2Items.AddItem(view);
229 else if (toMode == 2)
230 fMode3Items.AddItem(view);
232 if (fMode >= toMode)
233 AddChild(view);
237 BRect
238 DialogPane::FrameForMode(int32 mode)
240 switch (mode) {
241 case 0:
242 return fMode1Frame;
244 case 1:
245 return fMode2Frame;
247 case 2:
248 return fMode3Frame;
251 return fMode1Frame;
255 BRect
256 DialogPane::BoundsForMode(int32 mode)
258 BRect result;
259 switch (mode) {
260 case 0:
261 result = fMode1Frame;
262 break;
264 case 1:
265 result = fMode2Frame;
266 break;
268 case 2:
269 result = fMode3Frame;
270 break;
272 result.OffsetTo(0, 0);
274 return result;
278 BRect
279 DialogPane::FrameForMode(int32 mode, BRect mode1Frame, BRect mode2Frame,
280 BRect mode3Frame)
282 switch (mode) {
283 case 0:
284 return mode1Frame;
286 case 1:
287 return mode2Frame;
289 case 2:
290 return mode3Frame;
293 return mode1Frame;
297 void
298 DialogPane::SetSwitch(BControl* control)
300 fLatch = control;
301 control->SetMessage(new BMessage(kValueChanged));
302 control->SetTarget(this);
306 void
307 DialogPane::MessageReceived(BMessage* message)
309 if (message->what == kValueChanged) {
310 int32 value;
311 if (message->FindInt32("be:value", &value) == B_OK)
312 SetMode(value);
313 } else
314 _inherited::MessageReceived(message);
318 // #pragma mark - PaneSwitch
321 PaneSwitch::PaneSwitch(BRect frame, const char* name, bool leftAligned,
322 uint32 resizeMask, uint32 flags)
324 BControl(frame, name, "", 0, resizeMask, flags),
325 fLeftAligned(leftAligned),
326 fPressing(false),
327 fLabelOn(NULL),
328 fLabelOff(NULL)
333 PaneSwitch::PaneSwitch(const char* name, bool leftAligned, uint32 flags)
335 BControl(name, "", 0, flags),
336 fLeftAligned(leftAligned),
337 fPressing(false),
338 fLabelOn(NULL),
339 fLabelOff(NULL)
344 PaneSwitch::~PaneSwitch()
346 free(fLabelOn);
347 free(fLabelOff);
351 void
352 PaneSwitch::Draw(BRect)
354 BRect bounds(Bounds());
356 // Draw the label, if any
357 const char* label = fLabelOff;
358 if (fLabelOn != NULL && Value() == B_CONTROL_ON)
359 label = fLabelOn;
361 if (label != NULL) {
362 BPoint point;
363 float labelDist = sLatchSize + ceilf(sLatchSize / 2.0);
364 if (fLeftAligned)
365 point.x = labelDist;
366 else
367 point.x = bounds.right - labelDist - StringWidth(label);
369 SetHighUIColor(B_PANEL_TEXT_COLOR);
370 font_height fontHeight;
371 GetFontHeight(&fontHeight);
372 point.y = (bounds.top + bounds.bottom
373 - ceilf(fontHeight.ascent) - ceilf(fontHeight.descent)) / 2
374 + ceilf(fontHeight.ascent);
376 DrawString(label, point);
379 // draw the latch
380 if (fPressing)
381 DrawInState(kPressed);
382 else if (Value())
383 DrawInState(kExpanded);
384 else
385 DrawInState(kCollapsed);
387 // ...and the focus indication
388 if (!IsFocus() || !Window()->IsActive())
389 return;
391 rgb_color markColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR);
393 BeginLineArray(2);
394 AddLine(BPoint(bounds.left + 2, bounds.bottom - 1),
395 BPoint(bounds.right - 2, bounds.bottom - 1), markColor);
396 AddLine(BPoint(bounds.left + 2, bounds.bottom),
397 BPoint(bounds.right - 2, bounds.bottom), kWhite);
398 EndLineArray();
402 void
403 PaneSwitch::MouseDown(BPoint)
405 if (!IsEnabled())
406 return;
408 fPressing = true;
409 MouseDownThread<PaneSwitch>::TrackMouse(this, &PaneSwitch::DoneTracking,
410 &PaneSwitch::Track);
411 Invalidate();
415 void
416 PaneSwitch::GetPreferredSize(float* _width, float* _height)
418 BSize size = MinSize();
419 if (_width != NULL)
420 *_width = size.width;
422 if (_height != NULL)
423 *_height = size.height;
427 BSize
428 PaneSwitch::MinSize()
430 BSize size;
431 float onLabelWidth = StringWidth(fLabelOn);
432 float offLabelWidth = StringWidth(fLabelOff);
433 float labelWidth = max_c(onLabelWidth, offLabelWidth);
434 size.width = sLatchSize;
435 if (labelWidth > 0.0)
436 size.width += ceilf(sLatchSize / 2.0) + labelWidth;
438 font_height fontHeight;
439 GetFontHeight(&fontHeight);
440 size.height = ceilf(fontHeight.ascent) + ceilf(fontHeight.descent);
441 size.height = max_c(size.height, sLatchSize);
443 return BLayoutUtils::ComposeSize(ExplicitMinSize(), size);
447 BSize
448 PaneSwitch::MaxSize()
450 return BLayoutUtils::ComposeSize(ExplicitMaxSize(), MinSize());
454 BSize
455 PaneSwitch::PreferredSize()
457 return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), MinSize());
461 void
462 PaneSwitch::SetLabels(const char* labelOn, const char* labelOff)
464 free(fLabelOn);
465 free(fLabelOff);
467 if (labelOn != NULL)
468 fLabelOn = strdup(labelOn);
469 else
470 fLabelOn = NULL;
472 if (labelOff != NULL)
473 fLabelOff = strdup(labelOff);
474 else
475 fLabelOff = NULL;
477 Invalidate();
478 InvalidateLayout();
482 void
483 PaneSwitch::DoneTracking(BPoint point)
485 BRect bounds(Bounds());
486 bounds.InsetBy(-3, -3);
488 fPressing = false;
489 Invalidate();
490 if (bounds.Contains(point)) {
491 SetValue(!Value());
492 Invoke();
497 void
498 PaneSwitch::Track(BPoint point, uint32)
500 BRect bounds(Bounds());
501 bounds.InsetBy(-3, -3);
503 bool newPressing = bounds.Contains(point);
504 if (newPressing != fPressing) {
505 fPressing = newPressing;
506 Invalidate();
511 void
512 PaneSwitch::DrawInState(PaneSwitch::State state)
514 BRect rect(0, 0, be_plain_font->Size(), be_plain_font->Size());
515 rect.OffsetBy(1, 1);
517 rgb_color arrowColor = state == kPressed ? kHighlightColor : kNormalColor;
518 int32 arrowDirection = BControlLook::B_RIGHT_ARROW;
519 float tint = IsEnabled() && Window()->IsActive() ? B_DARKEN_3_TINT
520 : B_DARKEN_1_TINT;
522 switch (state) {
523 case kCollapsed:
524 arrowDirection = BControlLook::B_RIGHT_ARROW;
525 break;
527 case kPressed:
528 arrowDirection = BControlLook::B_RIGHT_DOWN_ARROW;
529 break;
531 case kExpanded:
532 arrowDirection = BControlLook::B_DOWN_ARROW;
533 break;
536 SetDrawingMode(B_OP_COPY);
537 be_control_look->DrawArrowShape(this, rect, rect, arrowColor,
538 arrowDirection, 0, tint);