"Swap Tab Panel" overwrites info("Trigger") value

In tracking down an error in a procedure that makes extensive use of info(“Trigger”), I found that when the variable for a Tab Panel is changed, info(“Trigger”) becomes “Swap Tab Panel”.

In the screenshot below fgChartTab is the variable used by a TabPanel object. The Terminal window at the top shows the zlog entries and how it changes. If the value of fgChartTab does not change, neither does info(“Trigger”)

Screenshot 2022-10-26 at 1.20.50 PM

That’s not a bug, it’s a feature. You’ve changed the tab panel, so it has been triggered. There are other situations where this can happen as well. If you need to continue to use the original trigger value then you’ll need to start your procedure by saving the trigger into a variable.

Exactly the route I’ve taken, then restoring it at the end of the procedure for use in subsequent procedures. But it may as well be a bug since the trigger was being inexplicably changed to a value that wasn’t obvious. It took quite a while to figure out why a complex and lengthy procedure was sometimes failing.

It’s not “inexplicably”. An object changed state, that sets the trigger. If it didn’t set the trigger, that would be a bug.

I’m not out to beat a dead horse, especially since I now have this covered but this does strike me as a flaw in Panorama.

I had a lengthy and complex procedure that built matrices and charts; about 600 lines of code with loops, call, shortcalls… Which charts to build was being determined at the outset by the use of SetTrigger. It was working very nicely. Then it failed. I ran it again and it worked, then again and again it worked. Then it failed. Then it worked again.

Unknown to me, Panorama was changing the value of info(“Trigger”) - sometimes . If my procedure changed a Tab Panel to show a different chart configuration so did the trigger. But if the current configuration was used, the Tab Panel was not changed even though my procedure ran through the exact same steps, and the trigger was left untouched.

I do understand by your response that changing the TabPanel is technically a trigger. But in my code it was merely a change of a variable making it very un-obvious, aka inexplicable to me. Before I discovered that the issue was a change in the info(“Trigger”) value, I looked at seemingly more likely culprits such as the ChangeObject commands I was using to install new Plotly chart HTML in the Web Browser Objects. When I eventually found that the trigger value was changing to “Swap Tab Panel” I searched all the called procedures for where it might be getting changed to that value. It still took a while to track it down to the change of the variable value for a TabPanel. A Full Text Search in Help didn’t find it.

Perhaps Panorama should be restoring the trigger value instead of the end user having to know about and handle it - or somehow using a more recognizable value (clue). It’s been pointed out more than once that using and changing the contents of the Clipboard within a procedure isn’t good practice unless it’s the purpose of the procedure.

Now that I am aware of it, I have to wonder what other similar scenarios exist. I use TabPanels a lot, they’re a great feature. I’ve also used changes in their variables in order to change them versus requiring the user clicking on a tab. And I use info(“Trigger”) a lot.

Are there other objects that will have a similar effect?

I can see that an action - trigger - happened when the tab panel was clicked but in the documentation for Info(“trigger”), it only mentioned keys, buttons, and menus. So it’s understandable that clicking a tab would be overlooked. I would consider it a second cousin to clicking (switching) a window; i.e. not a triggerable event.

If moving from one window to another doesn’t activate a “trigger”, bringing a new tab forward might not either - especially if that action isn’t mentioned in the documentation.

I guess an “easy” fix is to add an, "AND NOT Info(“trigger”) = … to your tests. But if those tests are scattered throughout your procedures (and you have procedure code buried in objects), they all might be hard to find.

That’s the oldtimer’s problem I have with OOPS. When you are just given a program (Panorama or otherwise) with no documentation and a request to “Fix it”, a lot of the challenge is finding where the problem is. Sure, there is the actual fixing of it; but my experience has been that as much or more time is spent finding the erroneous code. Sure, you might find one place, but you’d have to check every nook and cranny to make sure it doesn’t also exist somewhere else. However, that’s another soap box.

This was not a case of anything being clicked. Tab Panels can be changed via a procedure that changes the variable that determines which panel is being displayed. Declaring a value for that variable is noted as a trigger if, and only if, it’s different than the existing value. So the value of info(“Trigger”) at the end of a procedure that sets a value for the Tab Panel may, or may not, be the same as when the procedure began.

So the ideal behavior would be to change the info(“trigger”) value only if the tab panels were toggled manually and left as is if changed via a procedure.

Apple’s code does not allow any way to differentiate between changing the tab panel by clicking on it vs. changing the tab panel state programmatically. When the state changes for any reason, Apple’s object sends out a notice that the state changed. Information about why the state changed is not included. This doesn’t just apply to tab panels, it also applies to text lists, matrix, and possibly other objects with state like sliders and checkboxes.

If your code will be changing the state of any graphic objects, best practice is to capture the trigger into a variable at the beginning of the code if you will need it later.

That’s what I was wondering about when I wrote “Are there other objects that will have a similar effect?” I may have a minefield behind me where I’ve been making a lot of use of SetTrigger with graphic objects in Pan X.

It seems like what you’ve just explained would be a useful addition to Help under info(“Trigger”).

If I’m understanding Gary’s suggestion can’t be done to when AND why the state changed because Apple’s code automatically changing the trigger does the same for both manual and programatic ‘whys.’ But if things happened programatically there must be code to which you can add. If one really wanted to differentiate between the two couldn’t one set up a separate variable, theWhy, which wouldn’t be touched by a manual change, but would be changed by another line of code when changing things programatically from a normal value of “Manual” to “Program”? Then by monitoring theWhy AND the trigger you could branch the code flow off their combined information, reseting theWhy to '“Manual” after the branching. More complex code, more to keep straight or risk going wrong, but conceptionally possible if really needed.

I would certainly accept that if it was submitted to the documentation correction system.

Never mind, I have added this to the documentation myself.

That’s actually not the case, for a couple of reasons. The primary reason is that macOS is not doing this synchronously. macOS is much more complicated than MacOS was. Panorama shields you from most of this complexity, but it can’t do so 100%.

I was about to do just that but when I went to submit it (below), I see that it’s been done.

Note: Changing the state of some types of graphic objects programmatically, causes them to become the trigger identified in info(“Tigger”). This includes such objects as tab panels, text lists, matrices, checkboxes and sliders.

If, beyond the start, your procedure depends on the value of the original trigger, it’s good practice to immediately assign that value to another variable that will carry over for as long as you need it.

Yes, I mentioned that I had gone ahead and done it in a subsequent post a couple of hours later. It was bugging me. :slight_smile: