2 * Copyright 2004-2011, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
6 * Mike Berg <mike@berg-net.us>
7 * Julun <host.haiku@gmx.de>
8 * Hamish Morrison <hamish@lavabit.com>
12 #include "SectionEdit.h"
15 #include <ControlLook.h>
16 #include <LayoutUtils.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
),
30 fSectionCount(sections
),
36 TSectionEdit::~TSectionEdit()
42 TSectionEdit::AttachedToWindow()
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
));
63 TSectionEdit::MouseDown(BPoint where
)
67 if (fUpRect
.Contains(where
))
69 else if (fDownRect
.Contains(where
))
71 else if (fSectionCount
> 0) {
72 for (uint32 idx
= 0; idx
< fSectionCount
; idx
++) {
73 if (FrameForSection(idx
).Contains(where
)) {
83 TSectionEdit::MaxSize()
85 return BLayoutUtils::ComposeSize(ExplicitMaxSize(),
86 BSize(B_SIZE_UNLIMITED
, PreferredHeight()));
91 TSectionEdit::MinSize()
94 minSize
.height
= PreferredHeight();
95 minSize
.width
= (SeparatorWidth() + MinSectionWidth())
97 return BLayoutUtils::ComposeSize(ExplicitMinSize(),
103 TSectionEdit::PreferredSize()
105 return BLayoutUtils::ComposeSize(ExplicitPreferredSize(),
111 TSectionEdit::FrameForSection(uint32 index
)
113 BRect area
= SectionArea();
114 float sepWidth
= SeparatorWidth();
116 float width
= (area
.Width() -
117 sepWidth
* (fSectionCount
- 1))
119 area
.left
+= index
* (width
+ sepWidth
);
120 area
.right
= area
.left
+ width
;
127 TSectionEdit::FrameForSeparator(uint32 index
)
129 BRect area
= SectionArea();
130 float sepWidth
= SeparatorWidth();
132 float width
= (area
.Width() -
133 sepWidth
* (fSectionCount
- 1))
135 area
.left
+= (index
+ 1) * width
+ index
* sepWidth
;
136 area
.right
= area
.left
+ sepWidth
;
143 TSectionEdit::MakeFocus(bool focused
)
145 if (focused
== IsFocus())
148 BControl::MakeFocus(focused
);
153 SectionFocus(fFocus
);
158 TSectionEdit::KeyDown(const char* bytes
, int32 numbytes
)
167 fFocus
= fSectionCount
- 1;
168 SectionFocus(fFocus
);
173 if ((uint32
)fFocus
>= fSectionCount
)
175 SectionFocus(fFocus
);
187 BControl::KeyDown(bytes
, numbytes
);
195 TSectionEdit::DispatchMessage()
197 BMessage
message(H_USER_CHANGE
);
198 BuildDispatch(&message
);
199 Window()->PostMessage(&message
);
204 TSectionEdit::CountSections() const
206 return fSectionCount
;
211 TSectionEdit::FocusIndex() const
218 TSectionEdit::SectionArea() const
220 BRect sectionArea
= Bounds().InsetByCopy(2, 2);
221 sectionArea
.right
-= kArrowAreaWidth
;
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),
245 BPoint
left(fUpRect
.left
+ 3, fUpRect
.bottom
- 1);
246 BPoint
right(left
.x
+ 2 * (middle
.x
- left
.x
), fUpRect
.bottom
- 1);
249 SetLowColor(ViewColor());
251 if (updateRect
.Intersects(fUpRect
)) {
252 FillRect(fUpRect
, B_SOLID_LOW
);
254 AddLine(left
, middle
, HighColor());
255 AddLine(middle
, right
, HighColor());
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
);
264 AddLine(left
, middle
, HighColor());
265 AddLine(middle
, right
, HighColor());