00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "CEGUIExceptions.h"
00027 #include "CEGUIWindowManager.h"
00028 #include "elements/CEGUIListbox.h"
00029 #include "elements/CEGUIListboxItem.h"
00030 #include "elements/CEGUIScrollbar.h"
00031 #include "elements/CEGUITooltip.h"
00032
00033 #include <algorithm>
00034
00035
00036 namespace CEGUI
00037 {
00038 const String Listbox::EventNamespace("Listbox");
00039
00040
00041
00042
00043 ListboxProperties::Sort Listbox::d_sortProperty;
00044 ListboxProperties::MultiSelect Listbox::d_multiSelectProperty;
00045 ListboxProperties::ForceVertScrollbar Listbox::d_forceVertProperty;
00046 ListboxProperties::ForceHorzScrollbar Listbox::d_forceHorzProperty;
00047 ListboxProperties::ItemTooltips Listbox::d_itemTooltipsProperty;
00048
00049
00050
00051
00052
00053
00054 const String Listbox::EventListContentsChanged( (utf8*)"ListItemsChanged" );
00055 const String Listbox::EventSelectionChanged( (utf8*)"ItemSelectionChanged" );
00056 const String Listbox::EventSortModeChanged( (utf8*)"SortModeChanged" );
00057 const String Listbox::EventMultiselectModeChanged( (utf8*)"MuliselectModeChanged" );
00058 const String Listbox::EventVertScrollbarModeChanged( (utf8*)"VertScrollModeChanged" );
00059 const String Listbox::EventHorzScrollbarModeChanged( (utf8*)"HorzScrollModeChanged" );
00060
00061
00062
00063
00064
00065 Listbox::Listbox(const String& type, const String& name)
00066 : Window(type, name),
00067 d_sorted(false),
00068 d_multiselect(false),
00069 d_forceVertScroll(false),
00070 d_forceHorzScroll(false),
00071 d_itemTooltips(false),
00072 d_lastSelected(NULL)
00073 {
00074
00075 addListboxEvents();
00076
00077 addListboxProperties();
00078 }
00079
00080
00081
00082
00083
00084 Listbox::~Listbox(void)
00085 {
00086 resetList_impl();
00087 }
00088
00089
00090
00091
00092
00093 void Listbox::initialise(void)
00094 {
00095
00096 d_vertScrollbar = createVertScrollbar(getName() + "__auto_vscrollbar__");
00097 d_horzScrollbar = createHorzScrollbar(getName() + "__auto_hscrollbar__");
00098
00099 addChildWindow(d_vertScrollbar);
00100 addChildWindow(d_horzScrollbar);
00101
00102 d_vertScrollbar->subscribeEvent(Scrollbar::EventScrollPositionChanged, Event::Subscriber(&Listbox::handle_scrollChange, this));
00103 d_horzScrollbar->subscribeEvent(Scrollbar::EventScrollPositionChanged, Event::Subscriber(&Listbox::handle_scrollChange, this));
00104
00105 configureScrollbars();
00106 performChildWindowLayout();
00107 }
00108
00109
00110
00111
00112
00113 size_t Listbox::getSelectedCount(void) const
00114 {
00115 size_t count = 0;
00116
00117 for (size_t index = 0; index < d_listItems.size(); ++index)
00118 {
00119 if (d_listItems[index]->isSelected())
00120 {
00121 count++;
00122 }
00123
00124 }
00125
00126 return count;
00127 }
00128
00129
00130
00131
00132
00133 ListboxItem* Listbox::getFirstSelectedItem(void) const
00134 {
00135 return getNextSelected(NULL);
00136 }
00137
00138
00139
00140
00141
00142 ListboxItem* Listbox::getNextSelected(const ListboxItem* start_item) const
00143 {
00144
00145 size_t index = (start_item == NULL) ? 0 : (getItemIndex(start_item) + 1);
00146
00147 while (index < d_listItems.size())
00148 {
00149
00150 if (d_listItems[index]->isSelected())
00151 {
00152 return d_listItems[index];
00153 }
00154
00155 else
00156 {
00157 index++;
00158 }
00159
00160 }
00161
00162
00163 return NULL;
00164 }
00165
00166
00167
00168
00169
00170 ListboxItem* Listbox::getListboxItemFromIndex(size_t index) const
00171 {
00172 if (index < d_listItems.size())
00173 {
00174 return d_listItems[index];
00175 }
00176 else
00177 {
00178 throw InvalidRequestException((utf8*)"Listbox::getListboxItemFromIndex - the specified index is out of range for this Listbox.");
00179 }
00180 }
00181
00182
00183
00184
00185
00186 size_t Listbox::getItemIndex(const ListboxItem* item) const
00187 {
00188 LBItemList::const_iterator pos = std::find(d_listItems.begin(), d_listItems.end(), item);
00189
00190 if (pos != d_listItems.end())
00191 {
00192 return std::distance(d_listItems.begin(), pos);
00193 }
00194 else
00195 {
00196 throw InvalidRequestException((utf8*)"Listbox::getItemIndex - the specified ListboxItem is not attached to this Listbox.");
00197 }
00198
00199 }
00200
00201
00202
00203
00204
00205 bool Listbox::isItemSelected(size_t index) const
00206 {
00207 if (index < d_listItems.size())
00208 {
00209 return d_listItems[index]->isSelected();
00210 }
00211 else
00212 {
00213 throw InvalidRequestException((utf8*)"Listbox::isItemSelected - the specified index is out of range for this Listbox.");
00214 }
00215
00216 }
00217
00218
00219
00220
00221
00222 ListboxItem* Listbox::findItemWithText(const String& text, const ListboxItem* start_item)
00223 {
00224
00225 size_t index = (start_item == NULL) ? 0 : (getItemIndex(start_item) + 1);
00226
00227 while (index < d_listItems.size())
00228 {
00229
00230 if (d_listItems[index]->getText() == text)
00231 {
00232 return d_listItems[index];
00233 }
00234
00235 else
00236 {
00237 index++;
00238 }
00239
00240 }
00241
00242
00243 return NULL;
00244 }
00245
00246
00247
00248
00249
00250 bool Listbox::isListboxItemInList(const ListboxItem* item) const
00251 {
00252 return std::find(d_listItems.begin(), d_listItems.end(), item) != d_listItems.end();
00253 }
00254
00255
00256
00257
00258
00259
00260 void Listbox::resetList(void)
00261 {
00262 if (resetList_impl())
00263 {
00264 WindowEventArgs args(this);
00265 onListContentsChanged(args);
00266 }
00267
00268 }
00269
00270
00271
00272
00273
00274 void Listbox::addItem(ListboxItem* item)
00275 {
00276 if (item != NULL)
00277 {
00278
00279 item->setOwnerWindow(this);
00280
00281
00282 if (isSortEnabled())
00283 {
00284 d_listItems.insert(std::upper_bound(d_listItems.begin(), d_listItems.end(), item, &lbi_less), item);
00285
00286 }
00287
00288 else
00289 {
00290 d_listItems.push_back(item);
00291 }
00292
00293 WindowEventArgs args(this);
00294 onListContentsChanged(args);
00295 }
00296
00297 }
00298
00299
00300
00301
00302
00303
00304 void Listbox::insertItem(ListboxItem* item, const ListboxItem* position)
00305 {
00306
00307 if (isSortEnabled())
00308 {
00309 addItem(item);
00310 }
00311 else if (item != NULL)
00312 {
00313
00314 item->setOwnerWindow(this);
00315
00316
00317 LBItemList::iterator ins_pos;
00318
00319 if (position == NULL)
00320 {
00321 ins_pos = d_listItems.begin();
00322 }
00323 else
00324 {
00325 ins_pos = std::find(d_listItems.begin(), d_listItems.end(), position);
00326
00327
00328 if (ins_pos == d_listItems.end())
00329 {
00330 throw InvalidRequestException((utf8*)"Listbox::insertItem - the specified ListboxItem for parameter 'position' is not attached to this Listbox.");
00331 }
00332
00333 }
00334
00335 d_listItems.insert(ins_pos, item);
00336
00337 WindowEventArgs args(this);
00338 onListContentsChanged(args);
00339 }
00340
00341 }
00342
00343
00344
00345
00346
00347 void Listbox::removeItem(const ListboxItem* item)
00348 {
00349 if (item != NULL)
00350 {
00351 LBItemList::iterator pos = std::find(d_listItems.begin(), d_listItems.end(), item);
00352
00353
00354 if (pos != d_listItems.end())
00355 {
00356
00357 (*pos)->setOwnerWindow(NULL);
00358
00359
00360 d_listItems.erase(pos);
00361
00362
00363 if (item == d_lastSelected)
00364 {
00365 d_lastSelected = NULL;
00366 }
00367
00368
00369 if (item->isAutoDeleted())
00370 {
00371
00372 delete item;
00373 }
00374
00375 WindowEventArgs args(this);
00376 onListContentsChanged(args);
00377 }
00378
00379 }
00380
00381 }
00382
00383
00384
00385
00386
00387 void Listbox::clearAllSelections(void)
00388 {
00389
00390 if (clearAllSelections_impl())
00391 {
00392 WindowEventArgs args(this);
00393 onSelectionChanged(args);
00394 }
00395
00396 }
00397
00398
00399
00400
00401
00402 void Listbox::setSortingEnabled(bool setting)
00403 {
00404
00405 if (d_sorted != setting)
00406 {
00407 d_sorted = setting;
00408
00409
00410 if (d_sorted)
00411 {
00412 std::sort(d_listItems.begin(), d_listItems.end(), &lbi_greater);
00413 }
00414
00415 WindowEventArgs args(this);
00416 onSortModeChanged(args);
00417 }
00418
00419 }
00420
00421
00422
00423
00424
00425
00426 void Listbox::setMultiselectEnabled(bool setting)
00427 {
00428
00429 if (d_multiselect != setting)
00430 {
00431 d_multiselect = setting;
00432
00433
00434 WindowEventArgs args(this);
00435 if ((!d_multiselect) && (getSelectedCount() > 1))
00436 {
00437 ListboxItem* itm = getFirstSelectedItem();
00438
00439 while ((itm = getNextSelected(itm)))
00440 {
00441 itm->setSelected(false);
00442 }
00443
00444 onSelectionChanged(args);
00445
00446 }
00447
00448 onMultiselectModeChanged(args);
00449 }
00450
00451 }
00452
00453 void Listbox::setItemTooltipsEnabled(bool setting)
00454 {
00455 d_itemTooltips = setting;
00456 }
00457
00458
00459
00460
00461
00462
00463 void Listbox::setShowVertScrollbar(bool setting)
00464 {
00465 if (d_forceVertScroll != setting)
00466 {
00467 d_forceVertScroll = setting;
00468
00469 configureScrollbars();
00470 WindowEventArgs args(this);
00471 onVertScrollbarModeChanged(args);
00472 }
00473
00474 }
00475
00476
00477
00478
00479
00480 void Listbox::setShowHorzScrollbar(bool setting)
00481 {
00482 if (d_forceHorzScroll != setting)
00483 {
00484 d_forceHorzScroll = setting;
00485
00486 configureScrollbars();
00487 WindowEventArgs args(this);
00488 onHorzScrollbarModeChanged(args);
00489 }
00490
00491 }
00492
00493
00494
00495
00496
00497 void Listbox::setItemSelectState(ListboxItem* item, bool state)
00498 {
00499 LBItemList::iterator pos = std::find(d_listItems.begin(), d_listItems.end(), item);
00500
00501 if (pos != d_listItems.end())
00502 {
00503 setItemSelectState(std::distance(d_listItems.begin(), pos), state);
00504 }
00505 else
00506 {
00507 throw InvalidRequestException((utf8*)"Listbox::setItemSelectState - the specified ListboxItem is not attached to this Listbox.");
00508 }
00509 }
00510
00511
00512
00513
00514
00515 void Listbox::setItemSelectState(size_t item_index, bool state)
00516 {
00517 if (item_index < getItemCount())
00518 {
00519
00520 if (d_listItems[item_index]->isSelected() != state)
00521 {
00522
00523 if (state && !d_multiselect)
00524 {
00525 clearAllSelections_impl();
00526 }
00527
00528 d_listItems[item_index]->setSelected(state);
00529 WindowEventArgs args(this);
00530 onSelectionChanged(args);
00531 }
00532
00533 }
00534 else
00535 {
00536 throw InvalidRequestException((utf8*)"Listbox::setItemSelectState - the value passed in the 'item_index' parameter is out of range for this Listbox.");
00537 }
00538
00539 }
00540
00541
00542
00543
00544
00545
00546 void Listbox::handleUpdatedItemData(void)
00547 {
00548 configureScrollbars();
00549 requestRedraw();
00550 }
00551
00552
00553
00554
00555
00556 void Listbox::populateRenderCache()
00557 {
00558
00559 cacheListboxBaseImagery();
00560
00561
00562
00563
00564 Vector3 itemPos;
00565 Size itemSize;
00566 Rect itemClipper, itemRect;
00567 float widest = getWidestItemWidth();
00568
00569
00570 Rect itemsArea(getListRenderArea());
00571
00572
00573 itemPos.d_x = itemsArea.d_left - d_horzScrollbar->getScrollPosition();
00574 itemPos.d_y = itemsArea.d_top - d_vertScrollbar->getScrollPosition();
00575 itemPos.d_z = System::getSingleton().getRenderer()->getZLayer(3) - System::getSingleton().getRenderer()->getCurrentZ();
00576
00577 float alpha = getEffectiveAlpha();
00578
00579
00580 size_t itemCount = getItemCount();
00581
00582 for (size_t i = 0; i < itemCount; ++i)
00583 {
00584 itemSize.d_height = d_listItems[i]->getPixelSize().d_height;
00585
00586
00587 itemSize.d_width = ceguimax(itemsArea.getWidth(), widest);
00588
00589
00590 itemRect.d_left = itemPos.d_x;
00591 itemRect.d_top = itemPos.d_y;
00592 itemRect.setSize(itemSize);
00593 itemClipper = itemRect.getIntersection(itemsArea);
00594
00595
00596 if (itemClipper.getWidth() == 0)
00597 {
00598 itemPos.d_y += itemSize.d_height;
00599 continue;
00600 }
00601
00602
00603 d_listItems[i]->draw(d_renderCache, itemRect, itemPos.d_z, alpha, &itemClipper);
00604
00605
00606 itemPos.d_y += itemSize.d_height;
00607 }
00608
00609 }
00610
00611
00612
00613
00614
00615
00616 void Listbox::configureScrollbars(void)
00617 {
00618 Scrollbar* vertScrollbar;
00619 Scrollbar* horzScrollbar;
00620
00621 try
00622 {
00623 vertScrollbar = static_cast<Scrollbar*>(WindowManager::getSingleton().getWindow(getName() + "__auto_vscrollbar__"));
00624 horzScrollbar = static_cast<Scrollbar*>(WindowManager::getSingleton().getWindow(getName() + "__auto_hscrollbar__"));
00625 }
00626 catch (UnknownObjectException)
00627 {
00628
00629 return;
00630 }
00631
00632 float totalHeight = getTotalItemsHeight();
00633 float widestItem = getWidestItemWidth();
00634
00635
00636
00637
00638
00639 if ((totalHeight > getListRenderArea().getHeight()) || d_forceVertScroll)
00640 {
00641 vertScrollbar->show();
00642
00643
00644 if ((widestItem > getListRenderArea().getWidth()) || d_forceHorzScroll)
00645 {
00646 horzScrollbar->show();
00647 }
00648 else
00649 {
00650 horzScrollbar->hide();
00651 }
00652
00653 }
00654 else
00655 {
00656
00657 if ((widestItem > getListRenderArea().getWidth()) || d_forceHorzScroll)
00658 {
00659 horzScrollbar->show();
00660
00661
00662 if ((totalHeight > getListRenderArea().getHeight()) || d_forceVertScroll)
00663 {
00664 vertScrollbar->show();
00665 }
00666 else
00667 {
00668 vertScrollbar->hide();
00669 }
00670
00671 }
00672 else
00673 {
00674 vertScrollbar->hide();
00675 horzScrollbar->hide();
00676 }
00677
00678 }
00679
00680
00681
00682
00683 Rect renderArea(getListRenderArea());
00684
00685 vertScrollbar->setDocumentSize(totalHeight);
00686 vertScrollbar->setPageSize(renderArea.getHeight());
00687 vertScrollbar->setStepSize(ceguimax(1.0f, renderArea.getHeight() / 10.0f));
00688 vertScrollbar->setScrollPosition(vertScrollbar->getScrollPosition());
00689
00690 horzScrollbar->setDocumentSize(widestItem);
00691 horzScrollbar->setPageSize(renderArea.getWidth());
00692 horzScrollbar->setStepSize(ceguimax(1.0f, renderArea.getWidth() / 10.0f));
00693 horzScrollbar->setScrollPosition(horzScrollbar->getScrollPosition());
00694 }
00695
00696
00697
00698
00699
00700 void Listbox::selectRange(size_t start, size_t end)
00701 {
00702
00703 if (d_listItems.size() > 0)
00704 {
00705
00706 if (start > d_listItems.size())
00707 {
00708 start = 0;
00709 }
00710
00711
00712 if (end >= d_listItems.size())
00713 {
00714 end = d_listItems.size() - 1;
00715 }
00716
00717
00718 if (start > end)
00719 {
00720 size_t tmp;
00721 tmp = start;
00722 start = end;
00723 end = tmp;
00724 }
00725
00726
00727 for( ; start <= end; ++start)
00728 {
00729 d_listItems[start]->setSelected(true);
00730 }
00731
00732 }
00733
00734 }
00735
00736
00737
00738
00739
00740 float Listbox::getTotalItemsHeight(void) const
00741 {
00742 float height = 0;
00743
00744 for (size_t i = 0; i < getItemCount(); ++i)
00745 {
00746 height += d_listItems[i]->getPixelSize().d_height;
00747 }
00748
00749 return height;
00750 }
00751
00752
00753
00754
00755
00756 float Listbox::getWidestItemWidth(void) const
00757 {
00758 float widest = 0;
00759
00760 for (size_t i = 0; i < getItemCount(); ++i)
00761 {
00762 float thisWidth = d_listItems[i]->getPixelSize().d_width;
00763
00764 if (thisWidth > widest)
00765 {
00766 widest = thisWidth;
00767 }
00768
00769 }
00770
00771 return widest;
00772 }
00773
00774
00775
00776
00777
00778 bool Listbox::clearAllSelections_impl(void)
00779 {
00780
00781 bool modified = false;
00782
00783 for (size_t index = 0; index < d_listItems.size(); ++index)
00784 {
00785 if (d_listItems[index]->isSelected())
00786 {
00787 d_listItems[index]->setSelected(false);
00788 modified = true;
00789 }
00790
00791 }
00792
00793 return modified;
00794 }
00795
00796
00797
00798
00799
00800 ListboxItem* Listbox::getItemAtPoint(const Point& pt) const
00801 {
00802 Rect renderArea(getListRenderArea());
00803
00804
00805 if (renderArea.isPointInRect(pt))
00806 {
00807 float y = renderArea.d_top - d_vertScrollbar->getScrollPosition();
00808
00809
00810 if (pt.d_y >= y)
00811 {
00812 for (size_t i = 0; i < getItemCount(); ++i)
00813 {
00814 y += d_listItems[i]->getPixelSize().d_height;
00815
00816 if (pt.d_y < y)
00817 {
00818 return d_listItems[i];
00819 }
00820
00821 }
00822 }
00823 }
00824
00825 return NULL;
00826 }
00827
00828
00829
00830
00831
00832 void Listbox::addListboxEvents(void)
00833 {
00834 addEvent(EventListContentsChanged);
00835 addEvent(EventSelectionChanged);
00836 addEvent(EventSortModeChanged);
00837 addEvent(EventMultiselectModeChanged);
00838 addEvent(EventVertScrollbarModeChanged);
00839 addEvent(EventHorzScrollbarModeChanged);
00840 }
00841
00842
00843
00844
00845
00846 void Listbox::onListContentsChanged(WindowEventArgs& e)
00847 {
00848 configureScrollbars();
00849 requestRedraw();
00850 fireEvent(EventListContentsChanged, e, EventNamespace);
00851 }
00852
00853
00854
00855
00856
00857
00858 void Listbox::onSelectionChanged(WindowEventArgs& e)
00859 {
00860 requestRedraw();
00861 fireEvent(EventSelectionChanged, e, EventNamespace);
00862 }
00863
00864
00865
00866
00867
00868 void Listbox::onSortModeChanged(WindowEventArgs& e)
00869 {
00870 requestRedraw();
00871 fireEvent(EventSortModeChanged, e, EventNamespace);
00872 }
00873
00874
00875
00876
00877
00878 void Listbox::onMultiselectModeChanged(WindowEventArgs& e)
00879 {
00880 fireEvent(EventMultiselectModeChanged, e, EventNamespace);
00881 }
00882
00883
00884
00885
00886
00887
00888 void Listbox::onVertScrollbarModeChanged(WindowEventArgs& e)
00889 {
00890 requestRedraw();
00891 fireEvent(EventVertScrollbarModeChanged, e, EventNamespace);
00892 }
00893
00894
00895
00896
00897
00898
00899 void Listbox::onHorzScrollbarModeChanged(WindowEventArgs& e)
00900 {
00901 requestRedraw();
00902 fireEvent(EventHorzScrollbarModeChanged, e, EventNamespace);
00903 }
00904
00905
00906
00907
00908
00909 void Listbox::onSized(WindowEventArgs& e)
00910 {
00911
00912 Window::onSized(e);
00913
00914 configureScrollbars();
00915
00916 e.handled = true;
00917 }
00918
00919
00920
00921
00922
00923 void Listbox::onMouseButtonDown(MouseEventArgs& e)
00924 {
00925
00926 Window::onMouseButtonDown(e);
00927
00928 if (e.button == LeftButton)
00929 {
00930 bool modified = false;
00931
00932
00933 if (!(e.sysKeys & Control) || !d_multiselect)
00934 {
00935 modified = clearAllSelections_impl();
00936 }
00937
00938 Point localPos(screenToWindow(e.position));
00939
00940 if (getMetricsMode() == Relative)
00941 {
00942 localPos = relativeToAbsolute(localPos);
00943 }
00944
00945 ListboxItem* item = getItemAtPoint(localPos);
00946
00947 if (item != NULL)
00948 {
00949 modified = true;
00950
00951
00952 if (((e.sysKeys & Shift) && (d_lastSelected != NULL)) && d_multiselect)
00953 {
00954 selectRange(getItemIndex(item), getItemIndex(d_lastSelected));
00955 }
00956 else
00957 {
00958 item->setSelected(item->isSelected() ^ true);
00959 }
00960
00961
00962 d_lastSelected = item->isSelected() ? item : NULL;
00963 }
00964
00965
00966 if (modified)
00967 {
00968 WindowEventArgs args(this);
00969 onSelectionChanged(args);
00970 }
00971
00972 e.handled = true;
00973 }
00974
00975 }
00976
00977
00978
00979
00980
00981 void Listbox::onMouseWheel(MouseEventArgs& e)
00982 {
00983
00984 Window::onMouseWheel(e);
00985
00986 if (d_vertScrollbar->isVisible() && (d_vertScrollbar->getDocumentSize() > d_vertScrollbar->getPageSize()))
00987 {
00988 d_vertScrollbar->setScrollPosition(d_vertScrollbar->getScrollPosition() + d_vertScrollbar->getStepSize() * -e.wheelChange);
00989 }
00990 else if (d_horzScrollbar->isVisible() && (d_horzScrollbar->getDocumentSize() > d_horzScrollbar->getPageSize()))
00991 {
00992 d_horzScrollbar->setScrollPosition(d_horzScrollbar->getScrollPosition() + d_horzScrollbar->getStepSize() * -e.wheelChange);
00993 }
00994
00995 e.handled = true;
00996 }
00997
00998
00999
01000
01001 void Listbox::onMouseMove(MouseEventArgs& e)
01002 {
01003 if (d_itemTooltips)
01004 {
01005 static ListboxItem* lastItem = NULL;
01006
01007 Point posi = relativeToAbsolute(screenToWindow(e.position));
01008 ListboxItem* item = getItemAtPoint(posi);
01009 if (item != lastItem)
01010 {
01011 if (item != NULL)
01012 {
01013 setTooltipText(item->getTooltipText());
01014 }
01015 else
01016 {
01017 setTooltipText("");
01018 }
01019 lastItem = item;
01020 }
01021
01022
01023
01024 Tooltip* tooltip = getTooltip();
01025
01026 if (tooltip)
01027 {
01028 if (tooltip->getTargetWindow() != this)
01029 tooltip->setTargetWindow(this);
01030 else
01031 tooltip->positionSelf();
01032 }
01033 }
01034
01035 Window::onMouseMove(e);
01036 }
01037
01038
01039
01040
01041
01042 void Listbox::ensureItemIsVisible(size_t item_index)
01043 {
01044
01045 if (item_index >= getItemCount())
01046 {
01047 d_vertScrollbar->setScrollPosition(d_vertScrollbar->getDocumentSize() - d_vertScrollbar->getPageSize());
01048 }
01049 else
01050 {
01051 float bottom;
01052 float listHeight = getListRenderArea().getHeight();
01053 float top = 0;
01054
01055
01056 size_t i;
01057 for (i = 0; i < item_index; ++i)
01058 {
01059 top += d_listItems[i]->getPixelSize().d_height;
01060 }
01061
01062
01063 bottom = top + d_listItems[i]->getPixelSize().d_height;
01064
01065
01066 float currPos = d_vertScrollbar->getScrollPosition();
01067 top -= currPos;
01068 bottom -= currPos;
01069
01070
01071 if ((top < 0.0f) || ((bottom - top) > listHeight))
01072 {
01073
01074 d_vertScrollbar->setScrollPosition(currPos + top);
01075 }
01076
01077 else if (bottom >= listHeight)
01078 {
01079
01080 d_vertScrollbar->setScrollPosition(currPos + bottom - listHeight);
01081 }
01082
01083
01084 }
01085
01086 }
01087
01088
01089
01090
01091
01092 void Listbox::ensureItemIsVisible(const ListboxItem* item)
01093 {
01094 ensureItemIsVisible(getItemIndex(item));
01095 }
01096
01097
01098
01099
01100
01101 bool Listbox::isVertScrollbarAlwaysShown(void) const
01102 {
01103 return d_forceVertScroll;
01104 }
01105
01106
01107
01108
01109
01110 bool Listbox::isHorzScrollbarAlwaysShown(void) const
01111 {
01112 return d_forceHorzScroll;
01113 }
01114
01115
01116
01117
01118 void Listbox::addListboxProperties(void)
01119 {
01120 addProperty(&d_sortProperty);
01121 addProperty(&d_multiSelectProperty);
01122 addProperty(&d_forceHorzProperty);
01123 addProperty(&d_forceVertProperty);
01124 addProperty(&d_itemTooltipsProperty);
01125 }
01126
01127
01128
01129
01130
01131 bool Listbox::resetList_impl(void)
01132 {
01133
01134 if (getItemCount() == 0)
01135 {
01136 return false;
01137 }
01138
01139 else
01140 {
01141
01142 for (size_t i = 0; i < getItemCount(); ++i)
01143 {
01144
01145 if (d_listItems[i]->isAutoDeleted())
01146 {
01147
01148 delete d_listItems[i];
01149 }
01150
01151 }
01152
01153
01154 d_listItems.clear();
01155
01156 d_lastSelected = NULL;
01157
01158 return true;
01159 }
01160
01161 }
01162
01163
01164
01165
01166 bool Listbox::handle_scrollChange(const EventArgs& args)
01167 {
01168
01169 requestRedraw();
01170 return true;
01171 }
01172
01173
01175
01176
01177
01179
01180
01181
01182 bool lbi_less(const ListboxItem* a, const ListboxItem* b)
01183 {
01184 return *a < *b;
01185 }
01186
01187
01188
01189
01190 bool lbi_greater(const ListboxItem* a, const ListboxItem* b)
01191 {
01192 return *a > *b;
01193 }
01194
01195 }