Looping through all existing labels? [SOLVED]

Started by Knox, Wed 30/10/2013 20:15:56

Previous topic - Next topic

Knox

I've got a script that makes a list of labels visible, or invisible depending on the mode I enter. Since I'm not sure how many labels will exist in the game, is there a way to loop through all existing labels? Right now I'm manually adding all labels into the script, then setting the visibility to true or false.

Pseudo code example:

Code: ags

void toggleLabels(int iMode)
{
  if (iMode == 0) //HIDE ALL LABELS
  {
    int i;
    while (i < Game.LabelCount) //PSEUDO CODE
    {
      Label[i].Visible = false; //PSEUDO CODE
      i++;
    }
  }
  else if (iMode == 1) //SHOW ALL LABELS
  {
    int i;
    while (i < Game.LabelCount) //PSEUDO CODE
    {
      Label[i].Visible = true; //PSEUDO CODE
      i++;
    }
  } 
}
--All that is necessary for evil to triumph is for good men to do nothing.

monkey0506

There's not really anything built-in to track all GUIControls of a given type. If I understand you correctly, it seems like you've already done something like this, which is the best alternative ATM:

Code: ags
// top of script
Label *labels[];
int labelCount = 0;

function game_start()
{
  Label *tmp[] = new Label[Game.GUICount * AGS_MAX_CONTROLS_PER_GUI];
  int g = 0;
  while (g < Game.GUICount) // iterate all GUIs
  {
    int c = 0;
    while (c < gui[g].ControlCount) // iterate all GUIControls
    {
      if (gui[g].Controls[c].AsLabel != null) // found a Label
      {
        tmp[labelCount] = gui[g].Controls[c].AsLabel;
        labelCount++;
      }
      c++;
    }
    g++;
  }
  if (labelCount == 0) return; // we're done if there are no labels
  labels = new Label[labelCount]; // this is just to preserve memory
  // if necessary you *could* just do "labels = tmp;" to save time/speed (at the cost of the run-time memory)
  int l = 0;
  while (l < labelCount) // store the labels we found
  {
    labels[l] = tmp[l];
    l++;
  }
}

void toggleLabels(bool visible) // we're not returning anything, and we're using a boolean parameter
{
  int i = 0;
  while (i < labelCount)
  {
    labels[i].Visible = visible; // no need for a second loop here
    i++;
  }
}


I'm skeptical that something like GUIControl.Labels[n] would really be generally useful. If the engine is keeping track of it for any reason (I'll take a look at the code) then it wouldn't hurt to expose it, but I see no reason to add the additional burden for those who wouldn't be using it. ;)

Crimson Wizard

Quote from: monkey_05_06 on Wed 30/10/2013 22:31:54
If the engine is keeping track of it for any reason (I'll take a look at the code) then it wouldn't hurt to expose it, but I see no reason to add the additional burden for those who wouldn't be using it. ;)
Actually it does, in global array per each control type, although the reason might be simply a choice of architecture rather than necessity... I recall I was planning to change that in "develop" branch at some point.

Knox

Hey Monkey!

This works perfect! I'll be recycling your code for other purposes too, got to start chopping down that ugly monster I created. :)

I'm not sure what this means, but does "exposing" gui controls in the engine make the calculation faster or something? Personally I'm content with just using your script if changing the engine is too time consuming just to get a little gain in speed or efficiency or something.
--All that is necessary for evil to triumph is for good men to do nothing.

Crimson Wizard

Frankly, I would question why would you need to show/hide ALL labels altogether: this kind of action sounds is too general IMO. Imagine you will add more guis with labels, that should not be hidden, somewhere on later stages of development...

Perhaps using properties may help to distinguish labels, or guis with special labels.

Knox

#5
Yeah, I just ran into that actually...heh.

Is there a way I can add to the list ONLY the labels that contain the word "_Hotspot" in their name? Naming convention is: lblMyGui_Hotspot

Its for a game feature where if the user turns "hints" off in the general settings, all labels on GUIs that offer hints will just be made invisible.

I know Id have to tokenize the name once  the script has found a label and if "_Hotspot" is found, than add it to the list...only thing is, how do I query the actual label's name? Seems I can only grab the ID.

**EDIT**
Quote from: Crimson Wizard on Thu 31/10/2013 14:35:56
Perhaps using properties may help to distinguish labels, or guis with special labels.

Can we add custom properties to GUI controls? That would be awesome! :)
(I already reached my properties limit so I have to wait until 3.4 is more stable to do any tests.)
--All that is necessary for evil to triumph is for good men to do nothing.

Khris

You can't get object names in String form, no. What you can do is change the labels' height by a pixel, and have the code only show/hide labels with an even height.

Monsieur OUXX

i can't remember if controls have them but the common practice is to use the description property. E.g. set the label's description to "label1" and then check it as a String.

PS: Knox, if you wish, I can have a look at your code and give you advice on how to re-engineer it to make it more compact and, more importantly, more maintainable.
 

Khris

What description property? I'm not seeing that in the GUI editor or the scripting reference.

Monsieur OUXX

Quote from: Khris on Fri 01/11/2013 00:13:20
What description property? I'm not seeing that in the GUI editor or the scripting reference.

As I wrote, I didn't remember if GUI controls have it. I just checked; unfortunately they don't. Only hotspots have a description. The 9-verb template uses the description of the hotspots to set their "type" (door, etc.).
Monkey's script seems to be the best (and only) solution.
 

Knox

#10
I guess I'll use Monkey's script for now, in conjunction with Khris' suggestion (only add labels with a height of say 14 into the array). I can live with that :)

@Monsieur OUXX: The whole thing? That's quite a generous offer there...Ok, I'll send you a PM.

**EDIT**
Ok I added this line, seems to do the trick. I'll just make sure all hotspot labels are 14 in height, and all the others never have that value.
Code: ags

      if (gui[g].Controls[c].AsLabel != null && gui[g].Controls[c].AsLabel.Height == 14) // found a Label with 14 as height, the hotspot labels
      {
        tmp[labelCount] = gui[g].Controls[c].AsLabel;
        labelCount++;
      }
      c++;
--All that is necessary for evil to triumph is for good men to do nothing.

SMF spam blocked by CleanTalk