Need help in creating workspace like appinventor

Our backpack code relies on an older version of the Blockly Flyout class. You'll probably need to rework some of the code if you're targeting a newer version of Blockly.

Yes thank you now to add backpack in workspace can u get me the procedure please

What I tried is

1.imported backpack.js & backpackflyout.js & workspaceSVG.js

In main js file I created a workspace
var workspace = Blockly.inject('div', options) ;
Blockly.workspaceSVG.prototype.addbackpack() ;

Getting an error i.e.,

this.options.readOnly is undefined

Blockly.workspaceSVG.prototype.addbackpack()
in this function in the WorkspaceSvg.js library

Can u give me a detailed guide to proceed the Integration please

Yes thank you now to add backpack in workspace can u get me the procedure please

What I tried is

1.imported backpack.js & backpackflyout.js & workspaceSVG.js

In main js file I created a workspace
var workspace = Blockly.inject('div', options) ;
Blockly.workspaceSVG.prototype.addbackpack() ;

Getting an error i.e.,

this.options.readOnly is undefined

Blockly.workspaceSVG.prototype.addbackpack()
in this function in the WorkspaceSvg.js library

Can u give me a detailed guide to proceed the Integration please

I'm not sure there's any more detailed integration than the code that is already there that brings together our code and Blockly's code.

What does your options object look like? The error suggests that you haven't constructed it properly.

1 Like

i made a try and got the output as below

but with few errors like

typeblock.js:712 Uncaught TypeError: Cannot read property 'ArrayMatcher' of undefined
at typeblock.js:712

and in Blockly.ai_inject function in blocklyeditor.js line number:435

if condition is not working because

in workspace i can see the injected as true
but when i try workspace.injected it returns undefined

when i click on show warnings i get this error

Uncaught TypeError: window.parent.BlocklyPanel_callToggleWarning is not a function
at Blockly.WarningIndicator.onclickWarningToggle (warningIndicator.js:262)
at SVGGElement.e (blockly_compressed.js:18623)

And also the backpack flyout is in black colour

so if it is solved then my project is almost completed

Thank you.................

Typeblock makes use of the Google Closure Library's Autocomplete widget (the ArrayMatcher error). Newer versions of Blockly aren't built on the closure library any more, so you'll need to include that separately. There are also a number of functions that glue our Blockly workspace to the rest of the App Inventor UI. You'll need to mock those out and/or remove that functionality (anything beginning with BlocklyPanel_).

1 Like

// Set separators depends on this.multi_ being set correctly

this.setSeparators(opt_separators || goog.ui.ac.InputHandler.STANDARD_LIST_SEPARATORS);

this is undefined here

i have done that u told in the first point but i didnt get u the second point in here

and error is like this

inputhanler.js 138 is "this"
inputhandler.js 139 uis the error

if I try to remove that line other error at this.autocomplete , this is undefined occurs then removed it even, got everything good with no errors but also no workspace found

i have tried to export a block as png using below code

/**

  • Exports the block as a PNG file with the Blockly XML code included as a chunk in the PNG.
  • @param {!Blockly.BlockSvg} block the block to export
    */
    Blockly.exportBlockAsPng = function(block) {
    var xml = document.createElement('xml');
    xml.appendChild(Blockly.Xml.blockToDom(block, true));
    var code = Blockly.Xml.domToText(xml);
    console.log("surya",this);
    svgAsDataUri(block.svgGroup_, block.workspace.getMetrics(), null, function(uri) {
    var img = new Image();
    img.src = uri;
    img.onload = function() {
    var canvas = document.createElement('canvas');
    canvas.width = 2 * img.width;
    canvas.height = 2 * img.height;
    var context = canvas.getContext('2d');
    context.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height);

function download(png) {
png.setCodeChunk(code);
for (var i = 0; i < png.chunks.length; i++) {
var phy = [112, 72, 89, 115];
if (png.chunks[i].type == 'pHYs') {
png.chunks.splice(i, 1, new PNG.Chunk(9, 'pHYs', pHY_data, crc32(phy.concat(pHY_data)))); //replacing existing pHYs chunk
break;
} else if (png.chunks[i].type == 'IDAT') {
png.chunks.splice(i, 0, new PNG.Chunk(9, 'pHYs', pHY_data, crc32(phy.concat(pHY_data)))); // adding new pHYs chunk
break;
}
}
var blob = png.toBlob();
var a = document.createElement('a');
a.download = (block.getChildren().length === 0 ? block.type : 'blocks') + '.png';
a.target = '_self';
a.href = URL.createObjectURL(blob);
document.body.appendChild(a);
a.addEventListener("click", function(e) {
a.parentNode.removeChild(a);
});
a.click();
}

if (canvas.toBlob === undefined) {
var src = canvas.toDataURL('image/png');
var base64img = src.split(',')[1];
var decoded = window.atob(base64img);
var rawLength = decoded.length;
var buffer = new Uint8Array(new ArrayBuffer(rawLength));
for (var i = 0; i < rawLength; i++) {
buffer[i] = decoded.charCodeAt(i);
}
var blob = new Blob([buffer], {'type': 'image/png'});
new PNG().readFromBlob(blob, download);
} else {
canvas.toBlob(function (blob) {
new PNG().readFromBlob(blob, download);
});
}
}
});
};

