00001 00002 /* 00003 ----------------------------------------------------------------------------- 00004 This source file is part of OGRE 00005 (Object-oriented Graphics Rendering Engine) 00006 For the latest info, see http://www.ogre3d.org/ 00007 00008 Copyright © 2000-2002 The OGRE Team 00009 Also see acknowledgements in Readme.html 00010 00011 This program is free software you can redistribute it and/or modify it under 00012 the terms of the GNU Lesser General Public License as published by the Free Software 00013 Foundation either version 2 of the License, or (at your option) any later 00014 version. 00015 00016 This program is distributed in the hope that it will be useful, but WITHOUT 00017 ANY WARRANTY without even the implied warranty of MERCHANTABILITY or FITNESS 00018 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00019 00020 You should have received a copy of the GNU Lesser General Public License along with 00021 this program if not, write to the Free Software Foundation, Inc., 59 Temple 00022 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00023 http://www.gnu.org/copyleft/lesser.txt. 00024 ----------------------------------------------------------------------------- 00025 */ 00026 00027 #include "OgreListGuiElement.h" 00028 #include "OgreStringConverter.h" 00029 #include "OgreGuiManager.h" 00030 #include "OgreResource.h" 00031 #include "OgreException.h" 00032 00033 00034 namespace Ogre { 00035 00036 String ListGuiElement::msTypeName = "List"; 00037 ListGuiElement::CmdItemTemplate ListGuiElement::msCmdItemTemplate; 00038 ListGuiElement::CmdScrollBar ListGuiElement::msCmdScrollBar; 00039 ListGuiElement::CmdVSpacing ListGuiElement::msCmdVSpacing; 00040 ListGuiElement::CmdHSpacing ListGuiElement::msCmdHSpacing; 00041 ListGuiElement::CmdItemPanelMaterial ListGuiElement::msCmdItemPanelMaterial; 00042 ListGuiElement::CmdItemPanelMaterialSelected ListGuiElement::msCmdItemPanelMaterialSelected; 00043 00044 00045 ListGuiElement::ListGuiElement(const String& name) : 00046 PanelGuiElement(name) 00047 { 00048 if (createParamDictionary("ListGuiElement")) 00049 { 00050 addBaseParameters(); 00051 } 00052 mSelectedElement = 0; 00053 mVSpacing = 0; 00054 mHSpacing = 0; 00055 mPixelVSpacing = 0; 00056 mPixelHSpacing = 0; 00057 mFirstVisibleItem = 0; 00058 mScrollBar = 0; 00059 mItemPanelMaterial = ""; 00060 mItemPanelMaterialSelected = ""; 00061 00062 } 00063 //--------------------------------------------------------------------- 00064 ListGuiElement::~ListGuiElement() 00065 { 00066 for (ResourceList::iterator i = mResourceList.begin(); i != mResourceList.end(); ++i) 00067 delete *i; 00068 } 00069 00070 //--------------------------------------------------------------------- 00071 void ListGuiElement::addBaseParameters(void) 00072 { 00073 PanelGuiElement::addBaseParameters(); 00074 ParamDictionary* dict = getParamDictionary(); 00075 00076 dict->addParameter(ParameterDef("item_template", 00077 "The template of List Item objects." 00078 , PT_STRING), 00079 &ListGuiElement::msCmdItemTemplate); 00080 00081 dict->addParameter(ParameterDef("scroll_bar", 00082 "The name of the scroll bar template" 00083 , PT_STRING), 00084 &ListGuiElement::msCmdScrollBar); 00085 00086 dict->addParameter(ParameterDef("v_spacing", 00087 "The vertical spacing of the elements" 00088 , PT_STRING), 00089 &ListGuiElement::msCmdVSpacing); 00090 00091 00092 dict->addParameter(ParameterDef("h_spacing", 00093 "The horizontal spacing of the elements from the edge of the list" 00094 00095 , PT_STRING), 00096 &ListGuiElement::msCmdHSpacing); 00097 dict->addParameter(ParameterDef("item_material", 00098 "The material of the item panel" 00099 , PT_STRING), 00100 &ListGuiElement::msCmdItemPanelMaterial); 00101 dict->addParameter(ParameterDef("item_material_selected", 00102 "The material of the item panel when it is selected" 00103 , PT_STRING), 00104 &ListGuiElement::msCmdItemPanelMaterialSelected); 00105 } 00106 //--------------------------------------------------------------------- 00107 // Command objects 00108 //--------------------------------------------------------------------- 00109 00110 //----------------------------------------------------------------------- 00111 String ListGuiElement::CmdItemTemplate::doGet(const void* target) const 00112 { 00113 return static_cast<const ListGuiElement*>(target)->getItemTemplateName(); 00114 } 00115 void ListGuiElement::CmdItemTemplate::doSet(void* target, const String& val) 00116 { 00117 std::vector<String> vec = val.split(); 00118 00119 static_cast<ListGuiElement*>(target)->setItemTemplateName(val); 00120 } 00121 //----------------------------------------------------------------------- 00122 String ListGuiElement::CmdVSpacing::doGet(const void* target) const 00123 { 00124 const ListGuiElement *t = static_cast<const ListGuiElement*>(target); 00125 return StringConverter::toString(t->getVSpacing()); 00126 } 00127 void ListGuiElement::CmdVSpacing::doSet(void* target, const String& val) 00128 { 00129 std::vector<String> vec = val.split(); 00130 00131 static_cast<ListGuiElement*>(target)->setVSpacing(StringConverter::parseReal(val)); 00132 } 00133 00134 //----------------------------------------------------------------------- 00135 String ListGuiElement::CmdScrollBar::doGet(const void* target) const 00136 { 00137 return static_cast<const ListGuiElement*>(target)->getScrollBarName(); 00138 } 00139 void ListGuiElement::CmdScrollBar::doSet(void* target, const String& val) 00140 { 00141 std::vector<String> vec = val.split(); 00142 00143 static_cast<ListGuiElement*>(target)->setScrollBarName(val); 00144 } 00145 00146 00147 //----------------------------------------------------------------------- 00148 String ListGuiElement::CmdHSpacing::doGet(const void* target) const 00149 { 00150 const ListGuiElement *t = static_cast<const ListGuiElement*>(target); 00151 return StringConverter::toString(t->getHSpacing()); 00152 } 00153 void ListGuiElement::CmdHSpacing::doSet(void* target, const String& val) 00154 { 00155 std::vector<String> vec = val.split(); 00156 00157 static_cast<ListGuiElement*>(target)->setHSpacing(StringConverter::parseReal(val)); 00158 } 00159 //----------------------------------------------------------------------- 00160 String ListGuiElement::CmdItemPanelMaterialSelected::doGet(const void* target) const 00161 { 00162 return static_cast<const ListGuiElement*>(target)->getItemPanelMaterialSelected(); 00163 } 00164 void ListGuiElement::CmdItemPanelMaterialSelected::doSet(void* target, const String& val) 00165 { 00166 static_cast<ListGuiElement*>(target)->setItemPanelMaterialSelected(val); 00167 } 00168 //----------------------------------------------------------------------- 00169 String ListGuiElement::CmdItemPanelMaterial::doGet(const void* target) const 00170 { 00171 return static_cast<const ListGuiElement*>(target)->getItemPanelMaterial(); 00172 } 00173 void ListGuiElement::CmdItemPanelMaterial::doSet(void* target, const String& val) 00174 { 00175 static_cast<ListGuiElement*>(target)->setItemPanelMaterial(val); 00176 } 00177 //----------------------------------------------------------------------- 00178 String ListGuiElement::getItemTemplateName() const 00179 { 00180 return mItemTemplateName; 00181 00182 } 00183 void ListGuiElement::setItemTemplateName(const String& val) 00184 { 00185 mItemTemplateName = val; 00186 00187 } 00188 //----------------------------------------------------------------------- 00189 00190 void ListGuiElement::setHSpacing(Real val) 00191 { 00192 mHSpacing = val; 00193 } 00194 Real ListGuiElement::getHSpacing() const 00195 { 00196 return mHSpacing; 00197 00198 } 00199 00200 //----------------------------------------------------------------------- 00201 00202 void ListGuiElement::setVSpacing(Real val) 00203 { 00204 mVSpacing = val; 00205 } 00206 00207 Real ListGuiElement::getVSpacing() const 00208 { 00209 return mVSpacing; 00210 } 00211 00212 00213 String ListGuiElement::getScrollBarName() const 00214 { 00215 assert(mScrollBar); 00216 return mScrollBar->getName(); 00217 00218 } 00219 00220 void ListGuiElement::setScrollBarName(const String& val) 00221 { 00222 00223 if (mScrollBar != 0) 00224 { 00225 removeChild(mScrollBar->getName()); 00226 GuiManager::getSingleton().destroyGuiElement(mScrollBar->getName()); 00227 } 00228 mScrollBar = static_cast<ScrollBarGuiElement*> ( 00229 GuiManager::getSingleton().createGuiElementFromTemplate(val, "", mName + "/ScrollBar")); 00230 00231 mScrollBar->setLeft(getWidth()-mScrollBar->getWidth()-0.001); 00232 mScrollBar->setTop(0); 00233 mScrollBar->setHeight(getHeight()); 00234 00235 addChild(mScrollBar); 00236 mScrollBar->layoutItems(); 00237 mScrollBar->addScrollListener(this); 00238 00239 } 00240 00241 00242 //----------------------------------------------------------------------- 00243 String ListGuiElement::getItemPanelMaterial() const 00244 { 00245 return mItemPanelMaterial; 00246 00247 } 00248 void ListGuiElement::setItemPanelMaterial(const String& val) 00249 { 00250 mItemPanelMaterial = val; 00251 00252 } 00253 //----------------------------------------------------------------------- 00254 String ListGuiElement::getItemPanelMaterialSelected() const 00255 { 00256 return mItemPanelMaterialSelected; 00257 00258 } 00259 void ListGuiElement::setItemPanelMaterialSelected(const String& val) 00260 { 00261 mItemPanelMaterialSelected = val; 00262 00263 } 00264 //----------------------------------------------------------------------- 00265 00266 void ListGuiElement::addListItem(Resource* r) 00267 { 00268 GuiElement* mInsideObject = 00269 GuiManager::getSingleton().createGuiElementFromTemplate(mItemTemplateName, "", getListItemName(r)); 00270 00271 // create a back panel for the item 00272 00273 GuiContainer* pBackPanel = static_cast<GuiContainer*> 00274 (GuiManager::getSingleton().createGuiElement("Panel",getListItemPanelName(r))); 00275 00276 pBackPanel->setLeft(mHSpacing); 00277 Real scrollBarWidth = (mScrollBar) ? mScrollBar->getWidth() : 0; 00278 pBackPanel->setWidth(getWidth()-mHSpacing-scrollBarWidth); 00279 pBackPanel->setHeight(mInsideObject->getHeight()); 00280 pBackPanel->setChildrenProcessEvents(false); 00281 pBackPanel->addMouseListener(this); 00282 pBackPanel->addMouseMotionListener(this); 00283 00284 addChild(pBackPanel); 00285 00286 mInsideObject->setCaption(r->getName()); 00287 mInsideObject->setLeft(0); 00288 mInsideObject->setTop(0); 00289 mInsideObject->setWidth(pBackPanel->getWidth()); 00290 00291 00292 mResourceList.push_back(r); 00293 pBackPanel->addChild(mInsideObject); 00294 00295 00296 layoutItems(); 00297 00298 00299 if (mSelectedElement == NULL) 00300 { 00301 setSelectedItem(mInsideObject,true); 00302 mSelectedElement = mInsideObject; 00303 } 00304 else 00305 { 00306 setSelectedItem(mInsideObject,false); 00307 } 00308 00309 } 00310 00311 void ListGuiElement::removeListItem(Resource* r) 00312 { 00313 GuiContainer* backPanel = static_cast<GuiContainer*> (getChild(getListItemPanelName(r))); 00314 00315 if (mSelectedElement == backPanel->getChild(getListItemName(r))) 00316 mSelectedElement = 0; 00317 00318 00319 backPanel->removeChild(getListItemName(r)); 00320 removeChild(getListItemPanelName(r)); 00321 00322 00323 GuiManager::getSingleton().destroyGuiElement(getListItemName(r)); 00324 GuiManager::getSingleton().destroyGuiElement(getListItemPanelName(r)); 00325 00326 bool bFound = false; 00327 ResourceList::iterator i; 00328 for (i = mResourceList.begin(); i != mResourceList.end(); ++i) 00329 { 00330 if (*i == r) 00331 { 00332 delete *i; 00333 mResourceList.erase(i); 00334 bFound = true; 00335 break; 00336 00337 } 00338 } 00339 if (!bFound) 00340 { 00341 Except(Exception::ERR_ITEM_NOT_FOUND, "Cannot find Resource " + r->getName() + 00342 " to remove from list.", "ListGuiElement::removeListItem"); 00343 } 00344 00345 layoutItems(); 00346 00347 } 00348 00349 String ListGuiElement::getListItemName(Resource* r) const 00350 { 00351 return mName + "/" + r->getName(); 00352 00353 } 00354 00355 String ListGuiElement::getListItemPanelName(Resource* r) const 00356 { 00357 return getListItemName(r) + "/" + "BackPanel"; 00358 00359 } 00360 00361 00362 void ListGuiElement::layoutItems() 00363 { 00364 00365 Real currentTop = mVSpacing; 00366 unsigned int currentItemNo = 0; 00367 mVisibleRange = 0; 00368 ChildIterator it = getChildIterator(); 00369 while (it.hasMoreElements()) 00370 { 00371 GuiElement* currentElement = it.getNext(); 00372 00373 if (currentElement->getName() == mName + "/ScrollBar") 00374 { 00375 continue; 00376 } 00377 if (currentItemNo < mFirstVisibleItem) 00378 { 00379 currentElement->hide(); 00380 } 00381 else 00382 { 00383 currentElement->setTop(currentTop); 00384 currentElement->_update(); 00385 currentTop += currentElement->getHeight() + mVSpacing; 00386 if (currentTop > mHeight) 00387 { 00388 currentElement->hide(); 00389 } 00390 else 00391 { 00392 mVisibleRange ++; 00393 currentElement->show(); 00394 } 00395 } 00396 currentItemNo++; 00397 } 00398 if (mScrollBar) 00399 mScrollBar->setLimits(mFirstVisibleItem, mVisibleRange, mChildren.size()-1); // don't count the scroll bar child as a list item 00400 00401 } 00402 void ListGuiElement::scrollPerformed(ScrollEvent* se) 00403 { 00404 mFirstVisibleItem = se->getTopVisible(); 00405 layoutItems(); 00406 } 00407 00408 00409 00410 void ListGuiElement::setSelectedItem(GuiElement* item) 00411 { 00412 if (mSelectedElement) 00413 { 00414 setSelectedItem(mSelectedElement,false); 00415 } 00416 00417 mSelectedElement = item; 00418 setSelectedItem(mSelectedElement,true); 00419 if (mScrollBar) 00420 mScrollBar->scrollToIndex(getSelectedIndex()); 00421 } 00422 00423 void ListGuiElement::setSelectedIndex(size_t index) 00424 { 00425 if (mSelectedElement) 00426 { 00427 setSelectedItem(mSelectedElement,false); 00428 } 00429 00430 if (index < 0) 00431 { 00432 index = 0; 00433 } 00434 else if (index > getListSize()) 00435 { 00436 index = getListSize(); 00437 } 00438 00439 ChildIterator it = getChildIterator(); 00440 unsigned int indexCount = 0; 00441 while (it.hasMoreElements()) 00442 { 00443 GuiElement* currentElement = it.getNext(); 00444 if (currentElement->getName() == mName + "/ScrollBar") 00445 { 00446 continue; 00447 } 00448 if (indexCount == index) 00449 { 00450 mSelectedElement = static_cast<GuiContainer*>(currentElement)->getChildIterator().getNext(); 00451 break; 00452 } 00453 indexCount++; 00454 } 00455 00456 00457 setSelectedItem(mSelectedElement,true); 00458 if (mScrollBar) 00459 mScrollBar->scrollToIndex(index); 00460 } 00461 00462 00463 void ListGuiElement::setSelectedItem(GuiElement* item, bool on) 00464 { 00465 if (item != NULL) 00466 { 00467 00468 if (on) 00469 { 00470 item->getParent()->setMaterialName(mItemPanelMaterialSelected); 00471 } 00472 else 00473 { 00474 if (mItemPanelMaterial == "") 00475 00476 00477 { 00478 // default to the list material 00479 item->getParent()->setMaterialName(mMaterialName); 00480 } 00481 else 00482 { 00483 item->getParent()->setMaterialName(mItemPanelMaterial); 00484 00485 00486 } 00487 00488 } 00489 } 00490 00491 } 00492 void ListGuiElement::mouseDragged(MouseEvent* e) 00493 { 00494 // test to see if list should scroll up 00495 if ((e->getY() < _getDerivedTop() )&& (mFirstVisibleItem > 0)) 00496 { 00497 setSelectedIndex(mFirstVisibleItem-1); 00498 } 00499 00500 // test to see if list should scroll down 00501 if ((e->getY() > _getDerivedTop() + getHeight()) && (mFirstVisibleItem + mVisibleRange < getListSize())) 00502 { 00503 setSelectedIndex(mFirstVisibleItem+mVisibleRange+1); 00504 } 00505 else 00506 { 00507 GuiElement *dragTarget = findElementAt(e->getX(), e->getY()); 00508 if (dragTarget != NULL) 00509 { 00510 if ((dragTarget->getParent() == this) && // is the dragTarget a child of ListGui? 00511 (dragTarget != mScrollBar) && // ignore dragging onto the scrollbar 00512 (dragTarget != mSelectedElement->getParent())) // is this list item not already selected 00513 00514 { 00515 // drag target is a backpanel for a list item 00516 // get the child of the backpanel (backpanel is a container).. there is only 1 child 00517 setSelectedItem(static_cast<GuiContainer*>(dragTarget)->getChildIterator().getNext()); 00518 00519 00520 } 00521 } 00522 } 00523 } 00524 void ListGuiElement::mouseMoved(MouseEvent* e) 00525 { 00526 00527 00528 00529 } 00530 void ListGuiElement::mousePressed(MouseEvent* e) 00531 { 00532 if (mSelectedElement) 00533 { 00534 setSelectedItem(mSelectedElement,false); 00535 00536 00537 } 00538 00539 GuiContainer* backPanelSelected = static_cast<GuiContainer*>(static_cast<MouseTarget*>(e->getSource())); 00540 00541 // get the child of the backpanel.. there is only 1 child 00542 mSelectedElement = backPanelSelected->getChildIterator().getNext(); 00543 setSelectedItem(mSelectedElement,true); 00544 } 00545 00546 void ListGuiElement::setSelectedItem(Resource* r) 00547 { 00548 GuiContainer* backPanel = static_cast<GuiContainer*> (getChild(getListItemPanelName(r))); 00549 00550 setSelectedItem(backPanel->getChild(getListItemName(r))); 00551 } 00552 00553 void ListGuiElement::setSelectedItem(Resource* r, bool on) 00554 { 00555 GuiContainer* backPanel = static_cast<GuiContainer*> (getChild(getListItemPanelName(r))); 00556 00557 setSelectedItem(backPanel->getChild(getListItemName(r)), on); 00558 } 00559 00560 Resource* ListGuiElement::getSelectedItem() 00561 { 00562 Resource* selectedResource = NULL; 00563 ResourceList::iterator i; 00564 if (mSelectedElement != NULL) 00565 { 00566 00567 for (i = mResourceList.begin(); i != mResourceList.end(); ++i) 00568 { 00569 if ((*i)->getName() == mSelectedElement->getCaption()) 00570 { 00571 selectedResource = *i; 00572 break; 00573 } 00574 } 00575 } 00576 return selectedResource; 00577 } 00578 00579 int ListGuiElement::getSelectedIndex() const 00580 { 00581 int selectedIndex = -1; 00582 if (mSelectedElement != NULL) 00583 { 00584 ResourceList::const_iterator i; 00585 int currentIndex = 0; 00586 for (i = mResourceList.begin(); i != mResourceList.end(); ++i, currentIndex++) 00587 { 00588 if ((*i)->getName() == mSelectedElement->getCaption()) 00589 { 00590 selectedIndex = currentIndex; 00591 break; 00592 } 00593 } 00594 } 00595 return selectedIndex; 00596 } 00597 00598 00599 00600 ResourceListConstIterator ListGuiElement::getConstIterator() const 00601 { 00602 return ResourceListConstIterator(mResourceList.begin()); 00603 } 00604 00605 ResourceListConstIterator ListGuiElement::getConstEndIterator() const 00606 { 00607 return ResourceListConstIterator(mResourceList.end()); 00608 } 00609 Resource* ListGuiElement::popFront() 00610 { 00611 Resource* r = mResourceList.front(); 00612 mResourceList.pop_front(); 00613 00614 return r; 00615 } 00616 00617 size_t ListGuiElement::getListSize() const 00618 { 00619 return mResourceList.size(); 00620 } 00621 00622 const String& ListGuiElement::getTypeName(void) const 00623 { 00624 return msTypeName; 00625 } 00626 00627 00628 } 00629 00630 00631
Copyright © 2002-2003 by The OGRE Team
Last modified Fri May 14 23:22:19 2004