[Unsolvable] Accessing any button's script through the script

Started by Babar, Thu 13/06/2013 23:06:23

Previous topic - Next topic

Babar

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
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?
The ultimate Professional Amateur

Now, with his very own game: Alien Time Zone

Crimson Wizard

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.

Babar

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.
The ultimate Professional Amateur

Now, with his very own game: Alien Time Zone

Ghost

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.

Babar

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.
The ultimate Professional Amateur

Now, with his very own game: Alien Time Zone

Ghost

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.


Babar

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.
The ultimate Professional Amateur

Now, with his very own game: Alien Time Zone

Khris

To make things a bit more tidy and readable, you can add this function at the bottom of the GlobalScript:

Code: ags
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.

Babar

#8
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.
The ultimate Professional Amateur

Now, with his very own game: Alien Time Zone

Khris

Yes, just like variables, functions have to be declared before they are used.

monkey0506

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...).

Phemar

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

SMF spam blocked by CleanTalk