HeroEngine Forums
Welcome, Guest. Please login or Register for HeroCloud Account.

Author Topic: [Resolved] Hello World: trying to add list elements error  (Read 3433 times)

RavenX13

  • General Accounts
  • *
  • Posts: 5
    • View Profile

I'm trying to get the hang of HSL so I put together the Hello World example for creating a basic GUI window.
http://hewiki.heroengine.com/wiki/Creating_a_window

Then I made a small modification in the hopes that I could add extra lines of "Hello World" and test the scroll functionality.

Code: [Select]
function HelloWorld()
  // This creates a window GUIControl from a prototype
 
  myTestWindow as NodeRef of Class GUIControl = createNodeFromPrototype("MyTestWindow")
 
  // Make the new window renderable in the screen
  myTestWindow.build = true
 
  // Configure the window's position in the viewport
  screen as Vector3 = getViewPortSize()
  myTestWindow.position.x = (screen.x - myTestWindow.size.x) / 2
  myTestWindow.position.y = (screen.y - myTestWindow.size.y) / 2
 
  // Create a list of labels
  myWindowLabelList as List of Class GUILabel
 
  // Create the Label where the main window text will appear
  myTestDataLabel as NodeRef of Class GUILabel = createNodeFromPrototype("_label")
  myTestDataLabel.autoSetHeight = true
 
  // Add 20 Hello World labels to the list
  loop i from 1 to 20
      myTestDataLabel.text = "Hello World! " + "x" + i
      add back myTestDataLabel to myWindowLabelList
  .
 
  // Find the clientarea on the window control, and connect
  //   the new text label control to it.
  clientArea as NodeRef of Class GUIControl = findGUIControlByName(myTestWindow, "scrollable.clientarea")
  add back myWindowLabelList to clientArea.children
  myWindowLabelList.dockMode = TOP
 
  // This makes the new label renderable in the screen
  myWindowLabelList.build = true


now I get the error: item type doesn't match list element type
on the following lines
Code: [Select]
            add back myTestDataLabel to myWindowLabelList

Code: [Select]
    add back myWindowLabelList to clientArea.children

and the error: not a member of list
on the lines:
Code: [Select]
    myWindowLabelList.dockMode = TOP

Code: [Select]
  myWindowLabelList.build = true

Any help is much appreciated.
« Last Edit: Nov 01, 12, 02:47:04 PM by HE-Cooper »
Logged

FI-ScottZ

  • General Accounts
  • *
  • Posts: 1407
    • View Profile
    • Forever Interactive, Inc.
Re: Hello World: trying to add list elements error
« Reply #1 on: Dec 28, 11, 08:04:39 PM »

You declared myWindowLabelList as List of Class GUILabel, but the type of myTestDataLabel is NodeRef of Class GUILabel.  Thus, the list needs to also be List of NodeRef of Class GUILabel.

Declaring as simply Class is acceptable syntax in and of itself. When declaring as a Class instead of NodeRef, it works like a basic data structure.  On the plus side, you don't need to allocate/deallocate memory.  On the downside, there is no node created, so you cannot point a noderef to it, nor can you call any methods with it (since with no node, there would be no "me").  Something declared as Class can only be used to read/write fields and properties.

Also, you would need to create a separate label control for each one you want to add, not just one as you have it now.

Finally, the list itself is not a gui control but simply a list, which is why it does not have fields such as dockmode and build.  Those need to be set on each individual label created.  
« Last Edit: Dec 28, 11, 08:11:36 PM by ScottZarnke »
Logged
Scott Zarnke
Lead Programmer, Visions of Zosimos
CTO, Forever Interactive, Inc.

RavenX13

  • General Accounts
  • *
  • Posts: 5
    • View Profile
Re: Hello World: trying to add list elements error
« Reply #2 on: Dec 29, 11, 01:49:09 AM »

Thanks a ton Scott. I changed the code and it's working.

