This is a read-only archive of the old Scratch 1.x Forums.
Try searching the current Scratch discussion forums.

#1 2011-05-19 18:27:42

Baderous
New Scratcher
Registered: 2011-04-14
Posts: 100+

Add default initial block to new tab

I need your help on this one.

I've added a new tab to the tabpane component of ScratchScriptEditorMorph.
To do so, I did the following:
- Added the tab (called it "Teste") in ScratchScriptEditorMorph>>createTabPane

Code:

"add the tabs"
    #(Scripts Costumes Sounds Teste)

- Added a new instance variable called "testeBlocksBin" to ScriptableScratchMorph and assigned it a ScratchScriptsMorph in initialize method:

Code:

testeBlocksBin := ScratchScriptsMorph new.

- Added the selector method to retrieve the instance variable:

Code:

testeBlocksBin

    ^ testeBlocksBin

- Created the contents for the new tab in ScratchScriptEditorMorph>>currentCategory:

Code:

currentCategory = 'Teste' ifTrue: [
        pageViewerMorph contents: self target testeBlocksBin].

- Changed ScratchScriptEditorMorph>>mouseEnterDragging: so I could drag blocks to the scripting area of this new tab.

- Based on ScriptableScratchMorph>>scripts, I created the method ScriptableScratchMorph>>singleScript to return the script contained in the new tab:

Code:

singleScript

    (testeBlocksBin isKindOf: Morph) ifFalse: [^ testeBlocksBin].
    ^ testeBlocksBin submorphs select: [:m | m isKindOf: HatBlockMorph]

- Changed ScriptableScratchMorph>>eventReceived: to start the stack of the current tab (since now we have 2 tabs):

Code:

eventReceived: event
    "Start all non-running stacks with an EventHat matching the given events and answer a collection of the new processes. If a process is already running for a given stack, don't start a new one."

    | targetScripts newProcs ssem scpts sfm |
    targetScripts _ #().
    sfm _ World submorphs detect: [:subm | subm isKindOf: ScratchFrameMorph].
    ssem _ sfm submorphs detect: [:subm | subm isKindOf: ScratchScriptEditorMorph].
    ssem currentCategory = 'Teste'
        ifTrue: [scpts _ self singleScript]
        ifFalse: [scpts _ self scripts].
    event name = 'Scratch-KeyPressedEvent'
        ifTrue: [
            targetScripts _ scpts select: [:s |
                (s class == KeyEventHatMorph) and:
                 [s respondsToKeyEvent: event argument]]]
        ifFalse: [
            event name = 'Scratch-MouseClickEvent'
                ifTrue: [
                    self isHidden not ifTrue: [
                        targetScripts _ scpts select: [:s |
                            s class == MouseClickEventHatMorph]]]
                ifFalse: [
                    targetScripts _ scpts select: [:s |
                        (s class == EventHatMorph) and:
                         [s eventName caseInsensitiveEqual: event name]]]].
    
    newProcs _ targetScripts asArray collect: [:script | script startForEvent: event].
    ^ newProcs select: [:p | p notNil]

From this point, I was able to create scripts in the new tab (by dragging and dropping blocks from the palette) and execute them.

Now I want to add a default block that will always appear as a top block in this new tab. Let's pretend I wanted "When [green flag] clicked" block to be this top block. I did this:

- I added a new instance variable to ScriptableScratchMorph, called "scriptBlock", along with its getter method and added the following code in ScriptableScratchMorph>>initialize:

