2 * Copyright 2001-2009, Stephan Aßmus <superstippi@gmx.de>
3 * Copyright 2001-2009, Ingo Weinhold <ingo_weinhold@gmx.de>
4 * All rights reserved. Distributed under the terms of the MIT license.
8 #include "SeparatorView.h"
15 #include <ControlLook.h>
16 #include <LayoutUtils.h>
20 static const float kMinBorderLength
= 5.0f
;
23 // TODO: Actually implement alignment support!
24 // TODO: More testing, especially archiving.
27 BSeparatorView::BSeparatorView(orientation orientation
, border_style border
)
29 BView(NULL
, B_WILL_DRAW
| B_FULL_UPDATE_ON_RESIZE
)
31 _Init(NULL
, NULL
, orientation
, BAlignment(B_ALIGN_HORIZONTAL_CENTER
,
32 B_ALIGN_VERTICAL_CENTER
), border
);
36 BSeparatorView::BSeparatorView(const char* name
, const char* label
,
37 orientation orientation
, border_style border
, const BAlignment
& alignment
)
39 BView(name
, B_WILL_DRAW
| B_FULL_UPDATE_ON_RESIZE
)
41 _Init(label
, NULL
, orientation
, alignment
, border
);
45 BSeparatorView::BSeparatorView(const char* name
, BView
* labelView
,
46 orientation orientation
, border_style border
, const BAlignment
& alignment
)
48 BView(name
, B_WILL_DRAW
| B_FULL_UPDATE_ON_RESIZE
)
50 _Init(NULL
, labelView
, orientation
, alignment
, border
);
54 BSeparatorView::BSeparatorView(const char* label
,
55 orientation orientation
, border_style border
, const BAlignment
& alignment
)
57 BView("", B_WILL_DRAW
| B_FULL_UPDATE_ON_RESIZE
)
59 _Init(label
, NULL
, orientation
, alignment
, border
);
63 BSeparatorView::BSeparatorView(BView
* labelView
,
64 orientation orientation
, border_style border
, const BAlignment
& alignment
)
66 BView("", B_WILL_DRAW
| B_FULL_UPDATE_ON_RESIZE
)
68 _Init(NULL
, labelView
, orientation
, alignment
, border
);
72 BSeparatorView::BSeparatorView(BMessage
* archive
)
77 fOrientation(B_HORIZONTAL
),
78 fAlignment(BAlignment(B_ALIGN_HORIZONTAL_CENTER
,
79 B_ALIGN_VERTICAL_CENTER
)),
80 fBorder(B_FANCY_BORDER
)
82 // NULL archives will be caught by BView.
85 if (archive
->FindString("_labelview", &label
) == B_OK
) {
86 fLabelView
= FindView(label
);
87 } else if (archive
->FindString("_label", &label
) == B_OK
) {
92 if (archive
->FindInt32("_orientation", &orientation
) == B_OK
)
93 fOrientation
= (enum orientation
)orientation
;
97 if (archive
->FindInt32("_halignment", &hAlignment
) == B_OK
98 && archive
->FindInt32("_valignment", &vAlignment
) == B_OK
) {
99 fAlignment
.horizontal
= (alignment
)hAlignment
;
100 fAlignment
.vertical
= (vertical_alignment
)vAlignment
;
104 if (archive
->FindInt32("_border", &borderStyle
) != B_OK
)
105 fBorder
= (border_style
)borderStyle
;
109 BSeparatorView::~BSeparatorView()
114 // #pragma mark - Archiving
118 BSeparatorView::Instantiate(BMessage
* archive
)
120 if (validate_instantiation(archive
, "BSeparatorView"))
121 return new (std::nothrow
) BSeparatorView(archive
);
128 BSeparatorView::Archive(BMessage
* into
, bool deep
) const
131 status_t result
= BView::Archive(into
, deep
);
135 if (fLabelView
!= NULL
)
136 result
= into
->AddString("_labelview", fLabelView
->Name());
138 result
= into
->AddString("_label", fLabel
.String());
141 result
= into
->AddInt32("_orientation", fOrientation
);
144 result
= into
->AddInt32("_halignment", fAlignment
.horizontal
);
147 result
= into
->AddInt32("_valignment", fAlignment
.vertical
);
150 result
= into
->AddInt32("_border", fBorder
);
160 BSeparatorView::Draw(BRect updateRect
)
162 rgb_color base
= ui_color(B_PANEL_BACKGROUND_COLOR
);
163 if (BView
* parent
= Parent()) {
164 if (parent
->ViewColor() != B_TRANSPARENT_COLOR
)
165 base
= parent
->ViewColor();
169 if (fLabelView
!= NULL
) {
170 labelBounds
= fLabelView
->Frame();
171 } else if (fLabel
.CountChars() > 0) {
172 labelBounds
= _MaxLabelBounds();
173 float labelWidth
= StringWidth(fLabel
.String());
174 if (fOrientation
== B_HORIZONTAL
) {
175 switch (fAlignment
.horizontal
) {
178 labelBounds
.right
= labelBounds
.left
+ labelWidth
;
182 labelBounds
.left
= labelBounds
.right
- labelWidth
;
186 labelBounds
.left
= (labelBounds
.left
+ labelBounds
.right
188 labelBounds
.right
= labelBounds
.left
+ labelWidth
;
192 switch (fAlignment
.vertical
) {
195 labelBounds
.bottom
= labelBounds
.top
+ labelWidth
;
199 labelBounds
.top
= labelBounds
.bottom
- labelWidth
;
203 labelBounds
.top
= (labelBounds
.top
+ labelBounds
.bottom
205 labelBounds
.bottom
= labelBounds
.top
+ labelWidth
;
211 BRect bounds
= Bounds();
212 BRegion
region(bounds
);
213 if (labelBounds
.IsValid()) {
214 region
.Exclude(labelBounds
);
215 ConstrainClippingRegion(®ion
);
218 float borderSize
= _BorderSize();
219 if (borderSize
> 0.0f
) {
220 if (fOrientation
== B_HORIZONTAL
) {
221 bounds
.top
= floorf((bounds
.top
+ bounds
.bottom
+ 1 - borderSize
)
223 bounds
.bottom
= bounds
.top
+ borderSize
- 1;
224 region
.Exclude(bounds
);
225 be_control_look
->DrawBorder(this, bounds
, updateRect
, base
,
226 fBorder
, 0, BControlLook::B_TOP_BORDER
);
228 bounds
.left
= floorf((bounds
.left
+ bounds
.right
+ 1 - borderSize
)
230 bounds
.right
= bounds
.left
+ borderSize
- 1;
231 region
.Exclude(bounds
);
232 be_control_look
->DrawBorder(this, bounds
, updateRect
, base
,
233 fBorder
, 0, BControlLook::B_LEFT_BORDER
);
235 if (labelBounds
.IsValid())
236 region
.Include(labelBounds
);
238 ConstrainClippingRegion(®ion
);
242 FillRect(updateRect
, B_SOLID_LOW
);
244 if (fLabel
.CountChars() > 0) {
245 font_height fontHeight
;
246 GetFontHeight(&fontHeight
);
248 SetHighColor(0, 0, 0, 255);
250 if (fOrientation
== B_HORIZONTAL
) {
251 DrawString(fLabel
.String(), BPoint(labelBounds
.left
,
252 labelBounds
.top
+ ceilf(fontHeight
.ascent
)));
254 DrawString(fLabel
.String(), BPoint(labelBounds
.left
255 + ceilf(fontHeight
.ascent
), labelBounds
.bottom
));
262 BSeparatorView::GetPreferredSize(float* _width
, float* _height
)
267 if (fLabelView
!= NULL
) {
268 fLabelView
->GetPreferredSize(&width
, &height
);
269 } else if (fLabel
.CountChars() > 0) {
270 width
= StringWidth(fLabel
.String());
271 font_height fontHeight
;
272 GetFontHeight(&fontHeight
);
273 height
= ceilf(fontHeight
.ascent
) + ceilf(fontHeight
.descent
);
274 if (fOrientation
== B_VERTICAL
) {
275 // swap width and height
282 float borderSize
= _BorderSize();
284 // Add some room for the border
285 if (fOrientation
== B_HORIZONTAL
) {
286 width
+= kMinBorderLength
* 2.0f
;
287 height
= max_c(height
, borderSize
- 1.0f
);
289 height
+= kMinBorderLength
* 2.0f
;
290 width
= max_c(width
, borderSize
- 1.0f
);
302 BSeparatorView::MinSize()
305 GetPreferredSize(&size
.width
, &size
.height
);
306 return BLayoutUtils::ComposeSize(ExplicitMinSize(), size
);
311 BSeparatorView::MaxSize()
313 BSize
size(MinSize());
314 if (fOrientation
== B_HORIZONTAL
)
315 size
.width
= B_SIZE_UNLIMITED
;
317 size
.height
= B_SIZE_UNLIMITED
;
319 return BLayoutUtils::ComposeSize(ExplicitMaxSize(), size
);
324 BSeparatorView::PreferredSize()
327 GetPreferredSize(&size
.width
, &size
.height
);
329 return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), size
);
337 BSeparatorView::SetOrientation(orientation orientation
)
339 if (orientation
== fOrientation
)
342 fOrientation
= orientation
;
346 if (fOrientation
== B_VERTICAL
)
347 font
.SetRotation(90.0f
);
357 BSeparatorView::SetAlignment(const BAlignment
& aligment
)
359 if (aligment
== fAlignment
)
362 fAlignment
= aligment
;
370 BSeparatorView::SetBorderStyle(border_style border
)
372 if (border
== fBorder
)
382 BSeparatorView::SetLabel(const char* label
)
398 BSeparatorView::SetLabel(BView
* view
, bool deletePrevious
)
400 if (fLabelView
== view
)
403 if (fLabelView
!= NULL
) {
404 fLabelView
->RemoveSelf();
411 if (fLabelView
!= NULL
)
417 BSeparatorView::Perform(perform_code code
, void* data
)
419 return BView::Perform(code
, data
);
423 // #pragma mark - protected/private
427 BSeparatorView::DoLayout()
431 if (fLabelView
== NULL
)
434 BRect bounds
= _MaxLabelBounds();
435 BRect frame
= BLayoutUtils::AlignInFrame(bounds
, fLabelView
->MaxSize(),
438 fLabelView
->MoveTo(frame
.LeftTop());
439 fLabelView
->ResizeTo(frame
.Width(), frame
.Height());
444 BSeparatorView::_Init(const char* label
, BView
* labelView
,
445 orientation orientation
, BAlignment alignment
, border_style border
)
450 fOrientation
= B_HORIZONTAL
;
451 fAlignment
= alignment
;
454 SetFont(be_bold_font
);
455 SetViewColor(B_TRANSPARENT_32_BIT
);
458 SetLabel(labelView
, true);
459 SetOrientation(orientation
);
464 BSeparatorView::_BorderSize() const
466 // TODO: Get these values from the BControlLook class.
482 BSeparatorView::_MaxLabelBounds() const
484 BRect bounds
= Bounds();
485 if (fOrientation
== B_HORIZONTAL
)
486 bounds
.InsetBy(kMinBorderLength
, 0.0f
);
488 bounds
.InsetBy(0.0f
, kMinBorderLength
);
494 // #pragma mark - FBC padding
497 void BSeparatorView::_ReservedSeparatorView1() {}
498 void BSeparatorView::_ReservedSeparatorView2() {}
499 void BSeparatorView::_ReservedSeparatorView3() {}
500 void BSeparatorView::_ReservedSeparatorView4() {}
501 void BSeparatorView::_ReservedSeparatorView5() {}
502 void BSeparatorView::_ReservedSeparatorView6() {}
503 void BSeparatorView::_ReservedSeparatorView7() {}
504 void BSeparatorView::_ReservedSeparatorView8() {}
505 void BSeparatorView::_ReservedSeparatorView9() {}
506 void BSeparatorView::_ReservedSeparatorView10() {}