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
PaneSwitch(BRect frame,const char * name,bool leftAligned,uint32 resizeMask,uint32 flags)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
PaneSwitch(const char * name,bool leftAligned,uint32 flags)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
~PaneSwitch()75 PaneSwitch::~PaneSwitch()
76 {
77 free(fLabelOn);
78 free(fLabelOff);
79 }
80
81
82 void
Draw(BRect)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
MouseDown(BPoint)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
MouseMoved(BPoint point,uint32 code,const BMessage * message)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
MouseUp(BPoint point)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
GetPreferredSize(float * _width,float * _height)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
MinSize()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
MaxSize()222 PaneSwitch::MaxSize()
223 {
224 return BLayoutUtils::ComposeSize(ExplicitMaxSize(), MinSize());
225 }
226
227
228 BSize
PreferredSize()229 PaneSwitch::PreferredSize()
230 {
231 return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), MinSize());
232 }
233
234
235 void
SetLabels(const char * labelOn,const char * labelOff)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
DrawInState(PaneSwitch::State state)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