Code:

 scriptBlock _ (self blockFromSpec: #('when %m clicked' S -) color: (self class blockColorFor: 'control')).
    testeBlocksBin addMorph: scriptBlock; cleanUp.

When I open Scratch, I can see the block in the new tab but it doesn't react to the green flag. But if I drag the block from the palette and create a script under it, it works fine! I don't know if it is necessary to have scriptBlock as an instance variable, I tried previously to declare it as a local variable in initialize method and it didn't work too. I have spent a lot of hours looking through all the methods involved in this process since the click on the green flag, the broadcast of "Scratch-StartClicked" event, etc, and I couldn't find the answer to my problem.
One thing that I found is that if I inspect the block in the new tab and use the bottom workspace to run the following code, it gives "nil":

Code:

self scriptOwner owner

But, if I drag and drop the same block from the palette and do the same, it returns "a ScratchStageMorph()".
I believe that I am missing the link between the ScratchSpriteMorph, which is the scriptOwner, and the ScratchStageMorph which should be the owner of the ScratchSpriteMorph. I tried to add the scriptOwner to the collection of submorphs of the Stage but without success.

Let me just add that if I try to add this block as the default top one on Scripts tab (that is, if I call addMorph on blocksBin instead of testeBlocksBin), it works perfectly.

I hope you can help me solving this problem, I've been around this for more than a week.

Offline

 

#2 2011-05-20 08:38:38

Pecola1
Scratcher
Registered: 2010-09-06
Posts: 1000+

Re: Add default initial block to new tab

0.o Thats a lot of programming. I don't think I can help now.


If you are reading this, please read to the end, because if you don't you won't know what's at the end. Don't just skip to the end though otherwise you won't be able to read the middle, which is most important. Now you must be wondering why you just read all that, the reason is you may have not noticed something, read it again and see if you notice it this time  smile

Offline

 

#3 2011-05-20 10:37:30

rdococ
Scratcher
Registered: 2009-10-11
Posts: 1000+

Re: Add default initial block to new tab

Baderous wrote:

Code:

 scriptBlock _ (self blockFromSpec: #('when %m clicked' S -) color: (self class blockColorFor: 'control')).
    testeBlocksBin addMorph: scriptBlock; cleanUp.

It needs to be ('when %m clicked' #S #-), not ('when %m clicked' S -).

Offline

 

#4 2011-05-20 10:37:39

Baderous
New Scratcher
Registered: 2011-04-14
Posts: 100+

Re: Add default initial block to new tab

I just found that if I select the Stage icon at the left of the Sprite list, so that the scripts written thereafter afect only the Stage, everything works as expected! The block answers to the green flag and the script created (let's say it switches the stage background) works fine!
By inspecting the block in the new tab and running "self scriptOwner owner", it returns "a ScratchFrameMorph()", meaning that the morphs are all well connected (the block is linked to the Stage since its scriptOwner is a ScratchStageMorph(), and the latter is a submorph of the ScratchFrameMorph).
I need your help to discover why this doesn't work with Sprites.

Offline

 

#5 2011-05-20 10:38:57

rdococ
Scratcher
Registered: 2009-10-11
Posts: 1000+

Re: Add default initial block to new tab

rdococ wrote:

Baderous wrote:

Code:

 scriptBlock _ (self blockFromSpec: #('when %m clicked' S -) color: (self class blockColorFor: 'control')).
    testeBlocksBin addMorph: scriptBlock; cleanUp.

It needs to be ('when %m clicked' #S #-), not ('when %m clicked' S -).

Offline

 

#6 2011-05-20 10:46:11

Baderous
New Scratcher
Registered: 2011-04-14
Posts: 100+

Re: Add default initial block to new tab

rdococ wrote:

Baderous wrote:

Code:

 scriptBlock _ (self blockFromSpec: #('when %m clicked' S -) color: (self class blockColorFor: 'control')).
    testeBlocksBin addMorph: scriptBlock; cleanUp.

It needs to be ('when %m clicked' #S #-), not ('when %m clicked' S -).

I had already tried that and it didn't work.

Offline

 

#7 2011-05-20 11:19:02

johnnydean1
Scratcher
Registered: 2010-02-12
Posts: 1000+

Re: Add default initial block to new tab

Hmm, complex. Ill have a read over how things work and get back to you.


You can now reach me on Twitter @johnnydean1_

Offline

 

#8 2011-05-20 11:25:34

johnnydean1
Scratcher
Registered: 2010-02-12
Posts: 1000+

Re: Add default initial block to new tab

Look into hat blocks and broadcasts. I believe the Hat Block works, but if not receiving its trigger. And how do you know so much Squeak.


You can now reach me on Twitter @johnnydean1_

Offline

 

#9 2011-05-20 11:33:03

LS97
Scratcher
Registered: 2009-06-14
Posts: 1000+

Re: Add default initial block to new tab

rdococ wrote:

Baderous wrote:

Code:

 scriptBlock _ (self blockFromSpec: #('when %m clicked' S -) color: (self class blockColorFor: 'control')).
    testeBlocksBin addMorph: scriptBlock; cleanUp.

It needs to be ('when %m clicked' #S #-), not ('when %m clicked' S -).

Not necessarily. You only need one # to indicate it's an array, and it's already present before the brackets.

Offline

 

#10 2011-05-20 12:34:27

Baderous
New Scratcher
Registered: 2011-04-14
Posts: 100+

Re: Add default initial block to new tab

johnnydean1 wrote:

Look into hat blocks and broadcasts. I believe the Hat Block works, but if not receiving its trigger.

I've looked to HatBlockMorph and its subclass EventHatMorph (the type of the "when [green flag] clicked" block) and everything seems fine to me. Broadcasts are also well, the method ScratchStageMorph>>broadcastEventNamed:with: ends up calling ScriptableScratchMorph>>eventReceived: which I showed in my first post. This one calls EventHatMorph>>startForEvent: which has the following line:

Code:

(stage _ scriptOwner ownerThatIsA: ScratchStageMorph) ifNil: [^ nil].

Which I believe it's where my problem is, because "scriptOwner owner" returns nil to me.

This method (EventHatMorph>>startForEvent: ) has 2 senders: ScriptableScratchMorph>>hatBlockType, which builds the hat block with the green flag and ready to answer to the event fired by green flag ("Scratch-StartClicked"), and ScriptableScratchMorph>>hatBlockFromTuple:receiver:  which builds a block from a tuple. I haven't looked deeply at these methods that have "tuple" in their name, but by looking at their senders, I believe that they are related to writing/reading from files, so I don't think they have the answer to my problem.

Offline

 

#11 2011-05-20 12:56:07

johnnydean1
Scratcher
Registered: 2010-02-12
Posts: 1000+

Re: Add default initial block to new tab

Well the Flag is triggered by broadcasts and they work? Hmm... Can you post a .image of your modification. (By post I mean upload the .image to media fire and post a download link)

Last edited by johnnydean1 (2011-05-20 13:00:56)


You can now reach me on Twitter @johnnydean1_

Offline

 

#12 2011-05-20 13:16:33

Baderous
New Scratcher
Registered: 2011-04-14
Posts: 100+

Re: Add default initial block to new tab

I'm afraid I can't do that because this is part of an academic work and I don't want to take risks, I hope you understand. But I have registered all the modifications I've done to any method so let me know if you need to check something in order to help.

Offline

 

#13 2011-05-20 15:57:16

johnnydean1
Scratcher
Registered: 2010-02-12
Posts: 1000+

Re: Add default initial block to new tab

Ok, can anyone else make a mod with these specs please.


You can now reach me on Twitter @johnnydean1_

Offline

 

#14 2011-05-20 16:21:48

Baderous
New Scratcher
Registered: 2011-04-14
Posts: 100+

Re: Add default initial block to new tab

johnnydean1 wrote:

Ok, can anyone else make a mod with these specs please.

I've created it with just the new tab (basically, with everything I mentioned in my first post). Here it is: http://www.mediafire.com/?vtilth4t39it9lo

Offline

 

#15 2011-05-20 16:24:07

johnnydean1
Scratcher
Registered: 2010-02-12
Posts: 1000+

Re: Add default initial block to new tab

Thanks I think thats what I need.


You can now reach me on Twitter @johnnydean1_

Offline

 

#16 2011-05-20 16:29:40

JJROCKER
Scratcher
Registered: 2010-09-06
Posts: 1000+

Re: Add default initial block to new tab

WOW! Your a really good scripter!


http://www.blocks.scratchr.org/API.php?action=random&return=image&link1=http://img255.imageshack.us/img255/3491/signature1y.jpg&link2=http://img577.imageshack.us/img577/5272/signature1sx.jpg&link3=http://img4.imageshack.us/img4/8514/signature1et.jpg&link4=http://i.imgur.com/POEpQyZ.png&link5=http://img163.imageshack.us/img163/4640/jjrockerfinal.jpg

Offline

 

#17 2011-05-20 16:30:56

johnnydean1
Scratcher
Registered: 2010-02-12
Posts: 1000+

Re: Add default initial block to new tab

Its a problem with the when flag block only. The broadcast sent when the flag clicked 'Scratch-StartClicked' is picked up by the broadcast block, but not the flag block. So the when flag clicked block fails.


You can now reach me on Twitter @johnnydean1_

Offline

 

#18 2011-05-20 16:36:29

johnnydean1
Scratcher
Registered: 2010-02-12
Posts: 1000+

Re: Add default initial block to new tab

johnnydean1 wrote:

Its a problem with the when flag block only. The broadcast sent when the flag clicked 'Scratch-StartClicked' is picked up by the broadcast block, but not the flag block. So the when flag clicked block fails.

Weird its only the first hat block having the problem...


You can now reach me on Twitter @johnnydean1_

Offline

 

#19 2011-05-20 16:41:58

Baderous
New Scratcher
Registered: 2011-04-14
Posts: 100+

Re: Add default initial block to new tab

The "broadcast" block you talk about is the one in Control category?
If so, that block is associated with the ScriptableScratchMorph>>broadcast, which in turn calls ScriptableScratchMorph>>broadcast:withArgument:, and this one calls ScratchStageMorph>>broadcastEventNamed:with:, which is the same method called by ScratchFrameMorph>>shoutGo, the one triggered by the green flag.
I don't understand how you realized that. Can you explain a bit more?

Offline

 

#20 2011-05-20 17:05:16

johnnydean1
Scratcher
Registered: 2010-02-12
Posts: 1000+

Re: Add default initial block to new tab

I know from experience that 'Scratch-StartClicked' triggers green flag hats. So if you make a when broadcast received hat with the input 'Scratch-StartClicked' you basically get a green flag hat. From this being triggered when flag pressed, we know a broadcast is being sent. SO it is the first hat block that wrong.


You can now reach me on Twitter @johnnydean1_

Offline

 

#21 2011-05-20 17:07:31

johnnydean1
Scratcher
Registered: 2010-02-12
Posts: 1000+

Re: Add default initial block to new tab

So I think you have coded the hat block wrong, as when you click on it - the script does not run - and it does not respond to the flag being pressed.

I'm off to bed (10 pm) I can help tomorrow if your still stuck. Meanwhile can you tell me how to get scripts from both tabs running at the same time (E.G scripting pane and teste)

Last edited by johnnydean1 (2011-05-20 17:13:10)


You can now reach me on Twitter @johnnydean1_

Offline

 

#22 2011-05-20 17:11:57

Baderous
New Scratcher
Registered: 2011-04-14
Posts: 100+

Re: Add default initial block to new tab

johnnydean1 wrote:

So I think you have coded the hat block wrong, as when you click on it - the script does not run - and it does not respond to the flag being pressed.

Is it the hat block that is wrong coded or is it the new tab? I ask this because if you add the block to the Scripts tab instead, it work. Just change ScriptableScratchMorph>>initialize, instead of calling addMorph on testeBlocksBin, call it on blocksBin, and see it working.

Offline

 

#23 2011-05-20 17:14:25

johnnydean1
Scratcher
Registered: 2010-02-12
Posts: 1000+

Re: Add default initial block to new tab

Baderous wrote:

johnnydean1 wrote:

So I think you have coded the hat block wrong, as when you click on it - the script does not run - and it does not respond to the flag being pressed.

Is it the hat block that is wrong coded or is it the new tab? I ask this because if you add the block to the Scripts tab instead, it work. Just change ScriptableScratchMorph>>initialize, instead of calling addMorph on testeBlocksBin, call it on blocksBin, and see it working.

I believe that the Hat block is coded wrong. If you put in a new hat block it function correctly. So the way you put in the first one is wrong.


You can now reach me on Twitter @johnnydean1_

Offline

 

#24 2011-05-20 17:27:55

Baderous
New Scratcher
Registered: 2011-04-14
Posts: 100+

Re: Add default initial block to new tab

johnnydean1 wrote:

Baderous wrote:

johnnydean1 wrote:

So I think you have coded the hat block wrong, as when you click on it - the script does not run - and it does not respond to the flag being pressed.

Is it the hat block that is wrong coded or is it the new tab? I ask this because if you add the block to the Scripts tab instead, it work. Just change ScriptableScratchMorph>>initialize, instead of calling addMorph on testeBlocksBin, call it on blocksBin, and see it working.

I believe that the Hat block is coded wrong. If you put in a new hat block it function correctly. So the way you put in the first one is wrong.

Maybe the answer to this is on the method that's called when we drop a block from the palette in the new tab. I am trying to find which method it is.

Besides, I built the block just how it is built when creating the blocks palette. The method ScriptableScratchMorph>>blockFromSpec:color: creates a block from a given specification, and it is invoked by ScriptableScratchMorph>>blocksFor: that returns a collection of blocks for the given category, by reading the blockSpecs where blocks are defined. So I don't know where I am could possibly fail.

Offline

 

#25 2011-05-20 17:41:20

Baderous
New Scratcher
Registered: 2011-04-14
Posts: 100+

Re: Add default initial block to new tab

Hmm, by inspecting the hat block while in the palette, I found that it is correctly linked to the Sprite and Stage, that is, its scriptOwner is a ScratchSpriteMorph which has a ScratchStageMorph as its owner. So maybe you're right and the block is being wrong coded. But where...

Offline

 

Board footer