Delegation, anybody ?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

Delegation, anybody ?

Ankh'nAton
Hi all!

JSObjectProxy is a very nice approach to a Smalltalk instanciation of
JS objects, but one cannot pull JS objects into the class tree to use
them seamless within the Smalltalk development process.

So, how about delegation?

I try with Morph() from morphic.js

Object subclass: #AMorph
        instanceVariableNames: 'm'
        package: 'Amber-Morphic'.

        initialize
                m := Morph new.

        doesNotUnderstand: aMessage
                m perform: (aMessage selector) withArguments: aMessage arguments.


Shouldn't this delegate all unknown messages to the JSObjectProxy of
m?

What's the clue?

Regards...
Reply | Threaded
Open this post in threaded view
|

Re: Delegation, anybody ?

Nicolas Petton
Indeed. That doesn't work?

Cheers,
Nico

On 22/02/12 16:33, Tom wrote:

> Hi all!
>
> JSObjectProxy is a very nice approach to a Smalltalk instanciation of
> JS objects, but one cannot pull JS objects into the class tree to use
> them seamless within the Smalltalk development process.
>
> So, how about delegation?
>
> I try with Morph() from morphic.js
>
> Object subclass: #AMorph
> instanceVariableNames: 'm'
> package: 'Amber-Morphic'.
>
> initialize
> m := Morph new.
>
> doesNotUnderstand: aMessage
> m perform: (aMessage selector) withArguments: aMessage arguments.
>
>
> Shouldn't this delegate all unknown messages to the JSObjectProxy of
> m?
>
> What's the clue?
>
> Regards...


--
Nicolas Petton
http://nicolas-petton.fr
Reply | Threaded
Open this post in threaded view
|

Re: Delegation, anybody ?

Ankh'nAton
On 22 Feb., 16:49, Nicolas Petton <[hidden email]> wrote:
> Indeed. That doesn't work?
>

Indeed, it doesn't :)

Instanciation is ok, but doesNotUnderstand:withArguments: does not
delegate as one might expect. Instead I get an error in Firebugs
Console saying

self[aSymbol] is undefined
  return self[aSymbol].apply(self, aCollection); in Kernel-Objects.js
at line no. 693

which points to this little code fragment...