but got an error at svgAsDataUri is not a function

unable to rectify it need help
thanks in advance

Hai Mr ewpatton thank q for your guide in developing the appinventor workspace it's done now .

But i am making block from block factory as json do i need to make any changes in it to work with show warning and errors because it's not working properly now

With this solution my project will be completed ..

Thank q so much

@ewpatton
could u please help me to how make the code to get variables and procedures and also the warnings&error
.

.
.
PROBLEM1

i made a try like above got the instance but getting wrong error postioning on the block like in the image above
.
.
.
.
.
.
.
.
PROBLEM2

**when i click on the "show Warnings" it gives an error at this funtion **

Blockly.WarningIndicator.prototype.onclickWarningToggle = function() {

Blockly.hideChaff();

window.parent.BlocklyPanel_callToggleWarning();

};

and the error is at line window.parent.BlocklyPanel_callToggleWarning(); Error goes here as parent.BlocklyPanel_callToggleWarning() function not found
.
.
.
.
.
.
.
.
PROBLEM3

when i try for variables all worked fine, but the problem is with "local_declaration_expression" variable and the error is as in below image

also to handle the procedure and the variables on the workspace on drag

i tried a lot to solve this failed can u help me in solving please.........

it will be helpfull if u could make steps to follow in an order please

thank you............

I've already explained previously that any function names starting with BlocklyPanel_ will need to be mocked out. They are provided by the designer side of App Inventor and so you need to provide some naive implementation, even if it does nothing.

As for the other error, you need to grab the code for indented inputs from the App Inventor blockly sources. These are patches on top of Blockly core.

1 Like

@ewpatton

ok first one is clear

but i didnt get u at the second point
can u please tell me how to do that

and i dont understand why the error indication on the block is at wrong postion
where as warning indication is at correct position

i am missing any mandatory file to import if yes could u tell me what are those
thank you.....

