xref: /haiku/src/kits/interface/ListItem.cpp (revision 4f2fd49bdc6078128b1391191e4edac647044c3d)
1 //------------------------------------------------------------------------------
2 //	Copyright (c) 2001-2008, Haiku, Inc.
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:		ListItem.cpp
23 //	Author:			Ulrich Wimboeck
24 //				Marc Flerackers (mflerackers@androme.be)
25 //				Rene Gollent
26 //	Description:	BListItem is the base class for BListView's items,
27 //					BStringItem is a subclass of BListItem which draws a string.
28 //------------------------------------------------------------------------------
29 #include <stdlib.h>
30 #include <string.h>
31 
32 #include <ListItem.h>
33 #include <Message.h>
34 #include <View.h>
35 
36 
37 BListItem::BListItem(uint32 level, bool expanded)
38 	:	fTop(0.0),
39 		fWidth(0),
40 		fHeight(0),
41 		fLevel(level),
42 		fSelected(false),
43 		fEnabled(true),
44 		fExpanded(expanded),
45 		fHasSubitems(false),
46 		fVisible(true)
47 {
48 }
49 
50 
51 BListItem::BListItem(BMessage *data)
52 	:	BArchivable(data),
53 		fTop(0.0),
54 		fWidth(0),
55 		fHeight(0),
56 		fLevel(0),
57 		fSelected(false),
58 		fEnabled(true),
59 		fExpanded(false),
60 		fHasSubitems(false),
61 		fVisible(true)
62 {
63 	data->FindBool("_sel", &fSelected);
64 
65 	if (data->FindBool("_disable", &fEnabled) != B_OK)
66 		fEnabled = true;
67 	else
68 		fEnabled = false;
69 
70 	data->FindBool("_li_expanded", &fExpanded);
71 	data->FindInt32("_li_outline_level", (int32*)&fLevel);
72 }
73 
74 
75 BListItem::~BListItem()
76 {
77 }
78 
79 
80 status_t
81 BListItem::Archive(BMessage *archive, bool deep) const
82 {
83 	status_t status = BArchivable::Archive(archive, deep);
84 
85 	if (status == B_OK && fSelected)
86 		status = archive->AddBool("_sel", true);
87 
88 	if (status == B_OK && !fEnabled)
89 		status = archive->AddBool("_disable", true);
90 
91 	if (status == B_OK && fExpanded)
92 		status = archive->AddBool("_li_expanded", true);
93 
94 	if (status == B_OK && fLevel != 0)
95 		status = archive->AddInt32("_li_outline_level", fLevel);
96 
97 	return status;
98 }
99 
100 
101 float
102 BListItem::Height() const
103 {
104 	return fHeight;
105 }
106 
107 
108 float
109 BListItem::Width() const
110 {
111 	return fWidth;
112 }
113 
114 
115 bool
116 BListItem::IsSelected() const
117 {
118 	return fSelected;
119 }
120 
121 
122 void
123 BListItem::Select()
124 {
125 	fSelected = true;
126 }
127 
128 
129 void
130 BListItem::Deselect()
131 {
132 	fSelected = false;
133 }
134 
135 
136 void
137 BListItem::SetEnabled(bool on)
138 {
139 	fEnabled = on;
140 }
141 
142 
143 bool
144 BListItem::IsEnabled() const
145 {
146 	return fEnabled;
147 }
148 
149 
150 void
151 BListItem::SetHeight(float height)
152 {
153 	fHeight = height;
154 }
155 
156 
157 void
158 BListItem::SetWidth(float width)
159 {
160 	fWidth = width;
161 }
162 
163 
164 void
165 BListItem::Update(BView *owner, const BFont *font)
166 {
167 	font_height fh;
168 	font->GetHeight(&fh);
169 
170 	SetWidth(owner->Bounds().Width());
171 	SetHeight(fh.ascent + fh.descent + fh.leading);
172 }
173 
174 
175 status_t
176 BListItem::Perform(perform_code d, void *arg)
177 {
178 	return BArchivable::Perform(d, arg);
179 }
180 
181 
182 void
183 BListItem::SetExpanded(bool expanded)
184 {
185 	fExpanded = expanded;
186 }
187 
188 
189 bool
190 BListItem::IsExpanded() const
191 {
192 	return fExpanded;
193 }
194 
195 
196 uint32
197 BListItem::OutlineLevel() const
198 {
199 	return fLevel;
200 }
201 
202 
203 bool
204 BListItem::HasSubitems() const
205 {
206 	return fHasSubitems;
207 }
208 
209 
210 void BListItem::_ReservedListItem1() {}
211 void BListItem::_ReservedListItem2() {}
212 
213 
214 BListItem::BListItem(const BListItem &item)
215 {
216 }
217 
218 
219 BListItem &
220 BListItem::operator=(const BListItem &)
221 {
222 	return *this;
223 }
224 
225 
226 bool
227 BListItem::IsItemVisible() const
228 {
229 	return fVisible;
230 }
231 
232 void
233 BListItem::SetTop(float top)
234 {
235 	fTop = top;
236 }
237 
238 void
239 BListItem::SetItemVisible(bool visible)
240 {
241 	fVisible = visible;
242 }
243 
244 
245 // BStringItem
246 BStringItem::BStringItem(const char *text, uint32 level, bool expanded)
247 	:	BListItem(level, expanded),
248 		fText(NULL),
249 		fBaselineOffset(0)
250 {
251 	SetText(text);
252 }
253 
254 
255 BStringItem::BStringItem(BMessage *archive)
256 	:	BListItem(archive),
257 		fText(NULL),
258 		fBaselineOffset(0)
259 {
260 	const char *string;
261 
262 	if (archive->FindString("_label", &string) == B_OK)
263 		SetText(string);
264 }
265 
266 
267 BStringItem::~BStringItem()
268 {
269 	free(fText);
270 }
271 
272 
273 BArchivable	*
274 BStringItem::Instantiate(BMessage *archive)
275 {
276 	if (validate_instantiation(archive, "BStringItem"))
277 		return new BStringItem(archive);
278 	else
279 		return NULL;
280 }
281 
282 
283 status_t
284 BStringItem::Archive(BMessage *archive, bool deep) const
285 {
286 	status_t status = BListItem::Archive(archive);
287 
288 	if (status == B_OK && fText != NULL)
289 		status = archive->AddString("_label", fText);
290 
291 	return status;
292 }
293 
294 
295 void
296 BStringItem::DrawItem(BView *owner, BRect frame, bool complete)
297 {
298 	if (fText == NULL)
299 		return;
300 
301 	rgb_color highColor = owner->HighColor();
302 	rgb_color lowColor = owner->LowColor();
303 
304 	if (IsSelected() || complete) {
305 		if (IsSelected()) {
306 			owner->SetHighColor(tint_color(lowColor, B_DARKEN_2_TINT));
307 			owner->SetLowColor(owner->HighColor());
308 		} else
309 			owner->SetHighColor(lowColor);
310 
311 		owner->FillRect(frame);
312 	}
313 
314 	owner->MovePenTo(frame.left, frame.top + fBaselineOffset);
315 
316 	rgb_color black = {0, 0, 0, 255};
317 
318 	if (!IsEnabled())
319 		owner->SetHighColor(tint_color(black, B_LIGHTEN_2_TINT));
320 	else
321 		owner->SetHighColor(black);
322 
323 	owner->DrawString(fText);
324 
325 	owner->SetHighColor(highColor);
326 	owner->SetLowColor(lowColor);
327 }
328 
329 
330 void
331 BStringItem::SetText(const char *text)
332 {
333 	free(fText);
334 	fText = NULL;
335 
336 	if (text)
337 		fText = strdup(text);
338 }
339 
340 
341 const char *
342 BStringItem::Text() const
343 {
344 	return fText;
345 }
346 
347 
348 void
349 BStringItem::Update(BView *owner, const BFont *font)
350 {
351 	if (fText)
352 		SetWidth(owner->StringWidth(fText));
353 
354 	font_height fheight;
355 	font->GetHeight(&fheight);
356 
357 	fBaselineOffset = fheight.ascent + 2 + floorf(fheight.leading / 2);
358 
359 	SetHeight(ceilf(fheight.ascent) + ceilf(fheight.descent)
360 		+ ceilf(fheight.leading) + 4);
361 }
362 
363 
364 status_t
365 BStringItem::Perform(perform_code d, void *arg)
366 {
367 	return BListItem::Perform(d, arg);
368 }
369 
370 
371 void BStringItem::_ReservedStringItem1() {}
372 void BStringItem::_ReservedStringItem2() {}
373 
374 
375 BStringItem::BStringItem(const BStringItem &)
376 {
377 }
378 
379 
380 BStringItem	&
381 BStringItem::operator=(const BStringItem &)
382 {
383 	return *this;
384 }
385