guiPopUpCtrlEx.cpp
Engine/source/gui/controls/guiPopUpCtrlEx.cpp
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>" )
getColumnCount(const char * string, const char * set)
textCompare(const void * a, const void * b)
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