Regarding the second item, we have additional modifications to Blockly that exist as part of our own fork of Blockly (https://github.com/mit-cml/blockly). I've written a port of the indented input functionality on a newer version of Blockly last year, which is available as a pull request against the main Blockly repo. You may be able to apply these patches to the latest version of Blockly and rebuild it. Between our current master and Blockly's master, the Blockly team did a significant refactor of the rendering code. The PR I linked should be compatible with the more recent versions.

1 Like

@ewpatton

yes i am done, but when i drag a lexical variable on workspace, this happens

ERROR1:

i found there is no code for this type of blocks as getting undefined in blockly compressed.js, also i need variable like 'var' as javascript
ex:- var example;
not the android studio variables

ERROR2

if i use the local_declaration_expression i am getting above error

ERROR3
most importantly
how to set variables on events like below

this are my unsolved errors

can u mention the error for each solution please and thank you

Regarding error 1, our variable system works different from Blockly's. If you're using our blocks to build a workspace to create JavaScript, you'll need to write generator code for each of the blocks that goes beyond Blockly's built-in blocks.

Regarding error 2, I've already explained that our version of Blockly has input types beyond what Google provides. I pointed you to the pull request that fixes this, and I explained that you would need to build your own version of Blockly with those changes applied if you wanted this to work. I continue to stand by those claims.

Regarding error 3, I have no idea what you mean by this line of inquiry.

1 Like

@ewpatton

i have deleted previous two posts as i made few more tries on all the three errors so to update my trial errors i have done so , i am sorry for the inconvenice...

yes thank you first and second errors solved and

For error3

I mean how to change event block to get those return variables on them I am using block factory to make block in json

component_event (1)

how to place variables like tag & value as on the firebaseDB1 in the above block image......

This is what i tried

   Blockly.Blocks['button'] = {

  init: function() {

    this.jsonInit(

          //here i place the json data

        );

       this.localNames_ = ['value'];

        this.appendDummyInput().appendField(this.parameterFlydown(0), 'VAR0')

    

        this.blockType = 'event'

        this.typeName='Button'

        this.eventName='Click'

        this.instanceName='button1'

  },
 parameterFlydown: function (paramIndex) { // Return a new local variable parameter flydown
var initialParamName = this.localNames_[paramIndex];
var localDecl = this; // Here, "this" is the local decl block. Name it to use in function below
var localWorkspace = this.workspace;
var localParameterChangeHandler = function (newParamName) {
  // This handler has the same subtleties as procedureParameterChangeHandler in language/common/procedures.js,
  // but is somewhat simpler since doesn't have associated callers to change. See the notes there.

  // See Subtleties #1 and #2 in  procedureParameterChangeHandler in language/common/procedures.js
  var newLocals = localDecl.localNames_;
  newLocals[paramIndex] = newParamName;

  // If there's an open mutator, change the name in the corresponding slot.
  if (localDecl.mutator && localDecl.mutator.rootBlock_) {
    // Iterate through mutatorarg param blocks and change name of one at paramIndex
    var mutatorContainer = localDecl.mutator.rootBlock_;
    var mutatorargIndex = 0;
    var mutatorarg = mutatorContainer.getInputTargetBlock('STACK');
    while (mutatorarg && mutatorargIndex < paramIndex) {
      mutatorarg = mutatorarg.nextConnection && mutatorarg.nextConnection.targetBlock();
      mutatorargIndex++;
    }
    if (mutatorarg && mutatorargIndex == paramIndex) {
      // See Subtlety #3 in  procedureParameterChangeHandler in language/common/procedures.js
      Blockly.Field.prototype.setText.call(mutatorarg.getField("NAME"), newParamName);
    }
  }
}
return new Blockly.FieldParameterFlydown(initialParamName,
    true, // name is editable
    Blockly.FieldFlydown.DISPLAY_RIGHT,
    localParameterChangeHandler);

}

then i got the variable named as value on the block, but its function is similar to the local initialize block which is in lexical variable but not as the firebaseDB1 event block above

error2:-
How to make function like when Show Warnings clicked make warning visible & invisible on blocks without blocklypanel_, you told to remove all the code starts with BlocklyPannel_.

i made it but how to make it work as it is from the appinventor workspace...
i tried with this from warning_indicator.js

    Blockly.WarningIndicator.prototype.onclickWarningToggle = function() {
     Blockly.hideChaff();
  Blockly.WarningHandler.prototype.toggleWarning();
 
  
};

then in warning_handler.js

   Blockly.WarningHandler.prototype.checkAllBlocksForWarningsAndErrors = function() {
      // Do not attempt to update blocks before they are rendered.
      console.log(this)

      if (!this.workspace.rendered) {

        return;
      }
      if (Blockly.Instrument.isOn) {
        var start = new Date().getTime();
        var topBlocks = this.workspace.getTopBlocks();
      }
      var allBlocks = this.workspace.getAllBlocks();
      try {

        if (Blockly.Instrument.useLynCacheGlobalNames) {

          // Compute and cache the list of global names once only

          // so that each call to checkDropDownContainsValidValue needn't recalculate this.

          this.cacheGlobalNames = false; // Set to false to actually compute names in next line.

          this.cachedGlobalNames = Blockly.FieldLexicalVariable.getGlobalNames();

          this.cacheGlobalNames = true;

        }

        for(var i=0;i<allBlocks.length;i++) {

          var blockErrorResult = this.checkErrors(allBlocks[i]);

        }

        console.log(this)

      } finally {

        // [lyn, 04/13/14] Ensure that these are reset no matter what:

        this.cacheGlobalNames = false;

        this.cachedGlobalNames = [];

      }

      if (Blockly.Instrument.isOn) {

        var stop = new Date().getTime();

        var timeDiff = stop - start;

        Blockly.Instrument.stats.topBlockCount = topBlocks.length;

        Blockly.Instrument.stats.blockCount = allBlocks.length;

        Blockly.Instrument.stats.checkAllBlocksForWarningsAndErrorsCalls++;

        Blockly.Instrument.stats.checkAllBlocksForWarningsAndErrorsTime += timeDiff;

      }

    };

throws an error at if (!this.workspace.rendered) { called workspace is undefined........

error1

generally when we try duplicating an event block there throws an error icon on both events in appinventor , but in my case it is not happening instantly instead it shows error icons on the block when any of the blocks moved/selected/unselected/when block dragged from flyout

how to update a block with error icon instantly after duplicating and deleting

what i made is

Blockly.Blocks['button'] = {

  init: function() {

    this.jsonInit(

           //here i place the json data

        );

        this.warnings =  [{name:"checkBlockAtRoot"}];

        this.errors =[{name:'determineDuplicateComponentEventHandlers'},{name:'checkIfIAmADuplicateEventHandler'}];

        this.blockType = 'event'

        this.typeName='Button'

        this.eventName='Click'

        this.instanceName='button1'

  }

Thank you,
Hoping a positive response from you...

hello @ewpatton

i am done with all the thing same as the appinventor workspace but small problem is as below

see the warning text popup starts at perfect place but

error text popup is starting at wrong place , am i missing any thing ..

i can't make it please could you help me how to solve it

You may not have laid out the icons in the right positions, so I would check that code first. Another thing might be that because the renderer was reimplemented in newer versions of Blockly we aren't reporting the icon information in the correct way.

1 Like

@ewpatton

Every thing is fine a small problem with workspace visibility
I tried workspace.setVisible(true) then workspace is visible but not showing backpack and warning icon how to make workspace invisible on a button click and make visible on other button click with all icons on the workspace

Once the workspace is shown you'll need to have the backpack compute its position, otherwise on most browsers it will be 0, 0 since its parent isn't visible. Our workspace overrides the Blockly workspace's resize function to position the backpack, so my guess is you are missing this code in your own.

1 Like