guiBTViewCtrl.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2014 Guy Allard
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // 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 DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "guiBTViewCtrl.h"
  23. #include "gfx/gfxDrawUtil.h"
  24. #include "gui/worldEditor/editorIconRegistry.h"
  25. #include "gui/controls/guiTextEditCtrl.h"
  26. using namespace BadBehavior;
  27. IMPLEMENT_CONOBJECT(GuiBehaviorTreeViewCtrl);
  28. void GuiBehaviorTreeViewCtrl::onRenderCell(Point2I offset, Point2I cell, bool, bool )
  29. {
  30. if( !mVisibleItems.size() )
  31. return;
  32. // Do some sanity checking and data retrieval.
  33. AssertFatal(cell.y < mVisibleItems.size(), "GuiTreeViewCtrl::onRenderCell: invalid cell");
  34. Item * item = mVisibleItems[cell.y];
  35. // If there's no object, deal with it.
  36. if(item->isInspectorData())
  37. if(!item->getObject())
  38. return;
  39. RectI drawRect( offset, mCellSize );
  40. GFXDrawUtil *drawer = GFX->getDrawUtil();
  41. drawer->clearBitmapModulation();
  42. FrameAllocatorMarker txtBuff;
  43. // Ok, we have the item. There are a few possibilities at this point:
  44. // - We need to draw inheritance lines and a treeview-chosen icon
  45. // OR
  46. // - We have to draw an item-dependent icon
  47. // - If we're mouseover, we have to highlight it.
  48. //
  49. // - We have to draw the text for the item
  50. // - Taking into account various mouseover states
  51. // - Taking into account the value (set or not)
  52. // - If it's an inspector data, we have to do some custom rendering
  53. // - ADDED: If it is being renamed, we also have custom rendering.
  54. // Ok, first draw the tab and icon.
  55. // Do we draw the tree lines?
  56. if( mFlags.test(ShowTreeLines) )
  57. {
  58. drawRect.point.x += ( mTabSize * item->mTabLevel );
  59. Item* parent = item->mParent;
  60. for ( S32 i = item->mTabLevel; ( parent && i > 0 ); i-- )
  61. {
  62. drawRect.point.x -= mTabSize;
  63. if ( parent->mNext )
  64. drawer->drawBitmapSR( mProfile->mTextureObject, drawRect.point, mProfile->mBitmapArrayRects[BmpLine] );
  65. parent = parent->mParent;
  66. }
  67. }
  68. // Now, the icon...
  69. drawRect.point.x = offset.x + mTabSize * item->mTabLevel;
  70. // First, draw the rollover glow, if it's an inner node.
  71. if ( item->isParent() && item->mState.test( Item::MouseOverBmp ) )
  72. drawer->drawBitmapSR( mProfile->mTextureObject, drawRect.point, mProfile->mBitmapArrayRects[BmpGlow] );
  73. // Now, do we draw a treeview-selected item or an item dependent one?
  74. S32 newOffset = 0; // This is stored so we can render glow, then update render pos.
  75. S32 bitmap = 0;
  76. // Ok, draw the treeview lines as appropriate.
  77. bool drawBitmap = true;
  78. if ( !item->isParent() )
  79. {
  80. if( mFlags.test( ShowTreeLines ) )
  81. {
  82. if( ( item->mNext && item->mPrevious )
  83. || ( item->mNext && item->mParent && ( !_isRootLevelItem( item ) || mShowRoot ) ) )
  84. bitmap = BmpChild;
  85. else if( item->mNext && ( !item->mParent || !mShowRoot ) )
  86. bitmap = BmpFirstChild;
  87. else if( item->mPrevious || ( item->mParent && !_isRootLevelItem( item ) ) )
  88. bitmap = BmpLastChild;
  89. else
  90. drawBitmap = false;
  91. }
  92. else
  93. drawBitmap = false;
  94. }
  95. else
  96. {
  97. bitmap = item->isExpanded() ? BmpExp : BmpCon;
  98. if( mFlags.test( ShowTreeLines ) )
  99. {
  100. // Shift indices to show versions with tree lines.
  101. if ( item->mParent || item->mPrevious )
  102. bitmap += ( item->mNext ? 3 : 2 );
  103. else
  104. bitmap += ( item->mNext ? 1 : 0 );
  105. }
  106. }
  107. if( ( bitmap >= 0 ) && ( bitmap < mProfile->mBitmapArrayRects.size() ) )
  108. {
  109. if( drawBitmap )
  110. drawer->drawBitmapSR( mProfile->mTextureObject, drawRect.point, mProfile->mBitmapArrayRects[bitmap] );
  111. newOffset = mProfile->mBitmapArrayRects[bitmap].extent.x;
  112. }
  113. if(item->isInspectorData())
  114. {
  115. // draw lock icon if need be
  116. S32 icon = Lock1;
  117. S32 icon2 = Hidden;
  118. if (item->getObject() && item->getObject()->isLocked())
  119. {
  120. if (mIconTable[icon])
  121. {
  122. //drawRect.point.x = offset.x + mTabSize * item->mTabLevel + mIconTable[icon].getWidth();
  123. drawRect.point.x += mIconTable[icon].getWidth();
  124. drawer->drawBitmap( mIconTable[icon], drawRect.point );
  125. }
  126. }
  127. if (item->getObject() && item->getObject()->isHidden())
  128. {
  129. if (mIconTable[icon2])
  130. {
  131. //drawRect.point.x = offset.x + mTabSize * item->mTabLevel + mIconTable[icon].getWidth();
  132. drawRect.point.x += mIconTable[icon2].getWidth();
  133. drawer->drawBitmap( mIconTable[icon2], drawRect.point );
  134. }
  135. }
  136. /*SimObject * pObject = item->getObject();
  137. SimGroup * pGroup = ( pObject == NULL ) ? NULL : dynamic_cast<SimGroup*>( pObject );
  138. // If this item is a VirtualParent we can use the generic SimGroup123 icons.
  139. // However if there is already an icon in the EditorIconRegistry for this
  140. // exact class (not counting parent class icons) we want to use that instead.
  141. bool hasClassIcon = gEditorIcons.hasIconNoRecurse( pObject );
  142. // draw the icon associated with the item
  143. if ( !hasClassIcon && item->mState.test(Item::VirtualParent))
  144. {
  145. if ( pGroup != NULL)
  146. {
  147. if (item->isExpanded())
  148. item->mIcon = SimGroup1;
  149. else
  150. item->mIcon = SimGroup2;
  151. }
  152. else
  153. item->mIcon = SimGroup2;
  154. }
  155. if ( !hasClassIcon && item->mState.test(Item::Marked))
  156. {
  157. if (item->isInspectorData())
  158. {
  159. if ( pGroup != NULL )
  160. {
  161. if (item->isExpanded())
  162. item->mIcon = SimGroup3;
  163. else
  164. item->mIcon = SimGroup4;
  165. }
  166. }
  167. }*/
  168. GFXTexHandle iconHandle;
  169. if ( ( item->mIcon != -1 ) && mIconTable[item->mIcon] )
  170. iconHandle = mIconTable[item->mIcon];
  171. #ifdef TORQUE_TOOLS
  172. else
  173. iconHandle = gEditorIcons.findIcon( item->getObject() );
  174. #endif
  175. if ( iconHandle.isValid() )
  176. {
  177. S32 iconHeight = (mItemHeight - iconHandle.getHeight()) / 2;
  178. S32 oldHeight = drawRect.point.y;
  179. if(iconHeight > 0)
  180. drawRect.point.y += iconHeight;
  181. drawRect.point.x += iconHandle.getWidth();
  182. drawer->drawBitmap( iconHandle, drawRect.point );
  183. drawRect.point.y = oldHeight;
  184. }
  185. }
  186. else
  187. {
  188. S32 icon = item->isExpanded() ? item->mScriptInfo.mExpandedImage : item->mScriptInfo.mNormalImage;
  189. if ( icon )
  190. {
  191. if (mIconTable[icon])
  192. {
  193. S32 iconHeight = (mItemHeight - mIconTable[icon].getHeight()) / 2;
  194. S32 oldHeight = drawRect.point.y;
  195. if(iconHeight > 0)
  196. drawRect.point.y += iconHeight;
  197. drawRect.point.x += mIconTable[icon].getWidth();
  198. drawer->drawBitmap( mIconTable[icon], drawRect.point );
  199. drawRect.point.y = oldHeight;
  200. }
  201. }
  202. }
  203. // Ok, update offset so we can render some text!
  204. drawRect.point.x += newOffset;
  205. // Ok, now we're off to rendering the actual data for the treeview item.
  206. U32 bufLen = 1024; //item->mDataRenderWidth + 1;
  207. char *displayText = (char *)txtBuff.alloc(bufLen);
  208. displayText[bufLen-1] = 0;
  209. item->getDisplayText(bufLen, displayText);
  210. // Draw the rollover/selected bitmap, if one was specified.
  211. drawRect.extent.x = mProfile->mFont->getStrWidth( displayText ) + ( 2 * mTextOffset );
  212. if ( item->mState.test( Item::Selected ) && mTexSelected )
  213. drawer->drawBitmapStretch( mTexSelected, drawRect );
  214. else if ( item->mState.test( Item::MouseOverText ) && mTexRollover )
  215. drawer->drawBitmapStretch( mTexRollover, drawRect );
  216. // Offset a bit so as to space text properly.
  217. drawRect.point.x += mTextOffset;
  218. // Determine what color the font should be.
  219. ColorI fontColor;
  220. fontColor = item->mState.test( Item::Selected ) ? mProfile->mFontColorSEL :
  221. ( item->mState.test( Item::MouseOverText ) ? mProfile->mFontColorHL : mProfile->mFontColor );
  222. if (item->mState.test(Item::Selected))
  223. {
  224. drawer->drawRectFill(drawRect, mProfile->mFillColorSEL);
  225. }
  226. else if (item->mState.test(Item::MouseOverText))
  227. {
  228. drawer->drawRectFill(drawRect, mProfile->mFillColorHL);
  229. }
  230. if( item->mState.test(Item::MouseOverText) )
  231. {
  232. fontColor = mProfile->mFontColorHL;
  233. }
  234. drawer->setBitmapModulation( fontColor );
  235. // Center the text horizontally.
  236. S32 height = (mItemHeight - mProfile->mFont->getHeight()) / 2;
  237. if(height > 0)
  238. drawRect.point.y += height;
  239. // JDD - offset by two pixels or so to keep the text from rendering RIGHT ONTOP of the outline
  240. drawRect.point.x += 2;
  241. drawer->drawText( mProfile->mFont, drawRect.point, displayText, mProfile->mFontColors );
  242. if ( mRenamingItem == item && mRenameCtrl )
  243. {
  244. Point2I ctrPos = globalToLocalCoord( drawRect.point );
  245. ctrPos.y -= height;
  246. ctrPos.x -= 2;
  247. Point2I ctrExtent( getWidth() - ctrPos.x, drawRect.extent.y );
  248. mRenameCtrl->setPosition( ctrPos );
  249. mRenameCtrl->setExtent( ctrExtent );
  250. mRenameCtrl->setVisible( true );
  251. }
  252. }