<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>