Game Development Community

dev|Pro Game Development Curriculum

Code: Query Radio Group State

by Michael Perry · 11/13/2006 (4:38 pm) · 2 comments

After reviewing the GUIs I've created, I felt they were a little cluttered. I wanted to clean them up by replacing bulky guiPopupMenuCtrls with smaller guiRadioCtrls. However, by cleaning up my GUI screen, my script code got messier because I had to set up extra variables and control statements to determine which radios were on or off, plus grabbing their text.

This thread, Querying Radio Groups, inspired me to add new functionality to guiRadioCtrl.

Script Scenario: You have three radio buttons in a group, and you want to figure out which of the three is selected if a one function call.

Engine File Changes:
engine\gui\core\guiControl.h
engine\gui\core\guiControl.cc
engine\gui\controls\guiButtonBaseCtrl.h
engine\gui\controls\guiButtonBaseCtrl.cc

CODE CHANGES:

(Step 1) After onMessage(GuiControl *sender, S32 msg) (around line 591), DECLARE:
/////////////////////////////////////
// guiControl.h
/////////////////////////////////////

virtual const char* getSelectedRadio(GuiControl *sender, S32 msg);  ///< Find out which Radio is selected (MP)

(Step 2) After onMessage(GuiControl *sender, S32 msg) (around line 1548), DEFINE:
/////////////////////////////////////
// guiControl.cc
/////////////////////////////////////

const char* GuiControl::getSelectedRadio(GuiControl *sender, S32 msg)
{
	sender;
	msg;
	return "Blank";
}

(Step 3) After onAction() (around line 67), DECLARE:
/////////////////////////////////////
// guiButtonBaseCtrl.h
/////////////////////////////////////

const char* getSelectedRadioName(int groupNumber);
const char* getSelectedRadio(GuiControl* sender, S32 msg);

(Step 4) After onMessage( GuiControl *sender, S32 msg ) (around line 362), DEFINE:
/////////////////////////////////////
// guiButtonBaseCtrl.cc
/////////////////////////////////////

// MP - Checks to see if this control is a Radio, in the same group, and is active
//         Called by getSelectedRadioName()
const char* GuiButtonBaseCtrl::getSelectedRadio(GuiControl* sender, S32 msg)
{
	Parent::getSelectedRadio(sender, msg);

	if(mRadioGroup == msg && mButtonType == ButtonTypeRadio && mStateOn)
	{
		return getText();
	}
	else
		return NULL;
}

// MP - Iterates through all sibling controls checking for radio buttons of the same groupNumber
//         that are turned on.
const char* GuiButtonBaseCtrl::getSelectedRadioName(int groupNumber)
{
   GuiControl *parent = getParent();
   if (! parent) return "No Radio Selected";
   GuiControl::iterator i;
   for(i = parent->begin(); i != parent->end(); i++)
   {
      GuiControl *ctrl = dynamic_cast<GuiControl *>(*i);
	  //if(ctrl != this)
	  //{
		  const char* retBuffer = ctrl->getSelectedRadio(this, groupNumber);
		  if(retBuffer != NULL)
			  return retBuffer;
	  //}
   }
   return "No Radio Selected";
}

// MP - Exposes functionality of getting text to script interface
ConsoleMethod( GuiButtonBaseCtrl, getSelectedRadio, const char*, 3, 3, "(group number) - gets the name of the selected radio in a group." )
{
   argc;
   int iID = dAtoi(argv[2]);
   return object->getSelectedRadioName( iID );
}

Example Usage:
// Assuming you have three GuiRadioCtrls (guyRadio, girlRadio, kidRadio) with text ("Guy", "Girl", "Kid")
function getSelectedCharacter()
{
   %selectedRadioText = guyRadio.getSelectedRadio(guyRadio.groupNum);
   
   echo(%selectedRadioText);
}

Notes:
  • This was tested on an un-modified version of TGE 1.5[li] I didn't test it on 1.4, but the GUI code is pretty much identical, so I see no problems with previous versions [li] getSelectedRadioName returns the text of the radioButton, but other values can be returned
Acknowledgments: Stephen Zepp & Ben Garney for the idea, Scott Burns for helping me test, Joshua Dallman for posting how to get bullets in my own posts (finally!)

[EDIT]

  • Fixed formatting [li] Corrected code error [li] New Note: This is a temporary fix until I implement Zepp's latest suggestion, which is a more abstract data set style. I'll post the new change when it's done.
[/EDIT]

#1
02/08/2009 (11:21 am)
Thanks for that resource Michael, I'm using a modification of it with TGB 1.7.4 to eval the commands of GuiBitmapButtonCtrl's (RadioButton type) from script.
#2
02/14/2009 (11:48 pm)
There's a slight error when I tried implementing the resource. It only calls the base class function of guiControl that keeps returning "Blank" all the time.

This is what i did to make the resource work for me.


//---------------------------------------------
// guiButtonBaseCtrl.cc
//---------------------------------------------

const char* GuiButtonBaseCtrl::getSelectedRadioName(int groupNumber)
{
// Con::printf("GuiButtonBaseCtrl::getSelectedRadioName() -> groupNum = %d", groupNumber);

GuiControl *parent = getParent();
if (! parent) return "No Radio Selected";
GuiControl::iterator i;
for(i = parent->begin(); i != parent->end(); i++)
{
GuiControl *ctrl = dynamic_cast<GuiControl *>(*i);

// [tim] try casting to see if it is an instance of GuiButtonBaseCtrl...
GuiButtonBaseCtrl* temp = dynamic_cast<GuiButtonBaseCtrl*>(ctrl);

if (temp != NULL) {
const char* retBuffer = temp->getSelectedRadio(this, groupNumber);
if (retBuffer != NULL) {
return retBuffer;
}
}
}
return "No Radio Selected";
}