<div dir="ltr">Hey Hannes,<div><p>> Yes, indeed. And the zoomable UI of Cuis with high quality rendering is amazing in particular as you write about maps.</p><p>Definitely, it's been smooth sailing so far.</p><p>Re: your slides system, thanks for sharing that. It's encouraging that someone's done something similar before and that it worked well.</p><p>Slides in particular seem like a great use of morph direct manipulation. When you have good general-purpose tools so many special-case applications become unnecessary.</p><p>> I am not aware of this but did not check Pharo for a long time. I think that should be worthwhile to do.<br></p><p>I asked on their Discord and got some good responses, but at least none of the people online at the time knew about Pharo tools for the task. The best prior art I've found so far is Self's Transporter.</p><p>Re: sharing the code: thanks for the suggestion! At the moment the code's not yet past the "someone experienced could have done this in ten minutes" threshold. If it gets past that I'll consider sharing it:)</p><p>~ Ian Jeffries</p><p> </p></div></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Sat, Nov 23, 2024 at 9:25 PM H. Hirzel <<a href="mailto:hannes.hirzel@gmail.com">hannes.hirzel@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><u></u>
<div>
<p>(Attention: long post)<br>
</p>
<p>Hi Ian<br>
</p>
<div>On 21/11/2024 3:26 pm, Ian Jeffries via
Cuis-dev wrote:<br>
</div>
<blockquote type="cite">
<div dir="ltr">Hi folks,
<div><br>
</div>
<div>I'm experimenting with turning morphs created via direct
manipulation back into source code and am looking for some
tips.</div>
<div><br>
</div>
</div>
</blockquote>
<p>You bring up an interesting topic.<br>
</p>
<p>Years back before Cuis had good Unicode support. I was also
experimenting with this. <br>
</p>
<p>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.<br>
</p>
<blockquote type="cite">
<div dir="ltr">
<div>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.</div>
</div>
</blockquote>
<p>Yes, indeed. And the zoomable UI of Cuis with high quality
rendering is amazing in particular as you write about maps.</p>
<blockquote type="cite">
<div dir="ltr">
<div><br>
</div>
<div>Here's the twist: I'm already familiar with <a href="https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-UI/blob/a56d748ac25fadf3f1910f0666b7ea77bb3df286/tools/UI-Packager.pck.st" target="_blank">Cuis-UI-Packager</a> 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.</div>
<div><br>
</div>
</div>
</blockquote>
<p>What I did at that time was to create simple presentations in one
image and recreating them in a target image.</p>
<p>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.<br>
</p>
<p>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.</p>
<p>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.</p>
<p>A MorphDescriptionConstructor3 object went through all slides
(Squeak)<br>
</p>
<p> Project current world submorphs select: [:m | m isKindOf:
PasteUpMorphL]</p>
<p><br>
</p>
<p>and the morph tree on each of them </p>
<p>and created a MorphDescription</p>
<p><br>
</p>
<p>JsonObject subclass: #MorphDescription<br>
instanceVariableNames: 'morphClass properties'<br>
classVariableNames: ''<br>
poolDictionaries: ''<br>
category: 'HJHWork-Slides3-Data'<br>
</p>
<p><br>
</p>
<p>MorphDescription subclass: #StringMorphDescription<br>
instanceVariableNames: ''<br>
classVariableNames: ''<br>
poolDictionaries: ''<br>
category: 'HJHWork-Slides3-Dat'</p>
<p><br>
</p>
<p>MorphDescription subclass: #TextMorphDescription<br>
instanceVariableNames: 'text textStyle'<br>
classVariableNames: ''<br>
poolDictionaries: ''<br>
category: 'HJHWork-Slides3-Data'</p>
<p><br>
</p>
<p>The attributes the MorphDescriptionConstructor3 had to collect
were not many.</p>
<p>It used</p>
<p>DescriptionMethods at: #ImageMorph put: #describeImageMorph: .<br>
DescriptionMethods at: #SketchMorph put: #describeSketchMorph: .<br>
DescriptionMethods at: #StringMorph put: #describeStringMorph: .<br>
DescriptionMethods at: #TextMorph put: #describeTextMorph: .<br>
DescriptionMethods at: #PluggableSystemWindow put:
#describePluggableSystemWindow: .<br>
</p>
<p><br>
</p>
<p>and then</p>
<p>describeObject: anObject <br>
(self getSpecificDescriptionMethod: anObject)<br>
ifNil: [self assignBasicAttributesOf: anObject.<br>
self describeSubmorphs: anObject.<br>
^ self description]<br>
ifNotNil: [:meth | ^ self perform: meth with: anObject]<br>
</p>
<p><br>
</p>
<p>and</p>
<p><br>
</p>
<p>describeSubmorphs: anObject<br>
<br>
description submorphs: OrderedCollection new.<br>
anObject submorphsDo: [ :sm | description submorphs add:
(MorphDescriptionConstructor3 on: sm)].<br>
</p>
<p><br>
</p>
<p>The basic attributes of each morph were collected:</p>
<p><br>
</p>
<p>assignBasicAttributesOf: anObject<br>
<br>
self description morphClass: anObject class name .<br>
self description position: anObject position.<br>
self description extent: anObject extent.<br>
self description color: anObject color.<br>
</p>
<p><br>
</p>
<p><br>
</p>
<p>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.<br>
</p>
<p>Other builders created descriptions by source code and a HTML/CSS
export was also possible. <br>
</p>
<p>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.<br>
</p>
<p></p>
<blockquote type="cite">
<div dir="ltr">
<div>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).</div>
<div><br>
</div>
<div>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.</div>
</div>
</blockquote>
<p>I am not aware of this but did not check Pharo for a long time. I
think that should be worthwhile to do.<br>
</p>
<blockquote type="cite">
<div dir="ltr">
<div><br>
</div>
<div>I did find <a href="https://www.hpi.uni-potsdam.de/hirschfeld/trac/SqueakCommunityProjects/wiki/designer" target="_blank">Morphic Designer</a> 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).</div>
<div><br>
</div>
</div>
</blockquote>
<p>As mentioned above I agree with this, with a limited set of
supported morphs is you can actually do a lot. <br>
</p>
<p>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.<br>
</p>
<p>But just a hierarchy of dictionaries with Morph description
objects will do the job for a start. <br>
</p>
<p>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. </p>
<p>Currently I am mainly interested in Squeak and Cuis but I would
also be interested to have a it work in Pharo as well.</p>
<p>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.<br>
</p>
<blockquote type="cite">
<div dir="ltr">
<div>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.</div>
<div><br>
</div>
</div>
</blockquote>
<p>Please share this.<br>
</p>
<blockquote type="cite">
<div dir="ltr">
<div>Thanks,</div>
<div>Ian Jeffries</div>
</div>
</blockquote>
<p><br>
</p>
<p>Regards</p>
<p>Hannes Hirzel<br>
</p>
</div>
</blockquote></div>