As was my original concept, I was able to create the List of NodeRef of Class GUILabel and then add that list as a child to the _scrollablePanel area of the GUIControl (named "clientArea" in the code).

Code: [Select]
function HelloWorld()
  // This creates a window GUIControl from a prototype
 
  myTestWindow as NodeRef of Class GUIControl = createNodeFromPrototype("MyTestWindow")
 
  // Configure the window's position in the viewport
  screen as Vector3 = getViewPortSize()
  myTestWindow.position.x = (screen.x - myTestWindow.size.x) / 2
  myTestWindow.position.y = (screen.y - myTestWindow.size.y) / 2
 
  // Make the new window renderable in the screen
  myTestWindow.build = true
 
  // Create a list of labels
  myWindowLabelList as List of NodeRef of Class GUILabel
 

  // Add 20 Hello World labels to the list
  loop i from 1 to 20
      // Create the Label where the main window text will appear
      myTestDataLabel as NodeRef of Class GUILabel = createNodeFromPrototype("_label")
     
      // Add the text to the new Label
      myTestDataLabel.text = "Hello World! " + "x" + i
      myTestDataLabel.autoSetHeight = true
      myTestDataLabel.dockMode = TOP

      add back myTestDataLabel to myWindowLabelList
  .
 
  // Find the clientarea on the window control, and connect
  //   the new list of text labels to it.
  // "scrollable.clientarea" is the name of the _scrollablePanel in the GUI XML prototype definition
  clientArea as NodeRef of Class GUIControl = findGUIControlByName(myTestWindow, "scrollable.clientarea")
  add back myWindowLabelList to clientArea.children
 
  // myTestDataLabel.build = true

 .

I also re-wrote it slightly so that each label was added as a child to the _scrollablePanel area of the GUIControl ("clientArea") as it was created in the for loop, elminating the GUILabel list altogether. Is one method preferred over the other? Or am I going about adding text to a _scrollablePanel in the wrong way to begin with? (My current UI goal is to implement a chat window where the messages are persisted even if the chat window is closed.)

Code: [Select]

function HelloWorld2()
  // This creates a window GUIControl from a prototype
 
  myTestWindow as NodeRef of Class GUIControl = createNodeFromPrototype("MyTestWindow")
 
  // Configure the window's position in the viewport
  screen as Vector3 = getViewPortSize()
  myTestWindow.position.x = (screen.x - myTestWindow.size.x) / 2
  myTestWindow.position.y = (screen.y - myTestWindow.size.y) / 2
 
  // Make the new window renderable in the screen
  myTestWindow.build = true
 
 
  // Find the "scrollable.clientarea" which is the name of the _scrollablePanel in the GUI XML prototype definition
  clientArea as NodeRef of Class GUIControl = findGUIControlByName(myTestWindow, "scrollable.clientarea")
 
  // Add 20 Hello World labels to the list
  loop i from 1 to 20
      // Create the Label where the main window text will appear
      myTestDataLabel as NodeRef of Class GUILabel = createNodeFromPrototype("_label")
 
   
      // Add the text to the new Label
      myTestDataLabel.text = "Hello World! " + "x" + i
      myTestDataLabel.autoSetHeight = true
      myTestDataLabel.dockMode = TOP
     
      // Put the new label data into the _scrollablePanel
      add back myTestDataLabel to  clientArea.children

  .
   
  // myTestWindow.build = true

 .

Why is it necessary to create a new NodeRef each time within the loop? When I put the
Code: [Select]
      myTestDataLabel as NodeRef of Class GUILabel = createNodeFromPrototype("_label")
above the start of the for loop, the window only displays the last line created (i.e. "Hello World! x20"). What happens to the 20 instantiated nodes when I create the NodeRef from inside the loop? Do all 20 still exist somewhere as children in the _scrollablePanel even though each time a new one is defined it has the same name ("myTestDataLabel")? Are they destroyed when the window is closed?

