Page 1 of 1

Module: Blockly

Posted: Tue Jun 13, 2017 10:03 pm
by Peter
Hello,

here is a wrapper to use the JavaScript-Library Blockly from Google:

Image

Demo: http://spiderbytes.tuebben.de/demos/Blockly/

Download: http://spiderbytes.tuebben.de/downloads/blockly.zip

More informations: https://developers.google.com/blockly/

Have fun! ... Peter

Re: Module: Blockly

Posted: Wed Jun 14, 2017 11:28 am
by tj1010
Cool! Reminds me of Sketchy or whatever that educational programming thing MIT did years ago.

Re: Module: Blockly

Posted: Wed Jun 14, 2017 12:14 pm
by falsam
Hello Peter.

I am not a fan of code with blocks but congratulations and thank you for sharing. It is a beautiful result and easy to understand.

Re: Module: Blockly

Posted: Mon Nov 23, 2020 1:34 pm
by IdeasVacuum
Hello Peter

There are a number of online IDEs based on Blockly, I am using MIT's App Inventor to create Android Apps - it's very good. I would like to build a program alongside it (separate but smart) that can scrape key names (the names of Blocks) and store them in a sorted list with a record of their location on the canvas. This would be very useful because once your blocks count is above a thousand, it is difficult to navigate. So a dynamic list like Pure Basics' Procedures List would be great.

The browsers can find block names and highlight them, but it's not good enough, especially when the highlight is lost as soon as you scroll, and of course you have to remember the name to look for. Programatically, the find can be based on block type names e.g. find 'Procedure', then collect the User's name for it, e.g. 'MyDataIn'. That I think I can tackle - but how to determine the location on the canvas and scroll the Browser to it on demand?

Re: Module: Blockly

Posted: Mon Nov 23, 2020 4:54 pm
by Peter
@IdeasVacuum: Sorry, but this is too abstract for me. Do you have a sample code or a screenshot that illustrates your concern?

Re: Module: Blockly

Posted: Mon Nov 23, 2020 9:27 pm
by IdeasVacuum
Hi Peter - yup, a bit too wordy, a picture paints a thousand words:

Image

So I am collecting the title text from every main block, and listing them in the same way that PB lists Procedures. What I wish to do is click on a list item and take the User to the corresponding block.

Re: Module: Blockly

Posted: Mon Nov 23, 2020 11:21 pm
by Peter
First you have to go through all blocks to get the IDs of the ParentBlocks (parentBlock_==null). But I think you already know this because you have already determined the list of blocks.

If you have determined the ID of a ParentBlock you can center the complete block in the ViewPort.

That would look something like this:

Code: Select all

XIncludeFile "Blockly.sbi"

Enumeration
  #XmlToolbox
  #XmlWorkspace
  #Dialog
  #Xml
EndEnumeration

Runtime Enumeration
  #Window
  #Blockly
  #Splitter
  #ListView
EndEnumeration

Procedure SizeWindowEvent()
  ResizeGadget(#Splitter, 0, 0, WindowWidth(#Window), WindowHeight(#Window))
EndProcedure

Runtime Procedure OnListViewEvent()
  
  Protected SelectedID.s
  
  SelectedID = GetGadgetText(#ListView)
  
  Protected GID = GadgetID(#Blockly)
  
  ! var selector  = $(v_gid.div).find('.dijitContentPane');
  ! var workspace = selector.data("workspace");
  ! var block = workspace.getBlockById(v_selectedid);
  
  ! // https://github.com/google/blockly/issues/1013#issuecomment-290713644
  ! block.select(); // *block* is the block to scroll into view.
  ! var mWs = Blockly.mainWorkspace;
  ! var xy = block.getRelativeToSurfaceXY(); // Scroll the workspace so that the block's top left corner
  ! var m = mWs.getMetrics(); // is in the (0.2; 0.3) part of the viewport.
  ! mWs.scrollbar.set(	xy.x * mWs.scale - m.contentLeft - m.viewWidth  * 0.2, xy.y * mWs.scale - m.contentTop  - m.viewHeight * 0.3);  
    
EndProcedure

Procedure OnChange()
  
  Protected GID = GadgetID(#Blockly)
  
  ! var selector  = $(v_gid.div).find('.dijitContentPane');
  ! var workspace = selector.data("workspace");
  ! var allBlocks = workspace.getAllBlocks();
  
  Protected ID.s
  ClearGadgetItems(#ListView)
  
  ! for (var blockCounter = 0; blockCounter < allBlocks.length; blockCounter ++) {
  !   if (allBlocks[blockCounter].parentBlock_ == null) {
  !     v_id = allBlocks[blockCounter].id;
  AddGadgetItem(#ListView, -1, ID)
  !   }
  ! }
   
EndProcedure

Procedure Main()
  
  Protected XML.s
  
  XML = "<window id='#Window' name='Window' text='BlocklyDemo' minwidth='1000' minheight='600' flags='#PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget'>" +
        " <splitter id='#Splitter' flags='#PB_Splitter_Vertical'>" +
        "   <container id='#Blockly' />" +
        "   <vbox expand='item:2'>" +
        "     <text text='Block-IDs:' flags='#PB_Text_VerticalCenter' />" +
        "     <listview id='#ListView' onevent='OnListViewEvent()' />" +
        "   </vbox>" + 
        " </splitter>" +
        "</window>"
  
  
  If ParseXML(#Xml, XML) And XMLStatus(#Xml) = #PB_XML_Success
    
    If CreateDialog(#Dialog) And OpenXMLDialog(#Dialog, #Xml, "Window")
      
      ; setting splitter:
      
      SetGadgetState(#Splitter, 600)  
      
      ; setting blockly-container
      
      Blockly::BindGadget(#Blockly, ComposeXML(#XmlToolbox))
      Blockly::TextToWorkspace(#Blockly, ComposeXML(#XmlWorkspace))
      Blockly::Refresh(#Blockly)
      Blockly::ScrollCenter(#Blockly)
      Blockly::BindBlocklyEvent(#Blockly, @OnChange())
      
    Else  
      Debug "Dialog error: " + DialogError(#Dialog)
    EndIf
    
  Else
    Debug "XML error: " + XMLError(#Xml) + " (Line: " + XMLErrorLine(#Xml) + ")"
  EndIf
  
EndProcedure

Procedure Loading(Type, Filename.s, ObjectId)
  
  Static nbOfXml
  
  Select Type
      
    Case #PB_Loading_Xml
      
      nbOfXml + 1
      
      If nbOfXml = 2
        Blockly::Init(@Main())
      EndIf
      
  EndSelect
  
EndProcedure

Procedure LoadingError(Type, Filename.s)
  Debug "LoadingError: " + Filename
EndProcedure


BindEvent(#PB_Event_Loading, @Loading())
BindEvent(#PB_Event_LoadingError, @LoadingError())

LoadXML(#XmlToolbox,   "./resources/toolboxes/toolbox.xml")
LoadXML(#XmlWorkspace, "./resources/workspaces/workspace.xml")
(Place more ParentBlocks into the viewport and click on the listitems on the right to center them)

Re: Module: Blockly

Posted: Tue Nov 24, 2020 2:59 am
by IdeasVacuum
Phew - that's a fast and comprehensive response, thank you Peter. I was wondering if it could not be done with blockly API, I could do it via the DOM and find each elements scroll position, but a blockly approach is preferable. Thanks again!