Dynamic content of listbox selection?

Started by EliasFrost, Wed 18/09/2013 01:43:50

Previous topic - Next topic

EliasFrost

Hi again. In my game I have a note system that is used to (obviously) view notes. But I'm having a bit of a problem at the moment: I want to be able to change the text of a label dynamically depending on which selection from the listbox is activated. Setup of the problem below:

I have a GUI with a listbox, which accumulate over time (the player find new notes), no problem there
I also have another GUI with a label, the label contains the text I want the note to display, no problem here either.
The OnSelectionChanged function for the list, I have the following script:

Code: ags
function notelist_OnSelectionChanged(GUIControl *control)
{
  if (notelist.Contains("Strange Bill"))
  {
    gnotetext.SetPosition(182, 35);
    gnotes.Clickable = false;
    notetext.Text = "text";
    aOpennotes.Play();
    gnotetext.Visible = true;
  }
  else if (notelist.Contains("Note from Garbage Bin"))
  {
    gnotetext.SetPosition(182, 35);
    gnotes.Clickable = false;
    notetext.Text = "text";
    aOpennotes.Play();
    gnotetext.Visible = true;
  }
}



Which works fine on it's own, BUT my problem is with this script, which I imported from this thread: http://www.adventuregamestudio.co.uk/forums/index.php?topic=35346.msg463042#msg463042


Code: ags
bool Contains(this ListBox*, String s)
{
  int i = 0;
  bool found = false;
  while(i < this.ItemCount)
  {
    if(this.Items[i] == s) found = true;
    i++;
  }
  return found;
}



I understand how the script works, it's looking through the entire list for the argument passed through the call then returns it. That said, it doesn't matter which option I choose because it only goes so far as the top if statement (because it does find the string), but is there a way to check for the string within the selected list object only (and not the entire list)? If so, how do I access individual indexes dynamically?

Thanks in advance! :)

monkey0506

#1
Um... are you looking for ListBox.Items?

Code: ags
if ((notelist.SelectedIndex != -1) && (notelist.Items[notelist.SelectedIndex] == "Strange Bill"))
{
  // ...
}


For simplicity (since you're comparing multiple strings) you'd probably want to store the selected item in a temporary variable though:

Code: ags
String selectedItem = "";
if (notelist.SelectedIndex != -1) selectedItem = notelist.Items[notelist.SelectedIndex];
if (selectedItem == "Strange Bill")
{
  // ...
}
else if (selectedItem == "Note from Garbage Bin")
{
  // ...
}


Edit: It just occurred to me that the Contains method you were using actually uses the ListBox.Items property...so maybe you were just overlooking the SelectedIndex?

Khris

Yeah, my function isn't needed at all for this. Like the name suggests, it searches through the list for something. But the currently selected item can be compared to a String directly, like monkey showed.

As an aside, using the text string multiple times is discouraged; I'd store them in an array and possibly also use an enum:

Code: ags
// header
enum InvItems {
  eInvStrangeBill,
  eInvGarbageNote
};

import String inv_desc[100];

// main script
String inv_desc[100];
export inv_desc;

// in game_start
  inv_desc[eInvStrangeBill] = "Strange Bill";
  ...


EliasFrost

This pretty much shows how inexperienced I am at coding lol, that makes a lot of sense Monkey, thanks for the help! Also for Khris, why is it discouraged to use text strings multiple times?

Khris

There's a general coding principle going by DRY (Don't repeat yourself). It's also error-prone, because you might spell it slightly differently somewhere else and suddenly your comparison code breaks, but you might not notice that until much later, etc.

Also, let's say you want to change the description at some point: you'll have to through your code and change multiple instances, again rising the possibility of a hard to track down error.

EliasFrost

Oh alright that makes sense, I'll keep that in mind. Thanks a lot guys!

SMF spam blocked by CleanTalk