Torque3D Documentation / _generateds / guiPopUpCtrl.cpp

guiPopUpCtrl.cpp

Engine/source/gui/controls/guiPopUpCtrl.cpp

More...

Public Variables

colorWhite (255, 255, 255)

Public Functions

ConsoleDocClass(GuiPopUpMenuCtrl , "@brief A <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> that allows <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> select <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> from <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> drop-down <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">list.\n\n</a>" "For <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> nearly identical GUI with additional features, use <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiPopUpMenuCtrlEx.\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "<a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classguipopupmenuctrl/">GuiPopUpMenuCtrl</a>()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " maxPopupHeight=\"200\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "  sbUsesNAColor = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "  reverseTextList = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "  bitmapBounds = \"16 16\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "  maxLength = \"1024\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "  position = \"56 31\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "  extent = \"64 64\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "  minExtent = \"8 2\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "  profile = \"GuiPopUpMenuProfile\";\n" "  tooltipProfile = \"GuiToolTipProfile\";\n" "};\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@note This is definitely going <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be deprecated <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">soon.\n\n</a>" "@see <a href="/coding/class/classguipopupmenuctrlex/">GuiPopUpMenuCtrlEx</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> more features and better <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">explanations.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiControls\n</a>" )
DefineEngineMethod(GuiPopUpMenuCtrl , add , void , (const char *name, S32 idNum, U32 scheme) , ("", -1, 0) , "(string name, int idNum, int scheme=0)" )
DefineEngineMethod(GuiPopUpMenuCtrl , addScheme , void , (U32 id, ColorI fontColor, ColorI fontColorHL, ColorI fontColorSEL) , "(int <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a>, <a href="/coding/class/classcolori/">ColorI</a> fontColor, <a href="/coding/class/classcolori/">ColorI</a> fontColorHL, <a href="/coding/class/classcolori/">ColorI</a> fontColorSEL)" )
DefineEngineMethod(GuiPopUpMenuCtrl , changeTextById , void , (S32 id, const char *text) , "( int <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a>, string text )" )
DefineEngineMethod(GuiPopUpMenuCtrl , clear , void , () , "Clear the popup list." )
DefineEngineMethod(GuiPopUpMenuCtrl , clearEntry , void , (S32 entry) , "(S32 entry)" )
DefineEngineMethod(GuiPopUpMenuCtrl , findText , S32 , (const char *text) , "(string text)" "Returns the position of the first entry containing the specified text or -1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not found." )
DefineEngineMethod(GuiPopUpMenuCtrl , forceClose , void , () , "" )
DefineEngineMethod(GuiPopUpMenuCtrl , forceOnAction , void , () , "" )
DefineEngineMethod(GuiPopUpMenuCtrl , getSelected , S32 , () , "Gets the selected index" )
DefineEngineMethod(GuiPopUpMenuCtrl , getText , const char * , () , "" )
DefineEngineMethod(GuiPopUpMenuCtrl , getTextById , const char * , (S32 id) , "(int <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a>)" )
DefineEngineMethod(GuiPopUpMenuCtrl , replaceText , void , (bool doReplaceText) , "(bool doReplaceText)" )
DefineEngineMethod(GuiPopUpMenuCtrl , setEnumContent , void , (const char *className, const char *enumName) , "(string class, string enum)" "This fills the popup with <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> classrep's field enumeration type <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">info.\n\n</a>" "More of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> helper function than anything. If console access <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the field list is added, " "at least <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the enumerated types, then this should go away.." )
DefineEngineMethod(GuiPopUpMenuCtrl , setFirstSelected , void , (bool scriptCallback) , (true) , "([scriptCallback=true])" )
DefineEngineMethod(GuiPopUpMenuCtrl , setNoneSelected , void , () , "" )
DefineEngineMethod(GuiPopUpMenuCtrl , setSelected , void , (S32 id, bool scriptCallback) , (true) , "(int <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a>, [scriptCallback=true])" )
DefineEngineMethod(GuiPopUpMenuCtrl , size , S32 , () , "Get the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1ab7d671599a7b25ca99a487fa341bc33a">size</a> of the menu - the number of entries in it." )
DefineEngineMethod(GuiPopUpMenuCtrl , sort , void , () , "Sort the list alphabetically." )
DefineEngineMethod(GuiPopUpMenuCtrl , sortID , void , () , "Sort the list by ID." )
const char *
getColumn(const char * string, char * returnbuff, U32 index, const char * set)
getColumnCount(const char * string, const char * set)

Detailed Description

Public Variables

ColorI colorWhite (255, 255, 255)

Public Functions

ConsoleDocClass(GuiPopUpMenuCtrl , "@brief A <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> that allows <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> select <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> from <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> drop-down <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">list.\n\n</a>" "For <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> nearly identical GUI with additional features, use <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiPopUpMenuCtrlEx.\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "<a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classguipopupmenuctrl/">GuiPopUpMenuCtrl</a>()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " maxPopupHeight=\"200\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "  sbUsesNAColor = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "  reverseTextList = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "  bitmapBounds = \"16 16\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "  maxLength = \"1024\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "  position = \"56 31\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "  extent = \"64 64\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "  minExtent = \"8 2\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "  profile = \"GuiPopUpMenuProfile\";\n" "  tooltipProfile = \"GuiToolTipProfile\";\n" "};\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@note This is definitely going <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be deprecated <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">soon.\n\n</a>" "@see <a href="/coding/class/classguipopupmenuctrlex/">GuiPopUpMenuCtrlEx</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> more features and better <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">explanations.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiControls\n</a>" )

DefineEngineMethod(GuiPopUpMenuCtrl , add , void , (const char *name, S32 idNum, U32 scheme) , ("", -1, 0) , "(string name, int idNum, int scheme=0)" )

DefineEngineMethod(GuiPopUpMenuCtrl , addScheme , void , (U32 id, ColorI fontColor, ColorI fontColorHL, ColorI fontColorSEL) , "(int <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a>, <a href="/coding/class/classcolori/">ColorI</a> fontColor, <a href="/coding/class/classcolori/">ColorI</a> fontColorHL, <a href="/coding/class/classcolori/">ColorI</a> fontColorSEL)" )

DefineEngineMethod(GuiPopUpMenuCtrl , changeTextById , void , (S32 id, const char *text) , "( int <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a>, string text )" )

DefineEngineMethod(GuiPopUpMenuCtrl , clear , void , () , "Clear the popup list." )

DefineEngineMethod(GuiPopUpMenuCtrl , clearEntry , void , (S32 entry) , "(S32 entry)" )

DefineEngineMethod(GuiPopUpMenuCtrl , findText , S32 , (const char *text) , "(string text)" "Returns the position of the first entry containing the specified text or -1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not found." )

DefineEngineMethod(GuiPopUpMenuCtrl , forceClose , void , () , "" )

DefineEngineMethod(GuiPopUpMenuCtrl , forceOnAction , void , () , "" )

DefineEngineMethod(GuiPopUpMenuCtrl , getSelected , S32 , () , "Gets the selected index" )

DefineEngineMethod(GuiPopUpMenuCtrl , getText , const char * , () , "" )

DefineEngineMethod(GuiPopUpMenuCtrl , getTextById , const char * , (S32 id) , "(int <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a>)" )

DefineEngineMethod(GuiPopUpMenuCtrl , replaceText , void , (bool doReplaceText) , "(bool doReplaceText)" )

DefineEngineMethod(GuiPopUpMenuCtrl , setEnumContent , void , (const char *className, const char *enumName) , "(string class, string enum)" "This fills the popup with <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> classrep's field enumeration type <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">info.\n\n</a>" "More of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> helper function than anything. If console access <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the field list is added, " "at least <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the enumerated types, then this should go away.." )

DefineEngineMethod(GuiPopUpMenuCtrl , setFirstSelected , void , (bool scriptCallback) , (true) , "([scriptCallback=true])" )

DefineEngineMethod(GuiPopUpMenuCtrl , setNoneSelected , void , () , "" )

DefineEngineMethod(GuiPopUpMenuCtrl , setSelected , void , (S32 id, bool scriptCallback) , (true) , "(int <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a>, [scriptCallback=true])" )

DefineEngineMethod(GuiPopUpMenuCtrl , size , S32 , () , "Get the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1ab7d671599a7b25ca99a487fa341bc33a">size</a> of the menu - the number of entries in it." )

DefineEngineMethod(GuiPopUpMenuCtrl , sort , void , () , "Sort the list alphabetically." )

DefineEngineMethod(GuiPopUpMenuCtrl , sortID , void , () , "Sort the list by ID." )

getColumn(const char * string, char * returnbuff, U32 index, const char * set)

getColumnCount(const char * string, const char * set)

idCompare(const void * a, const void * b)

IMPLEMENT_CONOBJECT(GuiPopUpMenuCtrl )

textCompare(const void * a, const void * b)

   1
   2//-----------------------------------------------------------------------------
   3// Copyright (c) 2012 GarageGames, LLC
   4//
   5// Permission is hereby granted, free of charge, to any person obtaining a copy
   6// of this software and associated documentation files (the "Software"), to
   7// deal in the Software without restriction, including without limitation the
   8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   9// sell copies of the Software, and to permit persons to whom the Software is
  10// furnished to do so, subject to the following conditions:
  11//
  12// The above copyright notice and this permission notice shall be included in
  13// all copies or substantial portions of the Software.
  14//
  15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21// IN THE SOFTWARE.
  22//-----------------------------------------------------------------------------
  23
  24#include "gui/core/guiCanvas.h"
  25#include "gui/controls/guiPopUpCtrl.h"
  26#include "console/consoleTypes.h"
  27#include "console/engineAPI.h"
  28#include "gui/core/guiDefaultControlRender.h"
  29#include "gfx/primBuilder.h"
  30#include "gfx/gfxDrawUtil.h"
  31#include "console/engineAPI.h"
  32
  33static ColorI colorWhite(255,255,255); //  Added
  34
  35// Function to return the number of columns in 'string' given delimeters in 'set'
  36static U32 getColumnCount(const char *string, const char *set)
  37{
  38   U32 count = 0;
  39   U8 last = 0;
  40   while(*string)
  41   {
  42      last = *string++;
  43
  44      for(U32 i =0; set[i]; i++)
  45      {
  46         if(last == set[i])
  47         {
  48            count++;
  49            last = 0;
  50            break;
  51         }   
  52      }
  53   }
  54   if(last)
  55      count++;
  56   return count;
  57}   
  58
  59// Function to return the 'index' column from 'string' given delimeters in 'set'
  60static const char *getColumn(const char *string, char* returnbuff, U32 index, const char *set)
  61{
  62   U32 sz;
  63   while(index--)
  64   {
  65      if(!*string)
  66         return "";
  67      sz = dStrcspn(string, set);
  68      if (string[sz] == 0)
  69         return "";
  70      string += (sz + 1);    
  71   }
  72   sz = dStrcspn(string, set);
  73   if (sz == 0)
  74      return "";
  75   char *ret = returnbuff;
  76   dStrncpy(ret, string, sz);
  77   ret[sz] = '\0';
  78   return ret;
  79}   
  80
  81GuiPopUpBackgroundCtrl::GuiPopUpBackgroundCtrl(GuiPopUpMenuCtrl *ctrl, GuiPopupTextListCtrl *textList)
  82{
  83   mPopUpCtrl = ctrl;
  84   mTextList = textList;
  85}
  86
  87void GuiPopUpBackgroundCtrl::onMouseDown(const GuiEvent &event)
  88{
  89   mPopUpCtrl->mBackgroundCancel = true; //  Set that the user didn't click within the text list.  Replaces the line above.
  90   mPopUpCtrl->closePopUp();
  91}
  92
  93//------------------------------------------------------------------------------
  94GuiPopupTextListCtrl::GuiPopupTextListCtrl()
  95{
  96   mPopUpCtrl = NULL;
  97}
  98
  99
 100//------------------------------------------------------------------------------
 101GuiPopupTextListCtrl::GuiPopupTextListCtrl(GuiPopUpMenuCtrl *ctrl)
 102{
 103   mPopUpCtrl = ctrl;
 104}
 105
 106//------------------------------------------------------------------------------
 107
 108//------------------------------------------------------------------------------
 109//void GuiPopUpTextListCtrl::onCellSelected( Point2I /*cell*/ )
 110//{
 111//   // Do nothing, the parent control will take care of everything...
 112//}
 113void GuiPopupTextListCtrl::onCellSelected( Point2I cell )
 114{
 115   //  The old function is above.  This new one will only call the the select
 116   //      functions if we were not cancelled by a background click.
 117
 118   //  Check if we were cancelled by the user clicking on the Background ie: anywhere
 119   //      other than within the text list.
 120   if(mPopUpCtrl->mBackgroundCancel)
 121      return;
 122
 123   if( isMethod( "onSelect" ) )
 124      Con::executef(this, "onSelect", Con::getFloatArg(cell.x), Con::getFloatArg(cell.y));
 125
 126   //call the console function
 127   execConsoleCallback();
 128   //if (mConsoleCommand[0])
 129   //   Con::evaluate(mConsoleCommand, false);
 130
 131}
 132
 133//------------------------------------------------------------------------------
 134bool GuiPopupTextListCtrl::onKeyDown(const GuiEvent &event)
 135{
 136   //if the control is a dead end, don't process the input:
 137   if ( !mVisible || !mActive || !mAwake )
 138      return false;
 139
 140   //see if the key down is a <return> or not
 141   if ( event.modifier == 0 )
 142   {
 143      if ( event.keyCode == KEY_RETURN )
 144      {
 145         mPopUpCtrl->closePopUp();
 146         return true;
 147      }
 148      else if ( event.keyCode == KEY_ESCAPE )
 149      {
 150         mSelectedCell.set( -1, -1 );
 151         mPopUpCtrl->closePopUp();
 152         return true;
 153      }
 154   }
 155
 156   //otherwise, pass the event to it's parent
 157   return Parent::onKeyDown(event);
 158}
 159
 160void GuiPopupTextListCtrl::onMouseUp(const GuiEvent &event)
 161{
 162   Parent::onMouseUp( event );
 163   mPopUpCtrl->closePopUp();
 164}
 165
 166//------------------------------------------------------------------------------
 167void GuiPopupTextListCtrl::onRenderCell(Point2I offset, Point2I cell, bool selected, bool mouseOver)
 168{
 169   Point2I size;
 170   getCellSize( size );
 171
 172   // Render a background color for the cell
 173   if ( mouseOver )
 174   {      
 175      RectI cellR( offset.x, offset.y, size.x, size.y );
 176      GFX->getDrawUtil()->drawRectFill( cellR, mProfile->mFillColorHL );
 177
 178   }
 179   else if ( selected )
 180   {
 181      RectI cellR( offset.x, offset.y, size.x, size.y );
 182      GFX->getDrawUtil()->drawRectFill( cellR, mProfile->mFillColorSEL );
 183   }
 184
 185   //  Define the default x offset for the text
 186   U32 textXOffset = offset.x + mProfile->mTextOffset.x;
 187
 188   //  Do we also draw a colored box beside the text?
 189   ColorI boxColor;
 190   bool drawbox = mPopUpCtrl->getColoredBox( boxColor, mList[cell.y].id);
 191   if(drawbox)
 192   {
 193      Point2I coloredboxsize(15,10);
 194      RectI boxBounds(offset.x + mProfile->mTextOffset.x, offset.y+2, coloredboxsize.x, coloredboxsize.y);
 195      GFX->getDrawUtil()->drawRectFill(boxBounds, boxColor);
 196      GFX->getDrawUtil()->drawRect(boxBounds, ColorI(0,0,0));
 197
 198      textXOffset += coloredboxsize.x + mProfile->mTextOffset.x;
 199   }
 200
 201   ColorI fontColor;
 202   mPopUpCtrl->getFontColor( fontColor, mList[cell.y].id, selected, mouseOver );
 203
 204   GFX->getDrawUtil()->setBitmapModulation( fontColor );
 205   //GFX->drawText( mFont, Point2I( offset.x + 4, offset.y ), mList[cell.y].text );
 206
 207   //  Get the number of columns in the cell
 208   S32 colcount = getColumnCount(mList[cell.y].text, "\t");
 209
 210   //  Are there two or more columns?
 211   if(colcount >= 2)
 212   {
 213      char buff[256];
 214
 215      // Draw the first column
 216      getColumn(mList[cell.y].text, buff, 0, "\t");
 217      GFX->getDrawUtil()->drawText( mFont, Point2I( textXOffset, offset.y ), buff ); //  Used mTextOffset as a margin for the text list rather than the hard coded value of '4'.
 218
 219      // Draw the second column to the right
 220      getColumn(mList[cell.y].text, buff, 1, "\t");
 221      S32 txt_w = mFont->getStrWidth(buff);
 222
 223      GFX->getDrawUtil()->drawText( mFont, Point2I( offset.x+size.x-mProfile->mTextOffset.x-txt_w, offset.y ), buff ); //  Used mTextOffset as a margin for the text list rather than the hard coded value of '4'.
 224
 225   } else
 226   {
 227      GFX->getDrawUtil()->drawText( mFont, Point2I( textXOffset, offset.y ), mList[cell.y].text ); //  Used mTextOffset as a margin for the text list rather than the hard coded value of '4'.
 228   }
 229}
 230
 231//------------------------------------------------------------------------------
 232//------------------------------------------------------------------------------
 233
 234IMPLEMENT_CONOBJECT(GuiPopUpMenuCtrl);
 235
 236ConsoleDocClass( GuiPopUpMenuCtrl,
 237   "@brief A control that allows to select a value from a drop-down list.\n\n"
 238
 239   "For a nearly identical GUI with additional features, use GuiPopUpMenuCtrlEx.\n\n"
 240
 241   "@tsexample\n"
 242   "new GuiPopUpMenuCtrl()\n"
 243   "{\n"
 244   "  maxPopupHeight = \"200\";\n"
 245   "  sbUsesNAColor = \"0\";\n"
 246   "  reverseTextList = \"0\";\n"
 247   "  bitmapBounds = \"16 16\";\n"
 248   "  maxLength = \"1024\";\n"
 249   "  position = \"56 31\";\n"
 250   "  extent = \"64 64\";\n"
 251   "  minExtent = \"8 2\";\n"
 252   "  profile = \"GuiPopUpMenuProfile\";\n"
 253   "  tooltipProfile = \"GuiToolTipProfile\";\n"
 254   "};\n"
 255   "@endtsexample\n\n"
 256
 257   "@note This is definitely going to be deprecated soon.\n\n"
 258
 259   "@see GuiPopUpMenuCtrlEx for more features and better explanations.\n"
 260
 261   "@ingroup GuiControls\n");
 262
 263GuiPopUpMenuCtrl::GuiPopUpMenuCtrl(void)
 264{
 265   VECTOR_SET_ASSOCIATION(mEntries);
 266   VECTOR_SET_ASSOCIATION(mSchemes);
 267
 268   mSelIndex = -1;
 269   mActive = true;
 270   mMaxPopupHeight = 200;
 271   mScrollDir = GuiScrollCtrl::None;
 272   mScrollCount = 0;
 273   mLastYvalue = 0;
 274   mIncValue = 0;
 275   mRevNum = 0;
 276   mInAction = false;
 277   mMouseOver = false; //  Added
 278   mRenderScrollInNA = false; //  Added
 279   mBackgroundCancel = false; //  Added
 280   mReverseTextList = false; //  Added - Don't reverse text list if displaying up
 281   mBitmapName = StringTable->EmptyString(); //  Added
 282   mBitmapBounds.set(16, 16); //  Added
 283   mIdMax = -1;
 284   mBackground = NULL;
 285   mTl = NULL;
 286   mSc = NULL;
 287   mReplaceText = false;
 288}
 289
 290//------------------------------------------------------------------------------
 291GuiPopUpMenuCtrl::~GuiPopUpMenuCtrl()
 292{
 293}
 294
 295//------------------------------------------------------------------------------
 296void GuiPopUpMenuCtrl::initPersistFields(void)
 297{
 298   addField("maxPopupHeight",           TypeS32,          Offset(mMaxPopupHeight, GuiPopUpMenuCtrl));
 299   addField("sbUsesNAColor",            TypeBool,         Offset(mRenderScrollInNA, GuiPopUpMenuCtrl));
 300   addField("reverseTextList",          TypeBool,         Offset(mReverseTextList, GuiPopUpMenuCtrl));
 301   addField("bitmap",                   TypeFilename,     Offset(mBitmapName, GuiPopUpMenuCtrl));
 302   addField("bitmapBounds",             TypePoint2I,      Offset(mBitmapBounds, GuiPopUpMenuCtrl));
 303
 304   Parent::initPersistFields();
 305}
 306
 307//------------------------------------------------------------------------------
 308DefineEngineMethod( GuiPopUpMenuCtrl, add, void, (const char * name, S32 idNum, U32 scheme), ("", -1, 0), "(string name, int idNum, int scheme=0)")
 309{
 310   object->addEntry(name, idNum, scheme);
 311}
 312
 313DefineEngineMethod( GuiPopUpMenuCtrl, addScheme, void, (U32 id, ColorI fontColor, ColorI fontColorHL, ColorI fontColorSEL), , 
 314   "(int id, ColorI fontColor, ColorI fontColorHL, ColorI fontColorSEL)")
 315{
 316
 317   object->addScheme( id, fontColor, fontColorHL, fontColorSEL );
 318}
 319
 320DefineEngineMethod( GuiPopUpMenuCtrl, getText, const char*, (), , "")
 321{
 322   return object->getText();
 323}
 324
 325DefineEngineMethod( GuiPopUpMenuCtrl, clear, void, (), , "Clear the popup list.")
 326{
 327   object->clear();
 328}
 329
 330//FIXME: clashes with SimSet.sort
 331DefineEngineMethod(GuiPopUpMenuCtrl, sort, void, (), , "Sort the list alphabetically.")
 332{
 333   object->sort();
 334}
 335
 336//  Added to sort the entries by ID
 337DefineEngineMethod(GuiPopUpMenuCtrl, sortID, void, (), , "Sort the list by ID.")
 338{
 339   object->sortID();
 340}
 341
 342DefineEngineMethod( GuiPopUpMenuCtrl, forceOnAction, void, (), , "")
 343{
 344   object->onAction();
 345}
 346
 347DefineEngineMethod( GuiPopUpMenuCtrl, forceClose, void, (), , "")
 348{
 349   object->closePopUp();
 350}
 351
 352DefineEngineMethod( GuiPopUpMenuCtrl, getSelected, S32, (), , "Gets the selected index")
 353{
 354   return object->getSelected();
 355}
 356
 357DefineEngineMethod( GuiPopUpMenuCtrl, setSelected, void, (S32 id,  bool scriptCallback), (true), "(int id, [scriptCallback=true])")
 358{
 359   object->setSelected( id, scriptCallback );
 360}
 361
 362DefineEngineMethod( GuiPopUpMenuCtrl, setFirstSelected, void, (bool scriptCallback), (true), "([scriptCallback=true])")
 363{
 364   object->setFirstSelected( scriptCallback );
 365
 366}
 367
 368DefineEngineMethod( GuiPopUpMenuCtrl, setNoneSelected, void, (), , "")
 369{
 370   object->setNoneSelected();
 371}
 372
 373DefineEngineMethod( GuiPopUpMenuCtrl, getTextById, const char*, (S32 id), ,  "(int id)")
 374{
 375   return(object->getTextById(id));
 376}
 377
 378DefineEngineMethod( GuiPopUpMenuCtrl, changeTextById, void, ( S32 id, const char * text ), , "( int id, string text )" )
 379{
 380   object->setEntryText( id, text );
 381}
 382
 383DefineEngineMethod( GuiPopUpMenuCtrl, setEnumContent, void, (const char * className, const char * enumName), , "(string class, string enum)"
 384              "This fills the popup with a classrep's field enumeration type info.\n\n"
 385              "More of a helper function than anything.   If console access to the field list is added, "
 386              "at least for the enumerated types, then this should go away..")
 387{
 388   AbstractClassRep * classRep = AbstractClassRep::getClassList();
 389
 390   // walk the class list to get our class
 391   while(classRep)
 392   {
 393      if(!dStricmp(classRep->getClassName(), className))
 394         break;
 395      classRep = classRep->getNextClass();
 396   }
 397
 398   // get it?
 399   if(!classRep)
 400   {
 401      Con::warnf(ConsoleLogEntry::General, "failed to locate class rep for '%s'", className);
 402      return;
 403   }
 404
 405   // walk the fields to check for this one (findField checks StringTableEntry ptrs...)
 406   U32 i;
 407   for(i = 0; i < classRep->mFieldList.size(); i++)
 408      if(!dStricmp(classRep->mFieldList[i].pFieldname, enumName))
 409         break;
 410
 411   // found it?   
 412   if(i == classRep->mFieldList.size())
 413   {   
 414      Con::warnf(ConsoleLogEntry::General, "failed to locate field '%s' for class '%s'", enumName, className);
 415      return;
 416   }
 417
 418   const AbstractClassRep::Field & field = classRep->mFieldList[i];
 419   ConsoleBaseType* conType = ConsoleBaseType::getType( field.type );
 420
 421   // check the type
 422   if( !conType->getEnumTable() )
 423   {
 424      Con::warnf(ConsoleLogEntry::General, "field '%s' is not an enumeration for class '%s'", enumName, className);
 425      return;
 426   }
 427
 428   // fill it
 429   const EngineEnumTable& table = *( conType->getEnumTable() );
 430   const U32 numValues = table.getNumValues();
 431   
 432   for(i = 0; i < numValues; i++)
 433      object->addEntry( table[i].getName(), table[i] );
 434}
 435
 436//------------------------------------------------------------------------------
 437DefineEngineMethod( GuiPopUpMenuCtrl, findText, S32, (const char * text), , "(string text)"
 438              "Returns the position of the first entry containing the specified text or -1 if not found.")
 439{
 440   return( object->findText( text ) );   
 441}
 442
 443//------------------------------------------------------------------------------
 444DefineEngineMethod( GuiPopUpMenuCtrl, size, S32, (), , "Get the size of the menu - the number of entries in it.")
 445{
 446   return( object->getNumEntries() ); 
 447}
 448
 449//------------------------------------------------------------------------------
 450DefineEngineMethod( GuiPopUpMenuCtrl, replaceText, void, (bool doReplaceText), , "(bool doReplaceText)")
 451{
 452   object->replaceText(S32(doReplaceText));  
 453}
 454
 455//------------------------------------------------------------------------------
 456//  Added
 457bool GuiPopUpMenuCtrl::onWake()
 458{
 459   if ( !Parent::onWake() )
 460      return false;
 461
 462   // Set the bitmap for the popup.
 463   setBitmap( mBitmapName );
 464
 465   // Now update the Form Control's bitmap array, and possibly the child's too
 466   mProfile->constructBitmapArray();
 467
 468   if ( mProfile->getChildrenProfile() )
 469      mProfile->getChildrenProfile()->constructBitmapArray();
 470
 471   return true;
 472}
 473
 474//------------------------------------------------------------------------------
 475bool GuiPopUpMenuCtrl::onAdd()
 476{
 477   if ( !Parent::onAdd() )
 478      return false;
 479   mSelIndex = -1;
 480   mReplaceText = true;
 481   return true;
 482}
 483
 484//------------------------------------------------------------------------------
 485void GuiPopUpMenuCtrl::onSleep()
 486{
 487   mTextureNormal = NULL; //  Added
 488   mTextureDepressed = NULL; //  Added
 489   Parent::onSleep();
 490   closePopUp();  // Tests in function.
 491}
 492
 493//------------------------------------------------------------------------------
 494void GuiPopUpMenuCtrl::clear()
 495{
 496   mEntries.setSize(0);
 497   setText("");
 498   mSelIndex = -1;
 499   mRevNum = 0;
 500   mIdMax = -1;
 501}
 502
 503//------------------------------------------------------------------------------
 504void GuiPopUpMenuCtrl::clearEntry( S32 entry )
 505{  
 506   if( entry == -1 )
 507      return;
 508
 509   U32 i = 0;
 510   for ( ; i < mEntries.size(); i++ )
 511   {
 512      if ( mEntries[i].id == entry )
 513         break;
 514   }
 515
 516   mEntries.erase( i );
 517
 518   if( mEntries.size() <= 0 )
 519   {
 520      mEntries.setSize(0);
 521      setText("");
 522      mSelIndex = -1;
 523      mRevNum = 0;
 524   }
 525   else
 526   {
 527      if (entry < mSelIndex)
 528      {
 529         mSelIndex--;
 530      }
 531      else if( entry == mSelIndex )
 532      {
 533         setText("");
 534         mSelIndex = -1;
 535      }
 536   }
 537}
 538
 539//------------------------------------------------------------------------------
 540DefineEngineMethod( GuiPopUpMenuCtrl, clearEntry, void, (S32 entry), , "(S32 entry)")
 541{
 542   object->clearEntry(entry);
 543}
 544
 545//------------------------------------------------------------------------------
 546static S32 QSORT_CALLBACK textCompare(const void *a,const void *b)
 547{
 548   GuiPopUpMenuCtrl::Entry *ea = (GuiPopUpMenuCtrl::Entry *) (a);
 549   GuiPopUpMenuCtrl::Entry *eb = (GuiPopUpMenuCtrl::Entry *) (b);
 550   return (dStrnatcasecmp(ea->buf, eb->buf));
 551} 
 552
 553//  Added to sort by entry ID
 554//------------------------------------------------------------------------------
 555static S32 QSORT_CALLBACK idCompare(const void *a,const void *b)
 556{
 557   GuiPopUpMenuCtrl::Entry *ea = (GuiPopUpMenuCtrl::Entry *) (a);
 558   GuiPopUpMenuCtrl::Entry *eb = (GuiPopUpMenuCtrl::Entry *) (b);
 559   return ( (ea->id < eb->id) ? -1 : ((ea->id > eb->id) ? 1 : 0) );
 560} 
 561
 562//------------------------------------------------------------------------------
 563//  Added
 564void GuiPopUpMenuCtrl::setBitmap( const char *name )
 565{
 566   mBitmapName = StringTable->insert( name );
 567   if ( !isAwake() )
 568      return;
 569
 570   if ( *mBitmapName )
 571   {
 572      char buffer[1024];
 573      char *p;
 574      dStrcpy(buffer, name, 1024);
 575      p = buffer + dStrlen(buffer);
 576      S32 pLen = 1024 - dStrlen(buffer);
 577
 578      dStrcpy(p, "_n", pLen);
 579      mTextureNormal = GFXTexHandle( (StringTableEntry)buffer, &GFXDefaultGUIProfile, avar("%s() - mTextureNormal (line %d)", __FUNCTION__, __LINE__) );
 580
 581      dStrcpy(p, "_d", pLen);
 582      mTextureDepressed = GFXTexHandle( (StringTableEntry)buffer, &GFXDefaultGUIProfile, avar("%s() - mTextureDepressed (line %d)", __FUNCTION__, __LINE__) );
 583      if ( !mTextureDepressed )
 584         mTextureDepressed = mTextureNormal;
 585   }
 586   else
 587   {
 588      mTextureNormal = NULL;
 589      mTextureDepressed = NULL;
 590   }
 591   setUpdate();
 592}   
 593
 594//------------------------------------------------------------------------------
 595void GuiPopUpMenuCtrl::sort()
 596{
 597   S32 selId = getSelected();
 598   
 599   S32 size = mEntries.size();
 600   if( size > 0 )
 601      dQsort( mEntries.address(), size, sizeof(Entry), textCompare);
 602      
 603   if( selId != -1 )
 604      setSelected( selId, false );
 605}
 606
 607// Added to sort by entry ID
 608//------------------------------------------------------------------------------
 609void GuiPopUpMenuCtrl::sortID()
 610{
 611   S32 selId = getSelected();
 612   
 613   S32 size = mEntries.size();
 614   if( size > 0 )
 615      dQsort( mEntries.address(), size, sizeof(Entry), idCompare);
 616
 617   if( selId != -1 )
 618      setSelected( selId, false );
 619}
 620
 621//------------------------------------------------------------------------------
 622void GuiPopUpMenuCtrl::addEntry( const char *buf, S32 id, U32 scheme )
 623{
 624   if( !buf )
 625   {
 626      //Con::printf( "GuiPopupMenuCtrlEx::addEntry - Invalid buffer!" );
 627      return;
 628   }
 629   
 630   // Ensure that there are no other entries with exactly the same name
 631   for ( U32 i = 0; i < mEntries.size(); i++ )
 632   {
 633      if ( String::compare( mEntries[i].buf, buf ) == 0 )
 634         return;
 635   }
 636
 637   // If we don't give an id, create one from mIdMax
 638   if( id == -1 )
 639      id = mIdMax + 1;
 640   
 641   // Increase mIdMax when an id is greater than it
 642   if( id > mIdMax )
 643      mIdMax = id;
 644
 645   Entry e;
 646   dStrcpy( e.buf, buf, 256 );
 647   e.id = id;
 648   e.scheme = scheme;
 649
 650   // see if there is a shortcut key
 651   char * cp = dStrchr( e.buf, '~' );
 652   e.ascii = cp ? cp[1] : 0;
 653
 654   //  See if there is a colour box defined with the text
 655   char *cb = dStrchr( e.buf, '|' );
 656   if ( cb )
 657   {
 658      e.usesColorBox = true;
 659      cb[0] = '\0';
 660
 661      char* red = &cb[1];
 662      cb = dStrchr(red, '|');
 663      cb[0] = '\0';
 664      char* green = &cb[1];
 665      cb = dStrchr(green, '|');
 666      cb[0] = '\0';
 667      char* blue = &cb[1];
 668
 669      U32 r = dAtoi(red);
 670      U32 g = dAtoi(green);
 671      U32 b = dAtoi(blue);
 672
 673      e.colorbox = ColorI(r,g,b);
 674
 675   } 
 676   else
 677   {
 678      e.usesColorBox = false;
 679   }
 680
 681   mEntries.push_back(e);
 682
 683   if ( mInAction && mTl )
 684   {
 685      // Add the new entry:
 686      mTl->addEntry( e.id, e.buf );
 687      repositionPopup();
 688   }
 689}
 690
 691//------------------------------------------------------------------------------
 692void GuiPopUpMenuCtrl::addScheme( U32 id, ColorI fontColor, ColorI fontColorHL, ColorI fontColorSEL )
 693{
 694   if ( !id )
 695      return;
 696
 697   Scheme newScheme;
 698   newScheme.id = id;
 699   newScheme.fontColor = fontColor;
 700   newScheme.fontColorHL = fontColorHL;
 701   newScheme.fontColorSEL = fontColorSEL;
 702
 703   mSchemes.push_back( newScheme );
 704}
 705
 706//------------------------------------------------------------------------------
 707S32 GuiPopUpMenuCtrl::getSelected()
 708{
 709   if (mSelIndex == -1)
 710      return 0;
 711   return mEntries[mSelIndex].id;
 712}
 713
 714//------------------------------------------------------------------------------
 715bool GuiPopUpMenuCtrl::setEntryText( S32 id, const char* buf )
 716{
 717   const U32 numEntries = getNumEntries();
 718   for( U32 i = 0; i < numEntries; i++ )
 719   {
 720      if( mEntries[ i ].id == id )
 721      {
 722         Entry& entry = mEntries[ i ];
 723         dStrncpy( entry.buf, buf, sizeof( entry.buf ) );
 724         entry.buf[ sizeof( entry.buf ) - 1 ] = '\0';
 725         return true;
 726      }
 727   }
 728
 729   return false;
 730}
 731
 732//------------------------------------------------------------------------------
 733const char* GuiPopUpMenuCtrl::getTextById(S32 id)
 734{
 735   for ( U32 i = 0; i < mEntries.size(); i++ )
 736   {
 737      if ( mEntries[i].id == id )
 738         return( mEntries[i].buf );
 739   }
 740
 741   return( "" );
 742}
 743
 744//------------------------------------------------------------------------------
 745S32 GuiPopUpMenuCtrl::findText( const char* text )
 746{
 747   for ( U32 i = 0; i < mEntries.size(); i++ )
 748   {
 749      if ( String::compare( text, mEntries[i].buf ) == 0 )
 750         return( mEntries[i].id );        
 751   }
 752   return( -1 );
 753}
 754
 755//------------------------------------------------------------------------------
 756void GuiPopUpMenuCtrl::setSelected(S32 id, bool bNotifyScript )
 757{
 758   for( S32 i = 0; i < mEntries.size(); i++ )
 759   {
 760      if( id == mEntries[i].id )
 761      {
 762         i = ( mRevNum > i ) ? mRevNum - i : i;
 763         mSelIndex = i;
 764         
 765         if( mReplaceText ) //  Only change the displayed text if appropriate.
 766            setText( mEntries[ i ].buf );
 767
 768         // Now perform the popup action:
 769         
 770         if( bNotifyScript )
 771         {
 772            if( isMethod( "onSelect" ) )
 773               Con::executef( this, "onSelect", Con::getIntArg( mEntries[ mSelIndex ].id ), mEntries[mSelIndex].buf );
 774               
 775            execConsoleCallback();
 776         }
 777         
 778         return;
 779      }
 780   }
 781
 782   if( mReplaceText ) //  Only change the displayed text if appropriate.
 783   {
 784      setText("");
 785   }
 786   mSelIndex = -1;
 787
 788   if( bNotifyScript && isMethod( "onCancel" ) )
 789      Con::executef( this, "onCancel" );
 790
 791   if( id == -1 )
 792      return;
 793
 794   // Execute the popup console command:
 795   if( bNotifyScript )
 796      execConsoleCallback();
 797}
 798
 799//------------------------------------------------------------------------------
 800//  Added to set the first item as selected.
 801void GuiPopUpMenuCtrl::setFirstSelected( bool bNotifyScript )
 802{
 803   if( mEntries.size() > 0 )
 804   {
 805      mSelIndex = 0;
 806      if ( mReplaceText ) //  Only change the displayed text if appropriate.
 807      {
 808         setText( mEntries[0].buf );
 809      }
 810
 811      // Execute the popup console command:
 812      if( bNotifyScript )
 813      {
 814         if ( isMethod( "onSelect" ) )
 815            Con::executef( this, "onSelect", Con::getIntArg( mEntries[ mSelIndex ].id ), mEntries[mSelIndex].buf );
 816
 817         execConsoleCallback();
 818      }
 819   }
 820   else
 821   {
 822      if ( mReplaceText ) //  Only change the displayed text if appropriate.
 823         setText("");
 824      
 825      mSelIndex = -1;
 826
 827      if( bNotifyScript )
 828      {
 829         Con::executef( this, "onCancel" );
 830         execConsoleCallback();
 831      }
 832   }
 833}
 834
 835//------------------------------------------------------------------------------
 836//  Added to set no items as selected.
 837void GuiPopUpMenuCtrl::setNoneSelected()
 838{
 839   if ( mReplaceText ) //  Only change the displayed text if appropriate.
 840   {
 841      setText("");
 842   }
 843   mSelIndex = -1;
 844}
 845
 846//------------------------------------------------------------------------------
 847const char *GuiPopUpMenuCtrl::getScriptValue()
 848{
 849   return getText();
 850}
 851
 852//------------------------------------------------------------------------------
 853void GuiPopUpMenuCtrl::onRender( Point2I offset, const RectI &updateRect )
 854{
 855   TORQUE_UNUSED(updateRect);
 856   Point2I localStart;
 857
 858   if ( mScrollDir != GuiScrollCtrl::None )
 859      autoScroll();
 860
 861   GFXDrawUtil* drawUtil = GFX->getDrawUtil();
 862
 863   RectI baseRect( offset, getExtent() );
 864   if ( mInAction )
 865   {
 866      S32 left = baseRect.point.x, right = baseRect.point.x + baseRect.extent.x - 1;
 867      S32 top = baseRect.point.y, bottom = baseRect.point.y + baseRect.extent.y - 1;
 868
 869      // Do we render a bitmap border or lines?
 870      if ( mProfile->getChildrenProfile() && mProfile->mBitmapArrayRects.size() )
 871      {
 872         // Render the fixed, filled in border
 873         renderFixedBitmapBordersFilled(baseRect, 3, mProfile );
 874
 875      } 
 876      else
 877      {
 878         //renderSlightlyLoweredBox(r, mProfile);
 879         drawUtil->drawRectFill(baseRect, mProfile->mFillColor );
 880      }
 881
 882      //  Draw a bitmap over the background?
 883      if ( mTextureDepressed )
 884      {
 885         RectI rect(offset, mBitmapBounds);
 886         drawUtil->clearBitmapModulation();
 887         drawUtil->drawBitmapStretch( mTextureDepressed, rect );
 888      } 
 889      else if ( mTextureNormal )
 890      {
 891         RectI rect(offset, mBitmapBounds);
 892         drawUtil->clearBitmapModulation();
 893         drawUtil->drawBitmapStretch( mTextureNormal, rect );
 894      }
 895
 896      // Do we render a bitmap border or lines?
 897      if ( !( mProfile->getChildrenProfile() && mProfile->mBitmapArrayRects.size() ) )
 898      {
 899         drawUtil->drawLine(left, top, left, bottom, colorWhite );
 900         drawUtil->drawLine(left, top, right, top, colorWhite );
 901         drawUtil->drawLine(left + 1, bottom, right, bottom, mProfile->mBorderColor );
 902         drawUtil->drawLine(right, top + 1, right, bottom - 1, mProfile->mBorderColor );
 903      }
 904
 905   }
 906   else   
 907      // TODO: Implement
 908      // TODO: Add onMouseEnter() and onMouseLeave() and a definition of mMouseOver (see guiButtonBaseCtrl) for this to work.
 909      if ( mMouseOver ) 
 910      {
 911         S32 left = baseRect.point.x, right = baseRect.point.x + baseRect.extent.x - 1;
 912         S32 top = baseRect.point.y, bottom = baseRect.point.y + baseRect.extent.y - 1;
 913
 914         // Do we render a bitmap border or lines?
 915         if ( mProfile->getChildrenProfile() && mProfile->mBitmapArrayRects.size() )
 916         {
 917            // Render the fixed, filled in border
 918            renderFixedBitmapBordersFilled(baseRect, 2, mProfile );
 919
 920         } 
 921         else
 922         {
 923            drawUtil->drawRectFill(baseRect, mProfile->mFillColorHL );
 924         }
 925
 926         //  Draw a bitmap over the background?
 927         if ( mTextureNormal )
 928         {
 929            RectI rect( offset, mBitmapBounds );
 930            drawUtil->clearBitmapModulation();
 931            drawUtil->drawBitmapStretch( mTextureNormal, rect );
 932         }
 933
 934         // Do we render a bitmap border or lines?
 935         if ( !( mProfile->getChildrenProfile() && mProfile->mBitmapArrayRects.size() ) )
 936         {
 937          drawUtil->drawLine(left, top, left, bottom, colorWhite);
 938          drawUtil->drawLine(left, top, right, top, colorWhite);
 939          drawUtil->drawLine(left + 1, bottom, right, bottom, mProfile->mBorderColor);
 940          drawUtil->drawLine(right, top + 1, right, bottom - 1, mProfile->mBorderColor);
 941         }
 942      }
 943      else
 944      {
 945         // Do we render a bitmap border or lines?
 946         if ( mProfile->getChildrenProfile() && mProfile->mBitmapArrayRects.size() )
 947         {
 948            // Render the fixed, filled in border
 949            renderFixedBitmapBordersFilled(baseRect, 1, mProfile );
 950         } 
 951         else
 952         {
 953            drawUtil->drawRectFill(baseRect, mProfile->mFillColorNA );
 954         }
 955
 956         //  Draw a bitmap over the background?
 957         if ( mTextureNormal )
 958         {
 959            RectI rect(offset, mBitmapBounds);
 960            drawUtil->clearBitmapModulation();
 961            drawUtil->drawBitmapStretch( mTextureNormal, rect );
 962         }
 963
 964         // Do we render a bitmap border or lines?
 965         if ( !( mProfile->getChildrenProfile() && mProfile->mBitmapArrayRects.size() ) )
 966         {
 967            drawUtil->drawRect( baseRect, mProfile->mBorderColorNA );
 968         }
 969      }
 970      //      renderSlightlyRaisedBox(r, mProfile); //  Used to be the only 'else' condition to mInAction above.
 971
 972      S32 txt_w = mProfile->mFont->getStrWidth(mText);
 973      localStart.x = 0;
 974      localStart.y = (getHeight() - (mProfile->mFont->getHeight())) / 2;
 975
 976      // align the horizontal
 977      switch (mProfile->mAlignment)
 978      {
 979      case GuiControlProfile::RightJustify:
 980         if ( mProfile->getChildrenProfile() && mProfile->mBitmapArrayRects.size() )
 981         {
 982            // We're making use of a bitmap border, so take into account the
 983            // right cap of the border.
 984            RectI* bitmapBounds = mProfile->mBitmapArrayRects.address();
 985            localStart.x = getWidth() - bitmapBounds[2].extent.x - txt_w;
 986         } 
 987         else
 988         {
 989            localStart.x = getWidth() - txt_w;  
 990         }
 991         break;
 992      case GuiControlProfile::CenterJustify:
 993         if ( mProfile->getChildrenProfile() && mProfile->mBitmapArrayRects.size() )
 994         {
 995            // We're making use of a bitmap border, so take into account the
 996            // right cap of the border.
 997            RectI* bitmapBounds = mProfile->mBitmapArrayRects.address();
 998            localStart.x = (getWidth() - bitmapBounds[2].extent.x - txt_w) / 2;
 999
1000         } else
1001         {
1002            localStart.x = (getWidth() - txt_w) / 2;
1003         }
1004         break;
1005      default:
1006         // GuiControlProfile::LeftJustify
1007         if ( txt_w > getWidth() )
1008         {
1009            //  The width of the text is greater than the width of the control.
1010            // In this case we will right justify the text and leave some space
1011            // for the down arrow.
1012            if ( mProfile->getChildrenProfile() && mProfile->mBitmapArrayRects.size() )
1013            {
1014               // We're making use of a bitmap border, so take into account the
1015               // right cap of the border.
1016               RectI* bitmapBounds = mProfile->mBitmapArrayRects.address();
1017               localStart.x = getWidth() - bitmapBounds[2].extent.x - txt_w;
1018            } 
1019            else
1020            {
1021               localStart.x = getWidth() - txt_w - 12;
1022            }
1023         } 
1024         else
1025         {
1026            localStart.x = mProfile->mTextOffset.x; //  Use mProfile->mTextOffset as a controlable margin for the control's text.
1027         }
1028         break;
1029      }
1030
1031      //  Do we first draw a coloured box beside the text?
1032      ColorI boxColor;
1033      bool drawbox = getColoredBox( boxColor, mSelIndex);
1034      if ( drawbox )
1035      {
1036         Point2I coloredboxsize( 15, 10 );
1037         RectI boxBounds( offset.x + mProfile->mTextOffset.x, offset.y + ( (getHeight() - coloredboxsize.y ) / 2 ), coloredboxsize.x, coloredboxsize.y );
1038         drawUtil->drawRectFill(boxBounds, boxColor);
1039         drawUtil->drawRect(boxBounds, ColorI(0,0,0));
1040
1041         localStart.x += coloredboxsize.x + mProfile->mTextOffset.x;
1042      }
1043
1044      // Draw the text
1045      Point2I globalStart = localToGlobalCoord( localStart );
1046      ColorI fontColor   = mActive ? ( mInAction ? mProfile->mFontColor : mProfile->mFontColorNA ) : mProfile->mFontColorNA;
1047      drawUtil->setBitmapModulation( fontColor ); //  was: (mProfile->mFontColor);
1048
1049      //  Get the number of columns in the text
1050      S32 colcount = getColumnCount( mText, "\t" );
1051
1052      //  Are there two or more columns?
1053      if ( colcount >= 2 )
1054      {
1055         char buff[256];
1056
1057         // Draw the first column
1058         getColumn( mText, buff, 0, "\t" );
1059         drawUtil->drawText( mProfile->mFont, globalStart, buff, mProfile->mFontColors );
1060
1061         // Draw the second column to the right
1062         getColumn( mText, buff, 1, "\t" );
1063         S32 colTxt_w = mProfile->mFont->getStrWidth( buff );
1064         if ( mProfile->getChildrenProfile() && mProfile->mBitmapArrayRects.size() )
1065         {
1066            // We're making use of a bitmap border, so take into account the
1067            // right cap of the border.
1068            RectI* bitmapBounds = mProfile->mBitmapArrayRects.address();
1069            Point2I textpos = localToGlobalCoord( Point2I( getWidth() - colTxt_w - bitmapBounds[2].extent.x, localStart.y ) );
1070            drawUtil->drawText( mProfile->mFont, textpos, buff, mProfile->mFontColors );
1071
1072         } else
1073         {
1074            Point2I textpos = localToGlobalCoord( Point2I( getWidth() - colTxt_w - 12, localStart.y ) );
1075            drawUtil->drawText( mProfile->mFont, textpos, buff, mProfile->mFontColors );
1076         }
1077
1078      } else
1079      {
1080         drawUtil->drawText( mProfile->mFont, globalStart, mText, mProfile->mFontColors );
1081      }
1082
1083      // If we're rendering a bitmap border, then it will take care of the arrow.
1084      if ( !(mProfile->getChildrenProfile() && mProfile->mBitmapArrayRects.size()) )
1085      {
1086         //  Draw a triangle (down arrow)
1087         S32 left = baseRect.point.x + baseRect.extent.x - 12;
1088         S32 right = left + 8;
1089         S32 middle = left + 4;
1090         S32 top = baseRect.extent.y / 2 + baseRect.point.y - 4;
1091         S32 bottom = top + 8;
1092
1093         PrimBuild::color( mProfile->mFontColor );
1094
1095         PrimBuild::begin( GFXTriangleList, 3 );
1096            PrimBuild::vertex2fv( Point3F( (F32)left, (F32)top, 0.0f ) );
1097            PrimBuild::vertex2fv( Point3F( (F32)right, (F32)top, 0.0f ) );
1098            PrimBuild::vertex2fv( Point3F( (F32)middle, (F32)bottom, 0.0f ) );
1099         PrimBuild::end();
1100      }
1101}
1102
1103//------------------------------------------------------------------------------
1104void GuiPopUpMenuCtrl::closePopUp()
1105{
1106   if ( !mInAction )
1107      return;
1108
1109   // Get the selection from the text list:
1110   
1111   if( !mBackgroundCancel )
1112   {
1113      mSelIndex = mTl->getSelectedCell().y;
1114      mSelIndex = ( mRevNum >= mSelIndex && mSelIndex != -1 ) ? mRevNum - mSelIndex : mSelIndex;
1115      if ( mSelIndex != -1 )
1116      {
1117         if ( mReplaceText )
1118            setText( mEntries[mSelIndex].buf );
1119         setIntVariable( mEntries[mSelIndex].id );
1120      }
1121   }
1122
1123   // Release the mouse:
1124   mInAction = false;
1125   mTl->mouseUnlock();
1126
1127   // Now perform the popup action:
1128   if( mSelIndex != -1 && !mBackgroundCancel )
1129   {
1130      if ( isMethod( "onSelect" ) )
1131         Con::executef( this, "onSelect", Con::getIntArg( mEntries[ mSelIndex ].id ), mEntries[mSelIndex].buf );
1132
1133      // Execute the popup console command:
1134      execConsoleCallback();
1135   }
1136   else if ( isMethod( "onCancel" ) )
1137      Con::executef( this, "onCancel" );
1138
1139   // Pop the background:
1140   GuiCanvas *root = getRoot();
1141   if ( root )
1142      root->popDialogControl(mBackground);
1143
1144   // Kill the popup:
1145   mBackground->removeObject( mSc );
1146   mTl->deleteObject();
1147   mSc->deleteObject();
1148   mBackground->deleteObject();
1149   
1150   mBackground = NULL;
1151   mTl = NULL;
1152   mSc = NULL;
1153
1154   // Set this as the first responder:
1155   setFirstResponder();
1156}
1157
1158//------------------------------------------------------------------------------
1159bool GuiPopUpMenuCtrl::onKeyDown(const GuiEvent &event)
1160{
1161   //if the control is a dead end, don't process the input:
1162   if ( !mVisible || !mActive || !mAwake )
1163      return false;
1164
1165   //see if the key down is a <return> or not
1166   if ( event.keyCode == KEY_RETURN && event.modifier == 0 )
1167   {
1168      onAction();
1169      return true;
1170   }
1171
1172   //otherwise, pass the event to its parent
1173   return Parent::onKeyDown( event );
1174}
1175
1176//------------------------------------------------------------------------------
1177void GuiPopUpMenuCtrl::onAction()
1178{
1179   GuiControl *canCtrl = getParent();
1180
1181   addChildren();
1182
1183   GuiCanvas *root = getRoot();
1184   Point2I windowExt = root->getExtent();
1185
1186   mBackground->resize( Point2I(0,0), root->getExtent() );
1187   
1188   S32 textWidth = 0, width = getWidth();
1189   const S32 textSpace = 2;
1190   bool setScroll = false;
1191
1192   for ( U32 i = 0; i < mEntries.size(); ++i )
1193      if ( S32(mProfile->mFont->getStrWidth( mEntries[i].buf )) > textWidth )
1194         textWidth = mProfile->mFont->getStrWidth( mEntries[i].buf );
1195
1196   S32 sbWidth = mSc->getControlProfile()->mBorderThickness * 2 + mSc->scrollBarThickness(); //  Calculate the scroll bar width
1197   if ( textWidth > ( getWidth() - sbWidth-mProfile->mTextOffset.x - mSc->getChildMargin().x * 2 ) ) //  The text draw area to test against is the width of the drop-down minus the scroll bar width, the text margin and the scroll bar child margins.
1198   {
1199      textWidth +=sbWidth + mProfile->mTextOffset.x + mSc->getChildMargin().x * 2; //  The new width is the width of the text plus the scroll bar width plus the text margin size plus the scroll bar child margins.
1200      width = textWidth;
1201
1202      //  If a child margin is not defined for the scroll control, let's add
1203      //      some space between the text and scroll control for readability
1204      if(mSc->getChildMargin().x == 0)
1205         width += textSpace;
1206   }
1207
1208   mTl->setCellSize(Point2I(width, mProfile->mFont->getHeight() + textSpace));
1209
1210   for ( U32 j = 0; j < mEntries.size(); ++j )
1211      mTl->addEntry( mEntries[j].id, mEntries[j].buf );
1212
1213   if ( mSelIndex >= 0 )
1214      mTl->setSelectedCell( Point2I( 0, mSelIndex ) );
1215
1216   Point2I pointInGC = canCtrl->localToGlobalCoord( getPosition() );
1217   Point2I scrollPoint( pointInGC.x, pointInGC.y + getHeight() ); 
1218
1219   //Calc max Y distance, so Scroll Ctrl will fit on window 
1220
1221   S32 sbBorder = mSc->getControlProfile()->mBorderThickness * 2 + mSc->getChildMargin().y * 2;
1222   S32 maxYdis = windowExt.y - pointInGC.y - getHeight() - sbBorder;
1223
1224   //If scroll bars need to be added
1225   mRevNum = 0;
1226   if ( maxYdis < mTl->getHeight() + sbBorder )
1227   {
1228      //Should we pop menu list above the button
1229      if ( maxYdis < pointInGC.y )
1230      {
1231         if(mReverseTextList)
1232            reverseTextList();
1233
1234         maxYdis = pointInGC.y;
1235         //Does the menu need a scroll bar 
1236         if ( maxYdis < mTl->getHeight() + sbBorder )
1237         {
1238            setScroll = true;
1239         }
1240         //No scroll bar needed
1241         else
1242         {
1243            maxYdis = mTl->getHeight() + sbBorder;
1244         }
1245
1246         //  Added the next two lines
1247         scrollPoint.set(pointInGC.x, pointInGC.y - maxYdis); //  Used to have the following on the end: '-1);'
1248      } 
1249      //Scroll bar needed but Don't pop above button
1250      else
1251      {
1252         setScroll = true;
1253      }
1254   }
1255   //No scroll bar needed
1256   else
1257   {
1258      maxYdis = mTl->getHeight() + sbBorder;
1259   }
1260
1261   RectI newBounds = mSc->getBounds();
1262
1263   //offset it from the background so it lines up properly
1264   newBounds.point = mBackground->globalToLocalCoord( scrollPoint );
1265
1266   if ( newBounds.point.x + width > mBackground->getWidth() )
1267      if ( width - getWidth() > 0 )
1268         newBounds.point.x -= width - getWidth();
1269
1270   newBounds.extent.set( width, maxYdis );
1271   mSc->setBounds( newBounds );
1272
1273   mSc->registerObject();
1274   mTl->registerObject();
1275   mBackground->registerObject();
1276
1277   mSc->addObject( mTl );
1278   mBackground->addObject( mSc );
1279
1280   mBackgroundCancel = false; //  Setup check if user clicked on the background instead of the text list (ie: didn't want to change their current selection).
1281
1282   root->pushDialogControl( mBackground, 99 );
1283
1284   if ( setScroll )
1285   {
1286      // Resize the text list
1287     Point2I cellSize;
1288     mTl->getCellSize( cellSize );
1289     cellSize.x = width - mSc->scrollBarThickness() - sbBorder;
1290     mTl->setCellSize( cellSize );
1291     mTl->setWidth( cellSize.x );
1292
1293      if ( mSelIndex )
1294         mTl->scrollCellVisible( Point2I( 0, mSelIndex ) );
1295      else
1296         mTl->scrollCellVisible( Point2I( 0, 0 ) );
1297   }
1298
1299   mTl->setFirstResponder();
1300
1301   mInAction = true;
1302}
1303
1304//------------------------------------------------------------------------------
1305void GuiPopUpMenuCtrl::addChildren()
1306{
1307   // Create Text List.
1308   mTl = new GuiPopupTextListCtrl( this );
1309   AssertFatal( mTl, "Failed to create the GuiPopUpTextListCtrl for the PopUpMenu" );
1310   // Use the children's profile rather than the parent's profile, if it exists.
1311   mTl->setControlProfile( mProfile->getChildrenProfile() ? mProfile->getChildrenProfile() : mProfile ); 
1312   mTl->setField("noDuplicates", "false");
1313
1314   mSc = new GuiScrollCtrl;
1315   AssertFatal( mSc, "Failed to create the GuiScrollCtrl for the PopUpMenu" );
1316   GuiControlProfile *prof;
1317   if ( Sim::findObject( "GuiScrollProfile", prof ) )
1318   {
1319      mSc->setControlProfile( prof );
1320   }
1321   else
1322   {
1323      // Use the children's profile rather than the parent's profile, if it exists.
1324     mSc->setControlProfile( mProfile->getChildrenProfile() ? mProfile->getChildrenProfile() : mProfile );
1325   }
1326
1327   mSc->setField( "hScrollBar", "AlwaysOff" );
1328   mSc->setField( "vScrollBar", "dynamic" );
1329   //if(mRenderScrollInNA) //  Force the scroll control to render using fillColorNA rather than fillColor
1330   // mSc->mUseNABackground = true;
1331
1332   mBackground = new GuiPopUpBackgroundCtrl( this, mTl );
1333   AssertFatal( mBackground, "Failed to create the GuiBackgroundCtrl for the PopUpMenu" );
1334}
1335
1336//------------------------------------------------------------------------------
1337void GuiPopUpMenuCtrl::repositionPopup()
1338{
1339   if ( !mInAction || !mSc || !mTl )
1340      return;
1341
1342   // I'm not concerned with this right now...
1343}
1344
1345//------------------------------------------------------------------------------
1346void GuiPopUpMenuCtrl::reverseTextList()
1347{
1348   mTl->clear();
1349   for ( S32 i = mEntries.size()-1; i >= 0; --i )
1350      mTl->addEntry( mEntries[i].id, mEntries[i].buf );
1351
1352   // Don't lose the selected cell:
1353   if ( mSelIndex >= 0 )
1354      mTl->setSelectedCell( Point2I( 0, mEntries.size() - mSelIndex - 1 ) ); 
1355
1356   mRevNum = mEntries.size() - 1;
1357}
1358
1359//------------------------------------------------------------------------------
1360bool GuiPopUpMenuCtrl::getFontColor( ColorI &fontColor, S32 id, bool selected, bool mouseOver )
1361{
1362   U32 i;
1363   Entry* entry = NULL;
1364   for ( i = 0; i < mEntries.size(); i++ )
1365   {
1366      if ( mEntries[i].id == id )
1367      {
1368         entry = &mEntries[i];
1369         break;
1370      }
1371   }
1372
1373   if ( !entry )
1374      return( false );
1375
1376   if ( entry->scheme != 0 )
1377   {
1378      // Find the entry's color scheme:
1379      for ( i = 0; i < mSchemes.size(); i++ )
1380      {
1381         if ( mSchemes[i].id == entry->scheme )
1382         {
1383            fontColor = selected ? mSchemes[i].fontColorSEL : mouseOver ? mSchemes[i].fontColorHL : mSchemes[i].fontColor;
1384            return( true );
1385         }
1386      }
1387   }
1388
1389   // Default color scheme...
1390   fontColor = selected ? mProfile->mFontColorSEL : mouseOver ? mProfile->mFontColorHL : mProfile->mFontColorNA; //  Modified the final color choice from mProfile->mFontColor to mProfile->mFontColorNA
1391
1392   return( true );
1393}
1394
1395//------------------------------------------------------------------------------
1396//  Added
1397bool GuiPopUpMenuCtrl::getColoredBox( ColorI &fontColor, S32 id )
1398{
1399   U32 i;
1400   Entry* entry = NULL;
1401   for ( i = 0; i < mEntries.size(); i++ )
1402   {
1403      if ( mEntries[i].id == id )
1404      {
1405         entry = &mEntries[i];
1406         break;
1407      }
1408   }
1409
1410   if ( !entry )
1411      return false;
1412
1413   if ( entry->usesColorBox == false )
1414      return false;
1415
1416   fontColor = entry->colorbox;
1417
1418   return true;
1419}
1420
1421//------------------------------------------------------------------------------
1422void GuiPopUpMenuCtrl::onMouseDown( const GuiEvent &event )
1423{
1424   TORQUE_UNUSED(event);
1425
1426   if( !mVisible || !mActive || !mAwake )
1427      return;
1428
1429   onAction();
1430}
1431
1432//------------------------------------------------------------------------------
1433void GuiPopUpMenuCtrl::onMouseUp( const GuiEvent &event )
1434{
1435   TORQUE_UNUSED(event);
1436}
1437
1438//------------------------------------------------------------------------------
1439//  Added
1440void GuiPopUpMenuCtrl::onMouseEnter( const GuiEvent &event )
1441{
1442   mMouseOver = true;
1443}
1444
1445//------------------------------------------------------------------------------
1446//  Added
1447void GuiPopUpMenuCtrl::onMouseLeave( const GuiEvent &event )
1448{
1449   mMouseOver = false;
1450}
1451
1452//------------------------------------------------------------------------------
1453void GuiPopUpMenuCtrl::setupAutoScroll( const GuiEvent &event )
1454{
1455   GuiControl *parent = getParent();
1456   if ( !parent ) 
1457      return;
1458
1459   Point2I mousePt = mSc->globalToLocalCoord( event.mousePoint );
1460
1461   mEventSave = event;      
1462
1463   if ( mLastYvalue != mousePt.y )
1464   {
1465      mScrollDir = GuiScrollCtrl::None;
1466      if ( mousePt.y > mSc->getHeight() || mousePt.y < 0 )
1467      {
1468         S32 topOrBottom = ( mousePt.y > mSc->getHeight() ) ? 1 : 0;
1469         mSc->scrollTo( 0, topOrBottom );
1470         return;
1471      }   
1472
1473      F32 percent = (F32)mousePt.y / (F32)mSc->getHeight();
1474      if ( percent > 0.7f && mousePt.y > mLastYvalue )
1475      {
1476         mIncValue = percent - 0.5f;
1477         mScrollDir = GuiScrollCtrl::DownArrow;
1478      }
1479      else if ( percent < 0.3f && mousePt.y < mLastYvalue )
1480      {
1481         mIncValue = 0.5f - percent;         
1482         mScrollDir = GuiScrollCtrl::UpArrow;
1483      }
1484      mLastYvalue = mousePt.y;
1485   }
1486}
1487
1488//------------------------------------------------------------------------------
1489void GuiPopUpMenuCtrl::autoScroll()
1490{
1491   mScrollCount += mIncValue;
1492
1493   while ( mScrollCount > 1 )
1494   {
1495      mSc->autoScroll( mScrollDir );
1496      mScrollCount -= 1;
1497   }
1498   mTl->onMouseMove( mEventSave );
1499}
1500
1501//------------------------------------------------------------------------------
1502void GuiPopUpMenuCtrl::replaceText(S32 boolVal)
1503{
1504   mReplaceText = boolVal;
1505}
1506