[Cuis-dev] Turning morphs back into source code

H. Hirzel hannes.hirzel at gmail.com
Sat Nov 23 19:29:41 PST 2024


(Attention: long post)

Hi Ian

On 21/11/2024 3:26 pm, Ian Jeffries via Cuis-dev wrote:
> Hi folks,
>
> I'm experimenting with turning morphs created via direct manipulation 
> back into source code and am looking for some tips.
>
You bring up an interesting topic.

Years back before Cuis had good Unicode support. I was also 
experimenting with this.

Now Unicode support is excellent since 2022 (for what I need, this 
include combining diacritics). Cuis is well suited for this kind of work 
of creating source code representations of morph arrangements on the 
desk top or on a PasteUpMorph.

> As an example use case: I'm making a world map and would like to put 
> my house in it. The image will be pretty simple: just three or four 
> rectangles for the house, a rectangle for the garage, and a few 
> circles to represent trees. Certainly I could just write this in code, 
> but it seems like more fun to use the direct manipulation features of 
> Morphic to create the scene (duplicate, rotate, etc), then serialize 
> that scene to code.

Yes, indeed. And the zoomable UI of Cuis with high quality rendering is 
amazing in particular as you write about maps.

>
> Here's the twist: I'm already familiar with Cuis-UI-Packager 
> <https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-UI/blob/a56d748ac25fadf3f1910f0666b7ea77bb3df286/tools/UI-Packager.pck.st> which 
> is very cool, but my goal here is different. I'd like the result to be 
> source code, not object files, ideally similar to what I would have 
> written by hand.
>
What I did at that time was to create simple presentations in one image 
and recreating them in a target image.

In Squeak I had a collection of 'Slide' morphs (from a trimmed down 
clone of PasteUpMorph called PasteUpMorphL - 'l' for 'light', greatly 
reduced number of methods). They were placed on each other and a 
PresentationNavigationMorph object with arrows was controlling the 
visibility. Just one slide visible at the time.

The slides had morphs placed on them by direct manipulation but it was 
also possible  just like with PowerPoint slide templates to instantiate 
a slide type directly . I exported these presentations to Cuis and Pharo.

What I ended up with was to have a simple type of source code 
representation of these morphs as the morph classes in the target 
Smalltalk dialect were not necessarily the same.

A MorphDescriptionConstructor3 object went through all slides (Squeak)

     Project current world submorphs    select: [:m | m isKindOf: 
PasteUpMorphL]


and the morph tree on each of them

and created a MorphDescription


JsonObject subclass: #MorphDescription
     instanceVariableNames: 'morphClass properties'
     classVariableNames: ''
     poolDictionaries: ''
     category: 'HJHWork-Slides3-Data'


MorphDescription subclass: #StringMorphDescription
     instanceVariableNames: ''
     classVariableNames: ''
     poolDictionaries: ''
     category: 'HJHWork-Slides3-Dat'


MorphDescription subclass: #TextMorphDescription
     instanceVariableNames: 'text textStyle'
     classVariableNames: ''
     poolDictionaries: ''
     category: 'HJHWork-Slides3-Data'


The attributes the MorphDescriptionConstructor3 had to collect were not 
many.

It used

DescriptionMethods at: #ImageMorph put: #describeImageMorph: .
DescriptionMethods at: #SketchMorph put: #describeSketchMorph: .
DescriptionMethods at: #StringMorph put: #describeStringMorph: .
DescriptionMethods at: #TextMorph put: #describeTextMorph: .
DescriptionMethods at: #PluggableSystemWindow put: 
#describePluggableSystemWindow: .


and then

describeObject: anObject
     (self getSpecificDescriptionMethod: anObject)
         ifNil: [self assignBasicAttributesOf: anObject.
                 self describeSubmorphs: anObject.
                 ^ self description]
         ifNotNil: [:meth | ^ self perform: meth with: anObject]


and


describeSubmorphs: anObject

     description submorphs: OrderedCollection new.
     anObject submorphsDo: [ :sm   | description submorphs add: 
(MorphDescriptionConstructor3 on: sm)].


The basic attributes of each morph were collected:


assignBasicAttributesOf: anObject

     self description morphClass: anObject class name .
     self description position: anObject position.
     self description extent: anObject extent.
     self description color: anObject color.



A PresentationBuilder object then  created a Presentation in the target 
Smalltalk image (Squeak, Cuis or Pharo) from a dictionary hierarchy of 
MorphDescriptions. That means the morph hierarchies of the original were 
reconstructed as a hierarchy of dictionaries.

Other builders created descriptions by source code and a HTML/CSS export 
was also possible.

It went quite well with a limited type of morphs but for simple 
presentations it was OK.  The 'slides' could be very large (for example 
also posters and the element of them are then described by Smalltalk 
code. So your post made we think of reviving this code again.

> First question: is there a term in the Smalltalk community or the 
> academic literature for this task? Specifically for turning runtime 
> objects back into idiomatic source code. (I realize this problem 
> probably can't be solved in the general case since it's such a hard 
> one-- one of the reasons I'd like to read more about it).
>
> Second question: there isn't already a package for this in Cuis (or 
> even in Pharo etc)? I wouldn't think so and can't find one by 
> searching, but wanted to check.

I am not aware of this but did not check Pharo for a long time. I think 
that should be worthwhile to do.

>
> I did find Morphic Designer 
> <https://www.hpi.uni-potsdam.de/hirschfeld/trac/SqueakCommunityProjects/wiki/designer> 
> in Squeak, but that's a little different since you build the morphs in 
> a specialized app. I'm looking for something that you can target any 
> supported runtime morph with (though I don't care how small the set of 
> supported morphs is, any example would be helpful even if it only 
> supported one or two).
>
As mentioned above I agree with this, with a limited set of supported 
morphs is you can actually do a lot.

I could also think of a small morph oriented page description DSL which 
describes morphs and their placement in the world morph or on a 
PasteUpMorph object in a Smalltalk dialect independent way.

But  just a hierarchy of dictionaries with Morph description objects 
will do the job for a start.

Based on this different representations may be created. Source code 
representation in the target Smalltalk dialect may be created but also 
the object may be directly rebuilt.

Currently I am mainly interested in Squeak and Cuis but I would also be 
interested to have a it work in Pharo as well.

On the source code level I see as the means of exchange a folder with 
two subfolders: images (background images may be large) and source code 
(with maybe up to three sub-folders). If the images are small (e.g. 
icons) they may also be directly represented as Forms objects serialized 
as code.

> I've got a little demo working for myself which has also given me some 
> implementation questions, but I'll save those for a later thread.
>
Please share this.

> Thanks,
> Ian Jeffries


Regards

Hannes Hirzel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cuis.st/mailman/archives/cuis-dev/attachments/20241124/2749dc8c/attachment.htm>


More information about the Cuis-dev mailing list