smalltalk.addMethod(
unescape('_basicPerform_withArguments_'),
smalltalk.method({
selector: unescape('basicPerform%3AwithArguments%3A'),
category: 'message handling',
fn: function (aSymbol, aCollection) {
var self = this;
return self[aSymbol].apply(self, aCollection);
return self;
},
args: ["aSymbol", "aCollection"],
source: unescape('basicPerform%3A%20aSymbol%20withArguments%3A
%20aCollection%0A%09%3Creturn%20self%5BaSymbol%5D.apply%28self%2C
%20aCollection%29%3B%3E'),
messageSends: [],
referencedClasses: []
}),
smalltalk.Object);


Regards...
Reply | Threaded
Open this post in threaded view
|

Re: Delegation, anybody ?

Ankh'nAton
The Smalltalk code that leads to this JavaScript error goes like

  | m |
  m := AMorph new.
  "The next message is handled by #doesNotUnderstand: of an AMorph,
because AMorph doesn't know about a method #setColor:."
  m setColor: 'rgba(224,224,160,0.7)'.
  m show.
  world add: m.



On 22 Feb., 22:06, Tom <[hidden email]> wrote:

> On 22 Feb., 16:49, Nicolas Petton <[hidden email]> wrote:
>
> > Indeed. That doesn't work?
>
> Indeed, it doesn't :)
>
> Instanciation is ok, but doesNotUnderstand:withArguments: does not
> delegate as one might expect. Instead I get an error in Firebugs
> Console saying
>
> self[aSymbol] is undefined
>   return self[aSymbol].apply(self, aCollection); in Kernel-Objects.js
> at line no. 693
>
> which points to this little code fragment...
>
> smalltalk.addMethod(
> unescape('_basicPerform_withArguments_'),
> smalltalk.method({
> selector: unescape('basicPerform%3AwithArguments%3A'),
> category: 'message handling',
> fn: function (aSymbol, aCollection) {
> var self = this;
> return self[aSymbol].apply(self, aCollection);
> return self;},
>
> args: ["aSymbol", "aCollection"],
> source: unescape('basicPerform%3A%20aSymbol%20withArguments%3A
> %20aCollection%0A%09%3Creturn%20self%5BaSymbol%5D.apply%28self%2C
> %20aCollection%29%3B%3E'),
> messageSends: [],
> referencedClasses: []}),
>
> smalltalk.Object);
>
> Regards...
Reply | Threaded
Open this post in threaded view
|

Re: Delegation, anybody ?

Hannes Hirzel
Tom,
Could  you please show us the code for AMorph?


What I see from http://tcltalk.ath.cx/files/morphicAmber.zip (posted
by you on Feb, 8th, 2012)

I assume that in the meantime there is more Morphic code....


Smalltalk current createPackage: 'Morphic' properties: #{}!
Widget subclass: #MorphicWorld
        instanceVariableNames: 'canvas'
        category: 'Morphic'!
!MorphicWorld commentStamp!
thbr: This class a wrapper class for morphic.js's world canvas.
The wrapping is located in the method renderOn:!

!MorphicWorld methodsFor: 'opening'!

open
        "Append this world to the HTML body tag of the loading page."

        | body |
        body := 'body' asJQuery.
        self appendToJQuery: body.
! !

!MorphicWorld methodsFor: 'rendering'!

renderOn: html
        "create a canvas node with an id of 'world'."

        canvas := html canvas
                class: 'morphicWorld';
                id: 'world';
                style: 'position:absolute;';
                yourself.
        canvas at:'tabindex' put: 1.
        <
        function loop() {
                world.doOneCycle();
        }
  world = new WorldMorph(document.getElementById('world'));
        world.color = new Color(255,255,192);
        world.isDevMode = true;
        setInterval(loop, 50);
        >.
        ^self
! !

!MorphicWorld class methodsFor: 'instance creation'!

open
        "Answer a new opened instance of the receiver"

        ^self new open
! !

MorphicWorld subclass: #Welcome
        instanceVariableNames: ''
        category: 'Morphic'!
!Welcome commentStamp!
tb: This class adds a browser button and a welcome message to the
morphic world.!

!Welcome methodsFor: 'rendering'!

renderOn: html
        "create a canvas node with an id of 'world' and place additions"

        super renderOn: html.
        self
                addBrowserButton;
                addWelcome.
        ^self
! !

!Welcome methodsFor: 'setup'!

addBrowserButton
        "Adds a button to the world, which opens the Smalltalk IDE"

        | btn lbl |
        btn := CircleBoxMorph new.
        btn toggleOrientation: 'horizontal'.
        btn setPosition: (0@0) asMorphicPoint.
        btn at: 'mouseClickLeft' put: [Browser open].
        btn show.
        lbl := StringMorph new.
        lbl at: 'text' put: 'Open Browser'.
        lbl setColor: 'white'.
        lbl setPosition: (7@5) asMorphicPoint.
        lbl at: 'mouseEnter' put: [(SpeechBubbleMorph new)
                contents: 'Open the Smalltalk Class Browser';
                popUp: world at: (btn rightCenter) add: (-8@0) asMorphicPoint.
        ].
        lbl show.

        btn add: lbl.
        world add: btn.
        btn setPosition: (20@20) asMorphicPoint.
        world changed.
        ^self
!

addWelcome
        "Adds a welcome message"

        | header |
        header := StringMorph new.
        header at: 'text' put: 'Welcome!! - This is morphic.js running on Amber'.
        header setSerif.
        header setFontSize: 24.
        header toggleWeight.
        header toggleItalic.
        header setPosition: (140@21) asMorphicPoint.
        header show.
        world add: header.
        world changed.
        ^self
! !

--Hannes





On 2/22/12, Tom <[hidden email]> wrote:

> The Smalltalk code that leads to this JavaScript error goes like
>
>   | m |
>   m := AMorph new.
>   "The next message is handled by #doesNotUnderstand: of an AMorph,
> because AMorph doesn't know about a method #setColor:."
>   m setColor: 'rgba(224,224,160,0.7)'.
>   m show.
>   world add: m.
>
>
>
> On 22 Feb., 22:06, Tom <[hidden email]> wrote:
>> On 22 Feb., 16:49, Nicolas Petton <[hidden email]> wrote:
>>
>> > Indeed. That doesn't work?
>>
>> Indeed, it doesn't :)
>>
>> Instanciation is ok, but doesNotUnderstand:withArguments: does not
>> delegate as one might expect. Instead I get an error in Firebugs
>> Console saying
>>
>> self[aSymbol] is undefined
>>   return self[aSymbol].apply(self, aCollection); in Kernel-Objects.js
>> at line no. 693
>>
>> which points to this little code fragment...
>>
>> smalltalk.addMethod(
>> unescape('_basicPerform_withArguments_'),
>> smalltalk.method({
>> selector: unescape('basicPerform%3AwithArguments%3A'),
>> category: 'message handling',
>> fn: function (aSymbol, aCollection) {
>> var self = this;
>> return self[aSymbol].apply(self, aCollection);
>> return self;},
>>
>> args: ["aSymbol", "aCollection"],
>> source: unescape('basicPerform%3A%20aSymbol%20withArguments%3A
>> %20aCollection%0A%09%3Creturn%20self%5BaSymbol%5D.apply%28self%2C
>> %20aCollection%29%3B%3E'),
>> messageSends: [],
>> referencedClasses: []}),
>>
>> smalltalk.Object);
>>
>> Regards...
>
Reply | Threaded
Open this post in threaded view
|

Re: Delegation, anybody ?

Hannes Hirzel
Ah, I see in your first mail of Feb, 22nd

Object subclass: #AMorph
        instanceVariableNames: 'm'
        package: 'Amber-Morphic'.

        initialize
                m := Morph new.


How is the class Morph defined in your code?

--HH

On 2/22/12, H. Hirzel <[hidden email]> wrote:

> Tom,
> Could  you please show us the code for AMorph?
>
>
> What I see from http://tcltalk.ath.cx/files/morphicAmber.zip (posted
> by you on Feb, 8th, 2012)
>
> I assume that in the meantime there is more Morphic code....
>
>
> Smalltalk current createPackage: 'Morphic' properties: #{}!
> Widget subclass: #MorphicWorld
> instanceVariableNames: 'canvas'
> category: 'Morphic'!
> !MorphicWorld commentStamp!
> thbr: This class a wrapper class for morphic.js's world canvas.
> The wrapping is located in the method renderOn:!
>
> !MorphicWorld methodsFor: 'opening'!
>
> open
> "Append this world to the HTML body tag of the loading page."
>
> | body |
> body := 'body' asJQuery.
> self appendToJQuery: body.
> ! !
>
> !MorphicWorld methodsFor: 'rendering'!
>
> renderOn: html
> "create a canvas node with an id of 'world'."
>
> canvas := html canvas
> class: 'morphicWorld';
> id: 'world';
> style: 'position:absolute;';
> yourself.
> canvas at:'tabindex' put: 1.
> <
> function loop() {
> world.doOneCycle();
> }
>   world = new WorldMorph(document.getElementById('world'));
> world.color = new Color(255,255,192);
> world.isDevMode = true;
> setInterval(loop, 50);
> >.
> ^self
> ! !
>
> !MorphicWorld class methodsFor: 'instance creation'!
>
> open
> "Answer a new opened instance of the receiver"
>
> ^self new open
> ! !
>
> MorphicWorld subclass: #Welcome
> instanceVariableNames: ''
> category: 'Morphic'!
> !Welcome commentStamp!
> tb: This class adds a browser button and a welcome message to the
> morphic world.!
>
> !Welcome methodsFor: 'rendering'!
>
> renderOn: html
> "create a canvas node with an id of 'world' and place additions"
>
> super renderOn: html.
> self
> addBrowserButton;
> addWelcome.
> ^self
> ! !
>
> !Welcome methodsFor: 'setup'!
>
> addBrowserButton
> "Adds a button to the world, which opens the Smalltalk IDE"
>
> | btn lbl |
> btn := CircleBoxMorph new.
> btn toggleOrientation: 'horizontal'.
> btn setPosition: (0@0) asMorphicPoint.
> btn at: 'mouseClickLeft' put: [Browser open].
> btn show.
> lbl := StringMorph new.
> lbl at: 'text' put: 'Open Browser'.
> lbl setColor: 'white'.
> lbl setPosition: (7@5) asMorphicPoint.
> lbl at: 'mouseEnter' put: [(SpeechBubbleMorph new)
> contents: 'Open the Smalltalk Class Browser';
> popUp: world at: (btn rightCenter) add: (-8@0) asMorphicPoint.
> ].
> lbl show.
>
> btn add: lbl.
> world add: btn.
> btn setPosition: (20@20) asMorphicPoint.
> world changed.
> ^self
> !
>
> addWelcome
> "Adds a welcome message"
>
> | header |
> header := StringMorph new.
> header at: 'text' put: 'Welcome!! - This is morphic.js running on Amber'.
> header setSerif.
> header setFontSize: 24.
> header toggleWeight.
> header toggleItalic.
> header setPosition: (140@21) asMorphicPoint.
> header show.
> world add: header.
> world changed.
> ^self
> ! !
>
> --Hannes
>
>
>
>
>
> On 2/22/12, Tom <[hidden email]> wrote:
>> The Smalltalk code that leads to this JavaScript error goes like
>>
>>   | m |
>>   m := AMorph new.
>>   "The next message is handled by #doesNotUnderstand: of an AMorph,
>> because AMorph doesn't know about a method #setColor:."
>>   m setColor: 'rgba(224,224,160,0.7)'.
>>   m show.
>>   world add: m.
>>
>>
>>
>> On 22 Feb., 22:06, Tom <[hidden email]> wrote:
>>> On 22 Feb., 16:49, Nicolas Petton <[hidden email]> wrote:
>>>
>>> > Indeed. That doesn't work?
>>>
>>> Indeed, it doesn't :)
>>>
>>> Instanciation is ok, but doesNotUnderstand:withArguments: does not
>>> delegate as one might expect. Instead I get an error in Firebugs
>>> Console saying
>>>
>>> self[aSymbol] is undefined
>>>   return self[aSymbol].apply(self, aCollection); in Kernel-Objects.js
>>> at line no. 693
>>>
>>> which points to this little code fragment...
>>>
>>> smalltalk.addMethod(
>>> unescape('_basicPerform_withArguments_'),
>>> smalltalk.method({
>>> selector: unescape('basicPerform%3AwithArguments%3A'),
>>> category: 'message handling',
>>> fn: function (aSymbol, aCollection) {
>>> var self = this;
>>> return self[aSymbol].apply(self, aCollection);
>>> return self;},
>>>
>>> args: ["aSymbol", "aCollection"],
>>> source: unescape('basicPerform%3A%20aSymbol%20withArguments%3A
>>> %20aCollection%0A%09%3Creturn%20self%5BaSymbol%5D.apply%28self%2C
>>> %20aCollection%29%3B%3E'),
>>> messageSends: [],
>>> referencedClasses: []}),
>>>
>>> smalltalk.Object);
>>>
>>> Regards...
>>
>
Reply | Threaded
Open this post in threaded view
|

Re: Delegation, anybody ?

Hannes Hirzel
On http://chirp.scratchr.org/dl/experimental/JsMorphic/morphic.js

I find
// Morph instance creation:

function Morph() {
        this.init();
}

// Morph initialization:

Morph.prototype.init = function () {
        Morph.uber.init.call(this);
        this.isMorph = true;
        this.bounds = new Rectangle(0, 0, 50, 40);
        this.color = new Color(80, 80, 80);
        this.texture = null; // optional url of a fill-image
        this.cachedTexture = null; // internal cache of actual bg image
        this.alpha = 1;
        this.isVisible = true;
        this.isDraggable = false;
        this.isTemplate = false;
        this.acceptsDrops = false;
        this.noticesTransparentClick = false;
        this.drawNew();
        this.fps = 0;
        this.customContextMenu = null;
        this.lastTime = Date.now();
};



If I do

Morph new inspect

in an Amber workspace
I get a Morph object

I wonder how this is mapped.

And the method setColor is there in morphic.js

Morph.prototype.setColor = function (aColor) {
        if (aColor) {
                if (!this.color.eq(aColor)) {
                        this.color = aColor;
                        this.changed();
                        this.drawNew();
                }
        }
};


So in a Workspace the following is fine

"----------------------------------------------------------------------------------------------------"
box := BoxMorph new.
box at: 'mouseClickLeft' put: [Browser open].
<myColor = new Color(120, 120, 0, 255)>.

box setColor:  myColor.
box show.
  world add: box.
  world changed.

"----------------------------------------------------------------------------------------------------"

BTW how would I create a color with Smalltalk syntax?


-- Hannes

On 2/22/12, H. Hirzel <[hidden email]> wrote:

> Ah, I see in your first mail of Feb, 22nd
>
> Object subclass: #AMorph
>         instanceVariableNames: 'm'
>         package: 'Amber-Morphic'.
>
>         initialize
>                 m := Morph new.
>
>
> How is the class Morph defined in your code?
>
> --HH
>
> On 2/22/12, H. Hirzel <[hidden email]> wrote:
>> Tom,
>> Could  you please show us the code for AMorph?
>>
>>
>> What I see from http://tcltalk.ath.cx/files/morphicAmber.zip (posted
>> by you on Feb, 8th, 2012)
>>
>> I assume that in the meantime there is more Morphic code....
>>
>>
>> Smalltalk current createPackage: 'Morphic' properties: #{}!
>> Widget subclass: #MorphicWorld
>> instanceVariableNames: 'canvas'
>> category: 'Morphic'!
>> !MorphicWorld commentStamp!
>> thbr: This class a wrapper class for morphic.js's world canvas.
>> The wrapping is located in the method renderOn:!
>>
>> !MorphicWorld methodsFor: 'opening'!
>>
>> open
>> "Append this world to the HTML body tag of the loading page."
>>
>> | body |
>> body := 'body' asJQuery.
>> self appendToJQuery: body.
>> ! !
>>
>> !MorphicWorld methodsFor: 'rendering'!
>>
>> renderOn: html
>> "create a canvas node with an id of 'world'."
>>
>> canvas := html canvas
>> class: 'morphicWorld';
>> id: 'world';
>> style: 'position:absolute;';
>> yourself.
>> canvas at:'tabindex' put: 1.
>> <
>> function loop() {
>> world.doOneCycle();
>> }
>>   world = new WorldMorph(document.getElementById('world'));
>> world.color = new Color(255,255,192);
>> world.isDevMode = true;
>> setInterval(loop, 50);
>> >.
>> ^self
>> ! !
>>
>> !MorphicWorld class methodsFor: 'instance creation'!
>>
>> open
>> "Answer a new opened instance of the receiver"
>>
>> ^self new open
>> ! !
>>
>> MorphicWorld subclass: #Welcome
>> instanceVariableNames: ''
>> category: 'Morphic'!
>> !Welcome commentStamp!
>> tb: This class adds a browser button and a welcome message to the
>> morphic world.!
>>
>> !Welcome methodsFor: 'rendering'!
>>
>> renderOn: html
>> "create a canvas node with an id of 'world' and place additions"
>>
>> super renderOn: html.
>> self
>> addBrowserButton;
>> addWelcome.
>> ^self
>> ! !
>>
>> !Welcome methodsFor: 'setup'!
>>
>> addBrowserButton
>> "Adds a button to the world, which opens the Smalltalk IDE"
>>
>> | btn lbl |
>> btn := CircleBoxMorph new.
>> btn toggleOrientation: 'horizontal'.
>> btn setPosition: (0@0) asMorphicPoint.
>> btn at: 'mouseClickLeft' put: [Browser open].
>> btn show.
>> lbl := StringMorph new.
>> lbl at: 'text' put: 'Open Browser'.
>> lbl setColor: 'white'.
>> lbl setPosition: (7@5) asMorphicPoint.
>> lbl at: 'mouseEnter' put: [(SpeechBubbleMorph new)
>> contents: 'Open the Smalltalk Class Browser';
>> popUp: world at: (btn rightCenter) add: (-8@0) asMorphicPoint.
>> ].
>> lbl show.
>>
>> btn add: lbl.
>> world add: btn.
>> btn setPosition: (20@20) asMorphicPoint.
>> world changed.
>> ^self
>> !
>>
>> addWelcome
>> "Adds a welcome message"
>>
>> | header |
>> header := StringMorph new.
>> header at: 'text' put: 'Welcome!! - This is morphic.js running on
>> Amber'.
>> header setSerif.
>> header setFontSize: 24.
>> header toggleWeight.
>> header toggleItalic.
>> header setPosition: (140@21) asMorphicPoint.
>> header show.
>> world add: header.
>> world changed.
>> ^self
>> ! !
>>
>> --Hannes
>>
>>
>>
>>
>>
>> On 2/22/12, Tom <[hidden email]> wrote:
>>> The Smalltalk code that leads to this JavaScript error goes like
>>>
>>>   | m |
>>>   m := AMorph new.
>>>   "The next message is handled by #doesNotUnderstand: of an AMorph,
>>> because AMorph doesn't know about a method #setColor:."
>>>   m setColor: 'rgba(224,224,160,0.7)'.
>>>   m show.
>>>   world add: m.
>>>
>>>
>>>
>>> On 22 Feb., 22:06, Tom <[hidden email]> wrote:
>>>> On 22 Feb., 16:49, Nicolas Petton <[hidden email]> wrote:
>>>>
>>>> > Indeed. That doesn't work?
>>>>
>>>> Indeed, it doesn't :)
>>>>
>>>> Instanciation is ok, but doesNotUnderstand:withArguments: does not
>>>> delegate as one might expect. Instead I get an error in Firebugs
>>>> Console saying
>>>>
>>>> self[aSymbol] is undefined
>>>>   return self[aSymbol].apply(self, aCollection); in Kernel-Objects.js
>>>> at line no. 693
>>>>
>>>> which points to this little code fragment...
>>>>
>>>> smalltalk.addMethod(
>>>> unescape('_basicPerform_withArguments_'),
>>>> smalltalk.method({
>>>> selector: unescape('basicPerform%3AwithArguments%3A'),
>>>> category: 'message handling',
>>>> fn: function (aSymbol, aCollection) {
>>>> var self = this;
>>>> return self[aSymbol].apply(self, aCollection);
>>>> return self;},
>>>>
>>>> args: ["aSymbol", "aCollection"],
>>>> source: unescape('basicPerform%3A%20aSymbol%20withArguments%3A
>>>> %20aCollection%0A%09%3Creturn%20self%5BaSymbol%5D.apply%28self%2C
>>>> %20aCollection%29%3B%3E'),
>>>> messageSends: [],
>>>> referencedClasses: []}),
>>>>
>>>> smalltalk.Object);
>>>>
>>>> Regards...
>>>
>>
>
Reply | Threaded
Open this post in threaded view
|

Re: Delegation, anybody ?

Ankh'nAton
In reply to this post by Hannes Hirzel
Hello Hannes,

Amber can seamlessly instanciate JS objects and call their selectors,
using instances of JSObjectProxy internally. That works pretty well
and enables to use the prototypes of morphic.js like classes.

Anyway, I'd like to pull morphics class tree into Smalltalk's class
hierarchy for a more smalltalkese development process using the
browser. Therefor I started with Morph() and tried an approach with
delegation. The idea is, to have proxy classes in Smalltalk for the
most important morphs. These classes shall wrap around their
corresponding JS morph, holding an instance in an instance variable
(ivar) and then delegate unknown selectors to that ivar by overwriting
#doesNotUnderstand:.

That turns out to be a little unintuitive, as it does not work right
away. :)

If I can get this working then there will be more classes in my
Morphic package, but for now I'm just proving a concept.

Cheers...

On 22 Feb., 23:46, "H. Hirzel" <[hidden email]> wrote:

> Tom,
> Could  you please show us the code for AMorph?
>
> What I see fromhttp://tcltalk.ath.cx/files/morphicAmber.zip(posted
> by you on Feb, 8th, 2012)
>
> I assume that in the meantime there is more Morphic code....
>
> Smalltalk current createPackage: 'Morphic' properties: #{}!
> Widget subclass: #MorphicWorld
>         instanceVariableNames: 'canvas'
>         category: 'Morphic'!
> !MorphicWorld commentStamp!
> thbr: This class a wrapper class for morphic.js's world canvas.
> The wrapping is located in the method renderOn:!
>
> !MorphicWorld methodsFor: 'opening'!
>
> open
>         "Append this world to the HTML body tag of the loading page."
>
>         | body |
>         body := 'body' asJQuery.
>         self appendToJQuery: body.
> ! !
>
> !MorphicWorld methodsFor: 'rendering'!
>
> renderOn: html
>         "create a canvas node with an id of 'world'."
>
>         canvas := html canvas
>                 class: 'morphicWorld';
>                 id: 'world';
>                 style: 'position:absolute;';
>                 yourself.
>         canvas at:'tabindex' put: 1.
>         <
>         function loop() {
>                 world.doOneCycle();
>         }
>         world = new WorldMorph(document.getElementById('world'));
>         world.color = new Color(255,255,192);
>         world.isDevMode = true;
>         setInterval(loop, 50);
>         >.
>         ^self
> ! !
>
> !MorphicWorld class methodsFor: 'instance creation'!
>
> open
>         "Answer a new opened instance of the receiver"
>
>         ^self new open
> ! !
>
> MorphicWorld subclass: #Welcome
>         instanceVariableNames: ''
>         category: 'Morphic'!
> !Welcome commentStamp!
> tb: This class adds a browser button and a welcome message to the
> morphic world.!
>
> !Welcome methodsFor: 'rendering'!
>
> renderOn: html
>         "create a canvas node with an id of 'world' and place additions"
>
>         super renderOn: html.
>         self
>                 addBrowserButton;
>                 addWelcome.
>         ^self
> ! !
>
> !Welcome methodsFor: 'setup'!
>
> addBrowserButton
>         "Adds a button to the world, which opens the Smalltalk IDE"
>
>         | btn lbl |
>         btn := CircleBoxMorph new.
>         btn toggleOrientation: 'horizontal'.
>         btn setPosition: (0@0) asMorphicPoint.
>         btn at: 'mouseClickLeft' put: [Browser open].
>         btn show.
>         lbl := StringMorph new.
>         lbl at: 'text' put: 'Open Browser'.
>         lbl setColor: 'white'.
>         lbl setPosition: (7@5) asMorphicPoint.
>         lbl at: 'mouseEnter' put: [(SpeechBubbleMorph new)
>                 contents: 'Open the Smalltalk Class Browser';
>                 popUp: world at: (btn rightCenter) add: (-8@0) asMorphicPoint.
>         ].
>         lbl show.
>
>         btn add: lbl.
>         world add: btn.
>         btn setPosition: (20@20) asMorphicPoint.
>         world changed.
>         ^self
> !
>
> addWelcome
>         "Adds a welcome message"
>
>         | header |
>         header := StringMorph new.
>         header at: 'text' put: 'Welcome!! - This is morphic.js running on Amber'.
>         header setSerif.
>         header setFontSize: 24.
>         header toggleWeight.
>         header toggleItalic.
>         header setPosition: (140@21) asMorphicPoint.
>         header show.
>         world add: header.
>         world changed.
>         ^self
> ! !
>
> --Hannes
>
> On 2/22/12, Tom <[hidden email]> wrote:
>
>
>
>
>
>
>
> > The Smalltalk code that leads to this JavaScript error goes like
>
> >   | m |
> >   m := AMorph new.
> >   "The next message is handled by #doesNotUnderstand: of an AMorph,
> > because AMorph doesn't know about a method #setColor:."
> >   m setColor: 'rgba(224,224,160,0.7)'.
> >   m show.
> >   world add: m.
>
> > On 22 Feb., 22:06, Tom <[hidden email]> wrote:
> >> On 22 Feb., 16:49, Nicolas Petton <[hidden email]> wrote:
>
> >> > Indeed. That doesn't work?
>
> >> Indeed, it doesn't :)
>
> >> Instanciation is ok, but doesNotUnderstand:withArguments: does not
> >> delegate as one might expect. Instead I get an error in Firebugs
> >> Console saying
>
> >> self[aSymbol] is undefined
> >>   return self[aSymbol].apply(self, aCollection); in Kernel-Objects.js
> >> at line no. 693
>
> >> which points to this little code fragment...
>
> >> smalltalk.addMethod(
> >> unescape('_basicPerform_withArguments_'),
> >> smalltalk.method({
> >> selector: unescape('basicPerform%3AwithArguments%3A'),
> >> category: 'message handling',
> >> fn: function (aSymbol, aCollection) {
> >> var self = this;
> >> return self[aSymbol].apply(self, aCollection);
> >> return self;},
>
> >> args: ["aSymbol", "aCollection"],
> >> source: unescape('basicPerform%3A%20aSymbol%20withArguments%3A
> >> %20aCollection%0A%09%3Creturn%20self%5BaSymbol%5D.apply%28self%2C
> >> %20aCollection%29%3B%3E'),
> >> messageSends: [],
> >> referencedClasses: []}),
>
> >> smalltalk.Object);
>
> >> Regards...
Reply | Threaded
Open this post in threaded view
|

Re: Delegation, anybody ?

Ankh'nAton
In reply to this post by Hannes Hirzel
On 22 Feb., 23:52, "H. Hirzel" <[hidden email]> wrote:

> Ah, I see in your first mail of Feb, 22nd
>
> Object subclass: #AMorph
>         instanceVariableNames: 'm'
>         package: 'Amber-Morphic'.
>
>         initialize
>                 m := Morph new.
>
> How is the class Morph defined in your code?
>

It isn't. In Amber you can instanciate every JS Prototype just like a
Smalltalk class. Morph here is written in JavaScript as Morph() in
morphic.js.

> --HH
>
> On 2/22/12, H. Hirzel <[hidden email]> wrote:
>
>
>
>
>
>
>
> > Tom,
> > Could  you please show us the code for AMorph?
>
> > What I see fromhttp://tcltalk.ath.cx/files/morphicAmber.zip(posted
> > by you on Feb, 8th, 2012)
>
> > I assume that in the meantime there is more Morphic code....
>
> > Smalltalk current createPackage: 'Morphic' properties: #{}!
> > Widget subclass: #MorphicWorld
> >    instanceVariableNames: 'canvas'
> >    category: 'Morphic'!
> > !MorphicWorld commentStamp!
> > thbr: This class a wrapper class for morphic.js's world canvas.
> > The wrapping is located in the method renderOn:!
>
> > !MorphicWorld methodsFor: 'opening'!
>
> > open
> >    "Append this world to the HTML body tag of the loading page."
>
> >    | body |
> >    body := 'body' asJQuery.
> >    self appendToJQuery: body.
> > ! !
>
> > !MorphicWorld methodsFor: 'rendering'!
>
> > renderOn: html
> >    "create a canvas node with an id of 'world'."
>
> >    canvas := html canvas
> >            class: 'morphicWorld';
> >            id: 'world';
> >            style: 'position:absolute;';
> >            yourself.
> >    canvas at:'tabindex' put: 1.
> >    <
> >    function loop() {
> >            world.doOneCycle();
> >    }
> >    world = new WorldMorph(document.getElementById('world'));
> >    world.color = new Color(255,255,192);
> >    world.isDevMode = true;
> >    setInterval(loop, 50);
> >    >.
> >    ^self
> > ! !
>
> > !MorphicWorld class methodsFor: 'instance creation'!
>
> > open
> >    "Answer a new opened instance of the receiver"
>
> >    ^self new open
> > ! !
>
> > MorphicWorld subclass: #Welcome
> >    instanceVariableNames: ''
> >    category: 'Morphic'!
> > !Welcome commentStamp!
> > tb: This class adds a browser button and a welcome message to the
> > morphic world.!
>
> > !Welcome methodsFor: 'rendering'!
>
> > renderOn: html
> >    "create a canvas node with an id of 'world' and place additions"
>
> >    super renderOn: html.
> >    self
> >            addBrowserButton;
> >            addWelcome.
> >    ^self
> > ! !
>
> > !Welcome methodsFor: 'setup'!
>
> > addBrowserButton
> >    "Adds a button to the world, which opens the Smalltalk IDE"
>
> >    | btn lbl |
> >    btn := CircleBoxMorph new.
> >    btn toggleOrientation: 'horizontal'.
> >    btn setPosition: (0@0) asMorphicPoint.
> >    btn at: 'mouseClickLeft' put: [Browser open].
> >    btn show.
> >    lbl := StringMorph new.
> >    lbl at: 'text' put: 'Open Browser'.
> >    lbl setColor: 'white'.
> >    lbl setPosition: (7@5) asMorphicPoint.
> >    lbl at: 'mouseEnter' put: [(SpeechBubbleMorph new)
> >            contents: 'Open the Smalltalk Class Browser';
> >            popUp: world at: (btn rightCenter) add: (-8@0) asMorphicPoint.
> >    ].
> >    lbl show.
>
> >    btn add: lbl.
> >    world add: btn.
> >    btn setPosition: (20@20) asMorphicPoint.
> >    world changed.
> >    ^self
> > !
>
> > addWelcome
> >    "Adds a welcome message"
>
> >    | header |
> >    header := StringMorph new.
> >    header at: 'text' put: 'Welcome!! - This is morphic.js running on Amber'.
> >    header setSerif.
> >    header setFontSize: 24.
> >    header toggleWeight.
> >    header toggleItalic.
> >    header setPosition: (140@21) asMorphicPoint.
> >    header show.
> >    world add: header.
> >    world changed.
> >    ^self
> > ! !
>
> > --Hannes
>
> > On 2/22/12, Tom <[hidden email]> wrote:
> >> The Smalltalk code that leads to this JavaScript error goes like
>
> >>   | m |
> >>   m := AMorph new.
> >>   "The next message is handled by #doesNotUnderstand: of an AMorph,
> >> because AMorph doesn't know about a method #setColor:."
> >>   m setColor: 'rgba(224,224,160,0.7)'.
> >>   m show.
> >>   world add: m.
>
> >> On 22 Feb., 22:06, Tom <[hidden email]> wrote:
> >>> On 22 Feb., 16:49, Nicolas Petton <[hidden email]> wrote:
>
> >>> > Indeed. That doesn't work?
>
> >>> Indeed, it doesn't :)
>
> >>> Instanciation is ok, but doesNotUnderstand:withArguments: does not
> >>> delegate as one might expect. Instead I get an error in Firebugs
> >>> Console saying
>
> >>> self[aSymbol] is undefined
> >>>   return self[aSymbol].apply(self, aCollection); in Kernel-Objects.js
> >>> at line no. 693
>
> >>> which points to this little code fragment...
>
> >>> smalltalk.addMethod(
> >>> unescape('_basicPerform_withArguments_'),
> >>> smalltalk.method({
> >>> selector: unescape('basicPerform%3AwithArguments%3A'),
> >>> category: 'message handling',
> >>> fn: function (aSymbol, aCollection) {
> >>> var self = this;
> >>> return self[aSymbol].apply(self, aCollection);
> >>> return self;},
>
> >>> args: ["aSymbol", "aCollection"],
> >>> source: unescape('basicPerform%3A%20aSymbol%20withArguments%3A
> >>> %20aCollection%0A%09%3Creturn%20self%5BaSymbol%5D.apply%28self%2C
> >>> %20aCollection%29%3B%3E'),
> >>> messageSends: [],
> >>> referencedClasses: []}),
>
> >>> smalltalk.Object);
>
> >>> Regards...
Reply | Threaded
Open this post in threaded view
|

Re: Delegation, anybody ?

Ankh'nAton
In reply to this post by Hannes Hirzel
On 23 Feb., 01:45, "H. Hirzel" <[hidden email]> wrote:
> Onhttp://chirp.scratchr.org/dl/experimental/JsMorphic/morphic.js
>

[Morph() found in morphic.js]

>
> BTW how would I create a color with Smalltalk syntax?
>

I'm stuck to encoding colors like..

  myMorph setColor: 'rgba(255,255,255,1)'.

..where the last parameter of rgba is the color's opaqueness
(transparency)

Regards...
Reply | Threaded
Open this post in threaded view
|

Re: Delegation, anybody ?

Nicolas Petton
In reply to this post by Ankh'nAton
On 22/02/12 22:06, Tom wrote:
> On 22 Feb., 16:49, Nicolas Petton<[hidden email]>  wrote:
>> Indeed. That doesn't work?
>>
>
> Indeed, it doesn't :)


Ok, I just pushed a few changes that should make it easier :)

