Blockly toolbar and canvas customisations

245 views
Skip to first unread message

Adrian Schoenig

unread,
Nov 2, 2023, 9:14:37 AM11/2/23
to Blockly
Hello,

I am integrating Blockly into an iOS / macOS app to essentially provide a powerful way of building database views. This is really a fantastic library, and I love that it let's me add powerful features to my app without requiring my users to learn the underlying custom formula expression language for that.

I am embedding Blockly in a web view with native user interface components around it. I'd like some advice on a few challenges that I'm currently not sure how to tackle best:

1. Hiding the main toolbox:

The toolbox categories are displayed using native components, and when a user clicks on one of those, I then want to show just the available blocks in that category. So this is like the built-in toolbox, but without the categories visible. I achieve this using this method:

          function hideToolboxUI() {

            const toolbox = document.getElementsByClassName('blocklyToolboxDiv')[0];

            if (toolbox) {

              toolbox.style.display = 'none';

            }


            const workspaceBox = document.getElementsByClassName('blocklyWorkspaceBox')[0];

            if (workspaceBox) {

              workspaceBox.style.left = '0';

            }


            const blocklyDiv = document.getElementById('blocklyDiv');

            if (blocklyDiv) {

              const mainWorkspace = Blockly.getMainWorkspace();

              mainWorkspace.resize();

            }

          }


That works fine, until I also tried to disable the "move" option on the canvas by disabling the scrollbar interaction. Then I'm left with an usable whitespace on the left of my canvas, which would usually be occupied by the toolbox. I believe this is due to this transform being added dynamically by Blockly:


<g class="blocklyBlockCanvas" transform="translate(121,0) scale(1)">...</g>


Is there something I can do about this, or is there a better way to hide the toolbox categories from the canvas, while keeping the remainder of the toolbox functional?



2. "End" toolbox position issue


I tried to avoid the above issue by setting the toolboxPosition to "end". However, that completely broke my Blockly interactions. After setting this option, whenever I drag a block from the toolbox onto the canvas, it always goes straight in the bin. Same when I move any existing block. Did I break this option with my "hideToolboxUI()" function above?



3. Padding for the canvas


Is there a way to tell Blockly to maintain a padding of the blocks to the edges of the canvas? I'd basically like the (0, 0) coordinate to be offset by a couple of pixels, so that by default not all blocks bump right into the edge of my web view (and into other user interface elements).



Thank you very much in advance for guidance on any of these.


Adrian

Neil Fraser

unread,
Nov 3, 2023, 2:29:37 PM11/3/23
to blo...@googlegroups.com
1. Toolbox
Does this CSS work for you?
.blocklyBlockCanvas
.blocklyBubbleCanvas {
  transform: translate(0px, 0px) !important;
}

2. "End" toolbox
I think this problem goes away with the above solution?

3. Padding
Blockly's coordinate metrics are black magic.  Let me ask around and find someone who understands it...


--
You received this message because you are subscribed to the Google Groups "Blockly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/blockly/4d497612-1705-4877-9b38-96e66280f47cn%40googlegroups.com.


--
Neil Fraser, Switzerland
https://neil.fraser.name

Beka Westberg

unread,
Nov 9, 2023, 1:08:01 PM11/9/23
to Blockly
Hello!

1 & 2. So I think the issue you're running into with the blank space left by the toolbox is that we didn't previously support having a flyout toolbox that autocloses. Our metrics calculations just didn't account for that, so you would get that blank space when the flyout closed (and other weird behavior). I recently put up a PR that should fix this issue. It will go out with the next release at the beginning of December =)

3. You should be able to use a custom metrics manager to do this!

I created one that overrides `getScrollMetrics` like so:
```
getScrollMetrics(
    opt_getWorkspaceCoordinates?: boolean,
    opt_viewMetrics?: ContainerRegion,
    opt_contentMetrics?: ContainerRegion,
  ): ContainerRegion {
    const scrollMetrics = super(false, opt_viewMetrics, opt_contentMetrics);
    const scale = opt_getWorkspaceCoordinates ? this.workspace_.scale : 1;
    const margin = 20;

    return {
      top: (scrollMetrics.top + margin) / scale,
      left: (scrollMetrics.left + margin) / scale,
      width: (scrollMetrics.width - margin * 2) / scale,
      height: (scrollMetrics.height - margin * 2) / scale,
    };
  }
```

For some reason that's giving me slightly different margins for vertical vs horizontal, but the basic idea should be correct!

I hope that helps! If you have any further questions please reply =)
--Beka

Adrian Schoenig

unread,
Nov 12, 2023, 6:32:57 AM11/12/23
to Blockly
Hi Beka, Neil,

Thank you for the pointers. 2 & 3 are covered!

I still have some issues with always hiding the top-level toolbox (which shows the categories) is also working. I switched to using `workspace.getToolbox().setVisible(false);` and also pulled the last develop branch. The toolbox is hidden but when the toolbox is on the left there's still always that blank space; curiously when it's on the right, then the white space is also there when I programatically show a flyover for a specific category, but when I resize the window that disappears and the flyover snaps to the right.

Any suggestions for that? If it's in that "End" position, is there a particular method that I can call that would also make it snap to the side (as if resizing the window)?

Cheers,
Adrian

Maribeth Moffatt

unread,
Nov 13, 2023, 3:14:15 PM11/13/23
to Blockly
Using a categories toolbox is a slightly different use case than Beka was solving for.

Do you ever intend to show the list of categories to the user? If not, I think what you want to do is use a flyout toolbox instead. You can update the contents of the flyout toolbox to match the new contents you want to show. Hiding that should work better with the changes Beka just made.

Best,
Maribeth
Reply all
Reply to author
Forward
0 new messages