GuiStatusCtrl - *Updated* Display Field Name, Values, Status Bar for any field or method on any named object. TGEA and (new! TGE 1.52)
by Jaimi McEntire · 02/04/2009 (2:15 pm) · 44 comments
GuiStatusCtrl
Displays Field Name and/or value and/or bar graph for any field or method of any named object, using TorqueML for customization.The GuiStatusCtrl is a control that will monitor a field or method on any named object. This makes it easy to make status screens, etc. Also included is a GuiStatusController - a container that controls GuiStatusCtrls (more later on why this is useful).
The control can display the field name, value and the percentage of value as a progress bar. The field name and value can use TorqueML to customize the font, size, shadows, alignment, etc.
To use the GuiStatusCtrl, add the following files to your TGEA 1.7+ project, and recompile:
For TGEA 1.7+
Download Source Files for TGEA 1.7+
for TGE 1.5.2
Download Source Files for TGE 1.5.2
The GuiStatusCtrl has the following fields:
ObjectName: This is the name of the object that you want to monitor FieldName: This is the field that you want to monitor. New: Can also be a method on the class MaxFieldName: If displaying a status bar, this is the field (or method) that holds the maximum value IgnoreController: If set, this control will be ignored by any GuiStatusController objects FieldNameMLFormat: The TorqueML that is used to display the Field's Name FieldValueMLFormat: The TorqueML that is used to display the Field's Value DisplayFieldName: If true, then the field name is displayed to the left DisplayFieldValue: If true, then the field value is displayed. DisplayBar: If true, then a bar is displayed. The size is proportional to field/maxfield BarColor: The color of the status bar. Label: New: An alternate label to use instead of the FieldName.
The GuiStatusController is a container that is used to control any child GuiStatusCtrl objects. Lets say you have 25 GuiStatusCtrl controls all pointing to "PlayerBob", and you want them to show "PlayerJane" instead. Instead of manually coding the change to all 25 child controls, you instead just set the GuiStatusController ObjectName field, and it will update the child controls for you.
The GuiStatusController has all the fields that a GuiContainer has, with the addition of:
ObjectName: The name of the object to monitor.
If you do not wish for a child control to be changed by the controller, then set the "IgnoreController" field on the child.
Example: Lets create three named objects for our fictional RPG "Supergalactic Megawars" - put this in a test.cs file, and then execute it:
new SimObject("MainPlayer");
new SimObject("PartyPlayer");
new SimObject("GameData");
GameData.GameName = "Supergalactic Megawars";
GameData.LevelName = "Orion Quadrant";
MainPlayer.PlayerName = "Big Bob";
MainPlayer.Strength = 18;
MainPlayer.Vitality = 20;
MainPlayer.Intellect = 30;
MainPlayer.Health = 50;
MainPlayer.MaxHealth = 65;
PartyPlayer.PlayerName = "Sue (female)"; // differentiate from any boys named Sue
PartyPlayer.Strength = 22;
PartyPlayer.Vitality = 18;
PartyPlayer.Intellect = 24;
PartyPlayer.Health = 20;
PartyPlayer.MaxHealth = 65;Now, create a new gui, and put a GuiStatusController on it. Size it to hold 8 GuiStatusCtrl objects, and create and place the status controls in the controller.
Set the ObjectName on the top 2 to "GameData", and the field on the first one to "GameName" and the field on the second one to "LevelName". You should see the status control display the field names and values by default. Set "IgnoreController" to true for both controls. (you can also set the ML properties to apply formatting to the field name and value).
For the remainders, set the ObjectName to "MainPlayer", and the fieldnames to "PlayerName","Strength", "Vitality", "intellect", and "Health". On the Health Control, set "DisplayBar" to true, and set the MaxFieldName to "MaxHealth". You should now see all of the values displayed, and a proportional bar for health. (You can disable the field name and value on health if you don't want them printed).
To see how the controller works, set the Controller.ObjectName parameter to "PartyPlayer". now you are viewing her stats instead.
What's New
You can now use methods as well as field names. For example, to display "Health" on a player, you can add the following method to the Player.cs:
function Player::GetHealth(%this)
{
return %this.dataBlock.MaxDamage - (%this.dataBlock.MaxDamage * %this.getDamagePercent());
}
function Player::GetMaxHealth(%this)
{
return %this.dataBlock.MaxDamage;
}Now, instead of Field Names, use "GetHealth" for the Value and "GetMaxHealth" for the Max Value. Use the new "Label field" to override the display for the field name. (note: your Target object needs to be a "Player" for this to work. Or actually, any ShapeBase descended object)
Update
Here's a slightly more complicated version of the GetHealth function above, that shows how you can manipulate the control as part of the status function - we update the color and label that display based on how hurt the player is:
function Player::GetHealth(%this)
{
%perc = %this.getDamagePercent();
if (%perc < 0.25)
{
%newlabel = "Invincible";
%BarColor = "128 0 0 192";
}
else if (%perc < 0.50)
{
%newlabel = "But a scratch";
%BarColor = "160 0 0 192";
}
else if (%perc < 0.75)
{
%newlabel = "Just a flesh wound";
%BarColor = "192 0 0 192";
}
else
{
// Careful, he'll bite your legs off.
%newlabel = "Calling it a draw";
%BarColor = "255 0 0 192";
}
MyHealthStatus.Label = %newlabel;
MyHealthStatus.BarColor = %BarColor;
return mFloor(0.99 + (%this.dataBlock.MaxDamage - (%this.dataBlock.MaxDamage * %this.getDamagePercent())));
}Sample Pic:

#22
02/12/2009 (6:12 am)
Another great resource Jaimi!
#23
02/16/2009 (8:36 pm)
Great work :D i love it!
#24
BTW, according to your explanation, when we change the objectName in GuiStatusController, then it have to change all the children GuiStatusCtrls' objectName field. But I'm afraid it doesn't for me.
I took a look into GuiStatusController::onStaticModified(). And I found it is never called even when objectName field value is changed. As you made it overloaded, not using existing virtual method, I suppose you added this method somewhere in the simBase.cc. But as you didn't mentioned it, I'm wondering what's the problem with me.
Could you let me know if I missed something?
Edit: tested with TGE 1.5.2
02/20/2009 (7:21 pm)
Jami,thanks for the great resource.BTW, according to your explanation, when we change the objectName in GuiStatusController, then it have to change all the children GuiStatusCtrls' objectName field. But I'm afraid it doesn't for me.
I took a look into GuiStatusController::onStaticModified(). And I found it is never called even when objectName field value is changed. As you made it overloaded, not using existing virtual method, I suppose you added this method somewhere in the simBase.cc. But as you didn't mentioned it, I'm wondering what's the problem with me.
Could you let me know if I missed something?
Edit: tested with TGE 1.5.2
#25
Thanks again for your contribution.
02/21/2009 (1:37 am)
@Jamin, instead of waiting for the answer, I changed existing TGE 1.5.2 onStaticModified method to accept two parameters, which was quite simple and make this resource work properly.Thanks again for your contribution.
#26
03/04/2009 (6:26 am)
@Game4Rest - Sorry, this is apparently a difference between TGEA and TGE, changing the method is correct, it is supposed to be a simple override.
#27
04/03/2009 (11:25 am)
This is going straight into my RPG project, nice functionality there, kudos! (TGE 1.5.2)
#28
04/12/2009 (5:46 pm)
Great Resource. How did you get the drop shadow on the font in the sample pic?
#29
04/17/2009 (4:05 pm)
i can see a use for this in my project. will have to check it out. Thanks for sharing
#30
<shadow:x:y> Add a shadow to the text, displaced by (x, y).
<shadowcolor:RRGGBBAA> Sets the color of the text shadow.
For example: "<shadow:1:1><shadowcolor:000000FF>Health"
tdn.garagegames.com/wiki/GUI/TorqueML
05/01/2009 (1:27 pm)
@Rob - It's also a GuiMLtextCtrl, so you can use TorqueML:<shadow:x:y> Add a shadow to the text, displaced by (x, y).
<shadowcolor:RRGGBBAA> Sets the color of the text shadow.
For example: "<shadow:1:1><shadowcolor:000000FF>Health"
tdn.garagegames.com/wiki/GUI/TorqueML
#31
And just as I'm starting to look at Torque 3d beta. Now I have to look at what I can do there!
05/01/2009 (9:34 pm)
Ahhh. thanks for the info, Jaimi. Now I understand the earlier comment on TorqueML. And just as I'm starting to look at Torque 3d beta. Now I have to look at what I can do there!
#32
Can someone upload them somewhere for us to download or email the files to me and I'll put them up on my webserver and post links here. (Get my email from my profile.)
Much appreciated!
--Edit--
It seems I was pretty excited by this resource, enough to have downloaded the TGE 1.5.2 version prior to the domain expiring. I've uploaded it here. If anyone's got the TGEA version and can send it to me, I'll add it as well.
Cheers!
Great resource by-the-way!
06/13/2009 (8:04 am)
Just a quick note that the download links given are using an expired domain. I can't seem to download either file.Can someone upload them somewhere for us to download or email the files to me and I'll put them up on my webserver and post links here. (Get my email from my profile.)
Much appreciated!
--Edit--
It seems I was pretty excited by this resource, enough to have downloaded the TGE 1.5.2 version prior to the domain expiring. I've uploaded it here. If anyone's got the TGEA version and can send it to me, I'll add it as well.
Cheers!
Great resource by-the-way!
#33
06/16/2009 (6:07 am)
I just forgot to renew the domain. It should be back up and running now.
#34
This is exactly what I've been looking for.
Works in AFX for 1.5.2.
I got all the values in and they display the variables entered in test.cs.
06/30/2009 (8:47 am)
JaimiThis is exactly what I've been looking for.
Works in AFX for 1.5.2.
I got all the values in and they display the variables entered in test.cs.
#35
Here are some settings from my "test.cs" file:
And here is what I have in my player.cs file:
and it's not working. The Gui pulls the static variables : (vitality, strength, etc.) but the functions are not returning anything, apparently, because the space is blank where the value should be in game.
Which leads me to my question: how could the GetHealth() function be accessing a GetHealth function which exists only the Player namespace? I'm confused.
Can someone shed some light on this? It doesn't look like it should work, and it doesn't, but maybe there's something I'm missing.
This will also help me gain some insight on how to access functions within namespaces like Player and GameConnection when you are not currently operating within those namespaces.
06/30/2009 (9:10 pm)
JaimiHere are some settings from my "test.cs" file:
MainPlayer.PlayerName = "a guy"; MainPlayer.Strength = 18; MainPlayer.Vitality = 20; MainPlayer.Health = GetHealth(); MainPlayer.MaxHealth = GetMaxHealth();
And here is what I have in my player.cs file:
function Player::GetHealth(%this) {
return %this.dataBlock.MaxDamage - (%this.dataBlock.MaxDamage * %this.getDamagePercent());
}and it's not working. The Gui pulls the static variables : (vitality, strength, etc.) but the functions are not returning anything, apparently, because the space is blank where the value should be in game.
Which leads me to my question: how could the GetHealth() function be accessing a GetHealth function which exists only the Player namespace? I'm confused.
Can someone shed some light on this? It doesn't look like it should work, and it doesn't, but maybe there's something I'm missing.
This will also help me gain some insight on how to access functions within namespaces like Player and GameConnection when you are not currently operating within those namespaces.
#36
When you create the health status control, set the ObjectName to "MainPlayer", and the FieldName to "GetHealth", and the label to "Health". For the MaxHealth status control, it's similar.
What's happening is that in the C++ internally, it checks to see if the field is a Method, and if so it evaluates the method using Con::executef
This version of executef will call a member function on the target type.
07/01/2009 (7:44 am)
Okay - it's simpler than this. You don't have to assign the health and the max health, it will call the function on your player object at runtime to evaluate it.When you create the health status control, set the ObjectName to "MainPlayer", and the FieldName to "GetHealth", and the label to "Health". For the MaxHealth status control, it's similar.
What's happening is that in the C++ internally, it checks to see if the field is a Method, and if so it evaluates the method using Con::executef
if (mTarget->isMethod(this->mStatusFieldName))
{
SetStatusValue(Con::executef(mTarget,1,mStatusFieldName));
}This version of executef will call a member function on the target type.
#37
Update TGE: Fixed bug as found by game4rest in TGE 1.5.2 version
Update TGEA: Added additional checks to prevent reflowing the ML when non-ML items changed.
07/01/2009 (7:28 pm)
I've updated the downloads above with some bug fixes and enhancementsUpdate TGE: Fixed bug as found by game4rest in TGE 1.5.2 version
Update TGEA: Added additional checks to prevent reflowing the ML when non-ML items changed.
#38
Use the TGEA 1.7+ source code provided. At the top of GuiStatusCtrl.cpp, do the following:
07/04/2009 (12:59 pm)
This resource works great for me on T3D, Beta 3 with one small change.Use the TGEA 1.7+ source code provided. At the top of GuiStatusCtrl.cpp, do the following:
. . #include "gui/core/guiDefaultControlRender.h" #include "gfx/gfxDrawUtil.h" // <== insert this line to fix compile error
#40
In case some are interested, I confirm that last sources was working in T3D beta 5.
I will test the updated ones when available.
09/20/2009 (1:37 pm)
I confirm I can't get the updated resource.In case some are interested, I confirm that last sources was working in T3D beta 5.
I will test the updated ones when available.

Torque Owner John E. Nelson
Suspicious Activity
Kudos for you for sharing with everyone.