doesNotUnderstand: aMessage
        aMessage sendTo: m


Does that work for you?

Cheers,
Nico

>
> Instanciation is ok, but doesNotUnderstand:withArguments: does not
> delegate as one might expect. Instead I get an error in Firebugs
> Console saying
>
> self[aSymbol] is undefined
>    return self[aSymbol].apply(self, aCollection); in Kernel-Objects.js
> at line no. 693
>
> which points to this little code fragment...
>
> smalltalk.addMethod(
> unescape('_basicPerform_withArguments_'),
> smalltalk.method({
> selector: unescape('basicPerform%3AwithArguments%3A'),
> category: 'message handling',
> fn: function (aSymbol, aCollection) {
> var self = this;
> return self[aSymbol].apply(self, aCollection);
> return self;
> },
> args: ["aSymbol", "aCollection"],
> source: unescape('basicPerform%3A%20aSymbol%20withArguments%3A
> %20aCollection%0A%09%3Creturn%20self%5BaSymbol%5D.apply%28self%2C
> %20aCollection%29%3B%3E'),
> messageSends: [],
> referencedClasses: []
> }),
> smalltalk.Object);
>
>
> Regards...


--
Nicolas Petton
http://nicolas-petton.fr
Reply | Threaded
Open this post in threaded view
|

Re: Delegation, anybody ?

Ankh'nAton
Yes! Fantastic!

Although,  I cannot pass my proxy classes's instances as valid
arguments substituting JS prototype instances. I layed back, meditated
a little and added a new method #asMorph to my proxy class. It returns
the actual morph to be used as an argument to other morphic methods.
So, my testing code now goes like...

  | m |
  m := AMorph new.
  m setPosition: (100@100) asMorphicPoint.
  m show.
  world add: m asMorph.
  world changed.

...where AMorph is the wrapper class for Morph().

Thanks al lot!

Tom



On 23 Feb., 10:41, Nicolas Petton <[hidden email]> wrote:

> On 22/02/12 22:06, Tom wrote:
>
> > On 22 Feb., 16:49, Nicolas Petton<[hidden email]>  wrote:
> >> Indeed. That doesn't work?
>
> > Indeed, it doesn't :)
>
> Ok, I just pushed a few changes that should make it easier :)
>
> doesNotUnderstand: aMessage
>         aMessage sendTo: m
>
> Does that work for you?
>
> Cheers,
> Nico
>
>
>
>
>
>
>
>
>
>
>
> > Instanciation is ok, but doesNotUnderstand:withArguments: does not
> > delegate as one might expect. Instead I get an error in Firebugs
> > Console saying
>
> > self[aSymbol] is undefined
> >    return self[aSymbol].apply(self, aCollection); in Kernel-Objects.js
> > at line no. 693
>
> > which points to this little code fragment...
>
> > smalltalk.addMethod(
> > unescape('_basicPerform_withArguments_'),
> > smalltalk.method({
> > selector: unescape('basicPerform%3AwithArguments%3A'),
> > category: 'message handling',
> > fn: function (aSymbol, aCollection) {
> > var self = this;
> > return self[aSymbol].apply(self, aCollection);
> > return self;
> > },
> > args: ["aSymbol", "aCollection"],
> > source: unescape('basicPerform%3A%20aSymbol%20withArguments%3A
> > %20aCollection%0A%09%3Creturn%20self%5BaSymbol%5D.apply%28self%2C
> > %20aCollection%29%3B%3E'),
> > messageSends: [],
> > referencedClasses: []
> > }),
> > smalltalk.Object);
>
> > Regards...
>
> --
> Nicolas Pettonhttp://nicolas-petton.fr
Reply | Threaded
Open this post in threaded view
|

Re: Delegation, anybody ?

Ankh'nAton
Here is the code for the wrapper class of Morph()...

Object subclass: #AMorph
        instanceVariableNames: 'm'
        category: 'TB-Morphic'!


        asMorph
                "tb. Answer the receiver's proxy morph"
                ^m.

        initialize
                "tb: Initialize the receiver's instance variables"
                m := Morph new.
                super initialize.

        doesNotUnderstand: aMessage
                "tb. Delegating to the receiver's instance variable m"
                ^aMessage sendTo: m.


It can be used as a foundation for a complete tree of Morphic's
classes inside Smalltalk's class hierarchy. Every subclass of AMorph
(ie. ABoxMorph) must simply overwrite #initialize to instanciate the
right JS prototype from morphic.js.

Regards...

On 23 Feb., 11:21, Tom <[hidden email]> wrote:

> Yes! Fantastic!
>
> Although,  I cannot pass my proxy classes's instances as valid
> arguments substituting JS prototype instances. I layed back, meditated
> a little and added a new method #asMorph to my proxy class. It returns
> the actual morph to be used as an argument to other morphic methods.
> So, my testing code now goes like...
>
>   | m |
>   m := AMorph new.
>   m setPosition: (100@100) asMorphicPoint.
>   m show.
>   world add: m asMorph.
>   world changed.
>
> ...where AMorph is the wrapper class for Morph().
>
> Thanks al lot!
>
> Tom
>
> On 23 Feb., 10:41, Nicolas Petton <[hidden email]> wrote:
>
>
>
>
>
>
>
> > On 22/02/12 22:06, Tom wrote:
>
> > > On 22 Feb., 16:49, Nicolas Petton<[hidden email]>  wrote:
> > >> Indeed. That doesn't work?
>
> > > Indeed, it doesn't :)
>
> > Ok, I just pushed a few changes that should make it easier :)
>
> > doesNotUnderstand: aMessage
> >         aMessage sendTo: m
>
> > Does that work for you?
>
> > Cheers,
> > Nico
>
> > > Instanciation is ok, but doesNotUnderstand:withArguments: does not
> > > delegate as one might expect. Instead I get an error in Firebugs
> > > Console saying
>
> > > self[aSymbol] is undefined
> > >    return self[aSymbol].apply(self, aCollection); in Kernel-Objects.js
> > > at line no. 693
>
> > > which points to this little code fragment...
>
> > > smalltalk.addMethod(
> > > unescape('_basicPerform_withArguments_'),
> > > smalltalk.method({
> > > selector: unescape('basicPerform%3AwithArguments%3A'),
> > > category: 'message handling',
> > > fn: function (aSymbol, aCollection) {
> > > var self = this;
> > > return self[aSymbol].apply(self, aCollection);
> > > return self;
> > > },
> > > args: ["aSymbol", "aCollection"],
> > > source: unescape('basicPerform%3A%20aSymbol%20withArguments%3A
> > > %20aCollection%0A%09%3Creturn%20self%5BaSymbol%5D.apply%28self%2C
> > > %20aCollection%29%3B%3E'),
> > > messageSends: [],
> > > referencedClasses: []
> > > }),
> > > smalltalk.Object);
>
> > > Regards...
>
> > --
> > Nicolas Pettonhttp://nicolas-petton.fr