Fix FreeBSD build.
[haiku.git] / src / preferences / time / SectionEdit.cpp
blobb04daab5e1134ba780f41299eb3a144bd604be69
1 /*
2 * Copyright 2004-2011, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Mike Berg <mike@berg-net.us>
7 * Julun <host.haiku@gmx.de>
8 * Hamish Morrison <hamish@lavabit.com>
9 */
12 #include "SectionEdit.h"
14 #include <Bitmap.h>
15 #include <ControlLook.h>
16 #include <LayoutUtils.h>
17 #include <List.h>
18 #include <Window.h>
20 #include "TimeMessages.h"
23 const uint32 kArrowAreaWidth = 16;
26 TSectionEdit::TSectionEdit(const char* name, uint32 sections)
28 BControl(name, NULL, NULL, B_WILL_DRAW | B_NAVIGABLE),
29 fFocus(-1),
30 fSectionCount(sections),
31 fHoldValue(0)
36 TSectionEdit::~TSectionEdit()
41 void
42 TSectionEdit::AttachedToWindow()
44 AdoptParentColors();
48 void
49 TSectionEdit::Draw(BRect updateRect)
51 DrawBorder(updateRect);
53 for (uint32 idx = 0; idx < fSectionCount; idx++) {
54 DrawSection(idx, FrameForSection(idx),
55 ((uint32)fFocus == idx) && IsFocus());
56 if (idx < fSectionCount - 1)
57 DrawSeparator(idx, FrameForSeparator(idx));
62 void
63 TSectionEdit::MouseDown(BPoint where)
65 MakeFocus(true);
67 if (fUpRect.Contains(where))
68 DoUpPress();
69 else if (fDownRect.Contains(where))
70 DoDownPress();
71 else if (fSectionCount > 0) {
72 for (uint32 idx = 0; idx < fSectionCount; idx++) {
73 if (FrameForSection(idx).Contains(where)) {
74 SectionFocus(idx);
75 return;
82 BSize
83 TSectionEdit::MaxSize()
85 return BLayoutUtils::ComposeSize(ExplicitMaxSize(),
86 BSize(B_SIZE_UNLIMITED, PreferredHeight()));
90 BSize
91 TSectionEdit::MinSize()
93 BSize minSize;
94 minSize.height = PreferredHeight();
95 minSize.width = (SeparatorWidth() + MinSectionWidth())
96 * fSectionCount;
97 return BLayoutUtils::ComposeSize(ExplicitMinSize(),
98 minSize);
102 BSize
103 TSectionEdit::PreferredSize()
105 return BLayoutUtils::ComposeSize(ExplicitPreferredSize(),
106 MinSize());
110 BRect
111 TSectionEdit::FrameForSection(uint32 index)
113 BRect area = SectionArea();
114 float sepWidth = SeparatorWidth();
116 float width = (area.Width() -
117 sepWidth * (fSectionCount - 1))
118 / fSectionCount;
119 area.left += index * (width + sepWidth);
120 area.right = area.left + width;
122 return area;
126 BRect
127 TSectionEdit::FrameForSeparator(uint32 index)
129 BRect area = SectionArea();
130 float sepWidth = SeparatorWidth();
132 float width = (area.Width() -
133 sepWidth * (fSectionCount - 1))
134 / fSectionCount;
135 area.left += (index + 1) * width + index * sepWidth;
136 area.right = area.left + sepWidth;
138 return area;
142 void
143 TSectionEdit::MakeFocus(bool focused)
145 if (focused == IsFocus())
146 return;
148 BControl::MakeFocus(focused);
150 if (fFocus == -1)
151 SectionFocus(0);
152 else
153 SectionFocus(fFocus);
157 void
158 TSectionEdit::KeyDown(const char* bytes, int32 numbytes)
160 if (fFocus == -1)
161 SectionFocus(0);
163 switch (bytes[0]) {
164 case B_LEFT_ARROW:
165 fFocus -= 1;
166 if (fFocus < 0)
167 fFocus = fSectionCount - 1;
168 SectionFocus(fFocus);
169 break;
171 case B_RIGHT_ARROW:
172 fFocus += 1;
173 if ((uint32)fFocus >= fSectionCount)
174 fFocus = 0;
175 SectionFocus(fFocus);
176 break;
178 case B_UP_ARROW:
179 DoUpPress();
180 break;
182 case B_DOWN_ARROW:
183 DoDownPress();
184 break;
186 default:
187 BControl::KeyDown(bytes, numbytes);
188 break;
190 Draw(Bounds());
194 void
195 TSectionEdit::DispatchMessage()
197 BMessage message(H_USER_CHANGE);
198 BuildDispatch(&message);
199 Window()->PostMessage(&message);
203 uint32
204 TSectionEdit::CountSections() const
206 return fSectionCount;
210 int32
211 TSectionEdit::FocusIndex() const
213 return fFocus;
217 BRect
218 TSectionEdit::SectionArea() const
220 BRect sectionArea = Bounds().InsetByCopy(2, 2);
221 sectionArea.right -= kArrowAreaWidth;
222 return sectionArea;
226 void
227 TSectionEdit::DrawBorder(const BRect& updateRect)
229 BRect bounds(Bounds());
230 bool showFocus = (IsFocus() && Window() && Window()->IsActive());
232 be_control_look->DrawBorder(this, bounds, updateRect, ViewColor(),
233 B_FANCY_BORDER, showFocus ? BControlLook::B_FOCUSED : 0);
235 // draw up/down control
237 bounds.left = bounds.right - kArrowAreaWidth;
238 bounds.right = Bounds().right - 2;
239 fUpRect.Set(bounds.left + 3, bounds.top + 2, bounds.right,
240 bounds.bottom / 2.0);
241 fDownRect = fUpRect.OffsetByCopy(0, fUpRect.Height() + 2);
243 BPoint middle(floorf(fUpRect.left + fUpRect.Width() / 2),
244 fUpRect.top + 1);
245 BPoint left(fUpRect.left + 3, fUpRect.bottom - 1);
246 BPoint right(left.x + 2 * (middle.x - left.x), fUpRect.bottom - 1);
248 SetPenSize(2);
249 SetLowColor(ViewColor());
251 if (updateRect.Intersects(fUpRect)) {
252 FillRect(fUpRect, B_SOLID_LOW);
253 BeginLineArray(2);
254 AddLine(left, middle, HighColor());
255 AddLine(middle, right, HighColor());
256 EndLineArray();
258 if (updateRect.Intersects(fDownRect)) {
259 middle.y = fDownRect.bottom - 1;
260 left.y = right.y = fDownRect.top + 1;
262 FillRect(fDownRect, B_SOLID_LOW);
263 BeginLineArray(2);
264 AddLine(left, middle, HighColor());
265 AddLine(middle, right, HighColor());
266 EndLineArray();
269 SetPenSize(1);