xref: /haiku/src/kits/interface/Box.cpp (revision 51978af14a173e7fae0563b562be5603bc652aeb)
1 //------------------------------------------------------------------------------
2 //	Copyright (c) 2001-2002, OpenBeOS
3 //
4 //	Permission is hereby granted, free of charge, to any person obtaining a
5 //	copy of this software and associated documentation files (the "Software"),
6 //	to deal in the Software without restriction, including without limitation
7 //	the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 //	and/or sell copies of the Software, and to permit persons to whom the
9 //	Software is furnished to do so, subject to the following conditions:
10 //
11 //	The above copyright notice and this permission notice shall be included in
12 //	all copies or substantial portions of the Software.
13 //
14 //	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 //	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 //	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 //	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 //	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 //	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 //	DEALINGS IN THE SOFTWARE.
21 //
22 //	File Name:		Box.cpp
23 //	Author:			Marc Flerackers (mflerackers@androme.be)
24 //	Description:	BBox objects group views together and draw a border
25 //                  around them.
26 //------------------------------------------------------------------------------
27 
28 // Standard Includes -----------------------------------------------------------
29 #include <stdlib.h>
30 #include <string.h>
31 
32 // System Includes -------------------------------------------------------------
33 #include <Box.h>
34 #include <Errors.h>
35 #include <Message.h>
36 
37 // Project Includes ------------------------------------------------------------
38 
39 // Local Includes --------------------------------------------------------------
40 
41 // Local Defines ---------------------------------------------------------------
42 
43 // Globals ---------------------------------------------------------------------
44 
45 //------------------------------------------------------------------------------
46 BBox::BBox(BRect frame, const char *name, uint32 resizingMode, uint32 flags,
47 		   border_style border)
48 	:	BView(frame, name, resizingMode, flags)
49 {
50 	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
51 	SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR));
52 
53 	InitObject();
54 }
55 //------------------------------------------------------------------------------
56 BBox::~BBox()
57 {
58 	ClearAnyLabel();
59 }
60 //------------------------------------------------------------------------------
61 BBox::BBox(BMessage *archive)
62 	:	BView(archive)
63 {
64 	InitObject(archive);
65 
66 	const char *string;
67 
68 	if (archive->FindString("_label", &string) == B_OK)
69 		SetLabel(string);
70 
71 	bool aBool;
72 	int32 anInt32;
73 
74 	if (archive->FindBool("_style", &aBool) == B_OK)
75 		fStyle = aBool ? B_FANCY_BORDER : B_PLAIN_BORDER;
76 	else if (archive->FindInt32("_style", &anInt32) == B_OK)
77 		fStyle = (border_style)anInt32;
78 
79 	if (archive->FindBool("_lblview", &aBool) == B_OK)
80 		fLabelView = ChildAt(0);
81 }
82 //------------------------------------------------------------------------------
83 BArchivable *BBox::Instantiate(BMessage *archive)
84 {
85 	if (validate_instantiation(archive, "BBox"))
86 		return new BBox(archive);
87 	else
88 		return NULL;
89 }
90 //------------------------------------------------------------------------------
91 status_t BBox::Archive(BMessage *archive, bool deep) const
92 {
93 	BView::Archive(archive, deep);
94 
95 	if (fLabel)
96 		 archive->AddString("_label", fLabel);
97 
98 	if (fLabelView)
99 		 archive->AddBool("_lblview", true);
100 
101 	if (fStyle != B_FANCY_BORDER)
102 		archive->AddInt32("_style", fStyle);
103 
104 	return B_OK;
105 }
106 //------------------------------------------------------------------------------
107 void BBox::SetBorder(border_style border)
108 {
109 	fStyle = border;
110 
111 	LockLooper();
112 	Invalidate();
113 	UnlockLooper();
114 }
115 //------------------------------------------------------------------------------
116 border_style BBox::Border() const
117 {
118 	return fStyle;
119 }
120 //------------------------------------------------------------------------------
121 void BBox::SetLabel(const char *string)
122 {
123 	ClearAnyLabel();
124 
125 	if (string)
126 	{
127 		// Update fBounds
128 		fBounds = Bounds();
129 		font_height fh;
130 		GetFontHeight(&fh);
131 
132 		fBounds.top = (float)ceil((fh.ascent + fh.descent) / 2.0f);
133 
134 		fLabel = strdup(string);
135 	}
136 
137 	if (Window())
138 		Invalidate();
139 }
140 //------------------------------------------------------------------------------
141 status_t BBox::SetLabel(BView *viewLabel)
142 {
143 	ClearAnyLabel();
144 
145 	if (viewLabel)
146 	{
147 		// Update fBounds
148 		fBounds = Bounds();
149 		font_height fh;
150 		GetFontHeight(&fh);
151 
152 		fBounds.top = (float)ceil(viewLabel->Bounds().Height() / 2.0f);
153 
154 		fLabelView = viewLabel;
155 		fLabelView->MoveTo(10.0f, 0.0f);
156 		AddChild(fLabelView, ChildAt(0));
157 	}
158 
159 	if (Window())
160 		Invalidate();
161 
162 	return B_OK;
163 }
164 //------------------------------------------------------------------------------
165 const char *BBox::Label() const
166 {
167 	return fLabel;
168 }
169 //------------------------------------------------------------------------------
170 BView *BBox::LabelView() const
171 {
172 	return fLabelView;
173 }
174 //------------------------------------------------------------------------------
175 void BBox::Draw(BRect updateRect)
176 {
177 	switch (fStyle)
178 	{
179 		case B_FANCY_BORDER:
180 			DrawFancy();
181 			break;
182 
183 		case B_PLAIN_BORDER:
184 			DrawPlain();
185 			break;
186 
187 		default:
188 			break;
189 	}
190 
191 	if (fLabel)
192 	{
193 		font_height fh;
194 		GetFontHeight(&fh);
195 
196 		SetHighColor(ViewColor());
197 
198 		FillRect(BRect(6.0f, 1.0f, 12.0f + StringWidth(fLabel),
199 			(float)ceil(fh.ascent + fh.descent))/*, B_SOLID_LOW*/);
200 
201 		SetHighColor(0, 0, 0);
202 		DrawString(fLabel, BPoint(10.0f, (float)ceil(fh.ascent - fh.descent)
203 			+ 1.0f));
204 	}
205 }
206 //------------------------------------------------------------------------------
207 void BBox::AttachedToWindow()
208 {
209 	if (Parent())
210 	{
211 		SetViewColor(Parent()->ViewColor());
212 		SetLowColor(Parent()->ViewColor());
213 	}
214 }
215 //------------------------------------------------------------------------------
216 void BBox::DetachedFromWindow()
217 {
218 	BView::DetachedFromWindow();
219 }
220 //------------------------------------------------------------------------------
221 void BBox::AllAttached()
222 {
223 	BView::AllAttached();
224 }
225 //------------------------------------------------------------------------------
226 void BBox::AllDetached()
227 {
228 	BView::AllDetached();
229 }
230 //------------------------------------------------------------------------------
231 void BBox::FrameResized(float width, float height)
232 {
233 	BRect bounds(Bounds());
234 
235 	fBounds.right = bounds.right;
236 	fBounds.bottom = bounds.bottom;
237 
238 	Invalidate();
239 }
240 //------------------------------------------------------------------------------
241 void BBox::MessageReceived(BMessage *message)
242 {
243 	BView::MessageReceived(message);
244 }
245 //------------------------------------------------------------------------------
246 void BBox::MouseDown(BPoint point)
247 {
248 	BView::MouseDown(point);
249 }
250 //------------------------------------------------------------------------------
251 void BBox::MouseUp(BPoint point)
252 {
253 	BView::MouseUp(point);
254 }
255 //------------------------------------------------------------------------------
256 void BBox::WindowActivated(bool active)
257 {
258 	BView::WindowActivated(active);
259 }
260 //------------------------------------------------------------------------------
261 void BBox::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
262 {
263 	BView::MouseMoved(point, transit, message);
264 }
265 //------------------------------------------------------------------------------
266 void BBox::FrameMoved(BPoint newLocation)
267 {
268 	BView::FrameMoved(newLocation);
269 }
270 //------------------------------------------------------------------------------
271 BHandler *BBox::ResolveSpecifier(BMessage *message, int32 index,
272 								 BMessage *specifier, int32 what,
273 								 const char *property)
274 {
275 	return BView::ResolveSpecifier(message, index, specifier, what, property);
276 }
277 //------------------------------------------------------------------------------
278 void BBox::ResizeToPreferred()
279 {
280 	BView::ResizeToPreferred();
281 }
282 //------------------------------------------------------------------------------
283 void BBox::GetPreferredSize(float *width, float *height)
284 {
285 /*	BRect rect(0,0,99,99);
286 
287 	if (Parent())
288 	{
289 		rect = Parent()->Bounds();
290 		rect.InsetBy(10,10);
291 	}
292 
293 	*width = rect.Width();
294 	*height = rect.Height();*/
295 
296 	BView::GetPreferredSize(width, height);
297 }
298 //------------------------------------------------------------------------------
299 void BBox::MakeFocus(bool focused)
300 {
301 	BView::MakeFocus(focused);
302 }
303 //------------------------------------------------------------------------------
304 status_t BBox::GetSupportedSuites(BMessage *message)
305 {
306 	return BView::GetSupportedSuites(message);
307 }
308 //------------------------------------------------------------------------------
309 status_t BBox::Perform(perform_code d, void *arg)
310 {
311 	return BView::Perform(d, arg);
312 }
313 //------------------------------------------------------------------------------
314 void BBox::_ReservedBox1() {}
315 void BBox::_ReservedBox2() {}
316 //------------------------------------------------------------------------------
317 BBox &BBox::operator=(const BBox &)
318 {
319 	return *this;
320 }
321 //------------------------------------------------------------------------------
322 void BBox::InitObject(BMessage *data)
323 {
324 	fLabel = NULL;
325 	fBounds = Bounds();
326 	fStyle = B_FANCY_BORDER;
327 	fLabelView = NULL;
328 
329 	int32 flags = 0;
330 
331 	BFont font(be_bold_font);
332 
333 	if (!data || !data->HasString("_fname"))
334 		flags = 1;
335 
336 	if (!data || !data->HasFloat("_fflt"))
337 		flags |= 2;
338 
339 	if (flags != 0)
340 		SetFont(&font, flags);
341 }
342 //------------------------------------------------------------------------------
343 void BBox::DrawPlain()
344 {
345 	BRect rect = fBounds;
346 
347 	SetHighColor(tint_color(ViewColor(), B_LIGHTEN_MAX_TINT));
348 	StrokeLine(BPoint(rect.left, rect.bottom), BPoint(rect.left, rect.top));
349 	StrokeLine(BPoint(rect.left+1.0f, rect.top), BPoint(rect.right, rect.top));
350 	SetHighColor(tint_color(ViewColor(), B_DARKEN_3_TINT));
351 	StrokeLine(BPoint(rect.left+1.0f, rect.bottom), BPoint(rect.right, rect.bottom));
352 	StrokeLine(BPoint(rect.right, rect.bottom), BPoint(rect.right, rect.top+1.0f));
353 }
354 //------------------------------------------------------------------------------
355 void BBox::DrawFancy()
356 {
357 	BRect rect = fBounds;
358 
359 	SetHighColor(tint_color(ViewColor(), B_LIGHTEN_MAX_TINT));
360 	rect.left++;
361 	rect.top++;
362 	StrokeRect(rect);
363 	SetHighColor(tint_color(ViewColor(), B_DARKEN_3_TINT));
364 	rect.OffsetBy(-1,-1);
365 	StrokeRect(rect);
366 }
367 //------------------------------------------------------------------------------
368 void BBox::ClearAnyLabel()
369 {
370 	if (fLabel)
371 	{
372 		free(fLabel);
373 		fLabel = NULL;
374 	}
375 	else if (fLabelView)
376 	{
377 		fLabelView->RemoveSelf();
378 		delete fLabelView;
379 		fLabelView = NULL;
380 	}
381 }
382 //------------------------------------------------------------------------------
383 
384 /*
385  * $Log $
386  *
387  * $Id  $
388  *
389  */
390