Ticket #5525: gridLayout.patch
File gridLayout.patch, 14.3 KB (added by , 14 years ago) |
---|
-
src/kits/interface/GridLayout.cpp
1 1 /* 2 * Copyright 2010, Haiku Inc. 2 3 * Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>. 3 4 * All rights reserved. Distributed under the terms of the MIT License. 4 5 */ … … 11 12 12 13 #include <LayoutItem.h> 13 14 #include <List.h> 15 #include <Message.h> 14 16 15 17 #include "ViewLayoutItem.h" 16 18 … … 21 23 MAX_COLUMN_ROW_COUNT = 1024, 22 24 }; 23 25 24 // a placeholder we put in our grid array to make a cell occupied 25 static BLayoutItem* const OCCUPIED_GRID_CELL = (BLayoutItem*)0x1; 26 namespace { 27 // a placeholder we put in our grid array to make a cell occupied 28 BLayoutItem* const OCCUPIED_GRID_CELL = (BLayoutItem*)0x1; 26 29 30 const char* kRowCountField = "gridlayout:rowcount"; 31 const char* kRowMinSizeField = "gridlayout:rowminsize"; 32 const char* kRowMaxSizeField = "gridlayout:rowmaxsize"; 33 const char* kRowWeightField = "gridlayout:rowweight"; 34 const char* kColumnCountField = "gridlayout:columncount"; 35 const char* kColumnMinSizeField = "gridlayout:columnminsize"; 36 const char* kColumnMaxSizeField = "gridlayout:columnmaxsize"; 37 const char* kColumnWeightField = "gridlayout:columnweight"; 38 const char* kItemHeight = "gridlayout:item:height"; 39 const char* kItemWidth = "gridlayout:item:width"; 40 const char* kItemX = "gridlayout:item:x"; 41 const char* kItemY = "gridlayout:item:y"; 42 } 27 43 28 // ItemLayoutData 44 29 45 struct BGridLayout::ItemLayoutData { 30 46 Dimensions dimensions; 31 47 … … 38 54 } 39 55 }; 40 56 41 // RowInfoArray 57 42 58 class BGridLayout::RowInfoArray { 43 59 public: 44 60 … … 135 151 }; 136 152 137 153 138 // constructor 154 139 155 BGridLayout::BGridLayout(float horizontal, float vertical) 140 : fGrid(NULL), 141 fColumnCount(0), 142 fRowCount(0), 143 fRowInfos(new RowInfoArray), 144 fColumnInfos(new RowInfoArray), 145 fMultiColumnItems(0), 146 fMultiRowItems(0) 156 : 157 fGrid(NULL), 158 fColumnCount(0), 159 fRowCount(0), 160 fRowInfos(new RowInfoArray), 161 fColumnInfos(new RowInfoArray), 162 fMultiColumnItems(0), 163 fMultiRowItems(0) 147 164 { 148 165 SetSpacing(horizontal, vertical); 149 166 } 150 167 151 // destructor 168 169 BGridLayout::BGridLayout(BMessage* from) 170 : 171 BTwoDimensionalLayout(BUnarchiver::PrepareArchive(from)), 172 fGrid(NULL), 173 fColumnCount(0), 174 fRowCount(0), 175 fRowInfos(new RowInfoArray), 176 fColumnInfos(new RowInfoArray), 177 fMultiColumnItems(0), 178 fMultiRowItems(0) 179 { 180 int32 rows; 181 int32 columns; 182 BUnarchiver unarchiver(from); 183 184 if (from->FindInt32(kRowCountField, &rows) != B_OK) 185 fRowCount = 0; 186 187 if (from->FindInt32(kColumnCountField, &columns) != B_OK) 188 fColumnCount = 0; 189 190 // sets fColumnCount && fRowCount on success 191 if (!_ResizeGrid(columns, rows)) { 192 unarchiver.Finish(B_NO_MEMORY); 193 return; 194 } 195 196 for (int32 i = 0; i < fRowCount; i++) { 197 float getter; 198 if (from->FindFloat(kRowWeightField, i, &getter) == B_OK) 199 fRowInfos->SetWeight(i, getter); 200 201 if (from->FindFloat(kRowMinSizeField, i, &getter) == B_OK) 202 fRowInfos->SetMinSize(i, getter); 203 204 if (from->FindFloat(kRowMaxSizeField, i, &getter) == B_OK) 205 fRowInfos->SetMaxSize(i, getter); 206 } 207 208 209 for (int32 i = 0; i < fColumnCount; i++) { 210 float getter; 211 if (from->FindFloat(kColumnWeightField, i, &getter) == B_OK) 212 fColumnInfos->SetWeight(i, getter); 213 214 if (from->FindFloat(kColumnMinSizeField, i, &getter) == B_OK) 215 fColumnInfos->SetMinSize(i, getter); 216 217 if (from->FindFloat(kColumnMaxSizeField, i, &getter) == B_OK) 218 fColumnInfos->SetMaxSize(i, getter); 219 } 220 } 221 222 152 223 BGridLayout::~BGridLayout() 153 224 { 154 225 delete fRowInfos; … … 156 227 } 157 228 158 229 159 // CountColumns160 230 int32 161 231 BGridLayout::CountColumns() const 162 232 { … … 164 234 } 165 235 166 236 167 // CountRows168 237 int32 169 238 BGridLayout::CountRows() const 170 239 { … … 172 241 } 173 242 174 243 175 // HorizontalSpacing176 244 float 177 245 BGridLayout::HorizontalSpacing() const 178 246 { 179 247 return fHSpacing; 180 248 } 181 249 182 // VerticalSpacing 250 183 251 float 184 252 BGridLayout::VerticalSpacing() const 185 253 { 186 254 return fVSpacing; 187 255 } 188 256 189 // SetHorizontalSpacing 257 190 258 void 191 259 BGridLayout::SetHorizontalSpacing(float spacing) 192 260 { … … 197 265 } 198 266 } 199 267 200 // SetVerticalSpacing 268 201 269 void 202 270 BGridLayout::SetVerticalSpacing(float spacing) 203 271 { … … 208 276 } 209 277 } 210 278 211 // SetSpacing 279 212 280 void 213 281 BGridLayout::SetSpacing(float horizontal, float vertical) 214 282 { … … 220 288 } 221 289 } 222 290 223 // ColumnWeight 291 224 292 float 225 293 BGridLayout::ColumnWeight(int32 column) const 226 294 { 227 295 return fColumnInfos->Weight(column); 228 296 } 229 297 230 // SetColumnWeight 298 231 299 void 232 300 BGridLayout::SetColumnWeight(int32 column, float weight) 233 301 { 234 302 fColumnInfos->SetWeight(column, weight); 235 303 } 236 304 237 // MinColumnWidth 305 238 306 float 239 307 BGridLayout::MinColumnWidth(int32 column) const 240 308 { 241 309 return fColumnInfos->MinSize(column); 242 310 } 243 311 244 // SetMinColumnWidth 312 245 313 void 246 314 BGridLayout::SetMinColumnWidth(int32 column, float width) 247 315 { 248 316 fColumnInfos->SetMinSize(column, width); 249 317 } 250 318 251 // MaxColumnWidth 319 252 320 float 253 321 BGridLayout::MaxColumnWidth(int32 column) const 254 322 { 255 323 return fColumnInfos->MaxSize(column); 256 324 } 257 325 258 // SetMaxColumnWidth 326 259 327 void 260 328 BGridLayout::SetMaxColumnWidth(int32 column, float width) 261 329 { 262 330 fColumnInfos->SetMaxSize(column, width); 263 331 } 264 332 265 // RowWeight 333 266 334 float 267 335 BGridLayout::RowWeight(int32 row) const 268 336 { 269 337 return fRowInfos->Weight(row); 270 338 } 271 339 272 // SetRowWeight 340 273 341 void 274 342 BGridLayout::SetRowWeight(int32 row, float weight) 275 343 { 276 344 fRowInfos->SetWeight(row, weight); 277 345 } 278 346 279 // MinRowHeight 347 280 348 float 281 349 BGridLayout::MinRowHeight(int row) const 282 350 { 283 351 return fRowInfos->MinSize(row); 284 352 } 285 353 286 // SetMinRowHeight 354 287 355 void 288 356 BGridLayout::SetMinRowHeight(int32 row, float height) 289 357 { 290 358 fRowInfos->SetMinSize(row, height); 291 359 } 292 360 293 // MaxRowHeight 361 294 362 float 295 363 BGridLayout::MaxRowHeight(int32 row) const 296 364 { 297 365 return fRowInfos->MaxSize(row); 298 366 } 299 367 300 // SetMaxRowHeight 368 301 369 void 302 370 BGridLayout::SetMaxRowHeight(int32 row, float height) 303 371 { 304 372 fRowInfos->SetMaxSize(row, height); 305 373 } 306 374 307 // AddView 375 308 376 BLayoutItem* 309 377 BGridLayout::AddView(BView* child) 310 378 { 311 379 return BTwoDimensionalLayout::AddView(child); 312 380 } 313 381 314 // AddView 382 315 383 BLayoutItem* 316 384 BGridLayout::AddView(int32 index, BView* child) 317 385 { 318 386 return BTwoDimensionalLayout::AddView(index, child); 319 387 } 320 388 321 // AddView 389 322 390 BLayoutItem* 323 391 BGridLayout::AddView(BView* child, int32 column, int32 row, int32 columnCount, 324 392 int32 rowCount) … … 335 403 return item; 336 404 } 337 405 338 // AddItem 406 339 407 bool 340 408 BGridLayout::AddItem(BLayoutItem* item) 341 409 { … … 351 419 return AddItem(item, fColumnCount, 0, 1, 1); 352 420 } 353 421 354 // AddItem 422 355 423 bool 356 424 BGridLayout::AddItem(int32 index, BLayoutItem* item) 357 425 { 358 426 return AddItem(item); 359 427 } 360 428 361 // AddItem 429 362 430 bool 363 431 BGridLayout::AddItem(BLayoutItem* item, int32 column, int32 row, 364 432 int32 columnCount, int32 rowCount) … … 378 446 data->dimensions.height = rowCount; 379 447 } 380 448 381 // resize the grid, if necessary 382 int32 newColumnCount = max_c(fColumnCount, column + columnCount); 383 int32 newRowCount = max_c(fRowCount, row + rowCount); 384 if (newColumnCount > fColumnCount || newRowCount > fRowCount) { 385 if (!_ResizeGrid(newColumnCount, newRowCount)) { 386 RemoveItem(item); 387 return false; 388 } 449 if (!_InsertItemIntoGrid(item)) { 450 RemoveItem(item); 451 return false; 389 452 } 390 453 391 // enter the item in the grid392 for (int32 x = 0; x < columnCount; x++) {393 for (int32 y = 0; y < rowCount; y++) {394 if (x == 0 && y == 0)395 fGrid[column + x][row + y] = item;396 else397 fGrid[column + x][row + y] = OCCUPIED_GRID_CELL;398 }399 }400 401 454 if (columnCount > 1) 402 455 fMultiColumnItems++; 403 456 if (rowCount > 1) … … 406 459 return success; 407 460 } 408 461 409 // ItemAdded 462 463 status_t 464 BGridLayout::Archive(BMessage* into, bool deep) const 465 { 466 BArchiver archiver(into); 467 status_t err = BTwoDimensionalLayout::Archive(into, deep); 468 469 if (err == B_OK) 470 err = into->AddInt32(kRowCountField, fRowCount); 471 if (err == B_OK) 472 err = into->AddInt32(kColumnCountField, fColumnCount); 473 474 for (int32 i = 0; i < fRowCount && err == B_OK; i++) { 475 err = into->AddFloat(kRowWeightField, fRowInfos->Weight(i)); 476 if (err == B_OK) 477 err = into->AddFloat(kRowMinSizeField, fRowInfos->MinSize(i)); 478 if (err == B_OK) 479 err = into->AddFloat(kRowMaxSizeField, fRowInfos->MaxSize(i)); 480 } 481 482 for (int32 i = 0; i < fColumnCount && err == B_OK; i++) { 483 err = into->AddFloat(kColumnWeightField, fRowInfos->Weight(i)); 484 if (err == B_OK) 485 err = into->AddFloat(kColumnMinSizeField, fRowInfos->MinSize(i)); 486 if (err == B_OK) 487 err = into->AddFloat(kColumnMaxSizeField, fRowInfos->MaxSize(i)); 488 } 489 490 return archiver.Finish(err); 491 } 492 493 494 BArchivable* 495 BGridLayout::Instantiate(BMessage* from) 496 { 497 if (validate_instantiation(from, "BGridLayout")) 498 return new BGridLayout(from); 499 return NULL; 500 } 501 502 503 status_t 504 BGridLayout::ItemArchived(BMessage* into, BLayoutItem* item, int32 index) const 505 { 506 ItemLayoutData* data = _LayoutDataForItem(item); 507 if (!data) // TODO: remove this check once AddItem() returns a bool 508 return B_ERROR; 509 510 status_t err = into->AddInt32(kItemX, data->dimensions.x); 511 if (err == B_OK) 512 err = into->AddInt32(kItemY, data->dimensions.y); 513 if (err == B_OK) 514 err = into->AddInt32(kItemWidth, data->dimensions.width); 515 if (err == B_OK) 516 err = into->AddInt32(kItemHeight, data->dimensions.height); 517 518 return err; 519 } 520 521 522 status_t 523 BGridLayout::ItemUnarchived(const BMessage* from, 524 BLayoutItem* item, int32 index) 525 { 526 ItemLayoutData* data = _LayoutDataForItem(item); 527 if (!data) { // TODO: remove this check once AddItem() returns a bool 528 data = new ItemLayoutData(); 529 item->SetLayoutData(data); 530 } 531 532 Dimensions& dimensions = data->dimensions; 533 status_t err = from->FindInt32(kItemX, index, &dimensions.x); 534 if (err == B_OK) 535 err = from->FindInt32(kItemY, index, &dimensions.y); 536 537 if (err == B_OK) 538 err = from->FindInt32(kItemWidth, index, &dimensions.width); 539 540 if (err == B_OK) 541 err = from->FindInt32(kItemHeight, index, &dimensions.height); 542 543 if (err == B_OK && !_AreGridCellsEmpty(dimensions.x, dimensions.y, 544 dimensions.width, dimensions.height)) 545 err = B_BAD_DATA; 546 547 if (err == B_OK && !_InsertItemIntoGrid(item)) 548 err = B_NO_MEMORY; 549 550 if (err == B_OK && dimensions.width > 1) 551 fMultiColumnItems++; 552 if (err == B_OK && dimensions.height > 1) 553 fMultiRowItems++; 554 555 return err; 556 } 557 558 410 559 void 411 560 BGridLayout::ItemAdded(BLayoutItem* item) 412 561 { 413 562 item->SetLayoutData(new ItemLayoutData); 414 563 } 415 564 416 // ItemRemoved 565 417 566 void 418 567 BGridLayout::ItemRemoved(BLayoutItem* item) 419 568 { … … 469 618 } 470 619 } 471 620 472 // HasMultiColumnItems 621 473 622 bool 474 623 BGridLayout::HasMultiColumnItems() 475 624 { 476 625 return (fMultiColumnItems > 0); 477 626 } 478 627 479 // HasMultiRowItems 628 480 629 bool 481 630 BGridLayout::HasMultiRowItems() 482 631 { 483 632 return (fMultiRowItems > 0); 484 633 } 485 634 486 // InternalCountColumns 635 487 636 int32 488 637 BGridLayout::InternalCountColumns() 489 638 { 490 639 return fColumnCount; 491 640 } 492 641 493 // InternalCountRows 642 494 643 int32 495 644 BGridLayout::InternalCountRows() 496 645 { 497 646 return fRowCount; 498 647 } 499 648 500 // GetColumnRowConstraints 649 501 650 void 502 651 BGridLayout::GetColumnRowConstraints(enum orientation orientation, int32 index, 503 652 ColumnRowConstraints* constraints) … … 513 662 } 514 663 } 515 664 516 // GetItemDimensions 665 517 666 void 518 667 BGridLayout::GetItemDimensions(BLayoutItem* item, Dimensions* dimensions) 519 668 { … … 521 670 *dimensions = data->dimensions; 522 671 } 523 672 524 // _IsGridCellEmpty 673 525 674 bool 526 675 BGridLayout::_IsGridCellEmpty(int32 column, int32 row) 527 676 { … … 533 682 return (fGrid[column][row] == NULL); 534 683 } 535 684 536 // _AreGridCellsEmpty 685 537 686 bool 538 687 BGridLayout::_AreGridCellsEmpty(int32 column, int32 row, int32 columnCount, 539 688 int32 rowCount) … … 553 702 return true; 554 703 } 555 704 556 // _ResizeGrid 705 557 706 bool 707 BGridLayout::_InsertItemIntoGrid(BLayoutItem* item) 708 { 709 BGridLayout::ItemLayoutData* data = _LayoutDataForItem(item); 710 int32 column = data->dimensions.x; 711 int32 columnCount = data->dimensions.width; 712 int32 row = data->dimensions.y; 713 int32 rowCount = data->dimensions.height; 714 715 // resize the grid, if necessary 716 int32 newColumnCount = max_c(fColumnCount, column + columnCount); 717 int32 newRowCount = max_c(fRowCount, row + rowCount); 718 if (newColumnCount > fColumnCount || newRowCount > fRowCount) { 719 if (!_ResizeGrid(newColumnCount, newRowCount)) 720 return false; 721 } 722 723 // enter the item in the grid 724 for (int32 x = 0; x < columnCount; x++) { 725 for (int32 y = 0; y < rowCount; y++) { 726 if (x == 0 && y == 0) 727 fGrid[column + x][row + y] = item; 728 else 729 fGrid[column + x][row + y] = OCCUPIED_GRID_CELL; 730 } 731 } 732 return true; 733 } 734 735 736 bool 558 737 BGridLayout::_ResizeGrid(int32 columnCount, int32 rowCount) 559 738 { 560 739 if (columnCount == fColumnCount && rowCount == fRowCount) … … 597 776 return success; 598 777 } 599 778 600 // _LayoutDataForItem 779 601 780 BGridLayout::ItemLayoutData* 602 781 BGridLayout::_LayoutDataForItem(BLayoutItem* item) const 603 782 { -
headers/os/interface/GridLayout.h
1 1 /* 2 * Copyright 2006 , Haiku, Inc. All rights reserved.2 * Copyright 2006-2010, Haiku, Inc. All rights reserved. 3 3 * Distributed under the terms of the MIT License. 4 4 */ 5 5 #ifndef _GRID_LAYOUT_H … … 8 8 #include <TwoDimensionalLayout.h> 9 9 10 10 11 12 11 class BGridLayout : public BTwoDimensionalLayout { 13 12 public: 14 13 BGridLayout(float horizontal = 0.0f, 15 14 float vertical = 0.0f); 15 BGridLayout(BMessage* from); 16 16 virtual ~BGridLayout(); 17 17 18 18 int32 CountColumns() const; … … 54 54 int32 row, int32 columnCount = 1, 55 55 int32 rowCount = 1); 56 56 57 virtual status_t Archive(BMessage* into, bool deep = true) const; 58 static BArchivable* Instantiate(BMessage* from); 59 60 virtual status_t ItemArchived(BMessage* into, 61 BLayoutItem* item, int32 index) const; 62 virtual status_t ItemUnarchived(const BMessage* from, 63 BLayoutItem* item, int32 index); 64 57 65 protected: 58 66 virtual void ItemAdded(BLayoutItem* item); 59 67 virtual void ItemRemoved(BLayoutItem* item); … … 67 75 enum orientation orientation, 68 76 int32 index, 69 77 ColumnRowConstraints* constraints); 70 virtual void 78 virtual void GetItemDimensions(BLayoutItem* item, 71 79 Dimensions* dimensions); 72 80 73 81 private: … … 78 86 bool _IsGridCellEmpty(int32 column, int32 row); 79 87 bool _AreGridCellsEmpty(int32 column, int32 row, 80 88 int32 columnCount, int32 rowCount); 81 89 90 bool _InsertItemIntoGrid(BLayoutItem* item); 82 91 bool _ResizeGrid(int32 columnCount, int32 rowCount); 83 92 84 93 ItemLayoutData* _LayoutDataForItem(BLayoutItem* item) const;