The move to relative image paths presents some problems for custom control developers. I'd like to see an attempt made to resolve the relative path relative to the stackFiles of behaviors a bit like resolving an image id.
Custom controls themselves will probably need to be delivered as directories (zipped??) of a stack file + relative images. We really need a custom control scheme in the IDE as DropTools currently is only in commercial. Any progress on the stuff that was pulled from 6?
@monte: The suggestion to resolve relative image files in a similar way to id's is certainly a good idea - I've put it on the internal list to look at for 6.6.
As you say, this does start to present a problem for delivery of custom controls. From the discussion on the list, whilst extending the density mapped mechanism to use resident images (i.e. non-referenced) would help here, I don't think its practical in terms of stackfile size and memory usage. (However, the ability to set the density of a resident image would be useful - perhaps a property that is read-only for referenced images, but settable for resident ones - not also on the list for 6.6).
In terms of the custom control system that was being developed prior to 6.0, not much progress has been made on there, no. The main problem with the approach was that we were struggling to make aggregate controls robust and efficient enough - they really do require substantially more engine support than currently exists. I've actually had some more thoughts on this lately, prompted by your proposed addition of moveControl/showControl messages and my messing around on the feature-widgets branch. (Which should perhaps be the focus of a different thread - once I've figured out how to articulate the thoughts in a suitably structured manner!).
I realize packaging such entities is a slightly different from the actual underlying architecture that runs custom controls, but they are related - if we can come up with the right approach in the engine for aggregate controls, then packaging should be integrated at that level. Image resources and such and how they are searched for is a good example for this.
I wondered about having multiple image "texts" in imported images... The texts of an image would return an array with density keys. While I understand the memory concerns I wonder if these could be worked around by only reading the required data from the stackFile. So it doesn't read in all the texts until something requests them... For the stackFile size concerns they have always been there with imported images and it's possible to design around them.
As for the custom control stuff I'd be really interested to hear about the problems you encountered and your proposed changes when you have time. We really need a built in drag and drop mechanism in the IDE for sharing and using controls ASAP.
The problem here is that stackfiles are merely a serialization mechanism - they don't have to exist after the objects have been loaded from them (you can load a stackfile and delete the file for example). Admittedly this problem is only in the IDE (which does mean it is perhaps something not to be too concerned about) - it is solvable relatively easily for standalones (since once built the mainstack file is read-only)... When the standalone is built the stackfile is re-saved in a special form spitting out all the non object-hierarcy data (like image text etc.) into a separate file and the stackfile stores indices into it. The stackfile is still loaded into memory completely, but the data file is memory mapped - with references into it being fixed up when the stackfile is deserialized.
The aggregated controls (parts) which they use are visible from external scripts. (Causes fragility and inefficiency as there are more controls to sift through in any chunk operation).
Encapsulating them with resources is not very easy because they have to use the same resource acquisition mechanisms (e.g. image ids) as the application they are embedded in.
I *think* the solution here is essentially to make it so that we no longer use the 'behavior' property to make aggregate controls. Instead, a custom control is created with an 'intrinsic' behavior which sits 'to the side' of the script-level message path. Its child controls would essentially live in their own message path, and not be visible from the outside; also because they live in (almost) their own world resource acquisition would be easier to define and make specific to the custom control. This intrinsic behavior would be able to completely control what messages are dispatched to the custom control's script and behavior hierarchy.
Now, there are lots of i's to dot and t's to cross but much of what is needed to do this already exists in the engine (behavior hierarchy, container - group - control etc.). Also, existing custom controls should not be at all hard to move to the encapsulated form - and the effort to do so would be more than worth it as they would become substantially more robust in doing so.
Doesn't this go away to an extent with parent behaviours as you can recursively find the last behavior in the chain and set the behavior of that.
Before and after handlers deal with the interception. Could leakage be governed by selectGroupedControls? Arguably a behavior could trap engine messages to avoid this too.
Hmm... if there isn't a way to make them visible then this could cause a problem for lcVCS. I implemented it from the start to support the custom control scheme that you were working on... objects have a class "com.runrev.engine.<object type>" and if they aren't an engine control at the moment it does nothing but eventually it would copy the current template object so as long as that mechanism worked I guess it would be fine but I worry about controls that store their data internally in some way (not as properties of the control) and don't init themselves based on their current data properly on preOpenControl.
Hmm... how would you want this to work differently as images are already resolved against the behavior hierarchy first?
Your solution sounds great but I'm not really sure if the IDE work (at least a large part of it) wouldn't be largely the same either way. Basically we need a custom control repository, a drag and drop tool palette and inclusion in standalones. To make control development part of people's workflow a control repository manager would help. At the IDE level the system could handle regular script based controls, behavior based controls and intrinsic behavior based controls. The reality is there's plenty of custom controls that work fine with the current engine but the IDE offers nothing but an object library that nobody has looked at since version 1.0.
Well that would apply the behavior to all uses of the custom control; and making your behavior inherit from the custom control behavior means that behavior can only be used for that custom control type.
You are right about before/after handlers. However, remember that behaviors trigger after the object script so the behavior can only stop leakage after that point - it can't stop messages from contained controls leaking into the object's script. The problem with controlling leakage with selectGroupedControls is that how do you decide what should pass and what shouldn't?
It would cause a problem for the IDE too - after all you need to be able to debug such controls. The point here is that (as discussed before) VCS is very much a meta operation, much like most of what the IDE does. There would have to be a mechanism to introspect into such objects for those kinds of purposes.
I worry about controls that store their data internally in some way (not as properties of the control) and don't init themselves based on their current data properly on preOpenControl.
Hmmm - surely if a control does such a thing then it isn't going to work right when you reload a stack containing it. In such a situation I'd class it not working again after export/import through VCS as a case of garbage-in-garbage-out rather than something to be concerned about. (Unless I misunderstand what you mean).
I'm not sure I expressed that very well. I was more meaning that at the moment the resources for a custom control have to live in the global environment, the id search means that the behavior will find them appropriately, but so could other things that don't actually want those resources (id conflicts and such).
Indeed, you are correct. I kind of went off on a slight tangent - the management of 'custom controls' at the IDE level is largely the same regardless of the form they take. Even a simple management system in the IDE now would be better than none, and at least mean we could guarantee some sort of forward compatibility with whatever developments occur in the future.
Anyway, in regards to the ideas expressed above, they do need more thought. The aggregate control thing is something I've been struggling with for quite a while in terms of trying to get a handle on the right architectural approach at the script level.
runrevmark wrote: Well that would apply the behavior to all uses of the custom control; and making your behavior inherit from the custom control behavior means that behavior can only be used for that custom control type.
Everything... if selectGroupedControls is on then the target of mouseEvents etc should be the whole object.
As long as it's not an IDE only feature because lcVCS has a CLI built with the standalone engine.
Yeah... probably not worth worrying about.
It's a complicated issue for sure and I wonder if some of the stack view ideas come into play here too.
Having just started to create some custom controls and not wishing to go down the Live Code Builder route did this discussion lead anywhere?
Basically we need a custom control repository, a drag and drop tool palette and inclusion in standalones. To make control development part of people's workflow a control repository manager would help.
Plus, I would suggest that a more robust or obvious method of allocating image icons would be a good idea. At present allocating an image by name may result in the wrong image being set as an icon if two or more images of the same name reside in memory.
Failing any changes to the IDE/Engine then an Edinburgh published intermediate/advanced guide to creating custom controls detailing best practise would be a start.
Thanks for the link. I had seen the thread and have visited Ken's web site. However, the thread is dated 2011 and the community does not seem to have embraced the concept, or at least don't seem to be talking about it, which is a pity.
I think that encapsulation of custom controls should be part of the language rather than a third party add on.
A pity indeed, because this is not an uncommon need, and Ken worked with dozens of developers to draft that spec.
The need hasn't gone away. Ken was just years ahead of his time.
This just came up on the use-lc mailing list and I don't thin BN will mind if I post his awesome solution here.
"NewGroup" is a message that the custom control gets when you paste it.
new stack it will assign the ids of the images to your buttons.
can be self contained, i.e. can be reused in a different stack.
This mostly works (not so well if you multiply the custom controls on the same card/stack).
After further fiddling with this Simon and I decided it is most robust to "hard code" the setting of the icons for goups/custom controls that are intended for reuse by copy and paste. Again this assumes that the images you want to use for the icons are contained in the group/custom control and are uniquely named within the group/custom control.
Just wanted to say a big thanks to Bernd for the two lines of code quoted above. Originally I failed to discover the syntax that allowed the line to specify exactly which image to use.