PDA

View Full Version : properly destroying GUI controls?


maximus_asinus
09-08-2017, 07:55 PM
I'm currently having issues with a custom sign system I am creating. I think the bug exists because the GUI controls aren't being destroyed properly (working theory for right now). This is how I am destroying the controls:

function DestroyGUI() {
hideimg(200);
first_object.destroy();
second_object.destroy();
}

Both are GuiBitmapCtrl controls which contain other controls. And this seems to work fine when you interact with one sign, but once you touch a second sign the F2 log starts throwing errors.

Script: Function first_object.destroy not found in function DestroyGUI of maximus_debug in script of Sign (in level maximus_asinus_test_03.nw at pos (44, 14))

Script: Function second_object.destroy not found in function DestroyGUI of maximus_debug in script of Sign (in level maximus_asinus_test_03.nw at pos (41, 14))

Once this starts to happen the sign starts pulling text from the other sign. I've read through the wiki about a dozen times now, and I still don't understand what I'm doing wrong.

maximus_asinus
09-12-2017, 12:32 AM
For future knowledge this was an issue with how I was calling the next function and not an issue with destroy(). It works as intended.

I would like to know a decent method for destroying a GUI control if the player is warped. If anyone has advice on that I'd like to hear. Thanks!

maximus_asinus
09-12-2017, 02:13 AM
I've run into another problem and I'm not entirely certain how to get around it or what is causing it. I am checking if a specific key is pressed when a control is active:

function CONTROLNAME.onKeyDown(keycode, keytext, scancode) {
if (keytext == "d") {
this.option = CONTROLNAME.getselectedrow();
CONTROLNAME.destroy();
}
}

But for whatever reason this block of code repeats multiple times before exiting the script. This is a problem as obviously the control is deleted, so this.option will be overwritten and return 0.

DustyPorViva
09-12-2017, 08:43 PM
You can use findobject("objectname") to check if an object exists before destroying it.

For clearing out GUIs when you leave a level(assuming you are creating the GUI's in a level script) you can try a serverside onPlayerLeaves(), like so:


function onPlayerLeaves() {
if (player != null) player.triggerClient("gui","SomeSystemWeapon","clearcontrols","ControlName");
}


Then have a system weapon to handle the client trigger:


//#CLIENTSIDE
function onActionClientside() {
if (params[0] == "clearcontrols") {
if (params[1] != null) {
temp.obj = findObject(params[1]);
if (temp.obj != null) temp.obj.destroy();
}
}
}

Other methods could be adding the control name to an array to clear out(along with a level name it should be linked to) and in a System weapon scanning through the array onPlayerEnters() and destroying any controls that exist if the player is not in the level name linked to that control.

For the other issue you can try keeping track of when an object is going to be destroyed. Just so you know, objects can also have dynamic variables assigned to them.


new GuiControl("Control") {
x = y = 10;
width = height = 100;
this.isSomeFlag = true;
}

You can now access Control.isSomeFlag as well as something like:


echo("Flag State: " @ Control.isSomeFlag);

// Will echo the same state as above
with (Control) {
echo("Flag State: " @ this.isSomeFlag);
}

So with that in mind, you can try something like this:
function CONTROLNAME.onKeyDown(keycode, keytext, scancode) {
if (keytext == "d") {
// Don't try to destroy if already queued to be destroyed;
if (CONTROLNAME.isDestroyed == true) return;

this.option = CONTROLNAME.getselectedrow();
CONTROLNAME.isDestroyed = true;
CONTROLNAME.destroy();
}
}

maximus_asinus
09-13-2017, 02:19 AM
I'm trying to what you suggested, but I am still having issues with the keydown repeating. Maybe showing exactly what I'm doing will shine more light on my problem.


//this.isDestroyed is set to false inside of say3_options_object
//say3_options_list is set to be the first responder
function say3_options_list.onKeyDown(keycode, keytext, scancode) {
if (keytext == "d") {
// say3_options_list is inside say3_options_object
if (say3_options_object.isDestroyed == true) return;
say3_options_object.isDestroyed = true;
this.option = say3_options_list.getselectedrow(); // get row value
DestroySay3(); // function to destroy all GUI objects
}
}


After I added your suggestion it only loops twice (before it looped three times). I still don't understand why it loops at all.

Also after testing a little bit it doesn't look like onPlayerLeaves is called, at least if the player uses "unstick me". I am going to look into that a bit more.

DustyPorViva
09-13-2017, 04:36 PM
Make sure onPlayerLeaves() {} is being used serverside, not clientside.

As for the issue you're encountering with the list selection... sometimes Graal is gonna be Graal. You can try using something other than getselectedrow(), like getselectedid() and assign ID's starting at 1 or such. That way if Graal returns 0 or such you'll know it's not a valid input and to just ignore it.

maximus_asinus
09-14-2017, 01:51 AM
For future reference, onPlayerLeaves works. When I was joining the class it was on CLIENTSIDE.

maximus_asinus
09-15-2017, 05:06 AM
How does GuiScrollCtrl.scrollto(int, int) work? I am having issues with scrolling a GuiTextListCtrl inside of a GuiScrollCtrl. For whatever reason when using the arrow keys to navigate the menu the control won't scroll to the highlighted option / row. Scrolling with the mouse wheel is the only way to see further down the page.

Also can I catch if a player resizes GraalControl?

Crow
09-15-2017, 05:49 AM
Also can I catch if a player resizes GraalControl?

function GraalControl.onResize(width, height) {
}

maximus_asinus
09-16-2017, 01:32 AM
I broke down and placed my script inside of a weapon NPC which has fixed a lot of the issues I was having before. Currently I am calling it in a level NPC like this:


function onPlayerTouchsMe() {
temp.npc = findweapon(WEAPON).FUNCTION(PARAM, PARAM);
}


but I realize I could do something like


function onPlayerTouchsMe() {
triggerClient("gui", "WEAPON", PARAM, PARAM);
}


I think I prefer the second method as it looks a lot cleaner, and believe it would function in the same way, but I'm wondering if one way is superior to the other, if there are any security flaws in either method, etc.

function GraalControl.onResize(width, height) {
}For whatever reason I assumed onResize was restricted to GUI Controls. Thanks, and thank you to everyone who has helped me out thus far.

Now I just need to understand this scrolling bug.

maximus_asinus
09-16-2017, 09:45 AM
okay to resolve the issue I used


function GuiTextListCtrl.onSelect(entryid,entrytext,entryin dex) {
GuiScrollCtrl.scrollto(0, GuiTextListCtrl.getselectedrow() * FONTSIZE);
}


Probably not the most elegant solution but it is effective.

maximus_asinus
09-17-2017, 01:35 AM
I'm actually having more trouble with that hack workaround. Is there any way to find the position of a row and then scroll to it that way? To me it is pretty ridiculous that it doesn't automatically scroll to a selected row when the row is highlighted. It might be a byproduct of my script, but I really don't think so.

maximus_asinus
09-18-2017, 03:50 AM
Can someone clarify the different between onKeyDown and keydown? I read somewhere that keydown works off the mapped keys in the options menu, and onKeyDown does not. If I wanted to allow the player to use mapped keys inside of a Gui would I have to use keydownglobal?