I do have a small hiccup in the results: the text in the window comes out red, even though the defaultStatePresentation color is defined to be dark grey in the _label prototype used to created the GUILabel NodeRef. Does this indicate some sort of error somewhere?

Finally, if I put the
Code: [Select]
  myTestWindow.build = true statement after the for loop it causes a strange result. Only "HelloWorld! x1" appears, and it's in red in the upper left corner of the screen. Also a solid red square appears in the center of the screen. There is no window border and no X to close it, though it can be dragged around the screen. Any ideas why the .build call for the window must come before rather than after the _scrollablePanel children are populated?

Thanks in advance.
Logged

FI-ScottZ

  • General Accounts
  • *
  • Posts: 1407
    • View Profile
    • Forever Interactive, Inc.
Re: Hello World: trying to add list elements error
« Reply #3 on: Dec 29, 11, 07:27:20 PM »

Quote
When I put the ... above the start of the for loop, the window only displays the last line created (i.e. "Hello World! x20").
With the creation outside of the loop, only one node (object) is being created.  The loop then assigns multiple references to that same object, but it is still only one.  Consequently, the gui shows the same single object 20 times, and furthermore, it contains the value last assigned to it (20).  Imagine a single circle with 20 arrows pointing to it.  For the lines to have independent values, each must reference a different node.

Quote
Do all 20 still exist somewhere as children in the _scrollablePanel even though each time a new one is defined it has the same name ("myTestDataLabel")?
Yes, they are allocated in dynamic memory and the system does not object to multiple gui controls having the same name, although siblings should all have names different from each other.  Often times when getting a control by name, we specify a path relative to a parent, something like: FindGUIControlByName(parentControlRef, "childName.grandchildName"), sort of like files in a folder system can have the same name as each other if they are not in same folder, but within a folder it needs to be able to distinguish which one you are talking about.  So in your case, naming all the siblings the same would prevent you from referencing one in particular.  If you tried, I imagine you would always get the first one.  If you are not interested in referring to them by name, you do not need to assign a name at all; their name will come from the prototype.

Quote
Are they destroyed when the window is closed?
Yes, fortunately when a control is destroyed, the system automatically destroys all descendents of it (but not ancestors or siblings).


Quote
Finally, if I put the [build= true] statement after the for loop it causes a strange result.
That is due to the fact that "build = true" not only makes the control appear the first time, it also builds the control's hierarchy.  That means no child controls exist until after build = true. Prior to that line, you can set properties of the control itself, but can't do anything to any children since they are not there, yet.  So, in your case, the error happens when you try to add to a non-existant child of the window.

As far as the red square, that typically happens to signal that you have a mistake preventing gui controls from being properly built.  Building before adding the labels should resolve that.

P.S. As far as your desire to retain messages after the window closes: it is true the labels get destroyed if you destroy the window. But instead of destroying the window, you could instead toggle the visible field to simply hide/show it, maintaining the labels.  Alternatively, if you really want to destroy the window, you would need to store the messages in some other node, perhaps a system node.
« Last Edit: Dec 29, 11, 07:30:57 PM by ScottZarnke »
Logged
Scott Zarnke
Lead Programmer, Visions of Zosimos
CTO, Forever Interactive, Inc.

FI-ScottZ

  • General Accounts
  • *
  • Posts: 1407
    • View Profile
    • Forever Interactive, Inc.
Re: Hello World: trying to add list elements error
« Reply #4 on: Dec 29, 11, 07:34:06 PM »

Also, the Chat Window that Hero comes with has some examples of managing a listing of labels that you can draw inspiration from.  In E_ChatWindowClassMethods, the method AddChatMessage() shows how they handle adding and rotating the incoming messages.

EDIT: Actually, looking at that one, I see they have all of the labels already in there (added via the gui editor) and then they control which label shows which message, and move them around in the children list to rotate.
« Last Edit: Dec 29, 11, 07:37:04 PM by ScottZarnke »
Logged
Scott Zarnke
Lead Programmer, Visions of Zosimos
CTO, Forever Interactive, Inc.

