102be5353SAxel Dörfler /*
202be5353SAxel Dörfler Open Tracker License
302be5353SAxel Dörfler
402be5353SAxel Dörfler Terms and Conditions
502be5353SAxel Dörfler
602be5353SAxel Dörfler Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
702be5353SAxel Dörfler
802be5353SAxel Dörfler Permission is hereby granted, free of charge, to any person obtaining a copy of
902be5353SAxel Dörfler this software and associated documentation files (the "Software"), to deal in
1002be5353SAxel Dörfler the Software without restriction, including without limitation the rights to
1102be5353SAxel Dörfler use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
1202be5353SAxel Dörfler of the Software, and to permit persons to whom the Software is furnished to do
1302be5353SAxel Dörfler so, subject to the following conditions:
1402be5353SAxel Dörfler
1502be5353SAxel Dörfler The above copyright notice and this permission notice applies to all licensees
1602be5353SAxel Dörfler and shall be included in all copies or substantial portions of the Software.
1702be5353SAxel Dörfler
1802be5353SAxel Dörfler THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1902be5353SAxel Dörfler IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
2002be5353SAxel Dörfler FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
2102be5353SAxel Dörfler BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2202be5353SAxel Dörfler AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
2302be5353SAxel Dörfler WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2402be5353SAxel Dörfler
2502be5353SAxel Dörfler Except as contained in this notice, the name of Be Incorporated shall not be
2602be5353SAxel Dörfler used in advertising or otherwise to promote the sale, use or other dealings in
2702be5353SAxel Dörfler this Software without prior written authorization from Be Incorporated.
2802be5353SAxel Dörfler
2902be5353SAxel Dörfler Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
3002be5353SAxel Dörfler of Be Incorporated in the United States and other countries. Other brand product
3102be5353SAxel Dörfler names are registered trademarks or trademarks of their respective holders.
3202be5353SAxel Dörfler All rights reserved.
3302be5353SAxel Dörfler */
3402be5353SAxel Dörfler
354242cbe2SJohn Scipione
3602be5353SAxel Dörfler #include "DialogPane.h"
373e3d7acbSStephan Aßmus
387e702e52SJohn Scipione #include <ControlLook.h>
393e3d7acbSStephan Aßmus #include <LayoutUtils.h>
403e3d7acbSStephan Aßmus
4102be5353SAxel Dörfler #include "Utilities.h"
423e3d7acbSStephan Aßmus #include "Window.h"
4302be5353SAxel Dörfler
4481202ff5SAxel Dörfler
4581202ff5SAxel Dörfler const rgb_color kNormalColor = {150, 150, 150, 255};
4681202ff5SAxel Dörfler const rgb_color kHighlightColor = {100, 100, 0, 255};
4781202ff5SAxel Dörfler
4802be5353SAxel Dörfler
493e3d7acbSStephan Aßmus // #pragma mark - PaneSwitch
5081202ff5SAxel Dörfler
5181202ff5SAxel Dörfler
PaneSwitch(BRect frame,const char * name,bool leftAligned,uint32 resizeMask,uint32 flags)5202be5353SAxel Dörfler PaneSwitch::PaneSwitch(BRect frame, const char* name, bool leftAligned,
5302be5353SAxel Dörfler uint32 resizeMask, uint32 flags)
543e3d7acbSStephan Aßmus :
553e3d7acbSStephan Aßmus BControl(frame, name, "", 0, resizeMask, flags),
5602be5353SAxel Dörfler fLeftAligned(leftAligned),
573e3d7acbSStephan Aßmus fPressing(false),
583e3d7acbSStephan Aßmus fLabelOn(NULL),
593e3d7acbSStephan Aßmus fLabelOff(NULL)
6002be5353SAxel Dörfler {
6102be5353SAxel Dörfler }
6202be5353SAxel Dörfler
6381202ff5SAxel Dörfler
PaneSwitch(const char * name,bool leftAligned,uint32 flags)643e3d7acbSStephan Aßmus PaneSwitch::PaneSwitch(const char* name, bool leftAligned, uint32 flags)
653e3d7acbSStephan Aßmus :
663e3d7acbSStephan Aßmus BControl(name, "", 0, flags),
673e3d7acbSStephan Aßmus fLeftAligned(leftAligned),
683e3d7acbSStephan Aßmus fPressing(false),
693e3d7acbSStephan Aßmus fLabelOn(NULL),
703e3d7acbSStephan Aßmus fLabelOff(NULL)
713e3d7acbSStephan Aßmus {
723e3d7acbSStephan Aßmus }
733e3d7acbSStephan Aßmus
743e3d7acbSStephan Aßmus
~PaneSwitch()753e3d7acbSStephan Aßmus PaneSwitch::~PaneSwitch()
763e3d7acbSStephan Aßmus {
778baeb63aSStephan Aßmus free(fLabelOn);
788baeb63aSStephan Aßmus free(fLabelOff);
793e3d7acbSStephan Aßmus }
803e3d7acbSStephan Aßmus
813e3d7acbSStephan Aßmus
823e3d7acbSStephan Aßmus void
Draw(BRect)833e3d7acbSStephan Aßmus PaneSwitch::Draw(BRect)
843e3d7acbSStephan Aßmus {
853e3d7acbSStephan Aßmus BRect bounds(Bounds());
863e3d7acbSStephan Aßmus
873e3d7acbSStephan Aßmus // Draw the label, if any
883e3d7acbSStephan Aßmus const char* label = fLabelOff;
893e3d7acbSStephan Aßmus if (fLabelOn != NULL && Value() == B_CONTROL_ON)
903e3d7acbSStephan Aßmus label = fLabelOn;
913e3d7acbSStephan Aßmus
923e3d7acbSStephan Aßmus if (label != NULL) {
933e3d7acbSStephan Aßmus BPoint point;
948854b897SAdrien Destugues float latchSize = be_plain_font->Size();
958854b897SAdrien Destugues float labelDist = latchSize + ceilf(latchSize / 2.0);
963e3d7acbSStephan Aßmus if (fLeftAligned)
973e3d7acbSStephan Aßmus point.x = labelDist;
983e3d7acbSStephan Aßmus else
993e3d7acbSStephan Aßmus point.x = bounds.right - labelDist - StringWidth(label);
1003e3d7acbSStephan Aßmus
101c5b4dc40Slooncraz SetHighUIColor(B_PANEL_TEXT_COLOR);
1023e3d7acbSStephan Aßmus font_height fontHeight;
1033e3d7acbSStephan Aßmus GetFontHeight(&fontHeight);
1043e3d7acbSStephan Aßmus point.y = (bounds.top + bounds.bottom
1053e3d7acbSStephan Aßmus - ceilf(fontHeight.ascent) - ceilf(fontHeight.descent)) / 2
1063e3d7acbSStephan Aßmus + ceilf(fontHeight.ascent);
1073e3d7acbSStephan Aßmus
1083e3d7acbSStephan Aßmus DrawString(label, point);
1093e3d7acbSStephan Aßmus }
1103e3d7acbSStephan Aßmus
1113e3d7acbSStephan Aßmus // draw the latch
1123e3d7acbSStephan Aßmus if (fPressing)
1133e3d7acbSStephan Aßmus DrawInState(kPressed);
1143e3d7acbSStephan Aßmus else if (Value())
1153e3d7acbSStephan Aßmus DrawInState(kExpanded);
1163e3d7acbSStephan Aßmus else
1173e3d7acbSStephan Aßmus DrawInState(kCollapsed);
1183e3d7acbSStephan Aßmus
1193e3d7acbSStephan Aßmus // ...and the focus indication
1203e3d7acbSStephan Aßmus if (!IsFocus() || !Window()->IsActive())
1213e3d7acbSStephan Aßmus return;
1223e3d7acbSStephan Aßmus
1233e3d7acbSStephan Aßmus rgb_color markColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR);
1243e3d7acbSStephan Aßmus
1253e3d7acbSStephan Aßmus BeginLineArray(2);
1263e3d7acbSStephan Aßmus AddLine(BPoint(bounds.left + 2, bounds.bottom - 1),
1273e3d7acbSStephan Aßmus BPoint(bounds.right - 2, bounds.bottom - 1), markColor);
1283e3d7acbSStephan Aßmus AddLine(BPoint(bounds.left + 2, bounds.bottom),
1293e3d7acbSStephan Aßmus BPoint(bounds.right - 2, bounds.bottom), kWhite);
1303e3d7acbSStephan Aßmus EndLineArray();
1313e3d7acbSStephan Aßmus }
1323e3d7acbSStephan Aßmus
1333e3d7acbSStephan Aßmus
1343e3d7acbSStephan Aßmus void
MouseDown(BPoint)1353e3d7acbSStephan Aßmus PaneSwitch::MouseDown(BPoint)
1363e3d7acbSStephan Aßmus {
1373e3d7acbSStephan Aßmus if (!IsEnabled())
1383e3d7acbSStephan Aßmus return;
1393e3d7acbSStephan Aßmus
1403e3d7acbSStephan Aßmus fPressing = true;
141*20f2ebaeSAdrien Destugues SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY);
1423e3d7acbSStephan Aßmus Invalidate();
1433e3d7acbSStephan Aßmus }
1443e3d7acbSStephan Aßmus
1453e3d7acbSStephan Aßmus
1463e3d7acbSStephan Aßmus void
MouseMoved(BPoint point,uint32 code,const BMessage * message)147*20f2ebaeSAdrien Destugues PaneSwitch::MouseMoved(BPoint point, uint32 code, const BMessage* message)
148*20f2ebaeSAdrien Destugues {
149*20f2ebaeSAdrien Destugues int32 buttons;
150*20f2ebaeSAdrien Destugues BMessage* currentMessage = Window()->CurrentMessage();
151*20f2ebaeSAdrien Destugues if (currentMessage == NULL
152*20f2ebaeSAdrien Destugues || currentMessage->FindInt32("buttons", &buttons) != B_OK) {
153*20f2ebaeSAdrien Destugues buttons = 0;
154*20f2ebaeSAdrien Destugues }
155*20f2ebaeSAdrien Destugues
156*20f2ebaeSAdrien Destugues if (buttons != 0) {
157*20f2ebaeSAdrien Destugues BRect bounds(Bounds());
158*20f2ebaeSAdrien Destugues bounds.InsetBy(-3, -3);
159*20f2ebaeSAdrien Destugues
160*20f2ebaeSAdrien Destugues bool newPressing = bounds.Contains(point);
161*20f2ebaeSAdrien Destugues if (newPressing != fPressing) {
162*20f2ebaeSAdrien Destugues fPressing = newPressing;
163*20f2ebaeSAdrien Destugues Invalidate();
164*20f2ebaeSAdrien Destugues }
165*20f2ebaeSAdrien Destugues }
166*20f2ebaeSAdrien Destugues
167*20f2ebaeSAdrien Destugues BControl::MouseMoved(point, code, message);
168*20f2ebaeSAdrien Destugues }
169*20f2ebaeSAdrien Destugues
170*20f2ebaeSAdrien Destugues
171*20f2ebaeSAdrien Destugues void
MouseUp(BPoint point)172*20f2ebaeSAdrien Destugues PaneSwitch::MouseUp(BPoint point)
173*20f2ebaeSAdrien Destugues {
174*20f2ebaeSAdrien Destugues BRect bounds(Bounds());
175*20f2ebaeSAdrien Destugues bounds.InsetBy(-3, -3);
176*20f2ebaeSAdrien Destugues
177*20f2ebaeSAdrien Destugues fPressing = false;
178*20f2ebaeSAdrien Destugues Invalidate();
179*20f2ebaeSAdrien Destugues if (bounds.Contains(point)) {
180*20f2ebaeSAdrien Destugues SetValue(!Value());
181*20f2ebaeSAdrien Destugues Invoke();
182*20f2ebaeSAdrien Destugues }
183*20f2ebaeSAdrien Destugues
184*20f2ebaeSAdrien Destugues BControl::MouseUp(point);
185*20f2ebaeSAdrien Destugues }
186*20f2ebaeSAdrien Destugues
187*20f2ebaeSAdrien Destugues
188*20f2ebaeSAdrien Destugues void
GetPreferredSize(float * _width,float * _height)1893e3d7acbSStephan Aßmus PaneSwitch::GetPreferredSize(float* _width, float* _height)
1903e3d7acbSStephan Aßmus {
1913e3d7acbSStephan Aßmus BSize size = MinSize();
1924242cbe2SJohn Scipione if (_width != NULL)
1933e3d7acbSStephan Aßmus *_width = size.width;
1944242cbe2SJohn Scipione
1954242cbe2SJohn Scipione if (_height != NULL)
1963e3d7acbSStephan Aßmus *_height = size.height;
1973e3d7acbSStephan Aßmus }
1983e3d7acbSStephan Aßmus
1993e3d7acbSStephan Aßmus
2003e3d7acbSStephan Aßmus BSize
MinSize()2013e3d7acbSStephan Aßmus PaneSwitch::MinSize()
2023e3d7acbSStephan Aßmus {
2033e3d7acbSStephan Aßmus BSize size;
2043e3d7acbSStephan Aßmus float onLabelWidth = StringWidth(fLabelOn);
2053e3d7acbSStephan Aßmus float offLabelWidth = StringWidth(fLabelOff);
2063e3d7acbSStephan Aßmus float labelWidth = max_c(onLabelWidth, offLabelWidth);
2078854b897SAdrien Destugues float latchSize = be_plain_font->Size();
2088854b897SAdrien Destugues size.width = latchSize;
2093e3d7acbSStephan Aßmus if (labelWidth > 0.0)
2108854b897SAdrien Destugues size.width += ceilf(latchSize / 2.0) + labelWidth;
2114242cbe2SJohn Scipione
2123e3d7acbSStephan Aßmus font_height fontHeight;
2133e3d7acbSStephan Aßmus GetFontHeight(&fontHeight);
2143e3d7acbSStephan Aßmus size.height = ceilf(fontHeight.ascent) + ceilf(fontHeight.descent);
2158854b897SAdrien Destugues size.height = max_c(size.height, latchSize);
2164242cbe2SJohn Scipione
2173e3d7acbSStephan Aßmus return BLayoutUtils::ComposeSize(ExplicitMinSize(), size);
2183e3d7acbSStephan Aßmus }
2193e3d7acbSStephan Aßmus
2203e3d7acbSStephan Aßmus
2213e3d7acbSStephan Aßmus BSize
MaxSize()2223e3d7acbSStephan Aßmus PaneSwitch::MaxSize()
2233e3d7acbSStephan Aßmus {
2243e3d7acbSStephan Aßmus return BLayoutUtils::ComposeSize(ExplicitMaxSize(), MinSize());
2253e3d7acbSStephan Aßmus }
2263e3d7acbSStephan Aßmus
2273e3d7acbSStephan Aßmus
2283e3d7acbSStephan Aßmus BSize
PreferredSize()2293e3d7acbSStephan Aßmus PaneSwitch::PreferredSize()
2303e3d7acbSStephan Aßmus {
2313e3d7acbSStephan Aßmus return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), MinSize());
2323e3d7acbSStephan Aßmus }
2333e3d7acbSStephan Aßmus
2343e3d7acbSStephan Aßmus
2353e3d7acbSStephan Aßmus void
SetLabels(const char * labelOn,const char * labelOff)2363e3d7acbSStephan Aßmus PaneSwitch::SetLabels(const char* labelOn, const char* labelOff)
2373e3d7acbSStephan Aßmus {
2383e3d7acbSStephan Aßmus free(fLabelOn);
2393e3d7acbSStephan Aßmus free(fLabelOff);
2403e3d7acbSStephan Aßmus
2413e3d7acbSStephan Aßmus if (labelOn != NULL)
2423e3d7acbSStephan Aßmus fLabelOn = strdup(labelOn);
2433e3d7acbSStephan Aßmus else
2443e3d7acbSStephan Aßmus fLabelOn = NULL;
2453e3d7acbSStephan Aßmus
2463e3d7acbSStephan Aßmus if (labelOff != NULL)
2473e3d7acbSStephan Aßmus fLabelOff = strdup(labelOff);
2483e3d7acbSStephan Aßmus else
2493e3d7acbSStephan Aßmus fLabelOff = NULL;
2503e3d7acbSStephan Aßmus
2513e3d7acbSStephan Aßmus Invalidate();
2523e3d7acbSStephan Aßmus InvalidateLayout();
2533e3d7acbSStephan Aßmus }
2543e3d7acbSStephan Aßmus
2553e3d7acbSStephan Aßmus
25602be5353SAxel Dörfler void
DrawInState(PaneSwitch::State state)25702be5353SAxel Dörfler PaneSwitch::DrawInState(PaneSwitch::State state)
25802be5353SAxel Dörfler {
259f7467fd1SJohn Scipione BRect rect(0, 0, be_plain_font->Size(), be_plain_font->Size());
260d3277fa8SJohn Scipione rect.OffsetBy(1, 1);
26102be5353SAxel Dörfler
2627e702e52SJohn Scipione rgb_color arrowColor = state == kPressed ? kHighlightColor : kNormalColor;
2637e702e52SJohn Scipione int32 arrowDirection = BControlLook::B_RIGHT_ARROW;
2647e702e52SJohn Scipione float tint = IsEnabled() && Window()->IsActive() ? B_DARKEN_3_TINT
2657e702e52SJohn Scipione : B_DARKEN_1_TINT;
26602be5353SAxel Dörfler
26702be5353SAxel Dörfler switch (state) {
26802be5353SAxel Dörfler case kCollapsed:
2697e702e52SJohn Scipione arrowDirection = BControlLook::B_RIGHT_ARROW;
27002be5353SAxel Dörfler break;
27102be5353SAxel Dörfler
27202be5353SAxel Dörfler case kPressed:
2737e702e52SJohn Scipione arrowDirection = BControlLook::B_RIGHT_DOWN_ARROW;
27402be5353SAxel Dörfler break;
27502be5353SAxel Dörfler
27602be5353SAxel Dörfler case kExpanded:
2777e702e52SJohn Scipione arrowDirection = BControlLook::B_DOWN_ARROW;
27802be5353SAxel Dörfler break;
27902be5353SAxel Dörfler }
2807e702e52SJohn Scipione
2817e702e52SJohn Scipione SetDrawingMode(B_OP_COPY);
2827e702e52SJohn Scipione be_control_look->DrawArrowShape(this, rect, rect, arrowColor,
2837e702e52SJohn Scipione arrowDirection, 0, tint);
28402be5353SAxel Dörfler }
285