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