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
"add the tabs"
#(Scripts Costumes Sounds Teste)- Added a new instance variable called "testeBlocksBin" to ScriptableScratchMorph and assigned it a ScratchScriptsMorph in initialize method:
testeBlocksBin := ScratchScriptsMorph new.
- Added the selector method to retrieve the instance variable:
testeBlocksBin
^ testeBlocksBin- Created the contents for the new tab in ScratchScriptEditorMorph>>currentCategory:
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:
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):
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:
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":
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
0.o Thats a lot of programming. I don't think I can help now.
Offline
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
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
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
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
Hmm, complex. Ill have a read over how things work and get back to you.
Offline
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.
Offline
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
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:
(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
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)
Offline
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
Ok, can anyone else make a mod with these specs please.
Offline
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
Thanks I think thats what I need.
Offline
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.
Offline
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...
Offline
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
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.
Offline
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)
Offline
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
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.
Offline
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
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