Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: Babar on Thu 13/06/2013 23:06:23

Title: [Unsolvable] Accessing any button's script through the script
Post by: Babar on Thu 13/06/2013 23:06:23
Hello BTF! Long time no see!

I've got this GUI that I want to be able to iterate through the buttons of, and then interact with the buttons.
I've got the first part down, which means I can access all the properties of whichever button I'm currently on (X position, width, ID, etc.).

But now I can't find any way to get the script associated with the button to run.
I had been using this:
Code (AGS) Select
ProcessClick(gOptions.X + gOptions.Controls[smb[1]].X + gOptions.Controls[smb[1]].Width/2, gOptions.Y + gOptions.Controls[smb[1]].Y + gOptions.Controls[smb[1]].Height/2, eModePointer);
But then I saw that ProcessClick ignores GUIs. GUIs or GUIControls don't seem to have a RunInteraction or a RunScript or any such thing either.

So is there a way to access any button's script at run-time? Or some way to accomplish what I'm trying without having to hardcode the different buttons' function names into an if-block in this code?
Title: Re: Accessing any button's script through the script
Post by: Crimson Wizard on Thu 13/06/2013 23:17:51
I don't think there's a way, you'll have to make a long switch iterating all possible buttons.

To make things easier for you, you may use GUI.GetAtScreenXY to get GUI and GUIControl.GetAtScreenXY to get gui control under mouse, instead of manually checking coordinate.
Then use their ID to choose proper function.
Title: Re: Accessing any button's script through the script
Post by: Babar on Thu 13/06/2013 23:22:59
That is very disappointing :(...
And not a switch (AGS doesn't have switch yet, does it?), it'll just be a big block of if-elses.

Gah.
Title: Re: Accessing any button's script through the script
Post by: Ghost on Fri 14/06/2013 00:04:17
Babar, the AGS 9Verb template seems to do just what you try to implement: In the main GUI all buttons run the same script, and the game just checks if a mouse-click hit the GUI and the stores the control's ID. Can't say how useful that is for you (since apparently the buttons only set mouse modes and run no complicated script).

It's a lot of script to sift through but maybe it'll get you started? At least it seems to be a convenient way to have ONE function where all button ids get some scripting assigned.
Title: Re: Accessing any button's script through the script
Post by: Babar on Fri 14/06/2013 00:20:04
I don't see how that would help, Ghost :(....
Having the code for the button pressing all together in one function in an if-block instead of just calling the functions for the button presses in the if-block is essentially the same amount of hard-codedness, and wouldn't work because I still want those buttons to be normally clickable.
Title: Re: Accessing any button's script through the script
Post by: Ghost on Fri 14/06/2013 00:35:54
Babar, I may have misread you, but to me it sounded like a good solution/workaround/step-in-the-right direction.

It's in the manual too, and better explained there ;)

Controls property (GUI)
GUIControl* GUI.Controls[index]
Provides an array which allows you to access controls on the GUI by their index. You should not normally need to do this, since accessing the controls by their name is far easier; however, if you need to interoperate with legacy code that uses the control number, this can come in useful.

You CAN iterate through arrays, can't you? So I thought it might work.

Title: Re: Accessing any button's script through the script
Post by: Babar on Fri 14/06/2013 00:54:42
I am using the Controls[index] thing as it is now already, but I have no method to go from there to accessing the script of that control/button. I am already iterating through a loop of the buttons on the GUI, but each button has pretty varied functionality (it is sort of a settings menu with SAVE, LOAD, VOLUME, SPEED, QUIT, etc.), so I wouldn't be able to have that all in a loop.
Title: Re: Accessing any button's script through the script
Post by: Khris on Fri 14/06/2013 01:27:40
To make things a bit more tidy and readable, you can add this function at the bottom of the GlobalScript:

Code (ags) Select
function MainGUIButton(GUIControl *control, MouseButton button) {
  if (control == btnQuit) btnQuit_OnClick(control, button);
  if (control == btnLoad) btnLoad_OnClick(control, button);
  ...
}

Now put "MainGUIButton" into every button's on click event field.

To run the button script, call MainGUIButton(btnLoad, eMouseLeft);
In a loop, use the Controls array element instead.
Title: Re: Accessing any button's script through the script
Post by: Babar on Fri 14/06/2013 03:29:07
That is useful. Thanks, Khris.

EDIT:I added it, but I it seems I had to add it BEFORE the function where I'm iterating through all the GUI buttons...I didn't realise that AGS only accepts functions in the order they're given (there's some technical term for that, which I've forgotten). If I put it afterwards, and then referenced it, I kept getting undefined token.
Title: Re: Accessing any button's script through the script
Post by: Khris on Fri 14/06/2013 10:26:17
Yes, just like variables, functions have to be declared before they are used.
Title: Re: [Unsolvable] Accessing any button's script through the script
Post by: monkey0506 on Fri 14/06/2013 14:08:11
To be entirely pedantic, functions (and variables, etc.) in AGS have to be defined before they can be used, not just declared.

Quote from: Babar on Fri 14/06/2013 03:29:07I didn't realise that AGS only accepts functions in the order they're given (there's some technical term for that, which I've forgotten).

Perhaps the "technical term" would be to say that AGS doesn't allow use of undefined forward-declared functions? AGS already supports forward-declaration to some degree (import keyword does this), but the compiler won't currently link the functions properly (and therefore explodes) if the function isn't fully defined yet. Seeing as every C++ compiler (pedantic: linker) in existence allows this as part of the C++ language, I'm actually curious how difficult it would be to actually implement this into the AGS engine (which could revolutionize the AGScript language).

And I've been advocating for a generic way of simulating GUI and GUIControl clicks for years. Unfortunately, as you've discovered, it's presently impossible to do this generically (though the engine itself has to be doing essentially that internally, so I imagine that exposing it wouldn't actually be that difficult...).
Title: Re: [Unsolvable] Accessing any button's script through the script
Post by: Phemar on Fri 14/06/2013 15:48:21
Quote from: monkey_05_06 on Fri 14/06/2013 14:08:11I'm actually curious how difficult it would be to actually implement this into the AGS engine (which could revolutionize the AGScript language).

At the cost of some compile time, since the compiler would first have to scan through all the scripts and note the position of each declaration before it actually does the compiling :D