Torque3D Documentation / _generateds / guiFrameCtrl.cpp

guiFrameCtrl.cpp

Engine/source/gui/containers/guiFrameCtrl.cpp

More...

Public Functions

ConsoleDocClass(GuiFrameSetCtrl , "@brief A gui <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> allowing <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> window <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be subdivided into panes, each " "of which displays <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> gui <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> child of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiFrameSetCtrl.\n\n</a>" "Each gui <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> child will have an associated FrameDetail through which " "frame-specific details can be assigned. Frame-specific values override the " "values specified <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the entire <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">frameset.\n\n</a>" "Note that it is possible <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> have more children than frames, or more frames " "than children. In the former case, the extra children will not be visible " "(they are moved beyond the visible extent of the frameset). In the latter " " case, frames will be empty. For example, <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> frameset had two columns and " "two rows but only three gui <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> children they would be assigned <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> " "frames as <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">follows:\n</a>" "< pre >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " 1|2\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " -----\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " 3|\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "</pre >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "The last frame would be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">blank.\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/classguiframesetctrl/">GuiFrameSetCtrl</a>()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " columns=\"3\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "   rows = \"2\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "   borderWidth = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "   borderColor = \"128 128 128\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "   borderEnable = \"dynamic\";\n" "   borderMovable = \"dynamic\";\n" "   autoBalance = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "   fudgeFactor = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "   //Properties not specific <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> this <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> have been omitted from this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">example.\n</a>" "};\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@ingroup GuiContainers" )
DefineEngineMethod(GuiFrameSetCtrl , addColumn , void , () , "Add <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">column.\n\n</a>" )
DefineEngineMethod(GuiFrameSetCtrl , addRow , void , () , "Add <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">row.\n\n</a>" )
DefineEngineMethod(GuiFrameSetCtrl , frameBorder , void , (S32 index, const char *state) , ("dynamic") , "Override the <<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a>>borderEnable</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a>> setting <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">frame.\n\n</a>" "@param index Index of the frame <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">modify\n</a>" "@param state New borderEnable state: \"on\" , \"off\" or \"dynamic\"\n" )
DefineEngineMethod(GuiFrameSetCtrl , frameMinExtent , void , (S32 index, S32 width, S32 height) , "Set the minimum width and height <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the frame. It will not be possible " "<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the user <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> resize the frame smaller than <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">this.\n\n</a>" "@param index Index of the frame <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">modify\n</a>" "@param width Minimum width in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">pixels\n</a>" "@param height Minimum height in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">pixels\n</a>" )
DefineEngineMethod(GuiFrameSetCtrl , frameMovable , void , (S32 index, const char *state) , ("dynamic") , "Override the <<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a>>borderMovable</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a>> setting <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">frame.\n\n</a>" "@param index Index of the frame <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">modify\n</a>" "@param state New borderEnable state: \"on\" , \"off\" or \"dynamic\"\n" )
DefineEngineMethod(GuiFrameSetCtrl , framePadding , void , (S32 index, RectSpacingI padding) , "Set the padding <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> this frame. Padding introduces blank space on the inside " "edge of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">frame.\n\n</a>" "@param index Index of the frame <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">modify\n</a>" "@param padding Frame top, bottom , left , and right <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">padding\n</a>" )
DefineEngineMethod(GuiFrameSetCtrl , getColumnCount , S32 , () , "Get the number of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">columns.\n\n</a>" "@return The number of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">columns\n</a>" )
DefineEngineMethod(GuiFrameSetCtrl , getColumnOffset , S32 , (S32 index) , "Get the horizontal offset of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">column.\n\n</a>" "@param index Index of the column <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">query\n</a>" "@return Column offset in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">pixels\n</a>" )
DefineEngineMethod(GuiFrameSetCtrl , getFramePadding , RectSpacingI , (S32 index) , "Get the padding <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">frame.\n\n</a>" "@param index Index of the frame <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">query\n</a>" )
DefineEngineMethod(GuiFrameSetCtrl , getRowCount , S32 , () , "Get the number of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">rows.\n\n</a>" "@return The number of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">rows\n</a>" )
DefineEngineMethod(GuiFrameSetCtrl , getRowOffset , S32 , (S32 index) , "Get the vertical offset of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">row.\n\n</a>" "@param index Index of the row <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">query\n</a>" "@return Row offset in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">pixels\n</a>" )
DefineEngineMethod(GuiFrameSetCtrl , removeColumn , void , () , "Remove the last (rightmost) <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">column.\n\n</a>" )
DefineEngineMethod(GuiFrameSetCtrl , removeRow , void , () , "Remove the last (bottom) <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">row.\n\n</a>" )
DefineEngineMethod(GuiFrameSetCtrl , setColumnOffset , void , (S32 index, S32 offset) , "Set the horizontal offset of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">column.\n\n</a>" "Note that column offsets must always be in increasing order, and therefore " "this offset must be between the offsets of the colunns either <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">side.\n</a>" " @param index Index of the column <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">modify\n</a>" " @param offset New column <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">offset\n</a>" )
DefineEngineMethod(GuiFrameSetCtrl , setRowOffset , void , (S32 index, S32 offset) , "Set the vertical offset of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">row.\n\n</a>" "Note that row offsets must always be in increasing order, and therefore " "this offset must be between the offsets of the rows either <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">side.\n</a>" " @param index Index of the row <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">modify\n</a>" " @param offset New row <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">offset\n</a>" )
DefineEngineMethod(GuiFrameSetCtrl , updateSizes , void , () , "Recalculates child <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> sizes." )
ImplementEnumType(GuiFrameState , "\n\n" "@ingroup GuiContainers" )

Detailed Description

Public Functions

ConsoleDocClass(GuiFrameSetCtrl , "@brief A gui <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> allowing <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> window <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be subdivided into panes, each " "of which displays <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> gui <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> child of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GuiFrameSetCtrl.\n\n</a>" "Each gui <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> child will have an associated FrameDetail through which " "frame-specific details can be assigned. Frame-specific values override the " "values specified <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the entire <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">frameset.\n\n</a>" "Note that it is possible <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> have more children than frames, or more frames " "than children. In the former case, the extra children will not be visible " "(they are moved beyond the visible extent of the frameset). In the latter " " case, frames will be empty. For example, <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> frameset had two columns and " "two rows but only three gui <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> children they would be assigned <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> " "frames as <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">follows:\n</a>" "< pre >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " 1|2\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " -----\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " 3|\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "</pre >\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "The last frame would be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">blank.\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/classguiframesetctrl/">GuiFrameSetCtrl</a>()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "{\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " columns=\"3\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "   rows = \"2\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "   borderWidth = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "   borderColor = \"128 128 128\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "   borderEnable = \"dynamic\";\n" "   borderMovable = \"dynamic\";\n" "   autoBalance = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "   fudgeFactor = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "   //Properties not specific <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> this <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> have been omitted from this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">example.\n</a>" "};\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@ingroup GuiContainers" )

DefineEngineMethod(GuiFrameSetCtrl , addColumn , void , () , "Add <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">column.\n\n</a>" )

DefineEngineMethod(GuiFrameSetCtrl , addRow , void , () , "Add <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">row.\n\n</a>" )

DefineEngineMethod(GuiFrameSetCtrl , frameBorder , void , (S32 index, const char *state) , ("dynamic") , "Override the <<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a>>borderEnable</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a>> setting <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">frame.\n\n</a>" "@param index Index of the frame <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">modify\n</a>" "@param state New borderEnable state: \"on\" , \"off\" or \"dynamic\"\n" )

DefineEngineMethod(GuiFrameSetCtrl , frameMinExtent , void , (S32 index, S32 width, S32 height) , "Set the minimum width and height <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the frame. It will not be possible " "<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> the user <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> resize the frame smaller than <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">this.\n\n</a>" "@param index Index of the frame <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">modify\n</a>" "@param width Minimum width in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">pixels\n</a>" "@param height Minimum height in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">pixels\n</a>" )

DefineEngineMethod(GuiFrameSetCtrl , frameMovable , void , (S32 index, const char *state) , ("dynamic") , "Override the <<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a>>borderMovable</<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1acb559820d9ca11295b4500f179ef6392">i</a>> setting <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">frame.\n\n</a>" "@param index Index of the frame <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">modify\n</a>" "@param state New borderEnable state: \"on\" , \"off\" or \"dynamic\"\n" )

DefineEngineMethod(GuiFrameSetCtrl , framePadding , void , (S32 index, RectSpacingI padding) , "Set the padding <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> this frame. Padding introduces blank space on the inside " "edge of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">frame.\n\n</a>" "@param index Index of the frame <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">modify\n</a>" "@param padding Frame top, bottom , left , and right <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">padding\n</a>" )

DefineEngineMethod(GuiFrameSetCtrl , getColumnCount , S32 , () , "Get the number of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">columns.\n\n</a>" "@return The number of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">columns\n</a>" )

DefineEngineMethod(GuiFrameSetCtrl , getColumnOffset , S32 , (S32 index) , "Get the horizontal offset of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">column.\n\n</a>" "@param index Index of the column <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">query\n</a>" "@return Column offset in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">pixels\n</a>" )

DefineEngineMethod(GuiFrameSetCtrl , getFramePadding , RectSpacingI , (S32 index) , "Get the padding <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">frame.\n\n</a>" "@param index Index of the frame <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">query\n</a>" )

DefineEngineMethod(GuiFrameSetCtrl , getRowCount , S32 , () , "Get the number of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">rows.\n\n</a>" "@return The number of <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">rows\n</a>" )

DefineEngineMethod(GuiFrameSetCtrl , getRowOffset , S32 , (S32 index) , "Get the vertical offset of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">row.\n\n</a>" "@param index Index of the row <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">query\n</a>" "@return Row offset in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">pixels\n</a>" )

DefineEngineMethod(GuiFrameSetCtrl , removeColumn , void , () , "Remove the last (rightmost) <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">column.\n\n</a>" )

DefineEngineMethod(GuiFrameSetCtrl , removeRow , void , () , "Remove the last (bottom) <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">row.\n\n</a>" )

DefineEngineMethod(GuiFrameSetCtrl , setColumnOffset , void , (S32 index, S32 offset) , "Set the horizontal offset of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">column.\n\n</a>" "Note that column offsets must always be in increasing order, and therefore " "this offset must be between the offsets of the colunns either <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">side.\n</a>" " @param index Index of the column <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">modify\n</a>" " @param offset New column <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">offset\n</a>" )

DefineEngineMethod(GuiFrameSetCtrl , setRowOffset , void , (S32 index, S32 offset) , "Set the vertical offset of <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">row.\n\n</a>" "Note that row offsets must always be in increasing order, and therefore " "this offset must be between the offsets of the rows either <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">side.\n</a>" " @param index Index of the row <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">modify\n</a>" " @param offset New row <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">offset\n</a>" )

DefineEngineMethod(GuiFrameSetCtrl , updateSizes , void , () , "Recalculates child <a href="/coding/file/guieditctrl_8cpp/#guieditctrl_8cpp_1abb04e3738c4c5a96b3ade6fa47013a6c">control</a> sizes." )

IMPLEMENT_CONOBJECT(GuiFrameSetCtrl )

ImplementEnumType(GuiFrameState , "\n\n" "@ingroup GuiContainers" )

   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 "platform/platform.h"
  25#include "gui/containers/guiFrameCtrl.h"
  26
  27#include "console/consoleTypes.h"
  28#include "console/engineAPI.h"
  29#include "gui/core/guiCanvas.h"
  30#include "gfx/gfxDrawUtil.h"
  31
  32
  33IMPLEMENT_CONOBJECT(GuiFrameSetCtrl);
  34
  35ConsoleDocClass( GuiFrameSetCtrl,
  36   "@brief A gui control allowing a window to be subdivided into panes, each "
  37   "of which displays a gui control child of the GuiFrameSetCtrl.\n\n"
  38
  39   "Each gui control child will have an associated FrameDetail through which "
  40   "frame-specific details can be assigned. Frame-specific values override the "
  41   "values specified for the entire frameset.\n\n"
  42
  43   "Note that it is possible to have more children than frames, or more frames "
  44   "than children. In the former case, the extra children will not be visible "
  45   "(they are moved beyond the visible extent of the frameset). In the latter "
  46   "case, frames will be empty. For example, if a frameset had two columns and "
  47   "two rows but only three gui control children they would be assigned to "
  48   "frames as follows:\n"
  49
  50   "<pre>\n"
  51   "                 1 | 2\n"
  52   "                 -----\n"
  53   "                 3 |\n"
  54   "</pre>\n"
  55
  56   "The last frame would be blank.\n\n"
  57
  58   "@tsexample\n"
  59   "new GuiFrameSetCtrl()\n"
  60   "{\n"
  61   "   columns = \"3\";\n"
  62   "   rows = \"2\";\n"
  63   "   borderWidth = \"1\";\n"
  64   "   borderColor = \"128 128 128\";\n"
  65   "   borderEnable = \"dynamic\";\n"
  66   "   borderMovable = \"dynamic\";\n"
  67   "   autoBalance = \"1\";\n"
  68   "   fudgeFactor = \"0\";\n"
  69   "   //Properties not specific to this control have been omitted from this example.\n"
  70   "};\n"
  71   "@endtsexample\n\n"
  72
  73   "@ingroup GuiContainers"
  74);
  75
  76//-----------------------------------------------------------------------------
  77
  78ImplementEnumType( GuiFrameState,
  79   "\n\n"
  80   "@ingroup GuiContainers" )
  81   { GuiFrameSetCtrl::FRAME_STATE_ON,    "alwaysOn"  },
  82   { GuiFrameSetCtrl::FRAME_STATE_OFF,   "alwaysOff" },
  83   { GuiFrameSetCtrl::FRAME_STATE_AUTO,  "dynamic"   }
  84EndImplementEnumType;
  85
  86//-----------------------------------------------------------------------------
  87void GuiFrameSetCtrl::initPersistFields()
  88{
  89   addField( "columns", TypeS32Vector, Offset(mColumnOffsets, GuiFrameSetCtrl),
  90      "A vector of column offsets (determines the width of each column)." );
  91
  92   addField( "rows", TypeS32Vector, Offset(mRowOffsets, GuiFrameSetCtrl),
  93      "A vector of row offsets (determines the height of each row)." );
  94
  95   addField( "borderWidth", TypeS32, Offset(mFramesetDetails.mBorderWidth, GuiFrameSetCtrl),
  96      "Width of interior borders between cells in pixels." );
  97
  98   addField( "borderColor", TypeColorI, Offset(mFramesetDetails.mBorderColor, GuiFrameSetCtrl),
  99      "Color of interior borders between cells." );
 100
 101   addField( "borderEnable", TYPEID< FrameState >(), Offset(mFramesetDetails.mBorderEnable, GuiFrameSetCtrl),
 102      "Controls whether frame borders are enabled.\n\nFrames use this value "
 103      "unless overridden for that frame using <i>%ctrl.frameBorder(index)</i>" );
 104
 105   addField( "borderMovable", TYPEID< FrameState >(), Offset(mFramesetDetails.mBorderMovable, GuiFrameSetCtrl),
 106      "Controls whether borders can be dynamically repositioned with the mouse "
 107      "by the user.\n\nFrames use this value unless overridden for that frame "
 108      "using <i>%ctrl.frameMovable(index)</i>" );
 109
 110   addField( "autoBalance", TypeBool, Offset(mAutoBalance, GuiFrameSetCtrl),
 111      "If true, row and column offsets are automatically scaled to match the "
 112      "new extents when the control is resized." );
 113
 114   addField( "fudgeFactor", TypeS32, Offset(mFudgeFactor, GuiFrameSetCtrl),
 115      "Offset for row and column dividers in pixels" );
 116
 117   Parent::initPersistFields();
 118}
 119
 120//-----------------------------------------------------------------------------
 121DefineEngineMethod( GuiFrameSetCtrl, frameBorder, void, ( S32 index, const char* state ), ( "dynamic" ),
 122   "Override the <i>borderEnable</i> setting for this frame.\n\n"
 123   "@param index  Index of the frame to modify\n"
 124   "@param state  New borderEnable state: \"on\", \"off\" or \"dynamic\"\n" )
 125{
 126   object->frameBorderEnable( index, state );
 127}
 128
 129DefineEngineMethod( GuiFrameSetCtrl, frameMovable, void, ( S32 index, const char* state ), ( "dynamic" ),
 130   "Override the <i>borderMovable</i> setting for this frame.\n\n"
 131   "@param index  Index of the frame to modify\n"
 132   "@param state  New borderEnable state: \"on\", \"off\" or \"dynamic\"\n" )
 133{
 134   object->frameBorderMovable( index, state );
 135}
 136
 137DefineEngineMethod( GuiFrameSetCtrl, frameMinExtent, void, ( S32 index, S32 width, S32 height ),,
 138   "Set the minimum width and height for the frame. It will not be possible "
 139   "for the user to resize the frame smaller than this.\n\n"
 140   "@param index  Index of the frame to modify\n"
 141   "@param width  Minimum width in pixels\n"
 142   "@param height Minimum height in pixels\n" )
 143{
 144   Point2I extent( getMax( 0, width ), getMax( 0, height ) );
 145   object->frameMinExtent( index, extent);
 146}
 147
 148DefineEngineMethod( GuiFrameSetCtrl, framePadding, void, ( S32 index, RectSpacingI padding ),,
 149   "Set the padding for this frame. Padding introduces blank space on the inside "
 150   "edge of the frame.\n\n"
 151   "@param index     Index of the frame to modify\n"
 152   "@param padding   Frame top, bottom, left, and right padding\n" )
 153{
 154   object->framePadding( index, padding);
 155}
 156
 157DefineEngineMethod( GuiFrameSetCtrl, getFramePadding, RectSpacingI, ( S32 index ),,
 158   "Get the padding for this frame.\n\n"
 159   "@param index     Index of the frame to query\n" )
 160{
 161   return object->getFramePadding( index );
 162}
 163
 164DefineEngineMethod( GuiFrameSetCtrl, addColumn, void, (),,
 165   "Add a new column.\n\n" )
 166{
 167   Vector<S32> * columns = object->columnOffsets();
 168   columns->push_back(0);
 169   object->balanceFrames();
 170}
 171
 172DefineEngineMethod( GuiFrameSetCtrl, addRow, void, (),,
 173   "Add a new row.\n\n" )
 174{
 175   Vector<S32> * rows = object->rowOffsets();
 176   rows->push_back(0);
 177   object->balanceFrames();
 178}
 179
 180DefineEngineMethod( GuiFrameSetCtrl, removeColumn, void, (),,
 181   "Remove the last (rightmost) column.\n\n" )
 182{
 183   Vector<S32> * columns = object->columnOffsets();
 184
 185   if(columns->size() > 0)
 186   {
 187      columns->setSize(columns->size() - 1);
 188      object->balanceFrames();
 189   }
 190   else
 191      Con::errorf(ConsoleLogEntry::General, "No columns exist to remove");
 192}
 193
 194DefineEngineMethod( GuiFrameSetCtrl, removeRow, void, (),,
 195   "Remove the last (bottom) row.\n\n" )
 196{
 197   Vector<S32> * rows = object->rowOffsets();
 198
 199   if(rows->size() > 0)
 200   {
 201      rows->setSize(rows->size() - 1);
 202      object->balanceFrames();
 203   }
 204   else
 205      Con::errorf(ConsoleLogEntry::General, "No rows exist to remove");
 206}
 207
 208DefineEngineMethod( GuiFrameSetCtrl, getColumnCount, S32, (),,
 209   "Get the number of columns.\n\n"
 210   "@return The number of columns\n" )
 211{
 212   return(object->columnOffsets()->size());
 213}
 214
 215DefineEngineMethod( GuiFrameSetCtrl, getRowCount, S32, (),,
 216   "Get the number of rows.\n\n"
 217   "@return The number of rows\n" )
 218{
 219   return(object->rowOffsets()->size());
 220}
 221
 222DefineEngineMethod( GuiFrameSetCtrl, getColumnOffset, S32, ( S32 index ),,
 223   "Get the horizontal offset of a column.\n\n"
 224   "@param index Index of the column to query\n"
 225   "@return Column offset in pixels\n" )
 226{
 227   if(index < 0 || index > object->columnOffsets()->size())
 228   {
 229      Con::errorf(ConsoleLogEntry::General, "Column index out of range");
 230      return(0);
 231   }
 232   return((*object->columnOffsets())[index]);
 233}
 234
 235DefineEngineMethod( GuiFrameSetCtrl, getRowOffset, S32, ( S32 index ),,
 236   "Get the vertical offset of a row.\n\n"
 237   "@param index Index of the row to query\n"
 238   "@return Row offset in pixels\n" )
 239{
 240   if(index < 0 || index > object->rowOffsets()->size())
 241   {
 242      Con::errorf(ConsoleLogEntry::General, "Row index out of range");
 243      return(0);
 244   }
 245   return((*object->rowOffsets())[index]);
 246}
 247
 248DefineEngineMethod( GuiFrameSetCtrl, setColumnOffset, void, ( S32 index, S32 offset ),,
 249   "Set the horizontal offset of a column.\n\n"
 250   "Note that column offsets must always be in increasing order, and therefore "
 251   "this offset must be between the offsets of the colunns either side.\n"
 252   "@param index  Index of the column to modify\n"
 253   "@param offset New column offset\n" )
 254{
 255   Vector<S32> & columns = *(object->columnOffsets());
 256
 257   if(index < 0 || index > columns.size())
 258   {
 259      Con::errorf(ConsoleLogEntry::General, "Column index out of range");
 260      return;
 261   }
 262
 263   // check the offset
 264   if(((index > 0) && (offset < columns[index-1])) ||
 265      ((index < (columns.size() - 1)) && (offset > columns[index+1])))
 266   {
 267      Con::errorf(ConsoleLogEntry::General, "Invalid column offset");
 268      return;
 269   }
 270
 271   columns[index] = offset;
 272   object->updateSizes();
 273}
 274
 275DefineEngineMethod( GuiFrameSetCtrl, setRowOffset, void, ( S32 index, S32 offset ),,
 276   "Set the vertical offset of a row.\n\n"
 277   "Note that row offsets must always be in increasing order, and therefore "
 278   "this offset must be between the offsets of the rows either side.\n"
 279   "@param index  Index of the row to modify\n"
 280   "@param offset New row offset\n" )
 281{
 282   Vector<S32> & rows = *(object->rowOffsets());
 283
 284   if(index < 0 || index > rows.size())
 285   {
 286      Con::errorf(ConsoleLogEntry::General, "Row index out of range");
 287      return;
 288   }
 289
 290   // check the offset
 291   if(((index > 0) && (offset < rows[index-1])) ||
 292      ((index < (rows.size() - 1)) && (offset > rows[index+1])))
 293   {
 294      Con::errorf(ConsoleLogEntry::General, "Invalid row offset");
 295      return;
 296   }
 297
 298   rows[index] = offset;
 299   object->updateSizes();
 300}
 301
 302DefineEngineMethod( GuiFrameSetCtrl, updateSizes, void, (),,
 303   "Recalculates child control sizes." )
 304{
 305   object->updateSizes();
 306}
 307
 308//-----------------------------------------------------------------------------
 309GuiFrameSetCtrl::GuiFrameSetCtrl()
 310{
 311   VECTOR_SET_ASSOCIATION(mColumnOffsets);
 312   VECTOR_SET_ASSOCIATION(mRowOffsets);
 313   VECTOR_SET_ASSOCIATION(mFrameDetails);
 314
 315   mAutoBalance = true;
 316   mIsContainer = true;
 317
 318   init(1, 1, NULL, NULL);
 319}
 320
 321//-----------------------------------------------------------------------------
 322GuiFrameSetCtrl::GuiFrameSetCtrl(U32 columns, U32 rows, const U32 columnOffsets[], const U32 rowOffsets[])
 323{
 324   init(columns, rows, columnOffsets, rowOffsets);
 325}
 326
 327//-----------------------------------------------------------------------------
 328GuiFrameSetCtrl::~GuiFrameSetCtrl()
 329{
 330   while (mFrameDetails.size() > 0)
 331   {
 332      delete mFrameDetails.last();
 333      mFrameDetails.pop_back();
 334   }
 335}
 336
 337//-----------------------------------------------------------------------------
 338
 339void GuiFrameSetCtrl::addObject(SimObject *object)
 340{
 341   AssertFatal(object != NULL, "GuiFrameSetCtrl::addObject: NULL object");
 342
 343   // assign the object to a frame - give it default frame details
 344   Parent::addObject(object);
 345   GuiControl *gc = dynamic_cast<GuiControl *>(object);
 346   if (gc != NULL)
 347   {
 348      FrameDetail *detail = new FrameDetail;
 349      detail->mMinExtent = gc->getMinExtent();
 350      mFrameDetails.push_back(detail);
 351   }
 352   else
 353      mFrameDetails.push_back(NULL);
 354   // resize it to fit into the frame to which it is assigned (if no frame for it, don't bother resizing)
 355   if(isAwake())
 356      computeSizes();
 357}
 358
 359//-----------------------------------------------------------------------------
 360void GuiFrameSetCtrl::removeObject(SimObject *object)
 361{
 362   if (object != NULL)
 363   {
 364      VectorPtr<SimObject *>::iterator soitr;
 365      VectorPtr<FrameDetail *>::iterator fditr = mFrameDetails.begin();
 366      for (soitr = begin(); soitr != end(); soitr++, fditr++)
 367      {
 368         if (*soitr == object)
 369         {
 370            delete *fditr;
 371            mFrameDetails.erase(fditr);
 372            break;
 373         }
 374      }
 375   }
 376   Parent::removeObject(object);
 377
 378   if(isAwake())
 379      computeSizes();
 380}
 381
 382//-----------------------------------------------------------------------------
 383bool GuiFrameSetCtrl::resize(const Point2I &newPos, const Point2I &newExtent)
 384{
 385   // rebalance before losing the old extent (if required)
 386   if (mAutoBalance == true)
 387      rebalance(newExtent);
 388
 389   if( !Parent::resize(newPos, newExtent) )
 390      return false;
 391
 392   // compute new sizing info for the frames - takes care of resizing the children
 393   computeSizes( !mAutoBalance );
 394
 395   return true;
 396}
 397
 398//-----------------------------------------------------------------------------
 399
 400void GuiFrameSetCtrl::getCursor(GuiCursor *&cursor, bool &showCursor, const GuiEvent &lastGuiEvent)
 401{
 402   GuiCanvas *pRoot = getRoot();
 403   if( !pRoot )
 404      return;
 405
 406   Region curRegion = NONE;
 407   // Determine the region by mouse position.
 408   Point2I curMousePos = globalToLocalCoord(lastGuiEvent.mousePoint);
 409   curRegion = pointInAnyRegion(curMousePos);
 410
 411   PlatformWindow *pWindow = pRoot->getPlatformWindow();
 412   AssertFatal(pWindow != NULL,"GuiControl without owning platform window!  This should not be possible.");
 413   PlatformCursorController *pController = pWindow->getCursorController();
 414   AssertFatal(pController != NULL,"PlatformWindow without an owned CursorController!");
 415
 416   switch (curRegion)
 417   {
 418   case VERTICAL_DIVIDER:
 419      // change to left-right cursor
 420      if(pRoot->mCursorChanged != PlatformCursorController::curResizeVert)
 421      {
 422         //*** We've already changed the cursor, so set it back before we change it again.
 423         if(pRoot->mCursorChanged != -1)
 424            pController->popCursor();
 425
 426         //*** Now change the cursor shape
 427         pController->pushCursor(PlatformCursorController::curResizeVert);
 428         pRoot->mCursorChanged = PlatformCursorController::curResizeVert;
 429
 430      }
 431      break;
 432
 433   case HORIZONTAL_DIVIDER:
 434      // change to up-down cursor
 435      if(pRoot->mCursorChanged != PlatformCursorController::curResizeHorz)
 436      {
 437         //*** We've already changed the cursor, so set it back before we change it again.
 438         if(pRoot->mCursorChanged != -1)
 439            pController->popCursor();
 440
 441         //*** Now change the cursor shape
 442         pController->pushCursor(PlatformCursorController::curResizeHorz);
 443         pRoot->mCursorChanged = PlatformCursorController::curResizeHorz;
 444      }
 445      break;
 446
 447   case DIVIDER_INTERSECTION:
 448      // change to move cursor
 449      if(pRoot->mCursorChanged != PlatformCursorController::curResizeAll)
 450      {
 451         //*** We've already changed the cursor, so set it back before we change it again.
 452         if(pRoot->mCursorChanged != -1)
 453            pController->popCursor();
 454
 455         //*** Now change the cursor shape
 456         pController->pushCursor(PlatformCursorController::curResizeAll);
 457         pRoot->mCursorChanged = PlatformCursorController::curResizeAll;
 458
 459      }
 460      break;
 461
 462   case NONE:
 463   default:
 464      if(pRoot->mCursorChanged != -1)
 465      {
 466         //*** We've already changed the cursor, so set it back before we change it again.
 467         pController->popCursor();
 468
 469         pRoot->mCursorChanged = -1;
 470      }
 471      break;
 472   }
 473
 474}
 475
 476//-----------------------------------------------------------------------------
 477void GuiFrameSetCtrl::onMouseDown(const GuiEvent &event)
 478{
 479   if (mFramesetDetails.mBorderEnable != FRAME_STATE_OFF && mFramesetDetails.mBorderMovable != FRAME_STATE_OFF)
 480   {
 481      // determine if a divider was hit
 482      Point2I curMousePos = globalToLocalCoord(event.mousePoint);
 483      findHitRegion(curMousePos);                        // sets mCurVerticalHit, mCurHorizontalHit, & mCurHitRegion
 484
 485      if (mCurHitRegion != NONE)
 486      {
 487         mouseLock();
 488         setFirstResponder();
 489         setUpdate();
 490      }
 491   }
 492}
 493
 494//-----------------------------------------------------------------------------
 495void GuiFrameSetCtrl::onMouseUp(const GuiEvent &event)
 496{
 497   TORQUE_UNUSED(event);
 498   if (mCurHitRegion != NONE)
 499   {
 500      mCurHitRegion = NONE;
 501      mCurVerticalHit = NO_HIT;
 502      mCurHorizontalHit = NO_HIT;
 503      mouseUnlock();
 504      setUpdate();
 505   }
 506}
 507
 508//-----------------------------------------------------------------------------
 509void GuiFrameSetCtrl::onMouseDragged(const GuiEvent &event)
 510{
 511   if (mCurHitRegion != NONE)
 512   {
 513      // identify the frames involved in the resizing, checking if they are resizable
 514      S32 indexes[4];
 515      S32 activeFrames = findResizableFrames(indexes);
 516      if (activeFrames > 0)
 517      {
 518         S32 range[4];
 519         // determine the range of movement, limiting as specified by individual frames
 520         computeMovableRange(mCurHitRegion, mCurVerticalHit, mCurHorizontalHit, activeFrames, indexes, range);
 521         Point2I curMousePos = globalToLocalCoord(event.mousePoint);
 522         switch (mCurHitRegion)
 523         {
 524            case VERTICAL_DIVIDER:
 525               mColumnOffsets[mCurVerticalHit] = getMin(getMax(range[0], curMousePos.x - mLocOnDivider.x), range[1]);
 526               break;
 527            case HORIZONTAL_DIVIDER:
 528               mRowOffsets[mCurHorizontalHit] = getMin(getMax(range[0], curMousePos.y - mLocOnDivider.y), range[1]);
 529               break;
 530            case DIVIDER_INTERSECTION:
 531               mColumnOffsets[mCurVerticalHit] = getMin(getMax(range[0], curMousePos.x - mLocOnDivider.x), range[1]);
 532               mRowOffsets[mCurHorizontalHit] = getMin(getMax(range[2], curMousePos.y - mLocOnDivider.y), range[3]);
 533               break;
 534            default:
 535               return;
 536         }
 537         computeSizes();
 538      }
 539   }
 540}
 541
 542//-----------------------------------------------------------------------------
 543bool GuiFrameSetCtrl::onAdd()
 544{
 545   if (Parent::onAdd() == false)
 546      return(false);
 547
 548   return(true);
 549}
 550
 551bool GuiFrameSetCtrl::onWake()
 552{
 553   if (Parent::onWake() == false)
 554      return(false);
 555
 556   computeSizes();
 557   return(true);
 558}
 559
 560//-----------------------------------------------------------------------------
 561void GuiFrameSetCtrl::onRender(Point2I offset, const RectI &updateRect )
 562{
 563
 564   Parent::onRender( offset, updateRect );
 565 
 566   drawDividers(offset);
 567
 568}
 569
 570//-----------------------------------------------------------------------------
 571bool GuiFrameSetCtrl::init(U32 columns, U32 rows, const U32 columnOffsets[], const U32 rowOffsets[])
 572{
 573   if (columns != 0 && rows != 0)
 574   {
 575      mColumnOffsets.clear();
 576      mRowOffsets.clear();
 577      U32 i;
 578      for (i = 0; i < columns; i++)
 579      {
 580         if (columnOffsets == NULL)
 581            mColumnOffsets.push_back(0);
 582         else
 583         {
 584            AssertFatal(columnOffsets != NULL, "GuiFrameSetCtrl::init: NULL column offsets");
 585            mColumnOffsets.push_back((U32)columnOffsets[i]);
 586            if (i > 0)
 587            {
 588               AssertFatal(mColumnOffsets[i - 1] < mColumnOffsets[i], "GuiFrameSetCtrl::init: column offsets must be monotonically increasing");
 589               mColumnOffsets.clear();
 590               return(false);
 591            }
 592         }
 593      }
 594      for (i = 0; i < rows; i++)
 595      {
 596         if (rowOffsets == NULL)
 597            mRowOffsets.push_back(0);
 598         else
 599         {
 600            AssertFatal(rowOffsets != NULL, "GuiFrameSetCtrl::init: NULL row offsets");
 601            mRowOffsets.push_back((U32)rowOffsets[i]);
 602            if (i > 0)
 603            {
 604               AssertFatal(mRowOffsets[i - 1] < mRowOffsets[i], "GuiFrameSetCtrl::init: row offsets must be monotonically increasing");
 605               mRowOffsets.clear();
 606               return(false);
 607            }
 608         }
 609      }
 610   }
 611   mFramesetDetails.mBorderWidth = DEFAULT_BORDER_WIDTH;
 612   mFramesetDetails.mBorderEnable = FRAME_STATE_AUTO;
 613   mFramesetDetails.mBorderMovable = FRAME_STATE_AUTO;
 614   mAutoBalance = false;
 615   mFudgeFactor = 0;
 616   mCurHitRegion = NONE;
 617   mCurVerticalHit = NO_HIT;
 618   mCurHorizontalHit = NO_HIT;
 619   return(true);
 620}
 621
 622//-----------------------------------------------------------------------------
 623// point is assumed to already be in local coordinates.
 624GuiFrameSetCtrl::Region GuiFrameSetCtrl::findHitRegion(const Point2I &point)
 625{
 626   Vector<S32>::iterator itr;
 627   S32 i = 1;
 628   // step through vertical dividers
 629   for (itr = mColumnOffsets.begin() + 1; itr < mColumnOffsets.end(); itr++, i++)
 630   {
 631      if (hitVerticalDivider(*itr, point) == true)
 632      {
 633         mCurVerticalHit = i;
 634         mLocOnDivider.x = point.x - (*itr);
 635         break;
 636      }
 637   }
 638   i = 1;
 639   // step through horizontal dividers
 640   for (itr = mRowOffsets.begin() + 1; itr < mRowOffsets.end(); itr++, i++)
 641   {
 642      if (hitHorizontalDivider(*itr, point) == true)
 643      {
 644         mCurHorizontalHit = i;
 645         mLocOnDivider.y = point.y - (*itr);
 646         break;
 647      }
 648   }
 649   // now set type of hit...
 650   if (mCurVerticalHit != NO_HIT)
 651   {
 652      if (mCurHorizontalHit != NO_HIT)
 653         return(mCurHitRegion = DIVIDER_INTERSECTION);
 654      else
 655         return(mCurHitRegion = VERTICAL_DIVIDER);
 656   }
 657   else if (mCurHorizontalHit != NO_HIT)
 658      return(mCurHitRegion = HORIZONTAL_DIVIDER);
 659   else
 660      return(mCurHitRegion = NONE);
 661}
 662
 663GuiFrameSetCtrl::Region GuiFrameSetCtrl::pointInAnyRegion(const Point2I &point)
 664{
 665   Vector<S32>::iterator itr;
 666   S32 i = 1;
 667   S32 curVertHit = NO_HIT, curHorzHit = NO_HIT;
 668   Region result = NONE;
 669   // step through vertical dividers
 670   for (itr = mColumnOffsets.begin() + 1; itr < mColumnOffsets.end(); itr++, i++)
 671   {
 672      if (hitVerticalDivider(*itr, point) == true)
 673      {
 674         curVertHit = i;
 675         break;
 676      }
 677   }
 678   i = 1;
 679   // step through horizontal dividers
 680   for (itr = mRowOffsets.begin() + 1; itr < mRowOffsets.end(); itr++, i++)
 681   {
 682      if (hitHorizontalDivider(*itr, point) == true)
 683      {
 684         curHorzHit = i;
 685         break;
 686      }
 687   }
 688   // now select the type of region in which the point lies
 689   if (curVertHit != NO_HIT)
 690   {
 691      if (curHorzHit != NO_HIT)
 692         result = DIVIDER_INTERSECTION;
 693      else
 694         result = VERTICAL_DIVIDER;
 695   }
 696   else if (curHorzHit != NO_HIT)
 697      result = HORIZONTAL_DIVIDER;
 698   return(result);
 699}
 700
 701//-----------------------------------------------------------------------------
 702// indexes must have at least 4 entries.
 703// This *may* modify mCurVerticalHit, mCurHorizontalHit, and mCurHitRegion if it
 704// determines that movement is disabled by frame content.
 705// If it does make such a change, it also needs to do the reset performed by
 706// onMouseUp if it sets mCurHitRegion to NONE.
 707S32 GuiFrameSetCtrl::findResizableFrames(S32 indexes[])
 708{
 709   AssertFatal(indexes != NULL, "GuiFrameSetCtrl::findResizableFrames: NULL indexes");
 710
 711   // first, find the column and row indexes of the affected columns/rows
 712   S32 validIndexes = 0;
 713   switch (mCurHitRegion)
 714   {
 715      case VERTICAL_DIVIDER:                             // columns
 716         indexes[0] = mCurVerticalHit - 1;
 717         indexes[1] = mCurVerticalHit;
 718         validIndexes = 2;
 719         break;
 720      case HORIZONTAL_DIVIDER:                           // rows
 721         indexes[0] = mCurHorizontalHit - 1;
 722         indexes[1] = mCurHorizontalHit;
 723         validIndexes = 2;
 724         break;
 725      case DIVIDER_INTERSECTION:                         // columns & rows
 726         indexes[0] = mCurVerticalHit - 1;               // columns
 727         indexes[1] = mCurVerticalHit;
 728         indexes[2] = mCurHorizontalHit - 1;             // rows
 729         indexes[3] = mCurHorizontalHit;
 730         validIndexes = 4;
 731         break;
 732      default:
 733         break;
 734   }
 735   // now, make sure these indexes are for movable frames
 736   VectorPtr<SimObject *>::iterator soitr;
 737   VectorPtr<FrameDetail *>::iterator fditr = mFrameDetails.begin();
 738   GuiControl *gc;
 739   S32 column = 0;
 740   S32 row = 0;
 741   S32 columns = mColumnOffsets.size();
 742   S32 rows = mRowOffsets.size();
 743   for (soitr = begin(); soitr != end() && validIndexes > 0; soitr++, fditr++)
 744   {
 745      // don't continue if some of the frames are empty
 746      if (fditr == mFrameDetails.end())
 747         break;
 748      // otherwise, check the gui elements for move-restrictions
 749      gc = dynamic_cast<GuiControl *>(*soitr);
 750      if (gc != NULL)
 751      {
 752         if (column == columns)
 753         {
 754            column = 0;
 755            row++;
 756         }
 757         if (row == rows)
 758            break;
 759         switch (mCurHitRegion)
 760         {
 761            case VERTICAL_DIVIDER:
 762               if ((column == indexes[0] || column == indexes[1]) && (*fditr) && (*fditr)->mBorderMovable == FRAME_STATE_OFF)
 763                  validIndexes = 0;
 764               break;
 765            case HORIZONTAL_DIVIDER:
 766               if ((row == indexes[0] || row == indexes[1]) && (*fditr) && (*fditr)->mBorderMovable == FRAME_STATE_OFF)
 767                  validIndexes = 0;
 768               break;
 769            case DIVIDER_INTERSECTION:
 770               if ((column == indexes[0] || column == indexes[1]) && (*fditr) && (*fditr)->mBorderMovable == FRAME_STATE_OFF)
 771               {
 772                  if ((row == indexes[2] || row == indexes[3]) && (*fditr) && (*fditr)->mBorderMovable == FRAME_STATE_OFF)
 773                     validIndexes = 0;
 774                  else
 775                  {
 776                     mCurHitRegion = HORIZONTAL_DIVIDER;
 777                     mCurVerticalHit = NO_HIT;
 778                     indexes[0] = indexes[2];
 779                     indexes[1] = indexes[3];
 780                     validIndexes = 2;
 781                  }
 782               }
 783               else if ((row == indexes[2] || row == indexes[3]) && (*fditr) && (*fditr)->mBorderMovable == FRAME_STATE_OFF)
 784               {
 785                  mCurHitRegion = VERTICAL_DIVIDER;
 786                  mCurHorizontalHit = NO_HIT;
 787                  validIndexes = 2;
 788               }
 789               break;
 790            default:
 791               return(0);
 792         }
 793         column++;
 794      }
 795   }
 796   if (validIndexes == 0)
 797   {
 798      mCurHitRegion = NONE;
 799      mCurVerticalHit = NO_HIT;
 800      mCurHorizontalHit = NO_HIT;
 801      mouseUnlock();
 802      setUpdate();
 803   }
 804   return(validIndexes);
 805}
 806
 807//-----------------------------------------------------------------------------
 808// This method locates the gui control and frame detail associated with a
 809// particular frame index.
 810bool GuiFrameSetCtrl::findFrameContents(S32 index, GuiControl **gc, FrameDetail **fd)
 811{
 812   AssertFatal(gc != NULL, "GuiFrameSetCtrl::findFrameContents: NULL gui control pointer");
 813   AssertFatal(fd != NULL, "GuiFrameSetCtrl::findFrameContents: NULL frame detail pointer");
 814   AssertFatal(*gc == NULL, "GuiFrameSetCtrl::findFrameContents: contents of gui control must be NULL");
 815   AssertFatal(*fd == NULL, "GuiFrameSetCtrl::findFrameContents: contents of frame detail must be NULL");
 816
 817   if (index >= 0 && index < size())
 818   {
 819      VectorPtr<SimObject *>::iterator soitr;
 820      VectorPtr<FrameDetail *>::iterator fditr = mFrameDetails.begin();
 821      for (soitr = begin(); soitr != end(); soitr++, fditr++, index--)
 822      {
 823         if (index == 0)
 824         {
 825            GuiControl *guiCtrl = dynamic_cast<GuiControl *>(*soitr);
 826            if (guiCtrl != NULL)
 827            {
 828               *gc = guiCtrl;
 829               *fd = *fditr;
 830               return(true);
 831            }
 832            else
 833               break;
 834         }
 835      }
 836   }
 837   return(false);
 838}
 839
 840//-----------------------------------------------------------------------------
 841void GuiFrameSetCtrl::computeSizes(bool balanceFrames)
 842{
 843   S32 columns = mColumnOffsets.size();
 844   S32 rows = mRowOffsets.size();
 845   S32 vDividers = columns - 1;
 846   S32 hDividers = rows - 1;
 847
 848   if ( !balanceFrames && mFrameDetails.size() == ( columns * rows ) )
 849   {
 850      // This will do some goofy things if you allow this control to resize smaller than
 851      // the additive minimum extents of its frames--so don't.
 852      S32 index, delta;
 853
 854      if ( columns > 1 )
 855      {
 856         index = columns - 1;
 857         delta = mFrameDetails[index]->mMinExtent.x - ( getWidth() - mColumnOffsets[index] );
 858         while ( delta > 0 )
 859         {
 860            mColumnOffsets[index--] -= delta;
 861            if ( index >= 0 )
 862               delta = mFrameDetails[index]->mMinExtent.x - ( mColumnOffsets[index + 1] - mColumnOffsets[index] );
 863            else
 864               break;
 865         }
 866      }
 867
 868      if ( rows > 1 )
 869      {
 870         index = rows - 1;
 871         delta = mFrameDetails[columns * index]->mMinExtent.y - ( getHeight() - mRowOffsets[index] );
 872         while ( delta > 0 )
 873         {
 874            mRowOffsets[index--] -= delta;
 875            if ( index >= 0 )
 876               delta = mFrameDetails[columns * index]->mMinExtent.y - ( mRowOffsets[index + 1] - mRowOffsets[index] );
 877            else
 878               break;
 879         }
 880      }
 881   }
 882
 883   // first, update the divider placement if necessary
 884   if (balanceFrames == true && mColumnOffsets.size() > 0 && mRowOffsets.size() > 0)
 885   {
 886      Vector<S32>::iterator itr;
 887      F32 totWidth = F32(getWidth() - vDividers * mFramesetDetails.mBorderWidth);
 888      F32 totHeight = F32(getHeight() - hDividers * mFramesetDetails.mBorderWidth);
 889      F32 frameWidth = totWidth/(F32)columns;
 890      F32 frameHeight = totHeight/(F32)rows;
 891      F32 i = 0.;
 892      for (itr = mColumnOffsets.begin(); itr != mColumnOffsets.end(); itr++, i++)
 893         *itr = (S32)(i * (frameWidth + (F32)mFramesetDetails.mBorderWidth));
 894      i = 0.;
 895      for (itr = mRowOffsets.begin(); itr != mRowOffsets.end(); itr++, i++)
 896         *itr = (S32)(i * (frameHeight + (F32)mFramesetDetails.mBorderWidth));
 897   }
 898
 899   // now, resize the contents of each frame (and move content w/o a frame beyond visible range)
 900   VectorPtr<SimObject *>::iterator soitr;
 901   VectorPtr<FrameDetail *>::iterator fditr = mFrameDetails.begin();
 902   GuiControl *gc;
 903   S32 column = 0;
 904   S32 row = 0;
 905   Point2I newPos;
 906   Point2I newExtent;
 907   // step through all the children
 908   for (soitr = begin(); soitr != end(); soitr++, fditr++)
 909   {
 910      // column and row track the current frame being resized
 911      if (column == columns)
 912      {
 913         column = 0;
 914         row++;
 915      }
 916      // resize the contents if its a gui control...
 917      gc = dynamic_cast<GuiControl *>(*soitr);
 918      if (gc != NULL)
 919      {
 920         if (row >= rows)
 921         {
 922            // no more visible frames
 923            newPos = getExtent();
 924            newExtent.set(DEFAULT_MIN_FRAME_EXTENT, DEFAULT_MIN_FRAME_EXTENT);
 925            gc->resize(newPos, newExtent);
 926            continue;
 927         }
 928         else
 929         {
 930            // determine x components of new position & extent
 931            newPos.x = mColumnOffsets[column];
 932            if (column == vDividers)
 933               newExtent.x = getWidth() - mColumnOffsets[column];             // last column
 934            else
 935               newExtent.x = mColumnOffsets[column + 1] - mColumnOffsets[column] - mFramesetDetails.mBorderWidth;   // any other column
 936            // determine y components of new position & extent
 937            newPos.y = mRowOffsets[row];
 938            if (row == hDividers)
 939               newExtent.y = getHeight() - mRowOffsets[row];                   // last row
 940            else
 941               newExtent.y = mRowOffsets[row + 1] - mRowOffsets[row] - mFramesetDetails.mBorderWidth;            // any other row
 942
 943            if ( *fditr )
 944            {
 945               FrameDetail *fd = ( *fditr );
 946
 947               // Account for Padding.
 948               newPos.x    += fd->mPadding.left;
 949               newPos.y    += fd->mPadding.top;
 950               newExtent.x -= ( fd->mPadding.left + fd->mPadding.right );
 951               newExtent.y -= ( fd->mPadding.top + fd->mPadding.bottom );
 952            }
 953
 954            // apply the new position & extent
 955            gc->resize(newPos, newExtent);
 956            column++;
 957         }
 958      }
 959   }
 960}
 961
 962//-----------------------------------------------------------------------------
 963// this method looks at the previous offsets, and uses them to redistribute
 964// the available height & width proportionally.
 965void GuiFrameSetCtrl::rebalance(const Point2I &newExtent)
 966{
 967   TORQUE_UNUSED(newExtent);
 968
 969   // look at old_width and old_height - current extent
 970   F32 widthScale = (F32)newExtent.x/(F32)getWidth();
 971   F32 heightScale = (F32)newExtent.y/(F32)getHeight();
 972   Vector<S32>::iterator itr;
 973   // look at old width offsets
 974   for (itr = mColumnOffsets.begin() + 1; itr < mColumnOffsets.end(); itr++)
 975      // multiply each by new_width/old_width
 976      *itr = S32(F32(*itr) * widthScale);
 977   // look at old height offsets
 978   for (itr = mRowOffsets.begin() + 1; itr < mRowOffsets.end(); itr++)
 979      // multiply each by new_height/new_width
 980      *itr = S32(F32(*itr) * heightScale);
 981
 982}
 983
 984//-----------------------------------------------------------------------------
 985void GuiFrameSetCtrl::computeMovableRange(Region hitRegion, S32 vertHit, S32 horzHit, S32 numIndexes, const S32 indexes[], S32 ranges[])
 986{
 987   S32 hardRanges[4] = { 0 };
 988   switch (numIndexes)
 989   {
 990      case 2:
 991         switch (hitRegion)
 992         {
 993            case VERTICAL_DIVIDER:
 994               ranges[0] = hardRanges[0] = (vertHit <= 1) ? mFramesetDetails.mBorderWidth : mColumnOffsets[vertHit - 1] + mFramesetDetails.mBorderWidth;
 995               ranges[1] = hardRanges[1] = (vertHit >= (mColumnOffsets.size() - 1)) ? getWidth() : mColumnOffsets[vertHit + 1] - mFramesetDetails.mBorderWidth;
 996               break;
 997            case HORIZONTAL_DIVIDER:
 998               ranges[0] = hardRanges[0] = (horzHit <= 1) ? mFramesetDetails.mBorderWidth : mRowOffsets[horzHit - 1] + mFramesetDetails.mBorderWidth;
 999               ranges[1] = hardRanges[1] = (horzHit >= (mRowOffsets.size() - 1)) ? getHeight() : mRowOffsets[horzHit + 1] - mFramesetDetails.mBorderWidth;
1000               break;
1001            default:
1002               return;
1003         }
1004         break;
1005      case 4:
1006         if (hitRegion == DIVIDER_INTERSECTION)
1007         {
1008            ranges[0] = hardRanges[0] = (vertHit <= 1) ? mFramesetDetails.mBorderWidth : mColumnOffsets[vertHit - 1] + mFramesetDetails.mBorderWidth;
1009            ranges[1] = hardRanges[1] = (vertHit >= (mColumnOffsets.size() - 1)) ? getWidth() : mColumnOffsets[vertHit + 1] - mFramesetDetails.mBorderWidth;
1010            ranges[2] = hardRanges[2] = (horzHit <= 1) ? mFramesetDetails.mBorderWidth : mRowOffsets[horzHit - 1] + mFramesetDetails.mBorderWidth;
1011            ranges[3] = hardRanges[3] = (horzHit >= (mRowOffsets.size() - 1)) ? getHeight() : mRowOffsets[horzHit + 1] - mFramesetDetails.mBorderWidth;
1012         }
1013         else
1014            return;
1015         break;
1016      default:
1017         return;
1018   }
1019   // now that we have the hard ranges, reduce ranges based on minimum frame extents
1020   VectorPtr<SimObject *>::iterator soitr;
1021   VectorPtr<FrameDetail *>::iterator fditr = mFrameDetails.begin();
1022   GuiControl *gc;
1023   S32 column = 0;
1024   S32 row = 0;
1025   S32 columns = mColumnOffsets.size();
1026   S32 rows = mRowOffsets.size();
1027   for (soitr = begin(); soitr != end(); soitr++, fditr++)
1028   {
1029      // only worry about visible frames
1030      if (column == columns)
1031      {
1032         column = 0;
1033         row++;
1034      }
1035      if (row == rows)
1036         return;
1037      gc = dynamic_cast<GuiControl *>(*soitr);
1038      if (gc != NULL)
1039      {
1040         // the gui control is in a visible frame, so look at its frame details
1041         if ((*fditr) != NULL)
1042         {
1043            switch (hitRegion)
1044            {
1045               case VERTICAL_DIVIDER:
1046                  if (column == indexes[0])
1047                     ranges[0] = getMax(ranges[0], hardRanges[0] + (*fditr)->mMinExtent.x);
1048                  if (column == indexes[1])
1049                     ranges[1] = getMin(ranges[1], hardRanges[1] - (*fditr)->mMinExtent.x);
1050                  break;
1051               case HORIZONTAL_DIVIDER:
1052                  if (row == indexes[0])
1053                     ranges[0] = getMax(ranges[0], hardRanges[0] + (*fditr)->mMinExtent.y);
1054                  if (row == indexes[1])
1055                     ranges[1] = getMin(ranges[1], hardRanges[1] - (*fditr)->mMinExtent.y);
1056                  break;
1057               case DIVIDER_INTERSECTION:
1058                  if (column == indexes[0])
1059                     ranges[0] = getMax(ranges[0], hardRanges[0] + (*fditr)->mMinExtent.x);
1060                  if (column == indexes[1])
1061                     ranges[1] = getMin(ranges[1], hardRanges[1] - (*fditr)->mMinExtent.x);
1062                  if (row == indexes[2])
1063                     ranges[2] = getMax(ranges[2], hardRanges[2] + (*fditr)->mMinExtent.y);
1064                  if (row == indexes[3])
1065                     ranges[3] = getMin(ranges[3], hardRanges[3] - (*fditr)->mMinExtent.y);
1066                  break;
1067               default:
1068                  return;
1069            }
1070         }
1071         column++;
1072      }
1073   }
1074}
1075
1076//-----------------------------------------------------------------------------
1077void GuiFrameSetCtrl::drawDividers(const Point2I &offset)
1078{
1079   // draw the frame dividers, if they are enabled
1080   if (mFramesetDetails.mBorderEnable != FRAME_STATE_OFF)
1081   {
1082      RectI r;
1083      Vector<S32>::iterator itr;
1084      for (itr = mColumnOffsets.begin() + 1; itr < mColumnOffsets.end(); itr++)
1085      {
1086         r.point = Point2I(*itr - mFramesetDetails.mBorderWidth, mFudgeFactor) + offset;
1087         r.extent.set(mFramesetDetails.mBorderWidth, getHeight() - ( 2 * mFudgeFactor ) );
1088         GFX->getDrawUtil()->drawRectFill(r, mFramesetDetails.mBorderColor);
1089      }
1090      for (itr = mRowOffsets.begin() + 1; itr < mRowOffsets.end(); itr++)
1091      {
1092         r.point = Point2I(mFudgeFactor, *itr - mFramesetDetails.mBorderWidth) + offset;
1093         r.extent.set(getWidth() - ( 2 * mFudgeFactor ), mFramesetDetails.mBorderWidth);
1094         GFX->getDrawUtil()->drawRectFill(r, mFramesetDetails.mBorderColor);
1095      }
1096   }
1097}
1098
1099//-----------------------------------------------------------------------------
1100void GuiFrameSetCtrl::frameBorderEnable(S32 index, const char *state)
1101{
1102   GuiControl *gc = NULL;
1103   FrameDetail *fd = NULL;
1104   if (findFrameContents(index, &gc, &fd) == true && fd != NULL)
1105   {
1106      if (state != NULL)
1107         fd->mBorderEnable = EngineUnmarshallData< FrameState>()( state );
1108      else
1109         // defaults to AUTO if NULL passed in state
1110         fd->mBorderEnable = FRAME_STATE_AUTO;
1111   }
1112}
1113
1114//-----------------------------------------------------------------------------
1115void GuiFrameSetCtrl::frameBorderMovable(S32 index, const char *state)
1116{
1117   GuiControl *gc = NULL;
1118   FrameDetail *fd = NULL;
1119   if (findFrameContents(index, &gc, &fd) == true && fd != NULL)
1120   {
1121      if (state != NULL)
1122         fd->mBorderMovable = EngineUnmarshallData< FrameState>()( state );
1123      else
1124         // defaults to AUTO if NULL passed in state
1125         fd->mBorderMovable = FRAME_STATE_AUTO;
1126   }
1127}
1128
1129//-----------------------------------------------------------------------------
1130void GuiFrameSetCtrl::frameMinExtent(S32 index, const Point2I &extent)
1131{
1132   GuiControl *gc = NULL;
1133   FrameDetail *fd = NULL;
1134   if (findFrameContents(index, &gc, &fd) == true && fd != NULL)
1135      fd->mMinExtent = extent;
1136}
1137
1138void GuiFrameSetCtrl::framePadding(S32 index, const RectSpacingI &padding)
1139{
1140   GuiControl *gc = NULL;
1141   FrameDetail *fd = NULL;
1142   if (findFrameContents(index, &gc, &fd) == true && fd != NULL)
1143      fd->mPadding = padding;
1144}
1145
1146RectSpacingI GuiFrameSetCtrl::getFramePadding(S32 index)
1147{
1148   GuiControl *gc = NULL;
1149   FrameDetail *fd = NULL;
1150   if (findFrameContents(index, &gc, &fd) == true && fd != NULL)
1151      return fd->mPadding;
1152
1153   return RectSpacingI( 0, 0, 0, 0 );
1154}
1155