Skip to content

Commit 100e3f4

Browse files
committed
Adds custom menu support to block specs
1 parent 5238660 commit 100e3f4

File tree

3 files changed

+61
-13
lines changed

3 files changed

+61
-13
lines changed

src/blocks/BlockArg.as

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public class BlockArg extends Sprite {
5555
public var isEditable:Boolean;
5656
public var field:TextField;
5757
public var menuName:String;
58+
public var menuItems:Array;
5859

5960
private var menuIcon:Shape;
6061

@@ -88,7 +89,11 @@ public class BlockArg extends Sprite {
8889
addEventListener(MouseEvent.MOUSE_DOWN, invokeMenu);
8990
} else if (type == 'm') {
9091
base = new BlockShape(BlockShape.RectShape, c);
91-
this.menuName = menuName;
92+
if(menuName.charAt(0) == '[') {
93+
this.menuItems = menuName.slice(1,menuName.length - 1).split(',');
94+
} else {
95+
this.menuName = menuName;
96+
}
9297
addEventListener(MouseEvent.MOUSE_DOWN, invokeMenu);
9398
} else if (type == 'n') {
9499
base = new BlockShape(BlockShape.NumberShape, c);
@@ -249,9 +254,10 @@ public class BlockArg extends Sprite {
249254
private function invokeMenu(evt:MouseEvent):void {
250255
if ((menuIcon != null) && (evt.localX <= menuIcon.x)) return;
251256
if (Block.MenuHandlerFunction != null) {
252-
Block.MenuHandlerFunction(evt, parent, this, menuName);
257+
Block.MenuHandlerFunction(evt, parent, this, menuName, menuItems);
253258
evt.stopImmediatePropagation();
254259
}
255260
}
256261

257-
}}
262+
}
263+
}