Dothackking

  • General Accounts
  • *
  • Posts: 34
    • View Profile
Re: Hello World: trying to add list elements error
« Reply #5 on: Dec 29, 11, 10:57:16 PM »

I'm having problems with this tutorial as well.   I tried it with the GUI editor first.   Had errors.   Copy+pasted all of the script into the script editor...errors.   I have no idea what's wrong.



Code: [Select]
20:55:23: call testwindow MakeMyTestWindow
20:55:23: !ERROR!HeroScript::HeroMachine::ScriptError:Exception DefinitionNotFoundException in function 'createNodeFromPrototype' definition not found: MyTestWindow
20:55:23: !ERROR!System:SCRIPT ERROR: Exception DefinitionNotFoundException in function 'createNodeFromPrototype' definition not found: MyTestWindow
12/29/2011 20:55:16
Call trace:
  Script testwindow line 4 me[0]
starting method/function MAKEMYTESTWINDOW
starting me[id=0 invalid]
20:55:23: SYSTEM:System:call OK 0 : "HeroScript called"
Logged

FI-ScottZ

  • General Accounts
  • *
  • Posts: 1407
    • View Profile
    • Forever Interactive, Inc.
Re: Hello World: trying to add list elements error
« Reply #6 on: Dec 30, 11, 12:28:48 AM »

DotHacking:
It is telling you that the "MyTestWindow" gui prototype has not been defined, yet.  So, you will need to figure out why it did not define correctly.

You should find the gui prototype script in the script editor by clicking Open...GUI XML.  If you created it in the gui editor, the properties panel in that editor will state the name of the script it is in. The default is to name the script the same as the prototype, i.e. MyTestWindow.xml.

Do you have that script?
Logged
Scott Zarnke
Lead Programmer, Visions of Zosimos
CTO, Forever Interactive, Inc.

Gothrek

  • General Accounts
  • *
  • Posts: 92
    • View Profile
Re: Hello World: trying to add list elements error
« Reply #7 on: Dec 30, 11, 12:32:57 AM »

I'm having problems with this tutorial as well.   I tried it with the GUI editor first.   Had errors.   Copy+pasted all of the script into the script editor...errors.   I have no idea what's wrong.



Code: [Select]
20:55:23: call testwindow MakeMyTestWindow
20:55:23: !ERROR!HeroScript::HeroMachine::ScriptError:Exception DefinitionNotFoundException in function 'createNodeFromPrototype' definition not found: MyTestWindow
20:55:23: !ERROR!System:SCRIPT ERROR: Exception DefinitionNotFoundException in function 'createNodeFromPrototype' definition not found: MyTestWindow
12/29/2011 20:55:16
Call trace:
  Script testwindow line 4 me[0]
starting method/function MAKEMYTESTWINDOW
starting me[id=0 invalid]
20:55:23: SYSTEM:System:call OK 0 : "HeroScript called"

U miss something, or miss some steps, the tutorial work verygood, try it again step by step.
Logged

Dothackking

  • General Accounts
  • *
  • Posts: 34
    • View Profile
Re: Hello World: trying to add list elements error
« Reply #8 on: Dec 30, 11, 03:03:08 PM »

I will try again.  I did not retry it from scratch, but I tried every step multiple times.   Lets try again now that I've had some sleepx.x


after trying again, same problem.  It does not seem to create the prototype.    I look all throughout client and server prototypes and MyTestWindow is not there.

Console says it recieves it, and updates /guixml/mytestwindow.xml, but there file isn't there.


I'm very confused.
« Last Edit: Dec 30, 11, 03:37:47 PM by Dothackking »
Logged

RavenX13

  • General Accounts
  • *
  • Posts: 5
    • View Profile
Re: Hello World: trying to add list elements error
« Reply #9 on: Dec 30, 11, 04:40:07 PM »

Thanks a ton, Scott. That clarifies lots of things for me.

Cheers.
Logged