Torque3D Documentation / _generateds / guiPopUpCtrlEx.cpp

guiPopUpCtrlEx.cpp

Engine/source/gui/controls/guiPopUpCtrlEx.cpp

More...

Public Variables

_GuiPopUpMenuCtrlExsetFirstSelected ("brief Manually set the selection to the first entry\n\n" "@param scripCallback Optional boolean that forces the script callback if true\n", "GuiPopUpMenuCtrlEx", "setSelected(bool scriptCallback=true);")
_GuiPopUpMenuCtrlExsetSelected ("brief Manually set an entry as selected int his control\n\n" "@param id The ID of the entry to select\n" "@param scripCallback Optional boolean that forces the script callback if true\n", "GuiPopUpMenuCtrlEx", "setSelected(int id, bool scriptCallback=true);")
colorWhite (255, 255, 255)

Public Functions

_GuiPopUpMenuCtrlExAdd("@brief Adds an entry <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">list\n\n</a>" "@param name <a href="/coding/class/classstring/">String</a> containing the name of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">entry\n</a>" "@param idNum Numerical <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> assigned <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">name\n</a>" "@param scheme Optional ID associated with <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> scheme " "<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> font coloring, highlight coloring, and selection <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">coloring\n\n</a>" , "GuiPopUpMenuCtrlEx" , "void add(string name, <a href="/coding/file/types_8h/#types_8h_1a57a2244776e01ad620c556de58eb7880">S32</a> idNum, <a href="/coding/file/types_8h/#types_8h_1a57a2244776e01ad620c556de58eb7880">S32</a> scheme=0);" )
ConsoleDocClass(GuiPopUpMenuCtrlEx , "@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>" "This is essentially <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> GuiPopUpMenuCtrl, but with quite <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> few more <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">features.\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/classguipopupmenuctrlex/">GuiPopUpMenuCtrlEx</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>" "  hotTrackCallback = \"0\";\<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>" "  profile = \"GuiDefaultProfile\";\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>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiPopUpMenuCtrl\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiControls\n</a>" )
DefineEngineMethod(GuiPopUpMenuCtrlEx , add , void , (const char *name, S32 idNum, U32 scheme) , ("", -1, 0) , "(string name, int idNum, int scheme=0)" )
DefineEngineMethod(GuiPopUpMenuCtrlEx , addCategory , void , (const char *text) , "@brief Add <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> category <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">list.\n\n</a>" "Acts as <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> separator between entries, allowing <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> sub-<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">lists\n\n</a>" " @param text Name of the <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">category\n\n</a>" )
DefineEngineMethod(GuiPopUpMenuCtrlEx , addScheme , void , (S32 id, ColorI fontColor, ColorI fontColorHL, ColorI fontColorSEL) , "@brief Create <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> scheme and add it <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the list of choices <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> when <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> text entry is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">added.\n\n</a>" "@param <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> Numerical <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> associated with this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">scheme\n</a>" "@param fontColor The base text font color. Formatted as \"Red Green Blue\" , each <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> numerical between 0 and 255.\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " @param fontColorHL Color of text when being highlighted. Formatted as \"Red Green Blue\" , each <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> numerical between 0 and 255.\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " @param fontColorSel Color of text when being selected. Formatted as \"Red Green Blue\" , each <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> numerical between 0 and 255.\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" )
DefineEngineMethod(GuiPopUpMenuCtrlEx , clear , void , () , "@brief Clear the popup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">list.\n\n</a>" )
DefineEngineMethod(GuiPopUpMenuCtrlEx , clearEntry , void , (S32 entry) , "(S32 entry)" )
DefineEngineMethod(GuiPopUpMenuCtrlEx , findText , S32 , (const char *text) , "(string text)" "Returns the <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> of the first entry containing the specified text or -1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not found." "@param text <a href="/coding/class/classstring/">String</a> <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> used <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">query\n\n</a>" "@return Numerical ID of entry containing the text." )
DefineEngineMethod(GuiPopUpMenuCtrlEx , forceClose , void , () , "@brief Manually force this <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> collapse and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">close.\n\n</a>" )
DefineEngineMethod(GuiPopUpMenuCtrlEx , forceOnAction , void , () , "@brief Manually <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the onAction function, which updates everything in this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">control.\n\n</a>" )
DefineEngineMethod(GuiPopUpMenuCtrlEx , getColorById , ColorI , (S32 id) , "@brief Get color of an entry's <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">box\n\n</a>" "@param <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> ID number of entry <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">query\n\n</a>" "@return <a href="/coding/class/classcolori/">ColorI</a> in the format of \"Red Green Blue Alpha\" , each of with is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> between 0 - 255" )
DefineEngineMethod(GuiPopUpMenuCtrlEx , getSelected , S32 , () , "@brief Get the current selection of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">menu.\n\n</a>" "@return Returns the ID of the currently selected entry" )
DefineEngineMethod(GuiPopUpMenuCtrlEx , getText , const char * , () , "@brief Get <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">the.\n\n</a>" "Detailed <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">description\n\n</a>" "@param param <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Description\n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Comment\n</a>" "code();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@return Returns current text in string format" )
DefineEngineMethod(GuiPopUpMenuCtrlEx , getTextById , const char * , (S32 id) , "@brief Get the text of an entry based on an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ID.\n\n</a>" "@param <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> The ID assigned <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the entry being <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">queried\n\n</a>" "@return <a href="/coding/class/classstring/">String</a> contained by the specified entry, <a href="/coding/file/typesx86unix_8h/#typesx86unix_8h_1a070d2ce7b6bb7e5c05602aa8c308d0c4">NULL</a> <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> empty or bad ID" )
DefineEngineMethod(GuiPopUpMenuCtrlEx , replaceText , void , (S32 boolVal) , "@brief Flag that causes each <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> text addition <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> replace the current <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">entry\n\n</a>" "@param True <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> turn on replacing, false <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> disable it" )
DefineEngineMethod(GuiPopUpMenuCtrlEx , setEnumContent , void , (const char *className, const char *enumName) , "@brief 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 <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">away.\n\n</a>" " @param class Name of the class containing the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">enum\n</a>" " @param enum Name of the enum <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">acces\n</a>" )
DefineEngineMethod(GuiPopUpMenuCtrlEx , setFirstSelected , void , (bool scriptCallback) , (true) , "([scriptCallback=true])" "@hide" )
DefineEngineMethod(GuiPopUpMenuCtrlEx , setNoneSelected , void , (S32 param) , "@brief Clears selection in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">menu.\n\n</a>" )
DefineEngineMethod(GuiPopUpMenuCtrlEx , setSelected , void , (S32 id, bool scriptCallback) , (true) , "(int <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a>, [scriptCallback=true])" "@hide" )
DefineEngineMethod(GuiPopUpMenuCtrlEx , setText , void , (const char *text) , "@brief Set the current text <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> specified <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">value.\n\n</a>" "@param text <a href="/coding/class/classstring/">String</a> containing <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> text <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set\n\n</a>" )
DefineEngineMethod(GuiPopUpMenuCtrlEx , size , S32 , () , "@brief Get the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1ab7d671599a7b25ca99a487fa341bc33a">size</a> of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">menu\n\n</a>" "@return Number of entries in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">menu\n</a>" )
DefineEngineMethod(GuiPopUpMenuCtrlEx , sort , void , () , "@brief Sort the list <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">alphabetically.\n\n</a>" )
DefineEngineMethod(GuiPopUpMenuCtrlEx , sortID , void , () , "@brief Sort the list by <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ID.\n\n</a>" )
const char *
getColumn(const char * string, char * returnbuff, U32 index, const char * set)
getColumnCount(const char * string, const char * set)

Detailed Description

Public Variables

ConsoleDocFragment _GuiPopUpMenuCtrlExsetFirstSelected ("brief Manually set the selection to the first entry\n\n" "@param scripCallback Optional boolean that forces the script callback if true\n", "GuiPopUpMenuCtrlEx", "setSelected(bool scriptCallback=true);")
ConsoleDocFragment _GuiPopUpMenuCtrlExsetSelected ("brief Manually set an entry as selected int his control\n\n" "@param id The ID of the entry to select\n" "@param scripCallback Optional boolean that forces the script callback if true\n", "GuiPopUpMenuCtrlEx", "setSelected(int id, bool scriptCallback=true);")
ColorI colorWhite (255, 255, 255)

Public Functions

_GuiPopUpMenuCtrlExAdd("@brief Adds an entry <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">list\n\n</a>" "@param name <a href="/coding/class/classstring/">String</a> containing the name of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">entry\n</a>" "@param idNum Numerical <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> assigned <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">name\n</a>" "@param scheme Optional ID associated with <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> scheme " "<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> font coloring, highlight coloring, and selection <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">coloring\n\n</a>" , "GuiPopUpMenuCtrlEx" , "void add(string name, <a href="/coding/file/types_8h/#types_8h_1a57a2244776e01ad620c556de58eb7880">S32</a> idNum, <a href="/coding/file/types_8h/#types_8h_1a57a2244776e01ad620c556de58eb7880">S32</a> scheme=0);" )

ConsoleDocClass(GuiPopUpMenuCtrlEx , "@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>" "This is essentially <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> GuiPopUpMenuCtrl, but with quite <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> few more <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">features.\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/classguipopupmenuctrlex/">GuiPopUpMenuCtrlEx</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>" "  hotTrackCallback = \"0\";\<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>" "  profile = \"GuiDefaultProfile\";\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>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiPopUpMenuCtrl\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiControls\n</a>" )

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

DefineEngineMethod(GuiPopUpMenuCtrlEx , addCategory , void , (const char *text) , "@brief Add <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> category <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">list.\n\n</a>" "Acts as <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> separator between entries, allowing <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> sub-<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">lists\n\n</a>" " @param text Name of the <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">category\n\n</a>" )

DefineEngineMethod(GuiPopUpMenuCtrlEx , addScheme , void , (S32 id, ColorI fontColor, ColorI fontColorHL, ColorI fontColorSEL) , "@brief Create <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> scheme and add it <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the list of choices <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> when <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> text entry is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">added.\n\n</a>" "@param <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> Numerical <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> associated with this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">scheme\n</a>" "@param fontColor The base text font color. Formatted as \"Red Green Blue\" , each <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> numerical between 0 and 255.\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " @param fontColorHL Color of text when being highlighted. Formatted as \"Red Green Blue\" , each <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> numerical between 0 and 255.\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " @param fontColorSel Color of text when being selected. Formatted as \"Red Green Blue\" , each <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> numerical between 0 and 255.\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" )

DefineEngineMethod(GuiPopUpMenuCtrlEx , clear , void , () , "@brief Clear the popup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">list.\n\n</a>" )

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

DefineEngineMethod(GuiPopUpMenuCtrlEx , findText , S32 , (const char *text) , "(string text)" "Returns the <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> of the first entry containing the specified text or -1 <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> not found." "@param text <a href="/coding/class/classstring/">String</a> <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> used <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">query\n\n</a>" "@return Numerical ID of entry containing the text." )

DefineEngineMethod(GuiPopUpMenuCtrlEx , forceClose , void , () , "@brief Manually force this <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> collapse and <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">close.\n\n</a>" )

DefineEngineMethod(GuiPopUpMenuCtrlEx , forceOnAction , void , () , "@brief Manually <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the onAction function, which updates everything in this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">control.\n\n</a>" )

DefineEngineMethod(GuiPopUpMenuCtrlEx , getColorById , ColorI , (S32 id) , "@brief Get color of an entry's <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">box\n\n</a>" "@param <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> ID number of entry <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">query\n\n</a>" "@return <a href="/coding/class/classcolori/">ColorI</a> in the format of \"Red Green Blue Alpha\" , each of with is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> between 0 - 255" )

DefineEngineMethod(GuiPopUpMenuCtrlEx , getSelected , S32 , () , "@brief Get the current selection of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">menu.\n\n</a>" "@return Returns the ID of the currently selected entry" )

DefineEngineMethod(GuiPopUpMenuCtrlEx , getText , const char * , () , "@brief Get <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">the.\n\n</a>" "Detailed <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">description\n\n</a>" "@param param <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Description\n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Comment\n</a>" "code();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@return Returns current text in string format" )

DefineEngineMethod(GuiPopUpMenuCtrlEx , getTextById , const char * , (S32 id) , "@brief Get the text of an entry based on an <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ID.\n\n</a>" "@param <a href="/coding/file/win32cursorcontroller_8cpp/#win32cursorcontroller_8cpp_1ab38592509822a5f4674447022cc62efe">id</a> The ID assigned <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the entry being <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">queried\n\n</a>" "@return <a href="/coding/class/classstring/">String</a> contained by the specified entry, <a href="/coding/file/typesx86unix_8h/#typesx86unix_8h_1a070d2ce7b6bb7e5c05602aa8c308d0c4">NULL</a> <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> empty or bad ID" )

DefineEngineMethod(GuiPopUpMenuCtrlEx , replaceText , void , (S32 boolVal) , "@brief Flag that causes each <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> text addition <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> replace the current <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">entry\n\n</a>" "@param True <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> turn on replacing, false <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> disable it" )

DefineEngineMethod(GuiPopUpMenuCtrlEx , setEnumContent , void , (const char *className, const char *enumName) , "@brief 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 <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">away.\n\n</a>" " @param class Name of the class containing the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">enum\n</a>" " @param enum Name of the enum <a href="/coding/file/pointer_8h/#pointer_8h_1a32aff7c6c4cd253fdf6563677afab5ce">value</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">acces\n</a>" )

DefineEngineMethod(GuiPopUpMenuCtrlEx , setFirstSelected , void , (bool scriptCallback) , (true) , "([scriptCallback=true])" "@hide" )

DefineEngineMethod(GuiPopUpMenuCtrlEx , setNoneSelected , void , (S32 param) , "@brief Clears selection in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">menu.\n\n</a>" )

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

DefineEngineMethod(GuiPopUpMenuCtrlEx , setText , void , (const char *text) , "@brief Set the current text <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> specified <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">value.\n\n</a>" "@param text <a href="/coding/class/classstring/">String</a> containing <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> text <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">set\n\n</a>" )

DefineEngineMethod(GuiPopUpMenuCtrlEx , size , S32 , () , "@brief Get the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1ab7d671599a7b25ca99a487fa341bc33a">size</a> of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">menu\n\n</a>" "@return Number of entries in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">menu\n</a>" )

DefineEngineMethod(GuiPopUpMenuCtrlEx , sort , void , () , "@brief Sort the list <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">alphabetically.\n\n</a>" )

DefineEngineMethod(GuiPopUpMenuCtrlEx , sortID , void , () , "@brief Sort the list by <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">ID.\n\n</a>" )

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(GuiPopUpMenuCtrlEx )

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/guiPopUpCtrlEx.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
  33ConsoleDocClass( GuiPopUpMenuCtrlEx,
  34   "@brief A control that allows to select a value from a drop-down list.\n\n"
  35
  36   "This is essentially a GuiPopUpMenuCtrl, but with quite a few more features.\n\n"
  37
  38   "@tsexample\n"
  39   "new GuiPopUpMenuCtrlEx()\n"
  40   "{\n"
  41   "  maxPopupHeight = \"200\";\n"
  42   "  sbUsesNAColor = \"0\";\n"
  43   "  reverseTextList = \"0\";\n"
  44   "  bitmapBounds = \"16 16\";\n"
  45   "  hotTrackCallback = \"0\";\n"
  46   "  extent = \"64 64\";\n"
  47   "  profile = \"GuiDefaultProfile\";\n"
  48   "  tooltipProfile = \"GuiToolTipProfile\";\n"
  49   "};\n"
  50   "@endtsexample\n\n"
  51
  52   "@see GuiPopUpMenuCtrl\n"
  53
  54   "@ingroup GuiControls\n");
  55
  56static ColorI colorWhite(255,255,255); //  Added
  57
  58// Function to return the number of columns in 'string' given delimeters in 'set'
  59static U32 getColumnCount(const char *string, const char *set)
  60{
  61   U32 count = 0;
  62   U8 last = 0;
  63   while(*string)
  64   {
  65      last = *string++;
  66
  67      for(U32 i =0; set[i]; i++)
  68      {
  69         if(last == set[i])
  70         {
  71            count++;
  72            last = 0;
  73            break;
  74         }   
  75      }
  76   }
  77   if(last)
  78      count++;
  79   return count;
  80}   
  81
  82// Function to return the 'index' column from 'string' given delimeters in 'set'
  83static const char *getColumn(const char *string, char* returnbuff, U32 index, const char *set)
  84{
  85   U32 sz;
  86   while(index--)
  87   {
  88      if(!*string)
  89         return "";
  90      sz = dStrcspn(string, set);
  91      if (string[sz] == 0)
  92         return "";
  93      string += (sz + 1);    
  94   }
  95   sz = dStrcspn(string, set);
  96   if (sz == 0)
  97      return "";
  98   char *ret = returnbuff;
  99   dStrncpy(ret, string, sz);
 100   ret[sz] = '\0';
 101   return ret;
 102}   
 103
 104GuiPopUpBackgroundCtrlEx::GuiPopUpBackgroundCtrlEx(GuiPopUpMenuCtrlEx *ctrl, GuiPopupTextListCtrlEx *textList)
 105{
 106   mPopUpCtrl = ctrl;
 107   mTextList = textList;
 108}
 109
 110void GuiPopUpBackgroundCtrlEx::onMouseDown(const GuiEvent &event)
 111{
 112   //   mTextList->setSelectedCell(Point2I(-1,-1)); //  Removed
 113   mPopUpCtrl->mBackgroundCancel = true; //  Set that the user didn't click within the text list.  Replaces the line above.
 114   mPopUpCtrl->closePopUp();
 115}
 116
 117//------------------------------------------------------------------------------
 118GuiPopupTextListCtrlEx::GuiPopupTextListCtrlEx()
 119{
 120   mPopUpCtrl = NULL;
 121}
 122
 123
 124//------------------------------------------------------------------------------
 125GuiPopupTextListCtrlEx::GuiPopupTextListCtrlEx(GuiPopUpMenuCtrlEx *ctrl)
 126{
 127   mPopUpCtrl = ctrl;
 128}
 129
 130//------------------------------------------------------------------------------
 131
 132//------------------------------------------------------------------------------
 133//void GuiPopUpTextListCtrl::onCellSelected( Point2I /*cell*/ )
 134//{
 135//   // Do nothing, the parent control will take care of everything...
 136//}
 137void GuiPopupTextListCtrlEx::onCellSelected( Point2I cell )
 138{
 139   //  The old function is above.  This new one will only call the the select
 140   //      functions if we were not cancelled by a background click.
 141
 142   //  Check if we were cancelled by the user clicking on the Background ie: anywhere
 143   //      other than within the text list.
 144   if(mPopUpCtrl->mBackgroundCancel)
 145      return;
 146
 147   if( isMethod( "onSelect" ) )
 148      Con::executef(this, "onSelect", Con::getFloatArg(cell.x), Con::getFloatArg(cell.y));
 149
 150   //call the console function
 151   execConsoleCallback();
 152   //if (mConsoleCommand[0])
 153   //   Con::evaluate(mConsoleCommand, false);
 154
 155}
 156
 157bool GuiPopupTextListCtrlEx::hasCategories()
 158{
 159   for( S32 i = 0; i < mList.size(); i++)
 160   {
 161      if( mList[i].id == -1)
 162         return true;
 163   }
 164
 165   return false;
 166}
 167
 168//------------------------------------------------------------------------------
 169bool GuiPopupTextListCtrlEx::onKeyDown(const GuiEvent &event)
 170{
 171   //if the control is a dead end, don't process the input:
 172   if ( !mVisible || !mActive || !mAwake )
 173      return false;
 174
 175   //see if the key down is a <return> or not
 176   if ( event.modifier == 0 )
 177   {
 178      if ( event.keyCode == KEY_RETURN )
 179      {
 180         mPopUpCtrl->closePopUp();
 181         return true;
 182      }
 183      else if ( event.keyCode == KEY_ESCAPE )
 184      {
 185         mSelectedCell.set( -1, -1 );
 186         mPopUpCtrl->closePopUp();
 187         return true;
 188      }
 189   }
 190
 191   //otherwise, pass the event to it's parent
 192   return Parent::onKeyDown(event);
 193}
 194
 195void GuiPopupTextListCtrlEx::onMouseUp(const GuiEvent &event)
 196{
 197   Point2I pt = globalToLocalCoord(event.mousePoint);
 198   pt.x -= mHeaderDim.x; pt.y -= mHeaderDim.y;
 199   Point2I cell(
 200      (pt.x < 0 ? -1 : pt.x / mCellSize.x), 
 201      (pt.y < 0 ? -1 : pt.y / mCellSize.y)
 202      );
 203
 204   if (cell.x >= 0 && cell.x < mSize.x && cell.y >= 0 && cell.y < mSize.y)
 205   {
 206      if (mList[cell.y].id == -1)
 207         return;
 208   }
 209
 210   Parent::onMouseUp(event);
 211   mPopUpCtrl->closePopUp();
 212}
 213
 214void GuiPopupTextListCtrlEx::onMouseMove( const GuiEvent &event )
 215{
 216   if( !mPopUpCtrl || !mPopUpCtrl->isMethod("onHotTrackItem") )
 217      return Parent::onMouseMove( event );
 218
 219   Point2I pt = globalToLocalCoord(event.mousePoint);
 220   pt.x -= mHeaderDim.x; pt.y -= mHeaderDim.y;
 221   Point2I cell( (pt.x < 0 ? -1 : pt.x / mCellSize.x), (pt.y < 0 ? -1 : pt.y / mCellSize.y) );
 222
 223   // Within Bounds?
 224   if (cell.x >= 0 && cell.x < mSize.x && cell.y >= 0 && cell.y < mSize.y)
 225      // Hot Track notification
 226      Con::executef( mPopUpCtrl, "onHotTrackItem", Con::getIntArg(mList[cell.y].id) );
 227   else 
 228      // Hot Track -1
 229      Con::executef( mPopUpCtrl, "onHotTrackItem", Con::getIntArg(-1) );
 230
 231   // Call Parent
 232   Parent::onMouseMove(event);
 233}
 234
 235//------------------------------------------------------------------------------
 236void GuiPopupTextListCtrlEx::onRenderCell(Point2I offset, Point2I cell, bool selected, bool mouseOver)
 237{
 238   Point2I size;
 239   getCellSize( size );
 240
 241   // Render a background color for the cell
 242   if ( mouseOver )
 243   {      
 244      RectI cellR( offset.x, offset.y, size.x, size.y );
 245      GFX->getDrawUtil()->drawRectFill( cellR, mProfile->mFillColorHL );
 246   }
 247   else if ( selected )
 248   {
 249      RectI cellR( offset.x, offset.y, size.x, size.y );
 250      GFX->getDrawUtil()->drawRectFill( cellR, mProfile->mFillColorSEL );
 251   }
 252
 253   //  Define the default x offset for the text
 254   U32 textXOffset = offset.x + mProfile->mTextOffset.x;
 255
 256   //  Do we also draw a colored box beside the text?
 257   ColorI boxColor;
 258   bool drawbox = mPopUpCtrl->getColoredBox( boxColor, mList[cell.y].id );
 259   if ( drawbox )
 260   {
 261      Point2I coloredboxsize( 15, 10 );
 262      RectI r( offset.x + mProfile->mTextOffset.x, offset.y + 2, coloredboxsize.x, coloredboxsize.y );
 263      GFX->getDrawUtil()->drawRectFill( r, boxColor );
 264      GFX->getDrawUtil()->drawRect( r, ColorI( 0, 0, 0 ) );
 265
 266      textXOffset += coloredboxsize.x + mProfile->mTextOffset.x;
 267   }
 268
 269   // Render 'Group' background
 270   if ( mList[cell.y].id == -1)
 271   {
 272      RectI cellR( offset.x, offset.y, size.x, size.y );
 273      GFX->getDrawUtil()->drawRectFill( cellR, mProfile->mFillColorHL );
 274   }
 275
 276   ColorI fontColor;
 277   mPopUpCtrl->getFontColor( fontColor, mList[cell.y].id, selected, mouseOver );
 278
 279   GFX->getDrawUtil()->setBitmapModulation( fontColor );
 280   //GFX->drawText( mFont, Point2I( offset.x + 4, offset.y ), mList[cell.y].text );
 281
 282   //  Get the number of columns in the cell
 283   S32 colcount = getColumnCount(mList[cell.y].text, "\t");
 284
 285   //  Are there two or more columns?
 286   if(colcount >= 2)
 287   {
 288      char buff[256];
 289
 290      // Draw the first column
 291      getColumn(mList[cell.y].text, buff, 0, "\t");
 292      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'.
 293
 294      // Draw the second column to the right
 295      getColumn(mList[cell.y].text, buff, 1, "\t");
 296      S32 txt_w = mFont->getStrWidth(buff);
 297
 298      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'.
 299
 300   } else
 301   {
 302      if ((mList[cell.y].id == -1) || (!hasCategories()))
 303         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'.
 304      else
 305         GFX->getDrawUtil()->drawText( mFont, Point2I( textXOffset + 8, offset.y ), mList[cell.y].text ); //  Used mTextOffset as a margin for the text list rather than the hard coded value of '4'.
 306   }
 307}
 308
 309//------------------------------------------------------------------------------
 310//------------------------------------------------------------------------------
 311
 312IMPLEMENT_CONOBJECT(GuiPopUpMenuCtrlEx);
 313
 314GuiPopUpMenuCtrlEx::GuiPopUpMenuCtrlEx(void)
 315{
 316   VECTOR_SET_ASSOCIATION(mEntries);
 317   VECTOR_SET_ASSOCIATION(mSchemes);
 318
 319   mSelIndex = -1;
 320   mActive = true;
 321   mMaxPopupHeight = 200;
 322   mScrollDir = GuiScrollCtrl::None;
 323   mScrollCount = 0;
 324   mLastYvalue = 0;
 325   mIncValue = 0;
 326   mRevNum = 0;
 327   mInAction = false;
 328   mMouseOver = false; //  Added
 329   mRenderScrollInNA = false; //  Added
 330   mBackgroundCancel = false; //  Added
 331   mReverseTextList = false; //  Added - Don't reverse text list if displaying up
 332   mBitmapName = StringTable->EmptyString(); //  Added
 333   mBitmapBounds.set(16, 16); //  Added
 334   mHotTrackItems = false;
 335   mIdMax = -1;
 336   mBackground = NULL;
 337   mTl = NULL;
 338   mSc = NULL;
 339   mReplaceText = false;
 340}
 341
 342//------------------------------------------------------------------------------
 343GuiPopUpMenuCtrlEx::~GuiPopUpMenuCtrlEx()
 344{
 345}
 346
 347//------------------------------------------------------------------------------
 348void GuiPopUpMenuCtrlEx::initPersistFields(void)
 349{
 350   addField("maxPopupHeight",           TypeS32,          Offset(mMaxPopupHeight, GuiPopUpMenuCtrlEx), "Length of menu when it extends");
 351   addField("sbUsesNAColor",            TypeBool,         Offset(mRenderScrollInNA, GuiPopUpMenuCtrlEx), "Deprecated" "@internal");
 352   addField("reverseTextList",          TypeBool,         Offset(mReverseTextList, GuiPopUpMenuCtrlEx), "Reverses text list if popup extends up, instead of down");
 353   addField("bitmap",                   TypeFilename,     Offset(mBitmapName, GuiPopUpMenuCtrlEx), "File name of bitmap to use");
 354   addField("bitmapBounds",             TypePoint2I,      Offset(mBitmapBounds, GuiPopUpMenuCtrlEx), "Boundaries of bitmap displayed");
 355   addField("hotTrackCallback",         TypeBool,         Offset(mHotTrackItems, GuiPopUpMenuCtrlEx),
 356      "Whether to provide a 'onHotTrackItem' callback when a list item is hovered over");
 357
 358   Parent::initPersistFields();
 359}
 360
 361//------------------------------------------------------------------------------
 362ConsoleDocFragment _GuiPopUpMenuCtrlExAdd(
 363   "@brief Adds an entry to the list\n\n"
 364   "@param name String containing the name of the entry\n"
 365   "@param idNum Numerical value assigned to the name\n"
 366   "@param scheme Optional ID associated with a scheme "
 367   "for font coloring, highlight coloring, and selection coloring\n\n",
 368   "GuiPopUpMenuCtrlEx",
 369   "void add(string name, S32 idNum, S32 scheme=0);"
 370);
 371
 372DefineEngineMethod( GuiPopUpMenuCtrlEx, add, void, (const char * name, S32 idNum, U32 scheme), ("", -1, 0), "(string name, int idNum, int scheme=0)")
 373{
 374   object->addEntry(name, idNum, scheme);
 375}
 376
 377DefineEngineMethod( GuiPopUpMenuCtrlEx, addCategory, void, (const char* text),,
 378               "@brief Add a category to the list.\n\n"
 379
 380               "Acts as a separator between entries, allowing for sub-lists\n\n"
 381
 382               "@param text Name of the new category\n\n")
 383{
 384   object->addEntry(text, -1, 0);
 385}
 386
 387DefineEngineMethod( GuiPopUpMenuCtrlEx, addScheme, void, (S32 id, ColorI fontColor, ColorI fontColorHL, ColorI fontColorSEL),,
 388               "@brief Create a new scheme and add it to the list of choices for when a new text entry is added.\n\n"
 389               "@param id Numerical id associated with this scheme\n"
 390               "@param fontColor The base text font color. Formatted as \"Red Green Blue\", each a numerical between 0 and 255.\n"
 391               "@param fontColorHL Color of text when being highlighted. Formatted as \"Red Green Blue\", each a numerical between 0 and 255.\n"
 392               "@param fontColorSel Color of text when being selected. Formatted as \"Red Green Blue\", each a numerical between 0 and 255.\n")
 393{
 394   /*ColorI fontColor, fontColorHL, fontColorSEL;
 395   U32 r, g, b;
 396   char buf[64];
 397
 398   dStrcpy( buf, argv[3], 64 );
 399   char* temp = dStrtok( buf, " \0" );
 400   r = temp ? dAtoi( temp ) : 0;
 401   temp = dStrtok( NULL, " \0" );
 402   g = temp ? dAtoi( temp ) : 0;
 403   temp = dStrtok( NULL, " \0" );
 404   b = temp ? dAtoi( temp ) : 0;
 405   fontColor.set( r, g, b );
 406
 407   dStrcpy( buf, argv[4], 64 );
 408   temp = dStrtok( buf, " \0" );
 409   r = temp ? dAtoi( temp ) : 0;
 410   temp = dStrtok( NULL, " \0" );
 411   g = temp ? dAtoi( temp ) : 0;
 412   temp = dStrtok( NULL, " \0" );
 413   b = temp ? dAtoi( temp ) : 0;
 414   fontColorHL.set( r, g, b );
 415
 416   dStrcpy( buf, argv[5], 64 );
 417   temp = dStrtok( buf, " \0" );
 418   r = temp ? dAtoi( temp ) : 0;
 419   temp = dStrtok( NULL, " \0" );
 420   g = temp ? dAtoi( temp ) : 0;
 421   temp = dStrtok( NULL, " \0" );
 422   b = temp ? dAtoi( temp ) : 0;
 423   fontColorSEL.set( r, g, b );*/
 424
 425   object->addScheme( id, fontColor, fontColorHL, fontColorSEL );
 426}
 427
 428//ConsoleMethod( GuiPopUpMenuCtrlEx, addScheme, void, 6, 6, "(int id, ColorI fontColor, ColorI fontColorHL, ColorI fontColorSEL)")
 429//{
 430//   ColorI fontColor, fontColorHL, fontColorSEL;
 431//   U32 r, g, b;
 432//   char buf[64];
 433//
 434//   dStrcpy( buf, argv[3], 64 );
 435//   char* temp = dStrtok( buf, " \0" );
 436//   r = temp ? dAtoi( temp ) : 0;
 437//   temp = dStrtok( NULL, " \0" );
 438//   g = temp ? dAtoi( temp ) : 0;
 439//   temp = dStrtok( NULL, " \0" );
 440//   b = temp ? dAtoi( temp ) : 0;
 441//   fontColor.set( r, g, b );
 442//
 443//   dStrcpy( buf, argv[4], 64 );
 444//   temp = dStrtok( buf, " \0" );
 445//   r = temp ? dAtoi( temp ) : 0;
 446//   temp = dStrtok( NULL, " \0" );
 447//   g = temp ? dAtoi( temp ) : 0;
 448//   temp = dStrtok( NULL, " \0" );
 449//   b = temp ? dAtoi( temp ) : 0;
 450//   fontColorHL.set( r, g, b );
 451//
 452//   dStrcpy( buf, argv[5], 64 );
 453//   temp = dStrtok( buf, " \0" );
 454//   r = temp ? dAtoi( temp ) : 0;
 455//   temp = dStrtok( NULL, " \0" );
 456//   g = temp ? dAtoi( temp ) : 0;
 457//   temp = dStrtok( NULL, " \0" );
 458//   b = temp ? dAtoi( temp ) : 0;
 459//   fontColorSEL.set( r, g, b );
 460//
 461//   object->addScheme( dAtoi( argv[2] ), fontColor, fontColorHL, fontColorSEL );
 462//}
 463
 464DefineEngineMethod( GuiPopUpMenuCtrlEx, setText, void, ( const char* text),,
 465               "@brief Set the current text to a specified value.\n\n"
 466               "@param text String containing new text to set\n\n")
 467{
 468   object->setText(text);
 469}
 470
 471DefineEngineMethod( GuiPopUpMenuCtrlEx, getText, const char*, (),,
 472               "@brief Get the.\n\n"
 473
 474               "Detailed description\n\n"
 475
 476               "@param param Description\n\n"
 477
 478               "@tsexample\n"
 479               "// Comment\n"
 480               "code();\n"
 481               "@endtsexample\n\n"
 482
 483               "@return Returns current text in string format")
 484{
 485   return object->getText();
 486}
 487
 488DefineEngineMethod( GuiPopUpMenuCtrlEx, clear, void, (),,
 489               "@brief Clear the popup list.\n\n")
 490{
 491   object->clear();
 492}
 493
 494DefineEngineMethod( GuiPopUpMenuCtrlEx, sort, void, (),,
 495               "@brief Sort the list alphabetically.\n\n")
 496{
 497   object->sort();
 498}
 499
 500DefineEngineMethod( GuiPopUpMenuCtrlEx, sortID, void, (),,
 501               "@brief Sort the list by ID.\n\n")
 502{
 503   object->sortID();
 504}
 505
 506DefineEngineMethod( GuiPopUpMenuCtrlEx, forceOnAction, void, (),,
 507               "@brief Manually for the onAction function, which updates everything in this control.\n\n")
 508{
 509   object->onAction();
 510}
 511
 512DefineEngineMethod( GuiPopUpMenuCtrlEx, forceClose, void, (),,
 513               "@brief Manually force this control to collapse and close.\n\n")
 514{
 515   object->closePopUp();
 516}
 517
 518DefineEngineMethod( GuiPopUpMenuCtrlEx, getSelected, S32, (),,
 519               "@brief Get the current selection of the menu.\n\n"
 520               "@return Returns the ID of the currently selected entry")
 521{
 522   return object->getSelected();
 523}
 524
 525ConsoleDocFragment _GuiPopUpMenuCtrlExsetSelected(
 526   "brief Manually set an entry as selected int his control\n\n"
 527   "@param id The ID of the entry to select\n"
 528   "@param scripCallback Optional boolean that forces the script callback if true\n",
 529   "GuiPopUpMenuCtrlEx",
 530   "setSelected(int id, bool scriptCallback=true);"
 531);
 532
 533DefineEngineMethod( GuiPopUpMenuCtrlEx, setSelected, void, (S32 id, bool scriptCallback), (true), "(int id, [scriptCallback=true])"
 534           "@hide")
 535{
 536   object->setSelected( id, scriptCallback );
 537}
 538
 539ConsoleDocFragment _GuiPopUpMenuCtrlExsetFirstSelected(
 540   "brief Manually set the selection to the first entry\n\n"
 541   "@param scripCallback Optional boolean that forces the script callback if true\n",
 542   "GuiPopUpMenuCtrlEx",
 543   "setSelected(bool scriptCallback=true);"
 544);
 545
 546
 547DefineEngineMethod( GuiPopUpMenuCtrlEx, setFirstSelected, void, (bool scriptCallback), (true), "([scriptCallback=true])"
 548           "@hide")
 549{
 550   object->setFirstSelected( scriptCallback );
 551}
 552
 553DefineEngineMethod( GuiPopUpMenuCtrlEx, setNoneSelected, void, ( S32 param),,
 554               "@brief Clears selection in the menu.\n\n")
 555{
 556   object->setNoneSelected();
 557}
 558
 559
 560DefineEngineMethod( GuiPopUpMenuCtrlEx, getTextById, const char*, (S32 id),,
 561               "@brief Get the text of an entry based on an ID.\n\n"
 562               "@param id The ID assigned to the entry being queried\n\n"
 563               "@return String contained by the specified entry, NULL if empty or bad ID")
 564{
 565   return(object->getTextById(id));
 566}
 567
 568
 569DefineEngineMethod( GuiPopUpMenuCtrlEx, getColorById,  ColorI, (S32 id), ,  
 570           "@brief Get color of an entry's box\n\n"
 571           "@param id ID number of entry to query\n\n"
 572           "@return ColorI in the format of \"Red Green Blue Alpha\", each of with is a value between 0 - 255")
 573{
 574   ColorI color;
 575   object->getColoredBox(color, id);
 576   return color;
 577
 578}
 579
 580DefineEngineMethod( GuiPopUpMenuCtrlEx, setEnumContent, void, ( const char * className, const char * enumName ), ,
 581           "@brief This fills the popup with a classrep's field enumeration type info.\n\n"
 582              "More of a helper function than anything.   If console access to the field list is added, "
 583              "at least for the enumerated types, then this should go away.\n\n"
 584           "@param class Name of the class containing the enum\n"
 585           "@param enum Name of the enum value to acces\n")
 586{
 587   AbstractClassRep * classRep = AbstractClassRep::getClassList();
 588
 589   // walk the class list to get our class
 590   while(classRep)
 591   {
 592      if(!dStricmp(classRep->getClassName(), className))
 593         break;
 594      classRep = classRep->getNextClass();
 595   }
 596
 597   // get it?
 598   if(!classRep)
 599   {
 600      Con::warnf(ConsoleLogEntry::General, "failed to locate class rep for '%s'", className);
 601      return;
 602   }
 603
 604   // walk the fields to check for this one (findField checks StringTableEntry ptrs...)
 605   U32 i;
 606   for(i = 0; i < classRep->mFieldList.size(); i++)
 607      if(!dStricmp(classRep->mFieldList[i].pFieldname, enumName))
 608         break;
 609
 610   // found it?   
 611   if(i == classRep->mFieldList.size())
 612   {   
 613      Con::warnf(ConsoleLogEntry::General, "failed to locate field '%s' for class '%s'", enumName, className);
 614      return;
 615   }
 616
 617   const AbstractClassRep::Field & field = classRep->mFieldList[i];
 618   ConsoleBaseType* conType = ConsoleBaseType::getType( field.type );
 619
 620   // check the type
 621   if( !conType->getEnumTable() )
 622   {
 623      Con::warnf(ConsoleLogEntry::General, "field '%s' is not an enumeration for class '%s'", enumName, className);
 624      return;
 625   }
 626
 627   // fill it
 628   const EngineEnumTable& table = *( conType->getEnumTable() );
 629   const U32 numValues = table.getNumValues();
 630   
 631   for(i = 0; i < numValues; i++)
 632      object->addEntry( table[i].getName(), table[i] );
 633}
 634
 635//------------------------------------------------------------------------------
 636DefineEngineMethod( GuiPopUpMenuCtrlEx, findText, S32, (const char * text), , "(string text)"
 637              "Returns the id of the first entry containing the specified text or -1 if not found."
 638           "@param text String value used for the query\n\n"
 639           "@return Numerical ID of entry containing the text.")
 640{
 641   return( object->findText( text ) );
 642}
 643
 644//------------------------------------------------------------------------------
 645DefineEngineMethod( GuiPopUpMenuCtrlEx, size, S32, (), , 
 646           "@brief Get the size of the menu\n\n"
 647           "@return Number of entries in the menu\n")
 648{
 649   return( object->getNumEntries() ); 
 650}
 651
 652//------------------------------------------------------------------------------
 653DefineEngineMethod( GuiPopUpMenuCtrlEx, replaceText, void, (S32 boolVal), , 
 654           "@brief Flag that causes each new text addition to replace the current entry\n\n"
 655           "@param True to turn on replacing, false to disable it")
 656{
 657   object->replaceText(boolVal);
 658}
 659
 660//------------------------------------------------------------------------------
 661//  Added
 662bool GuiPopUpMenuCtrlEx::onWake()
 663{
 664   if ( !Parent::onWake() )
 665      return false;
 666
 667   // Set the bitmap for the popup.
 668   setBitmap( mBitmapName );
 669
 670   // Now update the Form Control's bitmap array, and possibly the child's too
 671   mProfile->constructBitmapArray();
 672
 673   if ( mProfile->getChildrenProfile() )
 674      mProfile->getChildrenProfile()->constructBitmapArray();
 675
 676   return true;
 677}
 678
 679//------------------------------------------------------------------------------
 680bool GuiPopUpMenuCtrlEx::onAdd()
 681{
 682   if ( !Parent::onAdd() )
 683      return false;
 684   mSelIndex = -1;
 685   mReplaceText = true;
 686   return true;
 687}
 688
 689//------------------------------------------------------------------------------
 690void GuiPopUpMenuCtrlEx::onSleep()
 691{
 692   mTextureNormal = NULL; //  Added
 693   mTextureDepressed = NULL; //  Added
 694   Parent::onSleep();
 695   closePopUp();  // Tests in function.
 696}
 697
 698//------------------------------------------------------------------------------
 699void GuiPopUpMenuCtrlEx::clear()
 700{
 701   mEntries.setSize(0);
 702   setText("");
 703   mSelIndex = -1;
 704   mRevNum = 0;
 705   mIdMax = -1;
 706}
 707
 708//------------------------------------------------------------------------------
 709void GuiPopUpMenuCtrlEx::clearEntry( S32 entry )
 710{
 711   if( entry == -1 )
 712      return;
 713
 714   U32 i = 0;
 715   for ( ; i < mEntries.size(); i++ )
 716   {
 717      if ( mEntries[i].id == entry )
 718         break;
 719   }
 720
 721   mEntries.erase( i );
 722
 723   if( mEntries.size() <= 0 )
 724   {
 725      mEntries.setSize(0);
 726      setText("");
 727      mSelIndex = -1;
 728      mRevNum = 0;
 729   }
 730   else
 731   {
 732      if( entry == mSelIndex )
 733      {
 734         setText("");
 735         mSelIndex = -1;
 736      }
 737      else
 738      {
 739         mSelIndex--;
 740      }
 741   }
 742}
 743
 744//------------------------------------------------------------------------------
 745DefineEngineMethod( GuiPopUpMenuCtrlEx, clearEntry, void, (S32 entry), , "(S32 entry)")
 746{
 747   object->clearEntry(entry);
 748}
 749
 750//------------------------------------------------------------------------------
 751static S32 QSORT_CALLBACK textCompare(const void *a,const void *b)
 752{
 753   GuiPopUpMenuCtrlEx::Entry *ea = (GuiPopUpMenuCtrlEx::Entry *) (a);
 754   GuiPopUpMenuCtrlEx::Entry *eb = (GuiPopUpMenuCtrlEx::Entry *) (b);
 755   return (dStrnatcasecmp(ea->buf, eb->buf));
 756} 
 757
 758//  Added to sort by entry ID
 759//------------------------------------------------------------------------------
 760static S32 QSORT_CALLBACK idCompare(const void *a,const void *b)
 761{
 762   GuiPopUpMenuCtrlEx::Entry *ea = (GuiPopUpMenuCtrlEx::Entry *) (a);
 763   GuiPopUpMenuCtrlEx::Entry *eb = (GuiPopUpMenuCtrlEx::Entry *) (b);
 764   return ( (ea->id < eb->id) ? -1 : ((ea->id > eb->id) ? 1 : 0) );
 765} 
 766
 767//------------------------------------------------------------------------------
 768//  Added
 769void GuiPopUpMenuCtrlEx::setBitmap(const char *name)
 770{
 771   mBitmapName = StringTable->insert( name );
 772   if ( !isAwake() )
 773      return;
 774
 775   if ( *mBitmapName )
 776   {
 777      char buffer[1024];
 778      char *p;
 779      dStrcpy(buffer, name, 1024);
 780      p = buffer + dStrlen(buffer);
 781      S32 pLen = 1024 - dStrlen(buffer);
 782
 783      dStrcpy(p, "_n", pLen);
 784      mTextureNormal = GFXTexHandle( (StringTableEntry)buffer, &GFXDefaultGUIProfile, avar("%s() - mTextureNormal (line %d)", __FUNCTION__, __LINE__) );
 785
 786      dStrcpy(p, "_d", pLen);
 787      mTextureDepressed = GFXTexHandle( (StringTableEntry)buffer, &GFXDefaultGUIProfile, avar("%s() - mTextureDepressed (line %d)", __FUNCTION__, __LINE__) );
 788      if ( !mTextureDepressed )
 789         mTextureDepressed = mTextureNormal;
 790   }
 791   else
 792   {
 793      mTextureNormal = NULL;
 794      mTextureDepressed = NULL;
 795   }
 796   setUpdate();
 797}   
 798
 799//------------------------------------------------------------------------------
 800void GuiPopUpMenuCtrlEx::sort()
 801{
 802   S32 size = mEntries.size();
 803   if( size > 0 )
 804      dQsort( mEntries.address(), size, sizeof(Entry), textCompare);
 805
 806   // Entries need to re-Id themselves
 807   for( U32 i = 0; i < mEntries.size(); i++ )
 808      mEntries[i].id = i;
 809}
 810
 811//  Added to sort by entry ID
 812//------------------------------------------------------------------------------
 813void GuiPopUpMenuCtrlEx::sortID()
 814{
 815   S32 size = mEntries.size();
 816   if( size > 0 )
 817      dQsort( mEntries.address(), size, sizeof(Entry), idCompare);
 818
 819   // Entries need to re-Id themselves
 820   for( U32 i = 0; i < mEntries.size(); i++ )
 821      mEntries[i].id = i;
 822}
 823
 824//------------------------------------------------------------------------------
 825void GuiPopUpMenuCtrlEx::addEntry(const char *buf, S32 id, U32 scheme)
 826{
 827   if( !buf )
 828   {
 829      //Con::printf( "GuiPopupMenuCtrlEx::addEntry - Invalid buffer!" );
 830      return;
 831   }
 832   
 833   // Ensure that there are no other entries with exactly the same name
 834   for ( U32 i = 0; i < mEntries.size(); i++ )
 835   {
 836      if ( String::compare( mEntries[i].buf, buf ) == 0 )
 837         return;
 838   }
 839
 840   // If we don't give an id, create one from mIdMax
 841   if( id == -1 )
 842      id = mIdMax + 1;
 843   
 844   // Increase mIdMax when an id is greater than it
 845   if( id > mIdMax )
 846      mIdMax = id;
 847
 848   Entry e;
 849   dStrcpy( e.buf, buf, 256 );
 850   e.id = id;
 851   e.scheme = scheme;
 852
 853   // see if there is a shortcut key
 854   char * cp = dStrchr( e.buf, '~' );
 855   e.ascii = cp ? cp[1] : 0;
 856
 857   //  See if there is a colour box defined with the text
 858   char *cb = dStrchr( e.buf, '|' );
 859   if ( cb )
 860   {
 861      e.usesColorBox = true;
 862      cb[0] = '\0';
 863
 864      char* red = &cb[1];
 865      cb = dStrchr(red, '|');
 866      cb[0] = '\0';
 867      char* green = &cb[1];
 868      cb = dStrchr(green, '|');
 869      cb[0] = '\0';
 870      char* blue = &cb[1];
 871
 872      U32 r = dAtoi(red);
 873      U32 g = dAtoi(green);
 874      U32 b = dAtoi(blue);
 875
 876      e.colorbox = ColorI(r,g,b);
 877
 878   } 
 879   else
 880   {
 881      e.usesColorBox = false;
 882   }
 883
 884   mEntries.push_back(e);
 885
 886   if ( mInAction && mTl )
 887   {
 888      // Add the new entry:
 889      mTl->addEntry( e.id, e.buf );
 890      repositionPopup();
 891   }
 892}
 893
 894//------------------------------------------------------------------------------
 895void GuiPopUpMenuCtrlEx::addScheme( U32 id, ColorI fontColor, ColorI fontColorHL, ColorI fontColorSEL )
 896{
 897   if ( !id )
 898      return;
 899
 900   Scheme newScheme;
 901   newScheme.id = id;
 902   newScheme.fontColor = fontColor;
 903   newScheme.fontColorHL = fontColorHL;
 904   newScheme.fontColorSEL = fontColorSEL;
 905
 906   mSchemes.push_back( newScheme );
 907}
 908
 909//------------------------------------------------------------------------------
 910S32 GuiPopUpMenuCtrlEx::getSelected()
 911{
 912   if (mSelIndex == -1)
 913      return 0;
 914   return mEntries[mSelIndex].id;
 915}
 916
 917//------------------------------------------------------------------------------
 918const char* GuiPopUpMenuCtrlEx::getTextById(S32 id)
 919{
 920   for ( U32 i = 0; i < mEntries.size(); i++ )
 921   {
 922      if ( mEntries[i].id == id )
 923         return( mEntries[i].buf );
 924   }
 925
 926   return( "" );
 927}
 928
 929//------------------------------------------------------------------------------
 930S32 GuiPopUpMenuCtrlEx::findText( const char* text )
 931{
 932   for ( U32 i = 0; i < mEntries.size(); i++ )
 933   {
 934      if ( String::compare( text, mEntries[i].buf ) == 0 )
 935         return( mEntries[i].id );        
 936   }
 937   return( -1 );
 938}
 939
 940//------------------------------------------------------------------------------
 941void GuiPopUpMenuCtrlEx::setSelected(S32 id, bool bNotifyScript )
 942{
 943   S32 i;
 944   for ( i = 0; U32(i) < mEntries.size(); i++ )
 945   {
 946      if ( id == mEntries[i].id )
 947      {
 948         i = ( mRevNum > i ) ? mRevNum - i : i;
 949         mSelIndex = i;
 950         if ( mReplaceText ) //  Only change the displayed text if appropriate.
 951         {
 952            setText(mEntries[i].buf);
 953         }
 954
 955         // Now perform the popup action:
 956         char idval[24];
 957         dSprintf( idval, sizeof(idval), "%d", mEntries[mSelIndex].id );
 958         if ( isMethod( "onSelect" ) && bNotifyScript )
 959            Con::executef( this, "onSelect", idval, mEntries[mSelIndex].buf );
 960         return;
 961      }
 962   }
 963
 964   if ( mReplaceText ) //  Only change the displayed text if appropriate.
 965   {
 966      setText("");
 967   }
 968   mSelIndex = -1;
 969
 970   if ( isMethod( "onCancel" ) && bNotifyScript )
 971      Con::executef( this, "onCancel" );
 972
 973   if ( id == -1 )
 974      return;
 975
 976   // Execute the popup console command:
 977   if ( bNotifyScript )
 978      execConsoleCallback();
 979   //if ( mConsoleCommand[0]  && bNotifyScript )
 980   //   Con::evaluate( mConsoleCommand, false );
 981}
 982
 983//------------------------------------------------------------------------------
 984//  Added to set the first item as selected.
 985void GuiPopUpMenuCtrlEx::setFirstSelected( bool bNotifyScript )
 986{
 987   if ( mEntries.size() > 0 )
 988   {
 989      mSelIndex = 0;
 990      if ( mReplaceText ) //  Only change the displayed text if appropriate.
 991      {
 992         setText( mEntries[0].buf );
 993      }
 994
 995      // Now perform the popup action:
 996      char idval[24];
 997      dSprintf( idval, sizeof(idval), "%d", mEntries[mSelIndex].id );
 998      if ( isMethod( "onSelect" ) )
 999         Con::executef( this, "onSelect", idval, mEntries[mSelIndex].buf );
1000      
1001      // Execute the popup console command:
1002      if ( bNotifyScript )
1003         execConsoleCallback();
1004   }
1005   else
1006   {
1007      if ( mReplaceText ) //  Only change the displayed text if appropriate.
1008         setText("");
1009      
1010      mSelIndex = -1;
1011
1012      if ( bNotifyScript )
1013         Con::executef( this, "onCancel" );
1014   }
1015}
1016
1017//------------------------------------------------------------------------------
1018//  Added to set no items as selected.
1019void GuiPopUpMenuCtrlEx::setNoneSelected()
1020{
1021   if ( mReplaceText ) //  Only change the displayed text if appropriate.
1022   {
1023      setText("");
1024   }
1025   mSelIndex = -1;
1026}
1027
1028//------------------------------------------------------------------------------
1029const char *GuiPopUpMenuCtrlEx::getScriptValue()
1030{
1031   return getText();
1032}
1033
1034//------------------------------------------------------------------------------
1035void GuiPopUpMenuCtrlEx::onRender(Point2I offset, const RectI &updateRect)
1036{
1037   TORQUE_UNUSED(updateRect);
1038   Point2I localStart;
1039
1040   if ( mScrollDir != GuiScrollCtrl::None )
1041      autoScroll();
1042
1043   GFXDrawUtil* drawUtil = GFX->getDrawUtil();
1044
1045   RectI r( offset, getExtent() );
1046   if ( mInAction )
1047   {
1048      S32 l = r.point.x, r2 = r.point.x + r.extent.x - 1;
1049      S32 t = r.point.y, b = r.point.y + r.extent.y - 1;
1050
1051      // Do we render a bitmap border or lines?
1052      if ( mProfile->getChildrenProfile() && mProfile->mBitmapArrayRects.size() )
1053      {
1054         // Render the fixed, filled in border
1055         renderFixedBitmapBordersFilled(r, 3, mProfile );
1056
1057      } 
1058      else
1059      {
1060         //renderSlightlyLoweredBox(r, mProfile);
1061         drawUtil->drawRectFill( r, mProfile->mFillColor );
1062      }
1063
1064      //  Draw a bitmap over the background?
1065      if ( mTextureDepressed )
1066      {
1067         RectI rect(offset, mBitmapBounds);
1068         drawUtil->clearBitmapModulation();
1069         drawUtil->drawBitmapStretch( mTextureDepressed, rect );
1070      } 
1071      else if ( mTextureNormal )
1072      {
1073         RectI rect(offset, mBitmapBounds);
1074         drawUtil->clearBitmapModulation();
1075         drawUtil->drawBitmapStretch( mTextureNormal, rect );
1076      }
1077
1078      // Do we render a bitmap border or lines?
1079      if ( !( mProfile->getChildrenProfile() && mProfile->mBitmapArrayRects.size() ) )
1080      {
1081         drawUtil->drawLine( l, t, l, b, colorWhite );
1082         drawUtil->drawLine( l, t, r2, t, colorWhite );
1083         drawUtil->drawLine( l + 1, b, r2, b, mProfile->mBorderColor );
1084         drawUtil->drawLine( r2, t + 1, r2, b - 1, mProfile->mBorderColor );
1085      }
1086
1087   }
1088   else   
1089      // TODO: Implement
1090      // TODO: Add onMouseEnter() and onMouseLeave() and a definition of mMouseOver (see guiButtonBaseCtrl) for this to work.
1091      if ( mMouseOver ) 
1092      {
1093         S32 l = r.point.x, r2 = r.point.x + r.extent.x - 1;
1094         S32 t = r.point.y, b = r.point.y + r.extent.y - 1;
1095
1096         // Do we render a bitmap border or lines?
1097         if ( mProfile->getChildrenProfile() && mProfile->mBitmapArrayRects.size() )
1098         {
1099            // Render the fixed, filled in border
1100            renderFixedBitmapBordersFilled( r, 2, mProfile );
1101
1102         } 
1103         else
1104         {
1105            drawUtil->drawRectFill( r, mProfile->mFillColorHL );
1106         }
1107
1108         //  Draw a bitmap over the background?
1109         if ( mTextureNormal )
1110         {
1111            RectI rect( offset, mBitmapBounds );
1112            drawUtil->clearBitmapModulation();
1113            drawUtil->drawBitmapStretch( mTextureNormal, rect );
1114         }
1115
1116         // Do we render a bitmap border or lines?
1117         if ( !( mProfile->getChildrenProfile() && mProfile->mBitmapArrayRects.size() ) )
1118         {
1119            drawUtil->drawLine( l, t, l, b, colorWhite );
1120            drawUtil->drawLine( l, t, r2, t, colorWhite );
1121            drawUtil->drawLine( l + 1, b, r2, b, mProfile->mBorderColor );
1122            drawUtil->drawLine( r2, t + 1, r2, b - 1, mProfile->mBorderColor );
1123         }
1124      }
1125      else
1126      {
1127         // Do we render a bitmap border or lines?
1128         if ( mProfile->getChildrenProfile() && mProfile->mBitmapArrayRects.size() )
1129         {
1130            // Render the fixed, filled in border
1131            renderFixedBitmapBordersFilled( r, 1, mProfile );
1132         } 
1133         else
1134         {
1135            drawUtil->drawRectFill( r, mProfile->mFillColorNA );
1136         }
1137
1138         //  Draw a bitmap over the background?
1139         if ( mTextureNormal )
1140         {
1141            RectI rect(offset, mBitmapBounds);
1142            drawUtil->clearBitmapModulation();
1143            drawUtil->drawBitmapStretch( mTextureNormal, rect );
1144         }
1145
1146         // Do we render a bitmap border or lines?
1147         if ( !( mProfile->getChildrenProfile() && mProfile->mBitmapArrayRects.size() ) )
1148         {
1149            drawUtil->drawRect( r, mProfile->mBorderColorNA );
1150         }
1151      }
1152      //      renderSlightlyRaisedBox(r, mProfile); //  Used to be the only 'else' condition to mInAction above.
1153
1154      S32 txt_w = mProfile->mFont->getStrWidth(mText);
1155      localStart.x = 0;
1156      localStart.y = (getHeight() - (mProfile->mFont->getHeight())) / 2;
1157
1158      // align the horizontal
1159      switch (mProfile->mAlignment)
1160      {
1161      case GuiControlProfile::RightJustify:
1162         if ( mProfile->getChildrenProfile() && mProfile->mBitmapArrayRects.size() )
1163         {
1164            // We're making use of a bitmap border, so take into account the
1165            // right cap of the border.
1166            RectI* bitmapBounds = mProfile->mBitmapArrayRects.address();
1167            localStart.x = getWidth() - bitmapBounds[2].extent.x - txt_w;
1168         } 
1169         else
1170         {
1171            localStart.x = getWidth() - txt_w;  
1172         }
1173         break;
1174      case GuiControlProfile::CenterJustify:
1175         if ( mProfile->getChildrenProfile() && mProfile->mBitmapArrayRects.size() )
1176         {
1177            // We're making use of a bitmap border, so take into account the
1178            // right cap of the border.
1179            RectI* bitmapBounds = mProfile->mBitmapArrayRects.address();
1180            localStart.x = (getWidth() - bitmapBounds[2].extent.x - txt_w) / 2;
1181
1182         } else
1183         {
1184            localStart.x = (getWidth() - txt_w) / 2;
1185         }
1186         break;
1187      default:
1188         // GuiControlProfile::LeftJustify
1189         if ( txt_w > getWidth() )
1190         {
1191            //  The width of the text is greater than the width of the control.
1192            // In this case we will right justify the text and leave some space
1193            // for the down arrow.
1194            if ( mProfile->getChildrenProfile() && mProfile->mBitmapArrayRects.size() )
1195            {
1196               // We're making use of a bitmap border, so take into account the
1197               // right cap of the border.
1198               RectI* bitmapBounds = mProfile->mBitmapArrayRects.address();
1199               localStart.x = getWidth() - bitmapBounds[2].extent.x - txt_w;
1200            } 
1201            else
1202            {
1203               localStart.x = getWidth() - txt_w - 12;
1204            }
1205         } 
1206         else
1207         {
1208            localStart.x = mProfile->mTextOffset.x; //  Use mProfile->mTextOffset as a controlable margin for the control's text.
1209         }
1210         break;
1211      }
1212
1213      //  Do we first draw a coloured box beside the text?
1214      ColorI boxColor;
1215      bool drawbox = getColoredBox( boxColor, mSelIndex);
1216      if ( drawbox )
1217      {
1218         Point2I coloredboxsize( 15, 10 );
1219         RectI boxBounds( offset.x + mProfile->mTextOffset.x, offset.y + ( (getHeight() - coloredboxsize.y ) / 2 ), coloredboxsize.x, coloredboxsize.y );
1220         drawUtil->drawRectFill(boxBounds, boxColor);
1221         drawUtil->drawRect(boxBounds, ColorI(0,0,0));
1222
1223         localStart.x += coloredboxsize.x + mProfile->mTextOffset.x;
1224      }
1225
1226      // Draw the text
1227      Point2I globalStart = localToGlobalCoord( localStart );
1228      ColorI fontColor   = mActive ? ( mInAction ? mProfile->mFontColor : mProfile->mFontColorNA ) : mProfile->mFontColorNA;
1229      drawUtil->setBitmapModulation( fontColor ); //  was: (mProfile->mFontColor);
1230
1231      //  Get the number of columns in the text
1232      S32 colcount = getColumnCount( mText, "\t" );
1233
1234      //  Are there two or more columns?
1235      if ( colcount >= 2 )
1236      {
1237         char buff[256];
1238
1239         // Draw the first column
1240         getColumn( mText, buff, 0, "\t" );
1241         drawUtil->drawText( mProfile->mFont, globalStart, buff, mProfile->mFontColors );
1242
1243         // Draw the second column to the right
1244         getColumn( mText, buff, 1, "\t" );
1245         S32 colTxt_w = mProfile->mFont->getStrWidth( buff );
1246         if ( mProfile->getChildrenProfile() && mProfile->mBitmapArrayRects.size() )
1247         {
1248            // We're making use of a bitmap border, so take into account the
1249            // right cap of the border.
1250            RectI* bitmapBounds = mProfile->mBitmapArrayRects.address();
1251            Point2I textpos = localToGlobalCoord( Point2I( getWidth() - colTxt_w - bitmapBounds[2].extent.x, localStart.y ) );
1252            drawUtil->drawText( mProfile->mFont, textpos, buff, mProfile->mFontColors );
1253
1254         } else
1255         {
1256            Point2I textpos = localToGlobalCoord( Point2I( getWidth() - colTxt_w - 12, localStart.y ) );
1257            drawUtil->drawText( mProfile->mFont, textpos, buff, mProfile->mFontColors );
1258         }
1259
1260      } else
1261      {
1262         drawUtil->drawText( mProfile->mFont, globalStart, mText, mProfile->mFontColors );
1263      }
1264
1265      // If we're rendering a bitmap border, then it will take care of the arrow.
1266      if ( !(mProfile->getChildrenProfile() && mProfile->mBitmapArrayRects.size()) )
1267      {
1268         //  Draw a triangle (down arrow)
1269         S32 left = r.point.x + r.extent.x - 12;
1270         S32 right = left + 8;
1271         S32 middle = left + 4;
1272         S32 top = r.extent.y / 2 + r.point.y - 4;
1273         S32 bottom = top + 8;
1274
1275         PrimBuild::color( mProfile->mFontColor );
1276
1277         PrimBuild::begin( GFXTriangleList, 3 );
1278            PrimBuild::vertex2fv( Point3F( (F32)left, (F32)top, 0.0f ) );
1279            PrimBuild::vertex2fv( Point3F( (F32)right, (F32)top, 0.0f ) );
1280            PrimBuild::vertex2fv( Point3F( (F32)middle, (F32)bottom, 0.0f ) );
1281         PrimBuild::end();
1282      }
1283}
1284
1285//------------------------------------------------------------------------------
1286void GuiPopUpMenuCtrlEx::closePopUp()
1287{
1288   if ( !mInAction )
1289      return;
1290
1291   // Get the selection from the text list:
1292   mSelIndex = mTl->getSelectedCell().y;
1293   mSelIndex = ( mRevNum >= mSelIndex && mSelIndex != -1 ) ? mRevNum - mSelIndex : mSelIndex;
1294   if ( mSelIndex != -1 )
1295   {
1296      if ( mReplaceText )
1297         setText( mEntries[mSelIndex].buf );
1298      setIntVariable( mEntries[mSelIndex].id );
1299   }
1300
1301   // Release the mouse:
1302   mInAction = false;
1303   mTl->mouseUnlock();
1304
1305   //  Commented out below and moved to the end of the function.  See the
1306   // note below for the reason why.
1307   /*
1308   // Pop the background:
1309   getRoot()->popDialogControl(mBackground);
1310
1311   // Kill the popup:
1312   mBackground->removeObject( mSc );
1313   mTl->deleteObject();
1314   mSc->deleteObject();
1315   mBackground->deleteObject();
1316
1317   // Set this as the first responder:
1318   setFocus();
1319   */
1320
1321   // Now perform the popup action:
1322   if ( mSelIndex != -1 )
1323   {
1324      char idval[24];
1325      dSprintf( idval, sizeof(idval), "%d", mEntries[mSelIndex].id );
1326      if ( isMethod( "onSelect" ) )
1327         Con::executef( this, "onSelect", idval, mEntries[mSelIndex].buf );
1328   }
1329   else if ( isMethod( "onCancel" ) )
1330      Con::executef( this, "onCancel" );
1331
1332   // Execute the popup console command:
1333   execConsoleCallback();
1334   //if ( mConsoleCommand[0] )
1335   //   Con::evaluate( mConsoleCommand, false );
1336
1337   //  Reordered this pop dialog to be after the script select callback.  When the
1338   // background was popped it was causing all sorts of focus issues when
1339   // suddenly the first text edit control took the focus before it came back
1340   // to this popup.
1341
1342   // Pop the background:
1343   GuiCanvas *root = getRoot();
1344   if ( root )
1345      root->popDialogControl(mBackground);
1346
1347   // Kill the popup:
1348   mBackground->removeObject( mSc );
1349   mTl->deleteObject();
1350   mSc->deleteObject();
1351   mBackground->deleteObject();
1352
1353   // Set this as the first responder:
1354   setFirstResponder();
1355}
1356
1357//------------------------------------------------------------------------------
1358bool GuiPopUpMenuCtrlEx::onKeyDown(const GuiEvent &event)
1359{
1360   //if the control is a dead end, don't process the input:
1361   if ( !mVisible || !mActive || !mAwake )
1362      return false;
1363
1364   //see if the key down is a <return> or not
1365   if ( event.keyCode == KEY_RETURN && event.modifier == 0 )
1366   {
1367      onAction();
1368      return true;
1369   }
1370
1371   //otherwise, pass the event to its parent
1372   return Parent::onKeyDown( event );
1373}
1374
1375//------------------------------------------------------------------------------
1376void GuiPopUpMenuCtrlEx::onAction()
1377{
1378   GuiControl *canCtrl = getParent();
1379
1380   addChildren();
1381
1382   GuiCanvas *root = getRoot();
1383   Point2I windowExt = root->getExtent();
1384
1385   mBackground->resize( Point2I(0,0), root->getExtent() );
1386   
1387   S32 textWidth = 0, width = getWidth();
1388   //const S32 menuSpace = 5; //  Removed as no longer used.
1389   const S32 textSpace = 2;
1390   bool setScroll = false;
1391
1392   for ( U32 i = 0; i < mEntries.size(); ++i )
1393      if ( S32(mProfile->mFont->getStrWidth( mEntries[i].buf )) > textWidth )
1394         textWidth = mProfile->mFont->getStrWidth( mEntries[i].buf );
1395
1396   //if(textWidth > getWidth())
1397   S32 sbWidth = mSc->getControlProfile()->mBorderThickness * 2 + mSc->scrollBarThickness(); //  Calculate the scroll bar width
1398   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.
1399   {
1400      //textWidth +=10;
1401      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.
1402      width = textWidth;
1403
1404      //  If a child margin is not defined for the scroll control, let's add
1405      //      some space between the text and scroll control for readability
1406      if(mSc->getChildMargin().x == 0)
1407         width += textSpace;
1408   }
1409
1410   //mTl->setCellSize(Point2I(width, mFont->getHeight()+3));
1411   mTl->setCellSize(Point2I(width, mProfile->mFont->getHeight() + textSpace)); //  Modified the above line to use textSpace rather than the '3' as this is what is used below.
1412
1413   for ( U32 j = 0; j < mEntries.size(); ++j )
1414      mTl->addEntry( mEntries[j].id, mEntries[j].buf );
1415
1416   if ( mSelIndex >= 0 )
1417      mTl->setSelectedCell( Point2I( 0, mSelIndex ) );
1418
1419   Point2I pointInGC = canCtrl->localToGlobalCoord( getPosition() );
1420   Point2I scrollPoint( pointInGC.x, pointInGC.y + getHeight() ); 
1421
1422   //Calc max Y distance, so Scroll Ctrl will fit on window 
1423   //S32 maxYdis = windowExt.y - pointInGC.y - getHeight() - menuSpace; 
1424   S32 sbBorder = mSc->getControlProfile()->mBorderThickness * 2 + mSc->getChildMargin().y * 2; //  Added to take into account the border thickness and the margin of the child controls of the scroll control when figuring out the size of the contained text list control
1425   S32 maxYdis = windowExt.y - pointInGC.y - getHeight() - sbBorder; // - menuSpace; //  Need to remove the border thickness from the contained control maximum extent and got rid of the 'menuspace' variable
1426
1427   //If scroll bars need to be added
1428   mRevNum = 0; //  Added here rather than within the following 'if' statements.
1429   if ( maxYdis < mTl->getHeight() + sbBorder ) //  Instead of adding sbBorder, it was: 'textSpace'
1430   {
1431      //Should we pop menu list above the button
1432      if ( maxYdis < pointInGC.y ) //  removed: '- menuSpace)' from check to see if there is more space above the control than below.
1433      {
1434         if(mReverseTextList) //  Added this check if we should reverse the text list.
1435            reverseTextList();
1436
1437         maxYdis = pointInGC.y; //  Was at the end: '- menuSpace;'
1438         //Does the menu need a scroll bar 
1439         if ( maxYdis < mTl->getHeight() + sbBorder ) //  Instead of adding sbBorder, it was: 'textSpace'
1440         {
1441            //  Removed width recalculation for scroll bar as the scroll bar is already being taken into account.
1442            //Calc for the width of the scroll bar 
1443            //            if(textWidth >=  width)
1444            //               width += 20;
1445            //            mTl->setCellSize(Point2I(width,mFont->getHeight() + textSpace));
1446
1447            //Pop menu list above the button
1448            //            scrollPoint.set(pointInGC.x, menuSpace - 1); //  Removed as calculated outside the 'if', and was wrong to begin with
1449            setScroll = true;
1450         }
1451         //No scroll bar needed
1452         else
1453         {
1454            maxYdis = mTl->getHeight() + sbBorder; //  Instead of adding sbBorder, it was: 'textSpace'
1455            //            scrollPoint.set(pointInGC.x, pointInGC.y - maxYdis -1); //  Removed as calculated outside the 'if' and the '-1' at the end is wrong
1456         }
1457
1458         //  Added the next two lines
1459         scrollPoint.set(pointInGC.x, pointInGC.y - maxYdis); //  Used to have the following on the end: '-1);'
1460      } 
1461      //Scroll bar needed but Don't pop above button
1462      else
1463      {
1464         //mRevNum = 0; //  Commented out as it has been added at the beginning of this function
1465
1466         //  Removed width recalculation for scroll bar as the scroll bar is already being taken into account.
1467         //Calc for the width of the scroll bar 
1468         //         if(textWidth >=  width)
1469         //            width += 20;
1470         //         mTl->setCellSize(Point2I(width,mFont->getHeight() + textSpace));
1471         setScroll = true;
1472      }
1473   }
1474   //No scroll bar needed
1475   else
1476   {
1477
1478      //maxYdis = mTl->getHeight() + textSpace;
1479      maxYdis = mTl->getHeight() + sbBorder; //  Added in the border thickness of the scroll control and removed the addition of textSpace
1480   }
1481
1482   RectI newBounds = mSc->getBounds();
1483
1484   //offset it from the background so it lines up properly
1485   newBounds.point = mBackground->globalToLocalCoord( scrollPoint );
1486
1487   if ( newBounds.point.x + width > mBackground->getWidth() )
1488      if ( width - getWidth() > 0 )
1489         newBounds.point.x -= width - getWidth();
1490
1491   //mSc->getExtent().set(width-1, maxYdis);
1492   newBounds.extent.set( width, maxYdis );
1493   mSc->setBounds( newBounds ); //  Not sure why the '-1' above.
1494
1495   mSc->registerObject();
1496   mTl->registerObject();
1497   mBackground->registerObject();
1498
1499   mSc->addObject( mTl );
1500   mBackground->addObject( mSc );
1501
1502   mBackgroundCancel = false; //  Setup check if user clicked on the background instead of the text list (ie: didn't want to change their current selection).
1503
1504   root->pushDialogControl( mBackground, 99 );
1505
1506   if ( setScroll )
1507   {
1508      // Resize the text list
1509     Point2I cellSize;
1510     mTl->getCellSize( cellSize );
1511     cellSize.x = width - mSc->scrollBarThickness() - sbBorder;
1512     mTl->setCellSize( cellSize );
1513     mTl->setWidth( cellSize.x );
1514
1515      if ( mSelIndex )
1516         mTl->scrollCellVisible( Point2I( 0, mSelIndex ) );
1517      else
1518         mTl->scrollCellVisible( Point2I( 0, 0 ) );
1519   }
1520
1521   mTl->setFirstResponder();
1522
1523   mInAction = true;
1524}
1525
1526//------------------------------------------------------------------------------
1527void GuiPopUpMenuCtrlEx::addChildren()
1528{
1529   mTl = new GuiPopupTextListCtrlEx( this );
1530   AssertFatal( mTl, "Failed to create the GuiPopUpTextListCtrlEx for the PopUpMenu" );
1531   // Use the children's profile rather than the parent's profile, if it exists.
1532   mTl->setControlProfile( mProfile->getChildrenProfile() ? mProfile->getChildrenProfile() : mProfile ); 
1533   mTl->setField("noDuplicates", "false");
1534
1535   mSc = new GuiScrollCtrl;
1536   AssertFatal( mSc, "Failed to create the GuiScrollCtrl for the PopUpMenu" );
1537   GuiControlProfile *prof;
1538   if ( Sim::findObject( "GuiScrollProfile", prof ) )
1539   {
1540      mSc->setControlProfile( prof );
1541   }
1542   else
1543   {
1544      // Use the children's profile rather than the parent's profile, if it exists.
1545     mSc->setControlProfile( mProfile->getChildrenProfile() ? mProfile->getChildrenProfile() : mProfile );
1546   }
1547   mSc->setField( "hScrollBar", "AlwaysOff" );
1548   mSc->setField( "vScrollBar", "dynamic" );
1549   //if(mRenderScrollInNA) //  Force the scroll control to render using fillColorNA rather than fillColor
1550   // mSc->mUseNABackground = true;
1551
1552   mBackground = new GuiPopUpBackgroundCtrlEx( this, mTl );
1553   AssertFatal( mBackground, "Failed to create the GuiBackgroundCtrlEx for the PopUpMenu" );
1554}
1555
1556//------------------------------------------------------------------------------
1557void GuiPopUpMenuCtrlEx::repositionPopup()
1558{
1559   if ( !mInAction || !mSc || !mTl )
1560      return;
1561
1562   // I'm not concerned with this right now...
1563}
1564
1565//------------------------------------------------------------------------------
1566void GuiPopUpMenuCtrlEx::reverseTextList()
1567{
1568   mTl->clear();
1569   for ( S32 i = mEntries.size()-1; i >= 0; --i )
1570      mTl->addEntry( mEntries[i].id, mEntries[i].buf );
1571
1572   // Don't lose the selected cell:
1573   if ( mSelIndex >= 0 )
1574      mTl->setSelectedCell( Point2I( 0, mEntries.size() - mSelIndex - 1 ) ); 
1575
1576   mRevNum = mEntries.size() - 1;
1577}
1578
1579//------------------------------------------------------------------------------
1580bool GuiPopUpMenuCtrlEx::getFontColor( ColorI &fontColor, S32 id, bool selected, bool mouseOver )
1581{
1582   U32 i;
1583   Entry* entry = NULL;
1584   for ( i = 0; i < mEntries.size(); i++ )
1585   {
1586      if ( mEntries[i].id == id )
1587      {
1588         entry = &mEntries[i];
1589         break;
1590      }
1591   }
1592
1593   if ( !entry )
1594      return( false );
1595
1596   if ( entry->scheme != 0 )
1597   {
1598      // Find the entry's color scheme:
1599      for ( i = 0; i < mSchemes.size(); i++ )
1600      {
1601         if ( mSchemes[i].id == entry->scheme )
1602         {
1603            fontColor = selected ? mSchemes[i].fontColorSEL : mouseOver ? mSchemes[i].fontColorHL : mSchemes[i].fontColor;
1604            return( true );
1605         }
1606      }
1607   }
1608
1609   if(id == -1)
1610      fontColor = mProfile->mFontColorHL;
1611   else
1612   // Default color scheme...
1613   fontColor = selected ? mProfile->mFontColorSEL : mouseOver ? mProfile->mFontColorHL : mProfile->mFontColorNA; //  Modified the final color choice from mProfile->mFontColor to mProfile->mFontColorNA
1614
1615   return( true );
1616}
1617
1618//------------------------------------------------------------------------------
1619//  Added
1620bool GuiPopUpMenuCtrlEx::getColoredBox( ColorI &fontColor, S32 id )
1621{
1622   U32 i;
1623   Entry* entry = NULL;
1624   for ( i = 0; i < mEntries.size(); i++ )
1625   {
1626      if ( mEntries[i].id == id )
1627      {
1628         entry = &mEntries[i];
1629         break;
1630      }
1631   }
1632
1633   if ( !entry )
1634      return false;
1635
1636   if ( entry->usesColorBox == false )
1637      return false;
1638
1639   fontColor = entry->colorbox;
1640
1641   return true;
1642}
1643
1644//------------------------------------------------------------------------------
1645void GuiPopUpMenuCtrlEx::onMouseDown(const GuiEvent &event)
1646{
1647   TORQUE_UNUSED(event);
1648   onAction();
1649}
1650
1651//------------------------------------------------------------------------------
1652void GuiPopUpMenuCtrlEx::onMouseUp(const GuiEvent &event)
1653{
1654   TORQUE_UNUSED(event);
1655}
1656
1657//------------------------------------------------------------------------------
1658//  Added
1659void GuiPopUpMenuCtrlEx::onMouseEnter(const GuiEvent &event)
1660{
1661   mMouseOver = true;
1662}
1663
1664//------------------------------------------------------------------------------
1665//  Added
1666void GuiPopUpMenuCtrlEx::onMouseLeave(const GuiEvent &)
1667{
1668   mMouseOver = false;
1669}
1670
1671//------------------------------------------------------------------------------
1672void GuiPopUpMenuCtrlEx::setupAutoScroll(const GuiEvent &event)
1673{
1674   GuiControl *parent = getParent();
1675   if ( !parent ) 
1676      return;
1677
1678   Point2I mousePt = mSc->globalToLocalCoord( event.mousePoint );
1679
1680   mEventSave = event;      
1681
1682   if ( mLastYvalue != mousePt.y )
1683   {
1684      mScrollDir = GuiScrollCtrl::None;
1685      if ( mousePt.y > mSc->getHeight() || mousePt.y < 0 )
1686      {
1687         S32 topOrBottom = ( mousePt.y > mSc->getHeight() ) ? 1 : 0;
1688         mSc->scrollTo( 0, topOrBottom );
1689         return;
1690      }   
1691
1692      F32 percent = (F32)mousePt.y / (F32)mSc->getHeight();
1693      if ( percent > 0.7f && mousePt.y > mLastYvalue )
1694      {
1695         mIncValue = percent - 0.5f;
1696         mScrollDir = GuiScrollCtrl::DownArrow;
1697      }
1698      else if ( percent < 0.3f && mousePt.y < mLastYvalue )
1699      {
1700         mIncValue = 0.5f - percent;         
1701         mScrollDir = GuiScrollCtrl::UpArrow;
1702      }
1703      mLastYvalue = mousePt.y;
1704   }
1705}
1706
1707//------------------------------------------------------------------------------
1708void GuiPopUpMenuCtrlEx::autoScroll()
1709{
1710   mScrollCount += mIncValue;
1711
1712   while ( mScrollCount > 1 )
1713   {
1714      mSc->autoScroll( mScrollDir );
1715      mScrollCount -= 1;
1716   }
1717   mTl->onMouseMove( mEventSave );
1718}
1719
1720//------------------------------------------------------------------------------
1721void GuiPopUpMenuCtrlEx::replaceText(S32 boolVal)
1722{
1723   mReplaceText = boolVal;
1724}
1725