The properties returns empty for widgets

I opened an issue over on GitHub for this but it was suggested to have a conversation here as well.

the properties returns an array of the properties for almost all objects.
For any widget, it returns an empty array. You are able to set the properties of widgets.
I believe that for the essentials (rect, visible, etc.), they should be included in what it returned for widgets. I would also think that including what is provided via “export widget x to array y” should be included as well, but would settle for the base properties.

This relates to this bug report:

1 Like

I guess a lot of it depends on what the builder environment makes available to the scripting environment.

Some of the properties go the other way though. The rect is not something that the builder environment is aware of. It only knows the size of itself (canvas) - not where it is on the card. Same thing for the object name - I don’t know if that is even visible to the widget.

The problem is exposed by the implementation of the Save as Project function. If you save a stack that contains widget, there is no way to get it recreated correctly. None of the properties needed to locate/name the widget are included in the JSON. Also none of the state is exported either (need to use export tObjectRef to array tArray). All of this can be overcome in script, but there is a property already in existence that should be able to supply this information.

Perhaps the most interesting question would be if it could break existing code. I cannot see how it could do much harm. How many people would have used “the properties” on generic controls and relied on the result being empty for widgets?

So I would support the idea, probably with the full export set of properties.

Anybody patient enough to re-read the old use-LC thread also mentioned on GitHub can maybe form an opinion:

I think two supporters from back then are prominently present here, so we can see if views have changed.

I believe that it would only potentially impact tools like Navigator if they had coded a workaround for the lack of values being returned. I can look to see how Navigator pulls the basics for widgets, but it should be an easy fix if needed.

Here are a few files that show what I’m thinking. The first is a property exporter stack that will gather information on a stack and generate a JSON file that contains most of the information that would be needed to track changes to it. It does not touch scripts yet. I had to use PhotonJSON to get a reasonable output and even had to tweak it some. Code is included as the stack script. (LC11 has JSON built into the engine and it is an order of magnitude faster than anything we see in the open source universe.) The second file is a torture test of sorts that includes a bunch of different controls and an empty data grid. The third file is the JSON export.

ExportTest.zip (105 KB)

Looks good. The export exactly has all the non-empty properties, correct?

A final version should maybe list some meta data. Exact HXT (OXT/LC/RR/MC :wink:) version number comes to mind.

I am sure we need this as well to do away with the long-standing JSON pain, but this is a different topic.

What I do is pull the template object for each type. I only export items that are different from the template. So some non-empty values are not exported.

Yeah, version number is easy (the version). Brand is a little more difficult. I can get the long name of stack "home" and then parse it. Easier on Mac since I can look for .app in an item of the path. In a repo, I’ll need to look above /ide/ and pull that folder (so if it is named something different it would be incorrect) or maybe look for the *.entitlements file (or something else that will be consistent between the 3 brand forks). For Windows, I’m guessing the path will work. That doesn’t work for a Linux appimage though - unless I can count on HyperX being in the path (currently 0.9.14 launches in /tmp/.mount_HyperXIHpFnN/... on my test seat). If there is an easier way, I’m open to suggestions as well.

Another thing I need to modify is handling of long values. I do have it encoding binary as base64 but for images that is not a great solution (I just added an image to my Torture Test stack and it is a huge chunk of text for a tiny image). YAML would be slightly better since it is naturally allows line splits so word wrap wouldn’t be needed, but still large blocks in the JSON file don’t seem desirable. SmartCrumbs parses text out to separate files. I think I’m going to go with a hybrid solution based on the size of the value. If longer than ~255 bytes then separate it out to a file (word wrapped that would be 4 or fewer lines depending on indent). Currently for binary, I’m adding an array with key %base64% and then the encoded value. Likely do the same but use a key of %filename%.

Nice move, but is there not a possibility that the template object has been changed and differs from one environment (or version) to the other?
If one would really aim for a transport format of stacks among different versions there should perhaps be no assumption of what to rely on. I know that exporting all values would be a bit mad and also against the grain. No idea.
We are only a small community, but surprisingly few people seem to have an opinion on this. Maybe it is too technical, while fancy UI stuff draws the crowd. Or you should just write a pull request and we lure the maintainer into integrating it with some nice treats. :grinning_face_with_smiling_eyes:
The stack exporter is your own concern anyway.

I probably should reset the template object before capturing the properties to be sure it wasn’t modified. The logic is that when any object is created, it will be created with the template object settings. So, all that needs to be captured to recreate an object is the differences from the template object. I doubt that other IDEs will mess around with the default settings for the templates. It really wouldn’t matter though, the purpose of my project is for a developer (or team) to easily keep track of what is changing in binary files in a way that separate changes could conceivably be merged.

True that the exporter will be my own project, but the logic that I’m using could also be employed with the “save as project” function - no need to capture everything in the file.

I’ll need to dig into the source and figure out where the properties are being exported and see what I can do.

Just mentioning, for other reasons I ran into this today, which looks like interesting code for JSON improvements:

Anyone any experience with it?

Looks interesting and it’s MIT-licensed, which is good, but it’s a command-line application rather than a library we can hook into. Probably more work to untangle it than it’s worth.

We use yyJSON GitHub - ibireme/yyjson: The fastest JSON library in C · GitHub in 0.9.15 for importing JSON

I’ve been playing around with exporting the binary stacks from HyperXTalk. Here’s a commit that shows the delta from initial import and the current state a few days ago:

There are a few stacks that I need to take a look at to see if I can reduce the output on. Things like the script editor, project browser, and message box seem to have stuff in there that probably should be excluded. Once nailed down I can grab a fresh export of the initial repo. It would probably be good to do an export for each tagged release just to have the deltas available. Longer term it would be good that whenever a binary stack was changed that the exports would also be made so that changes would be visible.

I’m probably going to move my stack back into an actual stack file instead of script only. This will make it easier to use it interactively from the IDE while also allowing it to be run from a command line invocation.

The PR for adding the properties was merged. Emily and I had a bit of a discussion on the state of getting all of the information about a widget. I think what we have now is pretty good (two statements needed to get everything). After thinking on the conversation, there is a way that we could leverage what was just merged to get that down to one.

I believe that we could add a new key in the MCInterfaceExecExportObjectToArray function (engine/src/exec-interface.cpp) if the desire is to have a way to fully get all Widget data at once. We could put the result of the properties into a $Properties key of the array.

Since I opened the can of worms, I would volunteer to work on it if others felt it would make sense to do it.

1 Like

I like that idea, that would allow us to get all the information about a widget in a single pass.