src/scratch/BlockMenus.as

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,32 @@ public class BlockMenus implements DragClient {
4444
private static const spriteAttributes:Array = ['x position', 'y position', 'direction', 'costume #', 'costume name', 'size', 'volume'];
4545
private static const stageAttributes:Array = ['backdrop #', 'backdrop name', 'volume'];
4646

47-
public static function BlockMenuHandler(evt:MouseEvent, block:Block, blockArg:BlockArg = null, menuName:String = null):void {
47+
public static function BlockMenuHandler(evt:MouseEvent, block:Block, blockArg:BlockArg = null, menuName:String = null, menuItems:Array = null):void {
4848
var menuHandler:BlockMenus = new BlockMenus(block, blockArg);
4949
var op:String = block.op;
50-
if (menuName == null) { // menu gesture on a block (vs. an arg)
51-
if (op == Specs.GET_LIST) menuName = 'list';
52-
if (op == Specs.GET_VAR) menuName = 'var';
53-
if ((op == Specs.PROCEDURE_DEF) || (op == Specs.CALL)) menuName = 'procMenu';
54-
if ((op == 'broadcast:') || (op == 'doBroadcastAndWait') || (op == 'whenIReceive')) menuName = 'broadcastInfoMenu';
55-
if ((basicMathOps.indexOf(op)) > -1) { menuHandler.changeOpMenu(evt, basicMathOps); return; }
56-
if ((comparisonOps.indexOf(op)) > -1) { menuHandler.changeOpMenu(evt, comparisonOps); return; }
57-
if (menuName == null) { menuHandler.genericBlockMenu(evt); return; }
50+
if (menuName == null) {
51+
if (menuItems == null) {
52+
// menu gesture on a block (vs. an arg)
53+
if (op == Specs.GET_LIST) menuName = 'list';
54+
if (op == Specs.GET_VAR) menuName = 'var';
55+
if ((op == Specs.PROCEDURE_DEF) || (op == Specs.CALL)) menuName = 'procMenu';
56+
if ((op == 'broadcast:') || (op == 'doBroadcastAndWait') || (op == 'whenIReceive')) menuName = 'broadcastInfoMenu';
57+
if ((basicMathOps.indexOf(op)) > -1) {
58+
menuHandler.changeOpMenu(evt, basicMathOps);
59+
return;
60+
}
61+
if ((comparisonOps.indexOf(op)) > -1) {
62+
menuHandler.changeOpMenu(evt, comparisonOps);
63+
return;
64+
}
65+
if (menuName == null) {
66+
menuHandler.genericBlockMenu(evt);
67+
return;
68+
}
69+
} else {
70+
menuHandler.customMenu(evt,menuItems);
71+
return;
72+
}
5873
}
5974
if (op.indexOf('.') > -1) {
6075
menuHandler.extensionMenu(evt, menuName);
@@ -160,6 +175,7 @@ public class BlockMenus implements DragClient {
160175
function isGeneric(s:String):Boolean {
161176
return ['duplicate', 'delete', 'add comment'].indexOf(s) > -1;
162177
}
178+
163179
switch (menuName) {
164180
case 'attribute':
165181
return spriteAttributes.indexOf(item) > -1 || stageAttributes.indexOf(item) > -1;
@@ -367,6 +383,7 @@ public class BlockMenus implements DragClient {
367383
if (s is Function) s()
368384
else setBlockArg(s);
369385
}
386+
370387
var m:Menu = new Menu(setSoundArg, 'sound');
371388
if (app.viewedObj() == null) return;
372389
for (var i:int = 0; i < app.viewedObj().sounds.length; i++) {
@@ -400,6 +417,7 @@ public class BlockMenus implements DragClient {
400417
}
401418
Scratch.app.setSaveNeeded();
402419
}
420+
403421
var spriteNames:Array = [];
404422
var m:Menu = new Menu(setSpriteArg, 'sprite');
405423
if (includeMouse) m.addItem('mouse-pointer', 'mouse-pointer');
@@ -431,6 +449,7 @@ public class BlockMenus implements DragClient {
431449
block.type = block.isTerminal ? 'f' : ' ';
432450
Scratch.app.setSaveNeeded();
433451
}
452+
434453
var m:Menu = new Menu(setStopType, 'stop');
435454
if (!block.nextBlock) {
436455
m.addItem('all');
@@ -464,6 +483,7 @@ public class BlockMenus implements DragClient {
464483
if ('video motion' == s) app.libraryPart.showVideoButton();
465484
setBlockArg(s);
466485
}
486+
467487
var m:Menu = new Menu(setTriggerType, 'triggerSensor');
468488
m.addItem('loudness');
469489
m.addItem('timer');
@@ -519,6 +539,7 @@ public class BlockMenus implements DragClient {
519539
if (selection is Function) { selection(); return; }
520540
block.changeOperator(selection);
521541
}
542+
522543
if (!block) return;
523544
var m:Menu = new Menu(opMenu, 'changeOp');
524545
addGenericBlockItems(m);
@@ -647,6 +668,7 @@ public class BlockMenus implements DragClient {
647668
setBlockVarOrListName(newName);
648669
app.updatePalette();
649670
}
671+
650672
var d:DialogBox = new DialogBox(doVarRename);
651673
d.addTitle(Translator.map('Rename') + ' ' + blockVarOrListName());
652674
d.addField('New name', 120);
@@ -664,6 +686,7 @@ public class BlockMenus implements DragClient {
664686
app.updatePalette();
665687
app.setSaveNeeded();
666688
}
689+
667690
DialogBox.confirm(Translator.map('Delete') + ' ' + blockVarOrListName() + '?', app.stage, doDelete);
668691
}
669692

@@ -729,6 +752,7 @@ public class BlockMenus implements DragClient {
729752
if (selection is Function) selection();
730753
else setBlockArg(selection);
731754
}
755+
732756
var msgNames:Array = app.runtime.collectBroadcasts();
733757
if (msgNames.indexOf('message1') <= -1) msgNames.push('message1');
734758
msgNames.sort();
@@ -746,6 +770,7 @@ public class BlockMenus implements DragClient {
746770
if (newName.length == 0) return;
747771
setBlockArg(newName);
748772
}
773+
749774
var d:DialogBox = new DialogBox(changeBroadcast);
750775
d.addTitle('New Message');
751776
d.addField('Message Name', 120);
@@ -763,6 +788,7 @@ public class BlockMenus implements DragClient {
763788
if (selection == 'clear senders/receivers') sprites = [];
764789
app.highlightSprites(sprites);
765790
}
791+
766792
var m:Menu = new Menu(showBroadcasts, 'broadcastInfo');
767793
addGenericBlockItems(m);
768794
if (!isInPalette(block)) {
@@ -773,4 +799,13 @@ public class BlockMenus implements DragClient {
773799
showMenu(m);
774800
}
775801

802+
// ***** Custom menu *****
803+
804+
private function customMenu(evt:MouseEvent,menuItems:Array):void {
805+
var m:Menu = new Menu(setBlockArg);
806+
for each (var s:String in menuItems) {
807+
m.addItem(s);
808+
}
809+
showMenu(m);
810+
}
776811
}}

src/util/ReadStream.as

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,20 @@ public class ReadStream {
8787
if (atEnd()) return '';
8888
var isArg:Boolean;
8989
var start:int = i;
90+
var inBrackets:Boolean = false;
9091
while (i < src.length) {
91-
if (src.charCodeAt(i) <= 32) break;
92+
if (src.charCodeAt(i) <= 32 && !inBrackets) break;
9293
var ch:String = src.charAt(i);
9394
if (ch == '%') {
9495
if (i > start) break; // percent sign starts new token
9596
isArg = true;
9697
}
98+
if (ch == '[') {
99+
inBrackets = true;
100+
}
101+
if (ch == ']') {
102+
inBrackets = false;
103+
}
97104
// certain punctuation marks following an argument start a new token
98105
// example: 'touching %m?' (question mark after arg starts a new token) vs. 'loud?' (doesn't)
99106
if (isArg && ((ch == '?') || (ch == '-'))) break;

0 commit comments

Comments
 (0)